geonetwork-ui 2.4.2 → 2.4.4-dev.9094d472a

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 (188) hide show
  1. package/esm2022/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.mjs +31 -16
  2. package/esm2022/libs/api/repository/src/lib/gn4/gn4-repository.mjs +2 -2
  3. package/esm2022/libs/feature/dataviz/src/lib/chart-view/chart-view.component.mjs +7 -4
  4. package/esm2022/libs/feature/dataviz/src/lib/geo-table-view/geo-table-view.component.mjs +18 -16
  5. package/esm2022/libs/feature/dataviz/src/lib/service/data.service.mjs +24 -14
  6. package/esm2022/libs/feature/dataviz/src/lib/table-view/table-view.component.mjs +16 -18
  7. package/esm2022/libs/feature/editor/src/lib/components/wizard-summarize/wizard-summarize.component.mjs +11 -11
  8. package/esm2022/libs/feature/record/src/lib/data-view/data-view.component.mjs +4 -3
  9. package/esm2022/libs/feature/record/src/lib/feature-record.module.mjs +6 -7
  10. package/esm2022/libs/feature/record/src/lib/map-view/map-view.component.mjs +3 -2
  11. package/esm2022/libs/feature/record/src/lib/state/mdview.facade.mjs +8 -1
  12. package/esm2022/libs/feature/search/src/lib/utils/service/fields.mjs +46 -1
  13. package/esm2022/libs/feature/search/src/lib/utils/service/fields.service.mjs +3 -2
  14. package/esm2022/libs/ui/dataviz/src/index.mjs +3 -3
  15. package/esm2022/libs/ui/dataviz/src/lib/data-table/custom.mat.paginator.intl.mjs +51 -0
  16. package/esm2022/libs/ui/dataviz/src/lib/data-table/data-table.component.mjs +133 -0
  17. package/esm2022/libs/ui/dataviz/src/lib/data-table/data-table.data.source.mjs +24 -0
  18. package/esm2022/libs/ui/dataviz/src/lib/data-table/data-table.fixtures.mjs +82 -0
  19. package/esm2022/libs/ui/elements/src/index.mjs +2 -1
  20. package/esm2022/libs/ui/elements/src/lib/application-banner/application-banner.component.mjs +78 -0
  21. package/esm2022/libs/ui/elements/src/lib/markdown-parser/markdown-parser.component.mjs +3 -3
  22. package/esm2022/libs/ui/elements/src/lib/metadata-info/metadata-info.component.mjs +18 -10
  23. package/esm2022/libs/ui/elements/src/lib/record-api-form/record-api-form.component.mjs +2 -1
  24. package/esm2022/libs/ui/elements/src/lib/ui-elements.module.mjs +10 -4
  25. package/esm2022/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.mjs +7 -2
  26. package/esm2022/libs/ui/search/src/lib/results-table/results-table.component.mjs +14 -12
  27. package/esm2022/libs/util/data-fetcher/src/index.mjs +3 -1
  28. package/esm2022/libs/util/data-fetcher/src/lib/data-fetcher.mjs +5 -4
  29. package/esm2022/libs/util/data-fetcher/src/lib/model.mjs +7 -3
  30. package/esm2022/libs/util/data-fetcher/src/lib/readers/base-cache.mjs +12 -0
  31. package/esm2022/libs/util/data-fetcher/src/lib/readers/base-file.mjs +3 -3
  32. package/esm2022/libs/util/data-fetcher/src/lib/readers/base.mjs +1 -1
  33. package/esm2022/libs/util/data-fetcher/src/lib/readers/csv.mjs +2 -2
  34. package/esm2022/libs/util/data-fetcher/src/lib/readers/excel.mjs +2 -2
  35. package/esm2022/libs/util/data-fetcher/src/lib/readers/geojson.mjs +2 -2
  36. package/esm2022/libs/util/data-fetcher/src/lib/readers/gml.mjs +5 -3
  37. package/esm2022/libs/util/data-fetcher/src/lib/readers/json.mjs +2 -2
  38. package/esm2022/libs/util/data-fetcher/src/lib/readers/wfs.mjs +35 -9
  39. package/esm2022/libs/util/data-fetcher/src/lib/utils.mjs +14 -10
  40. package/esm2022/libs/util/shared/src/lib/services/date.service.mjs +41 -0
  41. package/esm2022/libs/util/shared/src/lib/services/index.mjs +2 -1
  42. package/esm2022/libs/util/shared/src/lib/utils/temporal-extent-union.mjs +4 -4
  43. package/esm2022/translations/de.json +6 -0
  44. package/esm2022/translations/en.json +6 -0
  45. package/esm2022/translations/es.json +6 -0
  46. package/esm2022/translations/fr.json +6 -0
  47. package/esm2022/translations/it.json +7 -0
  48. package/esm2022/translations/nl.json +6 -0
  49. package/esm2022/translations/pt.json +6 -0
  50. package/fesm2022/geonetwork-ui.mjs +957 -485
  51. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  52. package/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.d.ts +2 -1
  53. package/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.d.ts.map +1 -1
  54. package/libs/api/repository/src/lib/gn4/gn4-repository.d.ts.map +1 -1
  55. package/libs/feature/dataviz/src/lib/chart-view/chart-view.component.d.ts +2 -1
  56. package/libs/feature/dataviz/src/lib/chart-view/chart-view.component.d.ts.map +1 -1
  57. package/libs/feature/dataviz/src/lib/geo-table-view/geo-table-view.component.d.ts +7 -9
  58. package/libs/feature/dataviz/src/lib/geo-table-view/geo-table-view.component.d.ts.map +1 -1
  59. package/libs/feature/dataviz/src/lib/service/data.service.d.ts +2 -2
  60. package/libs/feature/dataviz/src/lib/service/data.service.d.ts.map +1 -1
  61. package/libs/feature/dataviz/src/lib/table-view/table-view.component.d.ts +5 -7
  62. package/libs/feature/dataviz/src/lib/table-view/table-view.component.d.ts.map +1 -1
  63. package/libs/feature/editor/src/lib/components/wizard-summarize/wizard-summarize.component.d.ts +3 -3
  64. package/libs/feature/editor/src/lib/components/wizard-summarize/wizard-summarize.component.d.ts.map +1 -1
  65. package/libs/feature/record/src/lib/data-view/data-view.component.d.ts +1 -0
  66. package/libs/feature/record/src/lib/data-view/data-view.component.d.ts.map +1 -1
  67. package/libs/feature/record/src/lib/feature-record.module.d.ts +2 -2
  68. package/libs/feature/record/src/lib/feature-record.module.d.ts.map +1 -1
  69. package/libs/feature/record/src/lib/map-view/map-view.component.d.ts.map +1 -1
  70. package/libs/feature/record/src/lib/state/mdview.facade.d.ts +1 -0
  71. package/libs/feature/record/src/lib/state/mdview.facade.d.ts.map +1 -1
  72. package/libs/feature/search/src/lib/utils/service/fields.d.ts +10 -0
  73. package/libs/feature/search/src/lib/utils/service/fields.d.ts.map +1 -1
  74. package/libs/feature/search/src/lib/utils/service/fields.service.d.ts.map +1 -1
  75. package/libs/ui/dataviz/src/index.d.ts +2 -2
  76. package/libs/ui/dataviz/src/index.d.ts.map +1 -1
  77. package/libs/ui/dataviz/src/lib/data-table/custom.mat.paginator.intl.d.ts +14 -0
  78. package/libs/ui/dataviz/src/lib/data-table/custom.mat.paginator.intl.d.ts.map +1 -0
  79. package/libs/ui/dataviz/src/lib/data-table/data-table.component.d.ts +45 -0
  80. package/libs/ui/dataviz/src/lib/data-table/data-table.component.d.ts.map +1 -0
  81. package/libs/ui/dataviz/src/lib/data-table/data-table.data.source.d.ts +12 -0
  82. package/libs/ui/dataviz/src/lib/data-table/data-table.data.source.d.ts.map +1 -0
  83. package/libs/ui/dataviz/src/lib/data-table/data-table.fixtures.d.ts +10 -0
  84. package/libs/ui/dataviz/src/lib/data-table/data-table.fixtures.d.ts.map +1 -0
  85. package/libs/ui/elements/src/index.d.ts +1 -0
  86. package/libs/ui/elements/src/index.d.ts.map +1 -1
  87. package/libs/ui/elements/src/lib/application-banner/application-banner.component.d.ts +16 -0
  88. package/libs/ui/elements/src/lib/application-banner/application-banner.component.d.ts.map +1 -0
  89. package/libs/ui/elements/src/lib/metadata-info/metadata-info.component.d.ts +5 -0
  90. package/libs/ui/elements/src/lib/metadata-info/metadata-info.component.d.ts.map +1 -1
  91. package/libs/ui/elements/src/lib/record-api-form/record-api-form.component.d.ts.map +1 -1
  92. package/libs/ui/elements/src/lib/ui-elements.module.d.ts +2 -1
  93. package/libs/ui/elements/src/lib/ui-elements.module.d.ts.map +1 -1
  94. package/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.d.ts.map +1 -1
  95. package/libs/ui/search/src/lib/results-table/results-table.component.d.ts +3 -2
  96. package/libs/ui/search/src/lib/results-table/results-table.component.d.ts.map +1 -1
  97. package/libs/util/data-fetcher/src/index.d.ts +3 -1
  98. package/libs/util/data-fetcher/src/index.d.ts.map +1 -1
  99. package/libs/util/data-fetcher/src/lib/data-fetcher.d.ts +2 -2
  100. package/libs/util/data-fetcher/src/lib/data-fetcher.d.ts.map +1 -1
  101. package/libs/util/data-fetcher/src/lib/model.d.ts +1 -1
  102. package/libs/util/data-fetcher/src/lib/model.d.ts.map +1 -1
  103. package/libs/util/data-fetcher/src/lib/readers/base-cache.d.ts +8 -0
  104. package/libs/util/data-fetcher/src/lib/readers/base-cache.d.ts.map +1 -0
  105. package/libs/util/data-fetcher/src/lib/readers/base-file.d.ts +2 -2
  106. package/libs/util/data-fetcher/src/lib/readers/base-file.d.ts.map +1 -1
  107. package/libs/util/data-fetcher/src/lib/readers/base.d.ts +2 -2
  108. package/libs/util/data-fetcher/src/lib/readers/base.d.ts.map +1 -1
  109. package/libs/util/data-fetcher/src/lib/readers/gml.d.ts +5 -3
  110. package/libs/util/data-fetcher/src/lib/readers/gml.d.ts.map +1 -1
  111. package/libs/util/data-fetcher/src/lib/readers/wfs.d.ts +7 -4
  112. package/libs/util/data-fetcher/src/lib/readers/wfs.d.ts.map +1 -1
  113. package/libs/util/data-fetcher/src/lib/utils.d.ts +2 -2
  114. package/libs/util/data-fetcher/src/lib/utils.d.ts.map +1 -1
  115. package/libs/util/shared/src/lib/services/date.service.d.ts +13 -0
  116. package/libs/util/shared/src/lib/services/date.service.d.ts.map +1 -0
  117. package/libs/util/shared/src/lib/services/index.d.ts +1 -0
  118. package/libs/util/shared/src/lib/services/index.d.ts.map +1 -1
  119. package/libs/util/shared/src/lib/utils/temporal-extent-union.d.ts +2 -1
  120. package/libs/util/shared/src/lib/utils/temporal-extent-union.d.ts.map +1 -1
  121. package/package.json +1 -1
  122. package/src/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.ts +33 -16
  123. package/src/libs/api/repository/src/lib/gn4/gn4-repository.ts +1 -5
  124. package/src/libs/feature/dataviz/src/lib/chart-view/chart-view.component.ts +4 -1
  125. package/src/libs/feature/dataviz/src/lib/geo-table-view/geo-table-view.component.html +3 -3
  126. package/src/libs/feature/dataviz/src/lib/geo-table-view/geo-table-view.component.ts +17 -15
  127. package/src/libs/feature/dataviz/src/lib/service/data.service.ts +43 -20
  128. package/src/libs/feature/dataviz/src/lib/table-view/table-view.component.html +4 -3
  129. package/src/libs/feature/dataviz/src/lib/table-view/table-view.component.ts +10 -18
  130. package/src/libs/feature/editor/src/lib/components/wizard-summarize/wizard-summarize.component.ts +3 -4
  131. package/src/libs/feature/record/src/lib/data-view/data-view.component.html +3 -1
  132. package/src/libs/feature/record/src/lib/data-view/data-view.component.ts +3 -0
  133. package/src/libs/feature/record/src/lib/feature-record.module.ts +6 -4
  134. package/src/libs/feature/record/src/lib/map-view/map-view.component.ts +2 -1
  135. package/src/libs/feature/record/src/lib/state/mdview.facade.ts +13 -0
  136. package/src/libs/feature/search/src/lib/utils/service/fields.service.ts +2 -0
  137. package/src/libs/feature/search/src/lib/utils/service/fields.ts +55 -0
  138. package/src/libs/ui/dataviz/src/index.ts +2 -2
  139. package/src/libs/ui/dataviz/src/lib/data-table/custom.mat.paginator.intl.ts +52 -0
  140. package/src/libs/ui/dataviz/src/lib/{table/table.component.css → data-table/data-table.component.css} +4 -0
  141. package/src/libs/ui/dataviz/src/lib/data-table/data-table.component.html +67 -0
  142. package/src/libs/ui/dataviz/src/lib/data-table/data-table.component.ts +173 -0
  143. package/src/libs/ui/dataviz/src/lib/data-table/data-table.data.source.ts +33 -0
  144. package/src/libs/ui/dataviz/src/lib/data-table/data-table.fixtures.ts +84 -0
  145. package/src/libs/ui/elements/src/index.ts +1 -0
  146. package/src/libs/ui/elements/src/lib/application-banner/application-banner.component.css +0 -0
  147. package/src/libs/ui/elements/src/lib/application-banner/application-banner.component.html +25 -0
  148. package/src/libs/ui/elements/src/lib/application-banner/application-banner.component.ts +70 -0
  149. package/src/libs/ui/elements/src/lib/markdown-parser/markdown-parser.component.ts +2 -2
  150. package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.html +3 -3
  151. package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.ts +12 -2
  152. package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.ts +2 -0
  153. package/src/libs/ui/elements/src/lib/ui-elements.module.ts +3 -0
  154. package/src/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.ts +6 -0
  155. package/src/libs/ui/search/src/lib/results-table/results-table.component.ts +4 -2
  156. package/src/libs/util/data-fetcher/src/index.ts +3 -0
  157. package/src/libs/util/data-fetcher/src/lib/data-fetcher.ts +13 -4
  158. package/src/libs/util/data-fetcher/src/lib/model.ts +6 -2
  159. package/src/libs/util/data-fetcher/src/lib/readers/base-cache.ts +14 -0
  160. package/src/libs/util/data-fetcher/src/lib/readers/base-file.ts +2 -1
  161. package/src/libs/util/data-fetcher/src/lib/readers/base.ts +2 -2
  162. package/src/libs/util/data-fetcher/src/lib/readers/csv.ts +1 -1
  163. package/src/libs/util/data-fetcher/src/lib/readers/excel.ts +1 -1
  164. package/src/libs/util/data-fetcher/src/lib/readers/geojson.ts +1 -1
  165. package/src/libs/util/data-fetcher/src/lib/readers/gml.ts +7 -7
  166. package/src/libs/util/data-fetcher/src/lib/readers/json.ts +1 -1
  167. package/src/libs/util/data-fetcher/src/lib/readers/wfs.ts +53 -8
  168. package/src/libs/util/data-fetcher/src/lib/utils.ts +38 -32
  169. package/src/libs/util/shared/src/lib/services/date.service.ts +45 -0
  170. package/src/libs/util/shared/src/lib/services/index.ts +1 -0
  171. package/src/libs/util/shared/src/lib/utils/temporal-extent-union.ts +6 -3
  172. package/translations/de.json +6 -0
  173. package/translations/en.json +6 -0
  174. package/translations/es.json +6 -0
  175. package/translations/fr.json +6 -0
  176. package/translations/it.json +7 -0
  177. package/translations/nl.json +6 -0
  178. package/translations/pt.json +6 -0
  179. package/translations/sk.json +6 -0
  180. package/esm2022/libs/ui/dataviz/src/lib/table/table.component.mjs +0 -61
  181. package/esm2022/libs/ui/dataviz/src/lib/table/table.fixtures.mjs +0 -40
  182. package/libs/ui/dataviz/src/lib/table/table.component.d.ts +0 -29
  183. package/libs/ui/dataviz/src/lib/table/table.component.d.ts.map +0 -1
  184. package/libs/ui/dataviz/src/lib/table/table.fixtures.d.ts +0 -11
  185. package/libs/ui/dataviz/src/lib/table/table.fixtures.d.ts.map +0 -1
  186. package/src/libs/ui/dataviz/src/lib/table/table.component.html +0 -40
  187. package/src/libs/ui/dataviz/src/lib/table/table.component.ts +0 -80
  188. package/src/libs/ui/dataviz/src/lib/table/table.fixtures.ts +0 -40
@@ -0,0 +1,173 @@
1
+ import { ScrollingModule } from '@angular/cdk/scrolling'
2
+ import {
3
+ AfterViewInit,
4
+ ChangeDetectionStrategy,
5
+ ChangeDetectorRef,
6
+ Component,
7
+ ElementRef,
8
+ EventEmitter,
9
+ Input,
10
+ OnChanges,
11
+ OnInit,
12
+ Output,
13
+ ViewChild,
14
+ } from '@angular/core'
15
+ import { MatSort, MatSortModule } from '@angular/material/sort'
16
+ import { MatTableModule } from '@angular/material/table'
17
+ import { TranslateModule, TranslateService } from '@ngx-translate/core'
18
+ import { DataTableDataSource } from './data-table.data.source'
19
+ import { BaseReader, FetchError } from '../../../../../../libs/util/data-fetcher/src'
20
+ import {
21
+ MatPaginator,
22
+ MatPaginatorIntl,
23
+ MatPaginatorModule,
24
+ } from '@angular/material/paginator'
25
+ import { CustomMatPaginatorIntl } from './custom.mat.paginator.intl'
26
+ import { CommonModule } from '@angular/common'
27
+ import { BehaviorSubject, filter, firstValueFrom } from 'rxjs'
28
+ import {
29
+ LoadingMaskComponent,
30
+ PopupAlertComponent,
31
+ } from '../../../../../../libs/ui/widgets/src'
32
+ import { LetDirective } from '@ngrx/component'
33
+
34
+ const rowIdPrefix = 'table-item-'
35
+
36
+ export type TableItemId = string | number
37
+ type TableItemType = string | number | Date
38
+
39
+ export interface TableItemModel {
40
+ id: TableItemId
41
+ [key: string]: TableItemType
42
+ }
43
+
44
+ @Component({
45
+ standalone: true,
46
+ imports: [
47
+ MatTableModule,
48
+ MatSortModule,
49
+ MatPaginatorModule,
50
+ ScrollingModule,
51
+ TranslateModule,
52
+ CommonModule,
53
+ LoadingMaskComponent,
54
+ PopupAlertComponent,
55
+ LetDirective,
56
+ ],
57
+ providers: [{ provide: MatPaginatorIntl, useClass: CustomMatPaginatorIntl }],
58
+ selector: 'gn-ui-data-table',
59
+ templateUrl: './data-table.component.html',
60
+ styleUrls: ['./data-table.component.css'],
61
+ changeDetection: ChangeDetectionStrategy.OnPush,
62
+ })
63
+ export class DataTableComponent implements OnInit, AfterViewInit, OnChanges {
64
+ @Input() set dataset(value: BaseReader) {
65
+ this.properties$.next(null)
66
+ this.dataset_ = value
67
+ this.dataset_.load()
68
+ this.dataset_.properties.then((properties) =>
69
+ this.properties$.next(properties.map((p) => p.name))
70
+ )
71
+ this.dataset_.info.then((info) => (this.count = info.itemsCount))
72
+ }
73
+ @Input() activeId: TableItemId
74
+ @Output() selected = new EventEmitter<any>()
75
+
76
+ @ViewChild(MatSort) sort: MatSort
77
+ @ViewChild(MatPaginator) paginator: MatPaginator
78
+
79
+ dataset_: BaseReader
80
+ properties$ = new BehaviorSubject<string[]>(null)
81
+ dataSource: DataTableDataSource
82
+ headerHeight: number
83
+ count: number
84
+ loading$ = new BehaviorSubject<boolean>(false)
85
+ error = null
86
+
87
+ constructor(
88
+ private eltRef: ElementRef,
89
+ private cdr: ChangeDetectorRef,
90
+ private translateService: TranslateService
91
+ ) {}
92
+
93
+ ngOnInit() {
94
+ this.dataSource = new DataTableDataSource()
95
+ }
96
+
97
+ ngAfterViewInit() {
98
+ this.headerHeight =
99
+ this.eltRef.nativeElement.querySelector('thead').offsetHeight
100
+ this.setPagination()
101
+ this.cdr.detectChanges()
102
+ }
103
+
104
+ ngOnChanges() {
105
+ this.setPagination()
106
+ }
107
+
108
+ setSort(sort: MatSort) {
109
+ if (!this.dataset_) return
110
+ if (!sort.active) {
111
+ this.dataset_.orderBy()
112
+ } else {
113
+ this.dataset_.orderBy([sort.direction || 'asc', sort.active])
114
+ }
115
+ this.readData()
116
+ }
117
+
118
+ setPagination() {
119
+ if (!this.paginator) return
120
+ if (!this.dataset_) return
121
+ this.dataset_.limit(
122
+ this.paginator.pageIndex * this.paginator.pageSize,
123
+ this.paginator.pageSize
124
+ )
125
+ this.readData()
126
+ }
127
+
128
+ async readData() {
129
+ this.loading$.next(true)
130
+ // wait for properties to be read
131
+ const properties = await firstValueFrom(
132
+ this.properties$.pipe(filter((p) => !!p))
133
+ )
134
+ const propsWithoutGeom = properties.filter(
135
+ (p) => !p.toLowerCase().startsWith('geom')
136
+ )
137
+ this.dataset_.select(...propsWithoutGeom)
138
+ try {
139
+ await this.dataSource.showData(this.dataset_.read())
140
+ this.error = null
141
+ } catch (error) {
142
+ this.handleError(error as FetchError | Error)
143
+ }
144
+ this.loading$.next(false)
145
+ }
146
+
147
+ scrollToItem(itemId: TableItemId): void {
148
+ const row = this.eltRef.nativeElement.querySelector(
149
+ `#${this.getRowEltId(itemId)}`
150
+ )
151
+ this.eltRef.nativeElement.scrollTop = row.offsetTop - this.headerHeight
152
+ }
153
+
154
+ public getRowEltId(id: TableItemId): string {
155
+ return rowIdPrefix + id
156
+ }
157
+
158
+ handleError(error: FetchError | Error) {
159
+ this.dataSource.clearData()
160
+ if (error instanceof FetchError) {
161
+ this.error = this.translateService.instant(
162
+ `dataset.error.${error.type}`,
163
+ {
164
+ info: error.info,
165
+ }
166
+ )
167
+ console.warn(error.message)
168
+ } else {
169
+ this.error = this.translateService.instant(error.message)
170
+ console.warn(error.stack || error)
171
+ }
172
+ }
173
+ }
@@ -0,0 +1,33 @@
1
+ import { DataSource } from '@angular/cdk/collections'
2
+ import { BehaviorSubject, Observable } from 'rxjs'
3
+ import { DataItem } from '../../../../../../libs/util/data-fetcher/src'
4
+ import { map } from 'rxjs/operators'
5
+ import { TableItemModel } from './data-table.component'
6
+
7
+ export class DataTableDataSource implements DataSource<TableItemModel> {
8
+ private dataItems$ = new BehaviorSubject<DataItem[]>([])
9
+
10
+ connect(): Observable<TableItemModel[]> {
11
+ return this.dataItems$.asObservable().pipe(
12
+ map((items) =>
13
+ items.map((item) => ({
14
+ id: item.id,
15
+ ...item.properties,
16
+ }))
17
+ )
18
+ )
19
+ }
20
+
21
+ disconnect(): void {
22
+ this.dataItems$.complete()
23
+ }
24
+
25
+ async showData(itemsPromise: Promise<DataItem[]>) {
26
+ const items = await itemsPromise
27
+ this.dataItems$.next(items)
28
+ }
29
+
30
+ clearData() {
31
+ this.dataItems$.next([])
32
+ }
33
+ }
@@ -0,0 +1,84 @@
1
+ import { DataItem, PropertyInfo } from '../../../../../../libs/util/data-fetcher/src'
2
+
3
+ export const tableItemsFixture = {
4
+ items: [
5
+ {
6
+ type: 'Feature',
7
+ geometry: null,
8
+ properties: {
9
+ id: '0001',
10
+ firstName: 'John',
11
+ lastName: 'Lennon',
12
+ },
13
+ },
14
+ {
15
+ type: 'Feature',
16
+ geometry: null,
17
+ properties: {
18
+ id: '0002',
19
+ firstName: 'Ozzy',
20
+ lastName: 'Osbourne',
21
+ },
22
+ },
23
+ {
24
+ type: 'Feature',
25
+ geometry: null,
26
+ properties: {
27
+ id: '0003',
28
+ firstName: 'Claude',
29
+ lastName: 'François',
30
+ },
31
+ },
32
+ ] as DataItem[],
33
+ properties: [
34
+ { name: 'id', label: 'id', type: 'string' },
35
+ { name: 'firstName', label: 'Firstname', type: 'string' },
36
+ { name: 'lastName', label: 'Lastname', type: 'string' },
37
+ ] as PropertyInfo[],
38
+ }
39
+
40
+ export const someHabTableItemFixture = {
41
+ items: [
42
+ {
43
+ type: 'Feature',
44
+ geometry: null,
45
+ properties: {
46
+ id: '1',
47
+ name: 'France',
48
+ pop: 50500000,
49
+ },
50
+ },
51
+ {
52
+ type: 'Feature',
53
+ geometry: null,
54
+ properties: {
55
+ id: '2',
56
+ name: 'Italy',
57
+ pop: 155878789655,
58
+ },
59
+ },
60
+ {
61
+ type: 'Feature',
62
+ geometry: null,
63
+ properties: {
64
+ id: '3',
65
+ name: 'UK',
66
+ pop: 31522456,
67
+ },
68
+ },
69
+ {
70
+ type: 'Feature',
71
+ geometry: null,
72
+ properties: {
73
+ id: '4',
74
+ name: 'US',
75
+ pop: 3215448888,
76
+ },
77
+ },
78
+ ] as DataItem[],
79
+ properties: [
80
+ { name: 'id', label: 'ID', type: 'string' },
81
+ { name: 'name', label: 'Name', type: 'string' },
82
+ { name: 'pop', label: 'Population', type: 'number' },
83
+ ] as PropertyInfo[],
84
+ }
@@ -22,3 +22,4 @@ export * from './lib/thumbnail/thumbnail.component'
22
22
  export * from './lib/ui-elements.module'
23
23
  export * from './lib/user-feedback-item/user-feedback-item.component'
24
24
  export * from './lib/user-preview/user-preview.component'
25
+ export * from './lib/application-banner/application-banner.component'
@@ -0,0 +1,25 @@
1
+ <div
2
+ *ngIf="message && bannerOpen"
3
+ class="absolute top-0 text-wrap bg-white mt-4 max-h-24"
4
+ >
5
+ <div
6
+ class="flex flex-row py-2.5 px-5 gap-5 justify-start border max-h-20"
7
+ [ngClass]="classList"
8
+ >
9
+ <div [ngClass]="{ 'pt-5': message.length > 200 }">
10
+ <ng-icon [name]="icon"></ng-icon>
11
+ </div>
12
+ <div class="flex flex-col justify-start gap-2.5">
13
+ <span *ngIf="title" class="font-bold">{{ title }}</span>
14
+ <span class="font-medium max-w-2xl" [innerHTML]="message"></span>
15
+ </div>
16
+ <button
17
+ *ngIf="closeEnabled"
18
+ class="self-start"
19
+ type="button"
20
+ (click)="closeMessage()"
21
+ >
22
+ <ng-icon name="matCloseOutline"> </ng-icon>
23
+ </button>
24
+ </div>
25
+ </div>
@@ -0,0 +1,70 @@
1
+ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
2
+ import { CommonModule } from '@angular/common'
3
+ import {
4
+ NgIconComponent,
5
+ provideIcons,
6
+ provideNgIconsConfig,
7
+ } from '@ng-icons/core'
8
+ import {
9
+ matCloseOutline,
10
+ matInfoOutline,
11
+ matWarningAmberOutline,
12
+ } from '@ng-icons/material-icons/outline'
13
+ import { matWarning } from '@ng-icons/material-icons/baseline'
14
+
15
+ @Component({
16
+ selector: 'gn-ui-application-banner',
17
+ standalone: true,
18
+ imports: [CommonModule, NgIconComponent],
19
+ changeDetection: ChangeDetectionStrategy.OnPush,
20
+ templateUrl: './application-banner.component.html',
21
+ styleUrl: './application-banner.component.css',
22
+ providers: [
23
+ provideIcons({
24
+ matWarningAmberOutline,
25
+ matInfoOutline,
26
+ matCloseOutline,
27
+ matWarning,
28
+ }),
29
+ provideNgIconsConfig({ size: '1.5em' }),
30
+ ],
31
+ })
32
+ export class ApplicationBannerComponent {
33
+ @Input() message: string
34
+ @Input() title: string
35
+ @Input() closeEnabled = false
36
+ @Input() extraClass = ''
37
+ @Input() icon = ''
38
+ msgClass = ''
39
+ bannerOpen = true
40
+
41
+ @Input() set type(value: 'primary' | 'secondary' | 'light') {
42
+ switch (value) {
43
+ case 'primary':
44
+ this.msgClass = 'bg-primary-darkest border-primary text-white'
45
+ this.icon = 'matWarning'
46
+ break
47
+ case 'light':
48
+ this.msgClass =
49
+ 'bg-primary-opacity-10 border-primary-lightest text-black'
50
+ this.icon = 'matInfoOutline'
51
+ break
52
+ case 'secondary':
53
+ default:
54
+ this.msgClass = 'bg-primary-opacity-50 border-primary-darker text-black'
55
+ this.icon = 'matWarningAmberOutline'
56
+ break
57
+ }
58
+ }
59
+
60
+ get classList() {
61
+ if (this.message.length > 200) {
62
+ return `${this.msgClass} ${this.extraClass} overflow-y-scroll items-start`
63
+ }
64
+ return `${this.msgClass} ${this.extraClass} items-center`
65
+ }
66
+
67
+ closeMessage() {
68
+ this.bannerOpen = false
69
+ }
70
+ }
@@ -1,4 +1,4 @@
1
- import { Component, Input, ChangeDetectionStrategy } from '@angular/core'
1
+ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
2
2
  import { marked } from 'marked'
3
3
 
4
4
  @Component({
@@ -13,6 +13,6 @@ export class MarkdownParserComponent {
13
13
  @Input() whitoutStyles?: boolean
14
14
 
15
15
  get parsedMarkdown() {
16
- return marked.parse(this.textContent)
16
+ return marked.parse(this.textContent ?? '')
17
17
  }
18
18
  }
@@ -163,13 +163,13 @@
163
163
  <div *ngIf="metadata.resourceCreated">
164
164
  <p class="text-sm" translate>record.metadata.creation</p>
165
165
  <p class="text-primary font-medium mt-1">
166
- {{ metadata.resourceCreated.toLocaleDateString() }}
166
+ {{ formatDate(metadata.resourceCreated) }}
167
167
  </p>
168
168
  </div>
169
169
  <div *ngIf="metadata.resourcePublished">
170
170
  <p class="text-sm" translate>record.metadata.publication</p>
171
171
  <p class="text-primary font-medium mt-1">
172
- {{ metadata.resourcePublished.toLocaleDateString() }}
172
+ {{ formatDate(metadata.resourcePublished) }}
173
173
  </p>
174
174
  </div>
175
175
  <div *ngIf="updateFrequency">
@@ -233,7 +233,7 @@
233
233
  <div *ngIf="metadata.recordUpdated">
234
234
  <p class="text-sm" translate>record.metadata.updatedOn</p>
235
235
  <p class="text-primary font-medium">
236
- {{ metadata.recordUpdated && metadata.recordUpdated.toLocaleString() }}
236
+ {{ metadata.recordUpdated && formatDateTime(metadata.recordUpdated) }}
237
237
  </p>
238
238
  </div>
239
239
  <div *ngIf="metadata.landingPage">
@@ -9,7 +9,7 @@ import {
9
9
  DatasetRecord,
10
10
  Keyword,
11
11
  } from '../../../../../../libs/common/domain/src/lib/model/record'
12
- import { getTemporalRangeUnion } from '../../../../../../libs/util/shared/src'
12
+ import { DateService, getTemporalRangeUnion } from '../../../../../../libs/util/shared/src'
13
13
  import { MarkdownParserComponent } from '../markdown-parser/markdown-parser.component'
14
14
  import {
15
15
  ExpandablePanelComponent,
@@ -60,6 +60,8 @@ export class MetadataInfoComponent {
60
60
  @Output() keyword = new EventEmitter<Keyword>()
61
61
  updatedTimes: number
62
62
 
63
+ constructor(private dateService: DateService) {}
64
+
63
65
  get hasUsage() {
64
66
  return (
65
67
  this.metadata.extras?.isOpenData === true ||
@@ -121,7 +123,7 @@ export class MetadataInfoComponent {
121
123
 
122
124
  get temporalExtent(): { start: string; end: string } {
123
125
  const temporalExtents = this.metadata.temporalExtents
124
- return getTemporalRangeUnion(temporalExtents)
126
+ return getTemporalRangeUnion(temporalExtents, this.dateService)
125
127
  }
126
128
 
127
129
  get shownOrganization() {
@@ -139,4 +141,12 @@ export class MetadataInfoComponent {
139
141
  onKeywordClick(keyword: Keyword) {
140
142
  this.keyword.emit(keyword)
141
143
  }
144
+
145
+ formatDate(date: Date): string {
146
+ return this.dateService.formatDate(date)
147
+ }
148
+
149
+ formatDateTime(date: Date): string {
150
+ return this.dateService.formatDateTime(date)
151
+ }
142
152
  }
@@ -161,6 +161,8 @@ export class RecordApiFormComponent {
161
161
  maxFeatures: limit !== '-1' ? Number(limit) : undefined,
162
162
  limit: limit !== '-1' ? Number(limit) : -1,
163
163
  offset: offset !== '' ? Number(offset) : undefined,
164
+ outputCrs:
165
+ format === ('application/json' || 'geojson') ? 'EPSG:4326' : undefined,
164
166
  }
165
167
 
166
168
  if (this.endpoint instanceof WfsEndpoint) {
@@ -19,6 +19,7 @@ import { MarkdownParserComponent } from './markdown-parser/markdown-parser.compo
19
19
  import { ThumbnailComponent } from './thumbnail/thumbnail.component'
20
20
  import { TimeSincePipe } from './user-feedback-item/time-since.pipe'
21
21
  import { UserPreviewComponent } from './user-preview/user-preview.component'
22
+ import { ApplicationBannerComponent } from './application-banner/application-banner.component'
22
23
 
23
24
  @NgModule({
24
25
  imports: [
@@ -40,6 +41,7 @@ import { UserPreviewComponent } from './user-preview/user-preview.component'
40
41
  MaxLinesComponent,
41
42
  TextInputComponent,
42
43
  ImageInputComponent,
44
+ ApplicationBannerComponent,
43
45
  ],
44
46
  providers: [
45
47
  provideNgIconsConfig({
@@ -53,6 +55,7 @@ import { UserPreviewComponent } from './user-preview/user-preview.component'
53
55
  UserPreviewComponent,
54
56
  MarkdownParserComponent,
55
57
  ImageInputComponent,
58
+ ApplicationBannerComponent,
56
59
  ],
57
60
  })
58
61
  export class UiElementsModule {}
@@ -147,6 +147,12 @@ export class AutocompleteComponent
147
147
  this.error = null
148
148
  }),
149
149
  switchMap((value) => this.action(value)),
150
+ tap((suggestions) => {
151
+ // forcing the panel to open if there are suggestions
152
+ if (suggestions.length > 0) {
153
+ this.triggerRef?.openPanel()
154
+ }
155
+ }),
150
156
  catchError((error: Error) => {
151
157
  this.error = error.message
152
158
  return of([])
@@ -21,6 +21,7 @@ import {
21
21
  InteractiveTableComponent,
22
22
  } from '../../../../../../libs/ui/layout/src'
23
23
  import {
24
+ DateService,
24
25
  FileFormat,
25
26
  formatUserInfo,
26
27
  getBadgeColor,
@@ -86,7 +87,8 @@ export class ResultsTableComponent {
86
87
  constructor(
87
88
  private overlay: Overlay,
88
89
  private viewContainerRef: ViewContainerRef,
89
- private cdr: ChangeDetectorRef
90
+ private cdr: ChangeDetectorRef,
91
+ private dateService: DateService
90
92
  ) {}
91
93
 
92
94
  openActionMenu(item, template) {
@@ -139,7 +141,7 @@ export class ResultsTableComponent {
139
141
  }
140
142
 
141
143
  dateToString(date: Date): string {
142
- return date?.toLocaleDateString(undefined, {
144
+ return this.dateService.formatDate(date, {
143
145
  year: 'numeric',
144
146
  month: 'long',
145
147
  day: 'numeric',
@@ -5,6 +5,9 @@ export {
5
5
  DataItem,
6
6
  FetchError,
7
7
  FieldAggregation,
8
+ PropertyInfo,
8
9
  } from './lib/model'
9
10
  export { getJsonDataItemsProxy } from './lib/utils'
10
11
  export { BaseReader } from './lib/readers/base'
12
+ export { BaseFileReader } from './lib/readers/base-file'
13
+ export { GeojsonReader } from './lib/readers/geojson'
@@ -17,10 +17,17 @@ export async function openDataset(
17
17
  namespace?: string
18
18
  wfsVersion?: WfsVersion
19
19
  wfsFeatureType?: string
20
- }
20
+ },
21
+ cacheActive?: boolean
21
22
  ): Promise<BaseReader> {
22
23
  const fileType = await inferDatasetType(url, typeHint)
23
- let reader: BaseReader
24
+ let reader:
25
+ | CsvReader
26
+ | JsonReader
27
+ | GeojsonReader
28
+ | ExcelReader
29
+ | GmlReader
30
+ | WfsReader
24
31
  try {
25
32
  switch (fileType) {
26
33
  case 'csv':
@@ -42,6 +49,7 @@ export async function openDataset(
42
49
  reader = await WfsReader.createReader(url, options.wfsFeatureType)
43
50
  break
44
51
  }
52
+ reader.setCacheActive(cacheActive)
45
53
  reader.load()
46
54
  return reader
47
55
  } catch (e: any) {
@@ -61,9 +69,10 @@ export async function openDataset(
61
69
  export async function readDataset(
62
70
  url: string,
63
71
  typeHint?: SupportedType,
64
- options?: any
72
+ options?: any,
73
+ cacheActive = true
65
74
  ): Promise<DataItem[]> {
66
- const reader = await openDataset(url, typeHint, options)
75
+ const reader = await openDataset(url, typeHint, options, cacheActive)
67
76
  try {
68
77
  return await reader.read()
69
78
  } catch (e: any) {
@@ -13,8 +13,12 @@ export class FetchError {
13
13
  ) {
14
14
  this.message = `An error happened in the data fetcher, type: ${type}, info: ${info}`
15
15
  }
16
- static http(code: number) {
17
- return new FetchError('http', '', code)
16
+ static http(code: number, body?: string) {
17
+ const info = body
18
+ ? `Error ${code}
19
+ ${body}`
20
+ : `${code}`
21
+ return new FetchError('http', info, code)
18
22
  }
19
23
  static corsOrNetwork(message: string) {
20
24
  return new FetchError('network', message, 0)
@@ -0,0 +1,14 @@
1
+ import { BaseReader } from './base'
2
+
3
+ export abstract class BaseCacheReader extends BaseReader {
4
+ constructor(
5
+ protected url: string,
6
+ protected cacheActive = true
7
+ ) {
8
+ super(url)
9
+ }
10
+
11
+ setCacheActive(value: boolean) {
12
+ this.cacheActive = value
13
+ }
14
+ }
@@ -2,13 +2,14 @@ import { BaseReader } from './base'
2
2
  import { DataItem, DatasetInfo, PropertyInfo } from '../model'
3
3
  import { getJsonDataItemsProxy, jsonToGeojsonFeature } from '../utils'
4
4
  import { generateSqlQuery } from '../sql-utils'
5
+ import { BaseCacheReader } from './base-cache'
5
6
 
6
7
  type ParseResult = {
7
8
  items: DataItem[]
8
9
  properties: PropertyInfo[]
9
10
  }
10
11
 
11
- export class BaseFileReader extends BaseReader {
12
+ export class BaseFileReader extends BaseCacheReader {
12
13
  private parseResult_: Promise<ParseResult>
13
14
 
14
15
  protected getData(): Promise<ParseResult> {
@@ -11,8 +11,8 @@ import {
11
11
 
12
12
  export class BaseReader {
13
13
  protected selected: FieldName[] = null
14
- protected groupedBy: FieldGroupBy[] = null
15
- protected aggregations: FieldAggregation[] = null
14
+ public groupedBy: FieldGroupBy[] = null
15
+ public aggregations: FieldAggregation[] = null
16
16
  protected filter: FieldFilter = null
17
17
  protected sort: FieldSort[] = null
18
18
  protected startIndex: number = null
@@ -47,6 +47,6 @@ export function parseCsv(text: string): {
47
47
 
48
48
  export class CsvReader extends BaseFileReader {
49
49
  getData() {
50
- return fetchDataAsText(this.url).then(parseCsv)
50
+ return fetchDataAsText(this.url, this.cacheActive).then(parseCsv)
51
51
  }
52
52
  }
@@ -28,6 +28,6 @@ export function parseExcel(buffer: ArrayBuffer): Promise<{
28
28
 
29
29
  export class ExcelReader extends BaseFileReader {
30
30
  getData() {
31
- return fetchDataAsArrayBuffer(this.url).then(parseExcel)
31
+ return fetchDataAsArrayBuffer(this.url, this.cacheActive).then(parseExcel)
32
32
  }
33
33
  }