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

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 (172) 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 +28 -3
  3. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/read-parts.mjs +2 -2
  4. package/esm2022/libs/api/repository/src/lib/gn4/elasticsearch/constant.mjs +2 -1
  5. package/esm2022/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.mjs +3 -3
  6. package/esm2022/libs/api/repository/src/lib/gn4/gn4-repository.mjs +28 -5
  7. package/esm2022/libs/common/domain/src/lib/model/record/metadata.model.mjs +1 -1
  8. package/esm2022/libs/common/domain/src/lib/repository/records-repository.interface.mjs +1 -1
  9. package/esm2022/libs/feature/dataviz/src/lib/service/data.service.mjs +32 -2
  10. package/esm2022/libs/feature/record/src/index.mjs +2 -3
  11. package/esm2022/libs/feature/record/src/lib/map-view/map-view.component.mjs +31 -5
  12. package/esm2022/libs/feature/record/src/lib/state/mdview.actions.mjs +3 -1
  13. package/esm2022/libs/feature/record/src/lib/state/mdview.effects.mjs +7 -1
  14. package/esm2022/libs/feature/record/src/lib/state/mdview.facade.mjs +13 -13
  15. package/esm2022/libs/feature/record/src/lib/state/mdview.reducer.mjs +7 -1
  16. package/esm2022/libs/feature/record/src/lib/state/mdview.selectors.mjs +3 -1
  17. package/esm2022/libs/feature/search/src/lib/constants.mjs +2 -1
  18. package/esm2022/libs/feature/search/src/lib/results-list/results-list.container.component.mjs +6 -2
  19. package/esm2022/libs/ui/elements/src/index.mjs +3 -1
  20. package/esm2022/libs/ui/elements/src/lib/geo-data-badge/geo-data-badge.component.mjs +55 -0
  21. package/esm2022/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.mjs +27 -53
  22. package/esm2022/libs/ui/elements/src/lib/kind-badge/kind-badge.component.mjs +22 -5
  23. package/esm2022/libs/ui/elements/src/lib/metadata-contact/metadata-contact.component.mjs +3 -3
  24. package/esm2022/libs/ui/elements/src/lib/metadata-info/metadata-info.component.mjs +3 -3
  25. package/esm2022/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.mjs +3 -3
  26. package/esm2022/libs/ui/elements/src/lib/record-feature-catalog/feature-catalog-list/feature-catalog-list.component.mjs +51 -0
  27. package/esm2022/libs/ui/elements/src/lib/related-record-card/related-record-card.component.mjs +17 -7
  28. package/esm2022/libs/ui/elements/src/lib/service-capabilities/service-capabilities.component.mjs +12 -4
  29. package/esm2022/libs/ui/elements/src/lib/ui-elements.module.mjs +10 -4
  30. package/esm2022/libs/ui/inputs/src/index.mjs +2 -1
  31. package/esm2022/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.mjs +3 -3
  32. package/esm2022/libs/ui/inputs/src/lib/search-feature-catalog/search-feature-catalog.component.mjs +68 -0
  33. package/esm2022/libs/ui/inputs/src/lib/star-toggle/star-toggle.component.mjs +3 -3
  34. package/esm2022/libs/ui/layout/src/lib/expandable-panel/expandable-panel.component.mjs +34 -13
  35. package/esm2022/libs/ui/layout/src/lib/truncated-text/truncated-text.component.mjs +65 -14
  36. package/esm2022/libs/ui/search/src/lib/record-preview-row/record-preview-row.component.mjs +4 -8
  37. package/esm2022/libs/ui/search/src/lib/results-hits-search-kind/results-hits-search-kind.component.mjs +3 -3
  38. package/esm2022/libs/ui/search/src/lib/results-list/results-layout.config.mjs +2 -2
  39. package/esm2022/libs/ui/search/src/lib/results-list/results-list.component.mjs +3 -3
  40. package/esm2022/libs/util/shared/src/lib/links/link-classifier.service.mjs +4 -1
  41. package/esm2022/libs/util/shared/src/lib/links/link-utils.mjs +4 -1
  42. package/esm2022/translations/de.json +6 -2
  43. package/esm2022/translations/en.json +7 -5
  44. package/esm2022/translations/es.json +6 -2
  45. package/esm2022/translations/fr.json +6 -4
  46. package/esm2022/translations/it.json +38 -34
  47. package/esm2022/translations/nl.json +6 -2
  48. package/esm2022/translations/pt.json +6 -2
  49. package/fesm2022/geonetwork-ui.mjs +959 -569
  50. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  51. package/libs/api/metadata-converter/src/lib/common/distribution.mapper.d.ts.map +1 -1
  52. package/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.d.ts.map +1 -1
  53. package/libs/api/metadata-converter/src/lib/iso19139/read-parts.d.ts.map +1 -1
  54. package/libs/api/repository/src/lib/gn4/elasticsearch/constant.d.ts.map +1 -1
  55. package/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.d.ts +1 -1
  56. package/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.d.ts.map +1 -1
  57. package/libs/api/repository/src/lib/gn4/gn4-repository.d.ts +3 -0
  58. package/libs/api/repository/src/lib/gn4/gn4-repository.d.ts.map +1 -1
  59. package/libs/common/domain/src/lib/model/record/metadata.model.d.ts +2 -1
  60. package/libs/common/domain/src/lib/model/record/metadata.model.d.ts.map +1 -1
  61. package/libs/common/domain/src/lib/repository/records-repository.interface.d.ts +2 -0
  62. package/libs/common/domain/src/lib/repository/records-repository.interface.d.ts.map +1 -1
  63. package/libs/feature/dataviz/src/lib/service/data.service.d.ts +1 -0
  64. package/libs/feature/dataviz/src/lib/service/data.service.d.ts.map +1 -1
  65. package/libs/feature/record/src/index.d.ts +1 -2
  66. package/libs/feature/record/src/index.d.ts.map +1 -1
  67. package/libs/feature/record/src/lib/map-view/map-view.component.d.ts.map +1 -1
  68. package/libs/feature/record/src/lib/state/mdview.actions.d.ts +10 -0
  69. package/libs/feature/record/src/lib/state/mdview.actions.d.ts.map +1 -1
  70. package/libs/feature/record/src/lib/state/mdview.effects.d.ts +6 -0
  71. package/libs/feature/record/src/lib/state/mdview.effects.d.ts.map +1 -1
  72. package/libs/feature/record/src/lib/state/mdview.facade.d.ts +28 -21
  73. package/libs/feature/record/src/lib/state/mdview.facade.d.ts.map +1 -1
  74. package/libs/feature/record/src/lib/state/mdview.reducer.d.ts +2 -0
  75. package/libs/feature/record/src/lib/state/mdview.reducer.d.ts.map +1 -1
  76. package/libs/feature/record/src/lib/state/mdview.selectors.d.ts +2 -0
  77. package/libs/feature/record/src/lib/state/mdview.selectors.d.ts.map +1 -1
  78. package/libs/feature/search/src/lib/constants.d.ts.map +1 -1
  79. package/libs/feature/search/src/lib/results-list/results-list.container.component.d.ts +1 -1
  80. package/libs/feature/search/src/lib/results-list/results-list.container.component.d.ts.map +1 -1
  81. package/libs/ui/elements/src/index.d.ts +2 -0
  82. package/libs/ui/elements/src/index.d.ts.map +1 -1
  83. package/libs/ui/elements/src/lib/geo-data-badge/geo-data-badge.component.d.ts +15 -0
  84. package/libs/ui/elements/src/lib/geo-data-badge/geo-data-badge.component.d.ts.map +1 -0
  85. package/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.d.ts +3 -7
  86. package/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.d.ts.map +1 -1
  87. package/libs/ui/elements/src/lib/kind-badge/kind-badge.component.d.ts +3 -1
  88. package/libs/ui/elements/src/lib/kind-badge/kind-badge.component.d.ts.map +1 -1
  89. package/libs/ui/elements/src/lib/record-feature-catalog/feature-catalog-list/feature-catalog-list.component.d.ts +16 -0
  90. package/libs/ui/elements/src/lib/record-feature-catalog/feature-catalog-list/feature-catalog-list.component.d.ts.map +1 -0
  91. package/libs/ui/elements/src/lib/related-record-card/related-record-card.component.d.ts +8 -1
  92. package/libs/ui/elements/src/lib/related-record-card/related-record-card.component.d.ts.map +1 -1
  93. package/libs/ui/elements/src/lib/service-capabilities/service-capabilities.component.d.ts +1 -0
  94. package/libs/ui/elements/src/lib/service-capabilities/service-capabilities.component.d.ts.map +1 -1
  95. package/libs/ui/elements/src/lib/ui-elements.module.d.ts +2 -1
  96. package/libs/ui/elements/src/lib/ui-elements.module.d.ts.map +1 -1
  97. package/libs/ui/inputs/src/index.d.ts +1 -0
  98. package/libs/ui/inputs/src/index.d.ts.map +1 -1
  99. package/libs/ui/inputs/src/lib/search-feature-catalog/search-feature-catalog.component.d.ts +17 -0
  100. package/libs/ui/inputs/src/lib/search-feature-catalog/search-feature-catalog.component.d.ts.map +1 -0
  101. package/libs/ui/layout/src/lib/expandable-panel/expandable-panel.component.d.ts +15 -8
  102. package/libs/ui/layout/src/lib/expandable-panel/expandable-panel.component.d.ts.map +1 -1
  103. package/libs/ui/layout/src/lib/truncated-text/truncated-text.component.d.ts +15 -6
  104. package/libs/ui/layout/src/lib/truncated-text/truncated-text.component.d.ts.map +1 -1
  105. package/libs/ui/search/src/lib/results-list/results-list.component.d.ts.map +1 -1
  106. package/libs/util/shared/src/lib/links/link-classifier.service.d.ts.map +1 -1
  107. package/libs/util/shared/src/lib/links/link-utils.d.ts.map +1 -1
  108. package/package.json +1 -1
  109. package/src/libs/api/metadata-converter/src/lib/common/distribution.mapper.ts +1 -0
  110. package/src/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts +44 -3
  111. package/src/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts +2 -1
  112. package/src/libs/api/repository/src/lib/gn4/elasticsearch/constant.ts +1 -0
  113. package/src/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.ts +2 -2
  114. package/src/libs/api/repository/src/lib/gn4/gn4-repository.ts +49 -5
  115. package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +8 -1
  116. package/src/libs/common/domain/src/lib/repository/records-repository.interface.ts +2 -0
  117. package/src/libs/common/fixtures/src/lib/elasticsearch/metadata-links.fixtures.ts +10 -0
  118. package/src/libs/common/fixtures/src/lib/link.fixtures.ts +14 -0
  119. package/src/libs/common/fixtures/src/lib/records.fixtures.ts +1 -1
  120. package/src/libs/feature/dataviz/src/lib/service/data.service.ts +37 -0
  121. package/src/libs/feature/record/src/index.ts +1 -2
  122. package/src/libs/feature/record/src/lib/map-view/map-view.component.ts +35 -4
  123. package/src/libs/feature/record/src/lib/state/mdview.actions.ts +10 -0
  124. package/src/libs/feature/record/src/lib/state/mdview.effects.ts +22 -0
  125. package/src/libs/feature/record/src/lib/state/mdview.facade.ts +22 -15
  126. package/src/libs/feature/record/src/lib/state/mdview.reducer.ts +12 -0
  127. package/src/libs/feature/record/src/lib/state/mdview.selectors.ts +9 -0
  128. package/src/libs/feature/search/src/lib/constants.ts +1 -0
  129. package/src/libs/feature/search/src/lib/results-list/results-list.container.component.ts +2 -0
  130. package/src/libs/ui/elements/src/index.ts +2 -0
  131. package/src/libs/ui/elements/src/lib/geo-data-badge/geo-data-badge.component.css +4 -0
  132. package/src/libs/ui/elements/src/lib/geo-data-badge/geo-data-badge.component.html +13 -0
  133. package/src/libs/ui/elements/src/lib/geo-data-badge/geo-data-badge.component.ts +54 -0
  134. package/src/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.html +133 -138
  135. package/src/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.ts +19 -47
  136. package/src/libs/ui/elements/src/lib/kind-badge/kind-badge.component.html +7 -5
  137. package/src/libs/ui/elements/src/lib/kind-badge/kind-badge.component.ts +21 -2
  138. package/src/libs/ui/elements/src/lib/metadata-contact/metadata-contact.component.html +6 -3
  139. package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.html +4 -0
  140. package/src/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.html +1 -1
  141. package/src/libs/ui/elements/src/lib/record-feature-catalog/feature-catalog-list/feature-catalog-list.component.html +48 -0
  142. package/src/libs/ui/elements/src/lib/record-feature-catalog/feature-catalog-list/feature-catalog-list.component.ts +52 -0
  143. package/src/libs/ui/elements/src/lib/related-record-card/related-record-card.component.html +8 -29
  144. package/src/libs/ui/elements/src/lib/related-record-card/related-record-card.component.ts +14 -1
  145. package/src/libs/ui/elements/src/lib/service-capabilities/service-capabilities.component.html +15 -1
  146. package/src/libs/ui/elements/src/lib/service-capabilities/service-capabilities.component.ts +9 -1
  147. package/src/libs/ui/elements/src/lib/ui-elements.module.ts +3 -1
  148. package/src/libs/ui/inputs/src/index.ts +1 -0
  149. package/src/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.html +1 -1
  150. package/src/libs/ui/inputs/src/lib/search-feature-catalog/search-feature-catalog.component.css +0 -0
  151. package/src/libs/ui/inputs/src/lib/search-feature-catalog/search-feature-catalog.component.html +43 -0
  152. package/src/libs/ui/inputs/src/lib/search-feature-catalog/search-feature-catalog.component.ts +77 -0
  153. package/src/libs/ui/inputs/src/lib/star-toggle/star-toggle.component.html +1 -2
  154. package/src/libs/ui/layout/src/lib/expandable-panel/expandable-panel.component.html +24 -8
  155. package/src/libs/ui/layout/src/lib/expandable-panel/expandable-panel.component.ts +36 -10
  156. package/src/libs/ui/layout/src/lib/truncated-text/truncated-text.component.html +8 -10
  157. package/src/libs/ui/layout/src/lib/truncated-text/truncated-text.component.ts +75 -7
  158. package/src/libs/ui/search/src/lib/record-preview-row/record-preview-row.component.html +9 -81
  159. package/src/libs/ui/search/src/lib/results-hits-search-kind/results-hits-search-kind.component.html +1 -0
  160. package/src/libs/ui/search/src/lib/results-list/results-layout.config.ts +2 -2
  161. package/src/libs/ui/search/src/lib/results-list/results-list.component.html +1 -0
  162. package/src/libs/ui/search/src/lib/results-list/results-list.component.ts +0 -1
  163. package/src/libs/util/shared/src/lib/links/link-classifier.service.ts +3 -0
  164. package/src/libs/util/shared/src/lib/links/link-utils.ts +3 -0
  165. package/translations/de.json +6 -2
  166. package/translations/en.json +7 -5
  167. package/translations/es.json +6 -2
  168. package/translations/fr.json +6 -4
  169. package/translations/it.json +38 -34
  170. package/translations/nl.json +6 -2
  171. package/translations/pt.json +6 -2
  172. package/translations/sk.json +6 -2
@@ -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
  }
@@ -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
  }
@@ -1,82 +1,10 @@
1
- <a
2
- class="group container-lg mx-auto flex cursor-pointer flex-wrap sm:flex-nowrap"
3
- [title]="record.title"
4
- [attr.href]="linkHref"
1
+ <gn-ui-internal-link-card
2
+ [linkHref]="linkHref"
3
+ [linkTarget]="linkTarget"
4
+ [record]="record"
5
+ [favoriteTemplate]="favoriteTemplate"
6
+ [metadataQualityDisplay]="metadataQualityDisplay"
7
+ (mdSelect)="mdSelect.emit($event)"
8
+ size="L"
5
9
  >
6
- <div class="shrink-0 w-full sm:w-52">
7
- <div
8
- class="overflow-hidden bg-gray-100 rounded-lg w-full border border-gray-300 h-36"
9
- >
10
- <gn-ui-thumbnail
11
- class="relative h-full w-full object-cover object-left-top"
12
- [thumbnailUrl]="[
13
- record.overviews?.[0]?.url?.toString(),
14
- organization?.logoUrl?.toString(),
15
- ]"
16
- [fit]="['cover', 'contain']"
17
- ></gn-ui-thumbnail>
18
- </div>
19
- </div>
20
- <div
21
- class="content grid grow relative sm:pl-6 sm:pr-12"
22
- style="grid-template-columns: auto 70px"
23
- >
24
- <div class="mb-3 mt-5 sm:mt-2">
25
- <div
26
- class="font-title text-21 text-title line-clamp-2 col-start-1 col-span-2 sm:line-clamp-1 group-hover:text-primary transition-colors"
27
- data-cy="recordTitle"
28
- >
29
- {{ record.title }}
30
- </div>
31
- </div>
32
- <div
33
- class="abstract mt-4 mb-5 h-36 line-clamp-6 col-start-1 col-span-2 row-start-3 sm:mb-2 sm:h-[4.5rem] sm:line-clamp-3 sm:row-start-2 sm:mt-0"
34
- data-cy="recordAbstract"
35
- >
36
- <gn-ui-markdown-parser
37
- [textContent]="abstract"
38
- whitoutStyles="true"
39
- ></gn-ui-markdown-parser>
40
- </div>
41
- <div
42
- class="text-primary opacity-45 uppercase col-start-1 col-span-2 row-start-2 sm:truncate sm:row-start-3 sm:col-span-1"
43
- data-cy="recordOrg"
44
- [class]="metadataQualityDisplay ? 'limit-organisation-with-quality' : ''"
45
- >
46
- {{ organization?.name }}
47
- </div>
48
- <div
49
- class="icons flex flex-row col-start-1 row-start-4 sm:col-start-2 sm:row-start-3 sm:absolute sm:right-[0.4em]"
50
- >
51
- <ng-icon
52
- *ngIf="isDownloadable"
53
- class="text-primary opacity-45 mx-1"
54
- name="matCloudDownloadOutline"
55
- ></ng-icon>
56
- <ng-icon
57
- *ngIf="isViewable"
58
- class="text-primary opacity-45 mx-1"
59
- name="matMapOutline"
60
- ></ng-icon>
61
- </div>
62
- <div
63
- *ngIf="metadataQualityDisplay"
64
- class="col-start-2 row-start-4 sm:row-start-3 absolute right-[4em] sm:right-[5em]"
65
- >
66
- <gn-ui-metadata-quality
67
- [smaller]="true"
68
- [metadata]="record"
69
- [metadataQualityDisplay]="metadataQualityDisplay"
70
- ></gn-ui-metadata-quality>
71
- </div>
72
- <div
73
- class="text-right col-start-3 row-start-4 sm:absolute sm:col-start-2 sm:row-start-1 sm:top-[-1.125em] sm:right-[0.4em]"
74
- data-cy="recordFav"
75
- >
76
- <ng-container
77
- [ngTemplateOutlet]="favoriteTemplate"
78
- [ngTemplateOutletContext]="{ $implicit: record }"
79
- ></ng-container>
80
- </div>
81
- </div>
82
- </a>
10
+ </gn-ui-internal-link-card>
@@ -5,6 +5,7 @@
5
5
  >
6
6
  <ng-template let-choice>
7
7
  <gn-ui-kind-badge
8
+ [styling]="'custom'"
8
9
  [kind]="choice.value"
9
10
  [contentTemplate]="customTemplate"
10
11
  class="gn-ui-btn-outline rounded-md py-2 px-2 border-gray-400 cursor-pointer focus-within:text-primary-darkest focus-within:bg-gray-50 transition-colors bg-transparent hover:text-primary-darker focus:text-primary-darker active:text-primary-black"
@@ -32,9 +32,9 @@ export const DEFAULT_RESULTS_LAYOUT_CONFIG: ResultsLayoutConfigModel = {
32
32
  ),
33
33
  ROW: new ResultsLayoutConfigItem(
34
34
  RecordPreviewRowComponent,
35
- 'pt-4 pb-5 sm:py-7',
35
+ 'py-2',
36
36
  '',
37
- 'grid grid-cols-1 divide-y divide-gray-300'
37
+ 'grid grid-cols-1 divide-y divide-gray-100'
38
38
  ),
39
39
  FEED: new ResultsLayoutConfigItem(
40
40
  RecordPreviewFeedComponent,
@@ -6,6 +6,7 @@
6
6
  *ngFor="let record of records"
7
7
  >
8
8
  <gn-ui-results-list-item
9
+ [attr.data-cy]="record.uniqueIdentifier"
9
10
  [record]="record"
10
11
  [layoutConfig]="layoutConfig"
11
12
  [metadataQualityDisplay]="metadataQualityDisplay"
@@ -3,7 +3,6 @@ import {
3
3
  Component,
4
4
  EventEmitter,
5
5
  Input,
6
- OnInit,
7
6
  Output,
8
7
  TemplateRef,
9
8
  } from '@angular/core'
@@ -31,7 +31,10 @@ export class LinkClassifierService {
31
31
  return [LinkUsage.API, LinkUsage.DOWNLOAD, LinkUsage.GEODATA]
32
32
  case 'wms':
33
33
  case 'wmts':
34
+ case 'tms':
34
35
  return [LinkUsage.API, LinkUsage.MAP_API]
36
+ case 'maplibre-style':
37
+ return [LinkUsage.GEODATA]
35
38
  case 'ogcFeatures':
36
39
  return [LinkUsage.API, LinkUsage.DOWNLOAD, LinkUsage.GEODATA]
37
40
  case 'GPFDL':
@@ -247,6 +247,9 @@ export function getLinkLabel(
247
247
  case 'wmts':
248
248
  format = 'WMTS'
249
249
  break
250
+ case 'tms':
251
+ format = 'TMS'
252
+ break
250
253
  case 'esriRest':
251
254
  format = 'REST'
252
255
  break
@@ -361,8 +361,9 @@
361
361
  "record.action.view": "Anzeigen",
362
362
  "record.card.metadata.contact": "",
363
363
  "record.externalViewer.open": "In externem Kartenviewer öffnen",
364
+ "record.feature.catalog.number.total.attribute": "",
365
+ "record.feature.catalog.number.total.object": "",
364
366
  "record.feature.limit": "Die Vorschau wurde aufgrund zu vieler Elemente deaktiviert",
365
- "record.kind.data": "",
366
367
  "record.kind.dataset": "",
367
368
  "record.kind.reuse": "",
368
369
  "record.kind.service": "",
@@ -405,6 +406,7 @@
405
406
  "record.metadata.creation": "Erstellungsdatum",
406
407
  "record.metadata.details": "Über die Daten",
407
408
  "record.metadata.download": "Downloads",
409
+ "record.metadata.feature.catalog": "",
408
410
  "record.metadata.formats": "Formate",
409
411
  "record.metadata.keywords": "Stichworte",
410
412
  "record.metadata.languages": "Sprachen",
@@ -448,7 +450,7 @@
448
450
  "record.metadata.temporalExtent.untilDate": "Bis {end}",
449
451
  "record.metadata.title": "Titel",
450
452
  "record.metadata.topics": "Kategorien",
451
- "record.metadata.type": "Geographischer Datensatz",
453
+ "record.metadata.isGeographical": "Geographischer Datensatz",
452
454
  "record.metadata.uniqueId": "Eindeutige Kennung",
453
455
  "record.metadata.updateFrequency": "Aktualisierungsfrequenz der Daten",
454
456
  "record.metadata.updatedOn": "Geändert am",
@@ -488,6 +490,7 @@
488
490
  "search.error.recordNotFound": "Der Datensatz mit der Kennung \"{ id }\" konnte nicht gefunden werden.",
489
491
  "search.field.any.placeholder": "Suche im katalog ...",
490
492
  "search.field.sortBy": "Sortieren nach:",
493
+ "search.filter.into.feature.catalog": "",
491
494
  "search.filters.availableServices.download": "",
492
495
  "search.filters.availableServices.view": "",
493
496
  "search.filters.changeDate": "Letzte Aktualisierung",
@@ -551,6 +554,7 @@
551
554
  "service.metadata.other": "",
552
555
  "service.metadata.question": "",
553
556
  "service.metadata.search": "",
557
+ "service.metadata.search.clear": "",
554
558
  "service.metadata.spatialExtent": "",
555
559
  "share.tab.permalink": "Teilen",
556
560
  "share.tab.webComponent": "Integrieren",
@@ -361,8 +361,9 @@
361
361
  "record.action.view": "View",
362
362
  "record.card.metadata.contact": "Metadata Contact",
363
363
  "record.externalViewer.open": "Open in the external map viewer",
364
+ "record.feature.catalog.number.total.attribute": "Total amount of objects",
365
+ "record.feature.catalog.number.total.object": "Total amount of attributes",
364
366
  "record.feature.limit": "Preview disabled due to too many elements",
365
- "record.kind.data": "Data",
366
367
  "record.kind.dataset": "Dataset",
367
368
  "record.kind.reuse": "Reuse",
368
369
  "record.kind.service": "Service",
@@ -405,6 +406,7 @@
405
406
  "record.metadata.creation": "Date of creation",
406
407
  "record.metadata.details": "About the data",
407
408
  "record.metadata.download": "Downloads",
409
+ "record.metadata.feature.catalog": "Feature catalog",
408
410
  "record.metadata.formats": "Formats",
409
411
  "record.metadata.keywords": "Keywords",
410
412
  "record.metadata.languages": "Languages",
@@ -435,7 +437,7 @@
435
437
  "record.metadata.quality.topic.success": "Topic is specified",
436
438
  "record.metadata.quality.updateFrequency.failed": "Update frequency is not specified",
437
439
  "record.metadata.quality.updateFrequency.success": "Update frequency is specified",
438
- "record.metadata.related": "Related datasets",
440
+ "record.metadata.related": "Related records",
439
441
  "record.metadata.related.contents": "Related content",
440
442
  "record.metadata.ressources.and.links": "Resources and links",
441
443
  "record.metadata.sheet": "Original metadata",
@@ -448,7 +450,7 @@
448
450
  "record.metadata.temporalExtent.untilDate": "Until { end }",
449
451
  "record.metadata.title": "Title",
450
452
  "record.metadata.topics": "Categories",
451
- "record.metadata.type": "Geographical dataset",
453
+ "record.metadata.isGeographical": "Geographical dataset",
452
454
  "record.metadata.uniqueId": "Unique Identifier",
453
455
  "record.metadata.updateFrequency": "Data Update Frequency",
454
456
  "record.metadata.updatedOn": "Updated on",
@@ -488,6 +490,7 @@
488
490
  "search.error.recordNotFound": "The dataset with identifier \"{ id }\" could not be found.",
489
491
  "search.field.any.placeholder": "Search in the catalog ...",
490
492
  "search.field.sortBy": "Sort by:",
493
+ "search.filter.into.feature.catalog": "Search a term",
491
494
  "search.filters.availableServices.download": "",
492
495
  "search.filters.availableServices.view": "",
493
496
  "search.filters.changeDate": "Updated",
@@ -551,6 +554,7 @@
551
554
  "service.metadata.other": "Other information",
552
555
  "service.metadata.question": "Ask a question",
553
556
  "service.metadata.search": "Search through the layer list",
557
+ "service.metadata.search.clear": "Clear the layer search",
554
558
  "service.metadata.spatialExtent": "Spatial extent",
555
559
  "share.tab.permalink": "Share",
556
560
  "share.tab.webComponent": "Integrate",
@@ -569,8 +573,6 @@
569
573
  "tooltip.url.open": "Open URL",
570
574
  "ui.readLess": "Read less",
571
575
  "ui.readMore": "Read more",
572
- "ui.hideFullText": "Hide complete text",
573
- "ui.showAllText": "Show all text",
574
576
  "wfs.feature.limit": "Too many features to display the WFS layer!",
575
577
  "wfs.featuretype.notfound": "No matching feature type was found in the service",
576
578
  "wfs.geojsongml.notsupported": "This service does not support the GeoJSON or GML format",
@@ -361,8 +361,9 @@
361
361
  "record.action.view": "",
362
362
  "record.card.metadata.contact": "",
363
363
  "record.externalViewer.open": "",
364
+ "record.feature.catalog.number.total.attribute": "",
365
+ "record.feature.catalog.number.total.object": "",
364
366
  "record.feature.limit": "",
365
- "record.kind.data": "",
366
367
  "record.kind.dataset": "",
367
368
  "record.kind.reuse": "",
368
369
  "record.kind.service": "",
@@ -405,6 +406,7 @@
405
406
  "record.metadata.creation": "",
406
407
  "record.metadata.details": "",
407
408
  "record.metadata.download": "",
409
+ "record.metadata.feature.catalog": "",
408
410
  "record.metadata.formats": "",
409
411
  "record.metadata.keywords": "",
410
412
  "record.metadata.languages": "",
@@ -448,7 +450,7 @@
448
450
  "record.metadata.temporalExtent.untilDate": "",
449
451
  "record.metadata.title": "",
450
452
  "record.metadata.topics": "",
451
- "record.metadata.type": "",
453
+ "record.metadata.isGeographical": "",
452
454
  "record.metadata.uniqueId": "",
453
455
  "record.metadata.updateFrequency": "",
454
456
  "record.metadata.updatedOn": "",
@@ -488,6 +490,7 @@
488
490
  "search.error.recordNotFound": "",
489
491
  "search.field.any.placeholder": "",
490
492
  "search.field.sortBy": "",
493
+ "search.filter.into.feature.catalog": "",
491
494
  "search.filters.availableServices.download": "",
492
495
  "search.filters.availableServices.view": "",
493
496
  "search.filters.changeDate": "Última actualización",
@@ -551,6 +554,7 @@
551
554
  "service.metadata.other": "",
552
555
  "service.metadata.question": "",
553
556
  "service.metadata.search": "",
557
+ "service.metadata.search.clear": "",
554
558
  "service.metadata.spatialExtent": "",
555
559
  "share.tab.permalink": "",
556
560
  "share.tab.webComponent": "",