geonetwork-ui 2.4.2 → 2.5.0-dev.22c177ea1

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 (120) 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/geo-table-view/geo-table-view.component.mjs +18 -16
  4. package/esm2022/libs/feature/dataviz/src/lib/service/data.service.mjs +3 -1
  5. package/esm2022/libs/feature/dataviz/src/lib/table-view/table-view.component.mjs +12 -17
  6. package/esm2022/libs/feature/editor/src/lib/components/wizard-summarize/wizard-summarize.component.mjs +11 -11
  7. package/esm2022/libs/feature/record/src/lib/data-view/data-view.component.mjs +3 -3
  8. package/esm2022/libs/feature/record/src/lib/feature-record.module.mjs +6 -7
  9. package/esm2022/libs/feature/search/src/lib/utils/service/fields.mjs +46 -1
  10. package/esm2022/libs/feature/search/src/lib/utils/service/fields.service.mjs +3 -2
  11. package/esm2022/libs/ui/dataviz/src/index.mjs +3 -3
  12. package/esm2022/libs/ui/dataviz/src/lib/data-table/custom.mat.paginator.intl.mjs +51 -0
  13. package/esm2022/libs/ui/dataviz/src/lib/data-table/data-table.component.mjs +133 -0
  14. package/esm2022/libs/ui/dataviz/src/lib/data-table/data-table.data.source.mjs +24 -0
  15. package/esm2022/libs/ui/dataviz/src/lib/data-table/data-table.fixtures.mjs +82 -0
  16. package/esm2022/libs/ui/elements/src/lib/metadata-info/metadata-info.component.mjs +18 -10
  17. package/esm2022/libs/ui/search/src/lib/results-table/results-table.component.mjs +14 -12
  18. package/esm2022/libs/util/data-fetcher/src/index.mjs +3 -1
  19. package/esm2022/libs/util/data-fetcher/src/lib/model.mjs +7 -3
  20. package/esm2022/libs/util/data-fetcher/src/lib/readers/wfs.mjs +20 -2
  21. package/esm2022/libs/util/data-fetcher/src/lib/utils.mjs +3 -3
  22. package/esm2022/libs/util/shared/src/lib/services/date.service.mjs +41 -0
  23. package/esm2022/libs/util/shared/src/lib/services/index.mjs +2 -1
  24. package/esm2022/libs/util/shared/src/lib/utils/temporal-extent-union.mjs +4 -4
  25. package/esm2022/translations/de.json +7 -0
  26. package/esm2022/translations/en.json +7 -0
  27. package/esm2022/translations/es.json +7 -0
  28. package/esm2022/translations/fr.json +7 -0
  29. package/esm2022/translations/it.json +7 -0
  30. package/esm2022/translations/nl.json +7 -0
  31. package/esm2022/translations/pt.json +7 -0
  32. package/fesm2022/geonetwork-ui.mjs +727 -379
  33. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  34. package/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.d.ts +2 -1
  35. package/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.d.ts.map +1 -1
  36. package/libs/api/repository/src/lib/gn4/gn4-repository.d.ts.map +1 -1
  37. package/libs/feature/dataviz/src/lib/geo-table-view/geo-table-view.component.d.ts +7 -9
  38. package/libs/feature/dataviz/src/lib/geo-table-view/geo-table-view.component.d.ts.map +1 -1
  39. package/libs/feature/dataviz/src/lib/service/data.service.d.ts.map +1 -1
  40. package/libs/feature/dataviz/src/lib/table-view/table-view.component.d.ts +3 -6
  41. package/libs/feature/dataviz/src/lib/table-view/table-view.component.d.ts.map +1 -1
  42. package/libs/feature/editor/src/lib/components/wizard-summarize/wizard-summarize.component.d.ts +3 -3
  43. package/libs/feature/editor/src/lib/components/wizard-summarize/wizard-summarize.component.d.ts.map +1 -1
  44. package/libs/feature/record/src/lib/feature-record.module.d.ts +2 -2
  45. package/libs/feature/record/src/lib/feature-record.module.d.ts.map +1 -1
  46. package/libs/feature/search/src/lib/utils/service/fields.d.ts +10 -0
  47. package/libs/feature/search/src/lib/utils/service/fields.d.ts.map +1 -1
  48. package/libs/feature/search/src/lib/utils/service/fields.service.d.ts.map +1 -1
  49. package/libs/ui/dataviz/src/index.d.ts +2 -2
  50. package/libs/ui/dataviz/src/index.d.ts.map +1 -1
  51. package/libs/ui/dataviz/src/lib/data-table/custom.mat.paginator.intl.d.ts +14 -0
  52. package/libs/ui/dataviz/src/lib/data-table/custom.mat.paginator.intl.d.ts.map +1 -0
  53. package/libs/ui/dataviz/src/lib/data-table/data-table.component.d.ts +45 -0
  54. package/libs/ui/dataviz/src/lib/data-table/data-table.component.d.ts.map +1 -0
  55. package/libs/ui/dataviz/src/lib/data-table/data-table.data.source.d.ts +12 -0
  56. package/libs/ui/dataviz/src/lib/data-table/data-table.data.source.d.ts.map +1 -0
  57. package/libs/ui/dataviz/src/lib/data-table/data-table.fixtures.d.ts +10 -0
  58. package/libs/ui/dataviz/src/lib/data-table/data-table.fixtures.d.ts.map +1 -0
  59. package/libs/ui/elements/src/lib/metadata-info/metadata-info.component.d.ts +5 -0
  60. package/libs/ui/elements/src/lib/metadata-info/metadata-info.component.d.ts.map +1 -1
  61. package/libs/ui/search/src/lib/results-table/results-table.component.d.ts +3 -2
  62. package/libs/ui/search/src/lib/results-table/results-table.component.d.ts.map +1 -1
  63. package/libs/util/data-fetcher/src/index.d.ts +3 -1
  64. package/libs/util/data-fetcher/src/index.d.ts.map +1 -1
  65. package/libs/util/data-fetcher/src/lib/model.d.ts +1 -1
  66. package/libs/util/data-fetcher/src/lib/model.d.ts.map +1 -1
  67. package/libs/util/data-fetcher/src/lib/readers/wfs.d.ts.map +1 -1
  68. package/libs/util/shared/src/lib/services/date.service.d.ts +13 -0
  69. package/libs/util/shared/src/lib/services/date.service.d.ts.map +1 -0
  70. package/libs/util/shared/src/lib/services/index.d.ts +1 -0
  71. package/libs/util/shared/src/lib/services/index.d.ts.map +1 -1
  72. package/libs/util/shared/src/lib/utils/temporal-extent-union.d.ts +2 -1
  73. package/libs/util/shared/src/lib/utils/temporal-extent-union.d.ts.map +1 -1
  74. package/package.json +1 -1
  75. package/src/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.ts +33 -16
  76. package/src/libs/api/repository/src/lib/gn4/gn4-repository.ts +1 -5
  77. package/src/libs/feature/dataviz/src/lib/geo-table-view/geo-table-view.component.html +3 -3
  78. package/src/libs/feature/dataviz/src/lib/geo-table-view/geo-table-view.component.ts +17 -15
  79. package/src/libs/feature/dataviz/src/lib/service/data.service.ts +2 -0
  80. package/src/libs/feature/dataviz/src/lib/table-view/table-view.component.html +4 -3
  81. package/src/libs/feature/dataviz/src/lib/table-view/table-view.component.ts +9 -18
  82. package/src/libs/feature/editor/src/lib/components/wizard-summarize/wizard-summarize.component.ts +3 -4
  83. package/src/libs/feature/record/src/lib/data-view/data-view.component.html +1 -1
  84. package/src/libs/feature/record/src/lib/feature-record.module.ts +6 -4
  85. package/src/libs/feature/search/src/lib/utils/service/fields.service.ts +2 -0
  86. package/src/libs/feature/search/src/lib/utils/service/fields.ts +55 -0
  87. package/src/libs/ui/dataviz/src/index.ts +2 -2
  88. package/src/libs/ui/dataviz/src/lib/data-table/custom.mat.paginator.intl.ts +52 -0
  89. package/src/libs/ui/dataviz/src/lib/{table/table.component.css → data-table/data-table.component.css} +4 -0
  90. package/src/libs/ui/dataviz/src/lib/data-table/data-table.component.html +67 -0
  91. package/src/libs/ui/dataviz/src/lib/data-table/data-table.component.ts +173 -0
  92. package/src/libs/ui/dataviz/src/lib/data-table/data-table.data.source.ts +33 -0
  93. package/src/libs/ui/dataviz/src/lib/data-table/data-table.fixtures.ts +84 -0
  94. package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.html +3 -3
  95. package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.ts +12 -2
  96. package/src/libs/ui/search/src/lib/results-table/results-table.component.ts +4 -2
  97. package/src/libs/util/data-fetcher/src/index.ts +3 -0
  98. package/src/libs/util/data-fetcher/src/lib/model.ts +6 -2
  99. package/src/libs/util/data-fetcher/src/lib/readers/wfs.ts +23 -1
  100. package/src/libs/util/data-fetcher/src/lib/utils.ts +2 -2
  101. package/src/libs/util/shared/src/lib/services/date.service.ts +45 -0
  102. package/src/libs/util/shared/src/lib/services/index.ts +1 -0
  103. package/src/libs/util/shared/src/lib/utils/temporal-extent-union.ts +6 -3
  104. package/translations/de.json +7 -0
  105. package/translations/en.json +7 -0
  106. package/translations/es.json +7 -0
  107. package/translations/fr.json +7 -0
  108. package/translations/it.json +7 -0
  109. package/translations/nl.json +7 -0
  110. package/translations/pt.json +7 -0
  111. package/translations/sk.json +7 -0
  112. package/esm2022/libs/ui/dataviz/src/lib/table/table.component.mjs +0 -61
  113. package/esm2022/libs/ui/dataviz/src/lib/table/table.fixtures.mjs +0 -40
  114. package/libs/ui/dataviz/src/lib/table/table.component.d.ts +0 -29
  115. package/libs/ui/dataviz/src/lib/table/table.component.d.ts.map +0 -1
  116. package/libs/ui/dataviz/src/lib/table/table.fixtures.d.ts +0 -11
  117. package/libs/ui/dataviz/src/lib/table/table.fixtures.d.ts.map +0 -1
  118. package/src/libs/ui/dataviz/src/lib/table/table.component.html +0 -40
  119. package/src/libs/ui/dataviz/src/lib/table/table.component.ts +0 -80
  120. 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
+ }
@@ -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
  }
@@ -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'
@@ -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)
@@ -4,6 +4,7 @@ import { fetchDataAsText } from '../utils'
4
4
  import { BaseReader } from './base'
5
5
  import { GmlReader, parseGml } from './gml'
6
6
  import { GeojsonReader, parseGeojson } from './geojson'
7
+ import { marker } from '@biesbjerg/ngx-translate-extract-marker'
7
8
 
8
9
  export class WfsReader extends BaseReader {
9
10
  endpoint: WfsEndpoint
@@ -18,7 +19,22 @@ export class WfsReader extends BaseReader {
18
19
  }
19
20
 
20
21
  get properties(): Promise<PropertyInfo[]> {
21
- return this.getData().then((result) => result.properties)
22
+ return this.endpoint
23
+ .getFeatureTypeFull(this.featureTypeName)
24
+ .then((featureType) =>
25
+ Object.keys(featureType.properties).map((prop) => {
26
+ const originalType = featureType.properties[prop]
27
+ const type =
28
+ originalType === 'float' || originalType === 'integer'
29
+ ? 'number'
30
+ : (originalType as PropertyInfo['type']) // FIXME: ogc-client typing is incorrect, should be a string union
31
+ return {
32
+ name: prop,
33
+ label: prop,
34
+ type,
35
+ }
36
+ })
37
+ )
22
38
  }
23
39
 
24
40
  get info(): Promise<DatasetInfo> {
@@ -75,12 +91,18 @@ export class WfsReader extends BaseReader {
75
91
  }
76
92
 
77
93
  protected getData() {
94
+ if (this.aggregations || this.groupedBy) {
95
+ throw new Error(marker('wfs.aggregations.notsupported'))
96
+ }
97
+
78
98
  const asJson = this.endpoint.supportsJson(this.featureTypeName)
99
+ const attributes = this.selected ?? undefined
79
100
  let url = this.endpoint.getFeatureUrl(this.featureTypeName, {
80
101
  ...(this.startIndex !== null && { startIndex: this.startIndex }),
81
102
  ...(this.count !== null && { maxFeatures: this.count }),
82
103
  asJson,
83
104
  outputCrs: 'EPSG:4326',
105
+ attributes,
84
106
  // sortBy: this.sort // TODO: no sort in ogc-client?
85
107
  })
86
108
 
@@ -60,7 +60,7 @@ export function fetchDataAsText(url: string): Promise<string> {
60
60
  })
61
61
  .then(async (response) => {
62
62
  if (!response.ok) {
63
- throw FetchError.http(response.status)
63
+ throw FetchError.http(response.status, await response.text())
64
64
  }
65
65
  return response.text()
66
66
  }),
@@ -77,7 +77,7 @@ export function fetchDataAsArrayBuffer(url: string): Promise<ArrayBuffer> {
77
77
  })
78
78
  .then(async (response) => {
79
79
  if (!response.ok) {
80
- throw FetchError.http(response.status)
80
+ throw FetchError.http(response.status, await response.text())
81
81
  }
82
82
  // convert to a numeric array so that we can store the response in cache
83
83
  return Array.from(new Uint8Array(await response.arrayBuffer()))
@@ -0,0 +1,45 @@
1
+ import { Injectable } from '@angular/core'
2
+ import { TranslateService } from '@ngx-translate/core'
3
+
4
+ @Injectable({
5
+ providedIn: 'root',
6
+ })
7
+ export class DateService {
8
+ constructor(private translateService: TranslateService) {}
9
+
10
+ private getDateObject(date: Date | string): Date {
11
+ if (typeof date === 'string') {
12
+ const dateObj = new Date(date)
13
+ if (isNaN(dateObj.getTime())) {
14
+ throw new Error('Invalid date string')
15
+ }
16
+ return dateObj
17
+ }
18
+ return date
19
+ }
20
+
21
+ private getLocaleAndDate(date: Date | string): {
22
+ locale: string
23
+ dateObj: Date
24
+ } {
25
+ const locale = this.translateService.currentLang || 'en-US'
26
+ const dateObj = this.getDateObject(date)
27
+ return { locale, dateObj }
28
+ }
29
+
30
+ formatDate(
31
+ date: Date | string,
32
+ options?: Intl.DateTimeFormatOptions
33
+ ): string {
34
+ const { locale, dateObj } = this.getLocaleAndDate(date)
35
+ return dateObj.toLocaleDateString(locale, options)
36
+ }
37
+
38
+ formatDateTime(
39
+ date: Date | string,
40
+ options?: Intl.DateTimeFormatOptions
41
+ ): string {
42
+ const { locale, dateObj } = this.getLocaleAndDate(date)
43
+ return dateObj.toLocaleString(locale, options)
44
+ }
45
+ }
@@ -1,3 +1,4 @@
1
1
  export * from './theme.service'
2
2
  export * from './log.service'
3
3
  export * from './proxy.service'
4
+ export * from './date.service'
@@ -1,8 +1,11 @@
1
+ import { DateService } from '../services'
2
+
1
3
  export function getTemporalRangeUnion(
2
4
  ranges: {
3
5
  start?: Date
4
6
  end?: Date
5
- }[]
7
+ }[],
8
+ dateService: DateService
6
9
  ) {
7
10
  let earliestStartDate = Infinity
8
11
  let latestEndDate = -Infinity
@@ -24,11 +27,11 @@ export function getTemporalRangeUnion(
24
27
  return {
25
28
  start:
26
29
  earliestStartDate !== -Infinity
27
- ? new Date(earliestStartDate).toLocaleDateString()
30
+ ? dateService.formatDate(new Date(earliestStartDate))
28
31
  : undefined,
29
32
  end:
30
33
  latestEndDate !== Infinity
31
- ? new Date(latestEndDate).toLocaleDateString()
34
+ ? dateService.formatDate(new Date(latestEndDate))
32
35
  : undefined,
33
36
  }
34
37
  } else {
@@ -589,6 +589,12 @@
589
589
  "share.tab.webComponent": "Integrieren",
590
590
  "table.loading.data": "Daten werden geladen...",
591
591
  "table.object.count": "Objekte in diesem Datensatz",
592
+ "table.paginator.firstPage": "Erste Seite",
593
+ "table.paginator.itemsPerPage": "Elemente pro Seite",
594
+ "table.paginator.lastPage": "Letzte Seite",
595
+ "table.paginator.nextPage": "Nächste Seite",
596
+ "table.paginator.previousPage": "Vorherige Seite",
597
+ "table.paginator.rangeLabel": "{startIndex} - {endIndex} von {length}",
592
598
  "table.select.data": "Datenquelle",
593
599
  "tooltip.html.copy": "HTML kopieren",
594
600
  "tooltip.id.copy": "Eindeutige Kennung kopieren",
@@ -596,6 +602,7 @@
596
602
  "tooltip.url.open": "URL öffnen",
597
603
  "ui.readLess": "Weniger lesen",
598
604
  "ui.readMore": "Weiterlesen",
605
+ "wfs.aggregations.notsupported": "",
599
606
  "wfs.feature.limit": "Zu viele Features, um den WFS-Layer anzuzeigen!",
600
607
  "wfs.featuretype.notfound": "Kein passender Feature-Typ wurde im Dienst gefunden",
601
608
  "wfs.geojsongml.notsupported": "Dieser Dienst unterstützt das GeoJSON- oder GML-Format nicht",
@@ -589,6 +589,12 @@
589
589
  "share.tab.webComponent": "Integrate",
590
590
  "table.loading.data": "Loading data...",
591
591
  "table.object.count": "Objects in this dataset",
592
+ "table.paginator.firstPage": "First page",
593
+ "table.paginator.itemsPerPage": "Items per page",
594
+ "table.paginator.lastPage": "Last page",
595
+ "table.paginator.nextPage": "Next page",
596
+ "table.paginator.previousPage": "Previous page",
597
+ "table.paginator.rangeLabel": "{startIndex} - {endIndex} of {length}",
592
598
  "table.select.data": "Data source",
593
599
  "tooltip.html.copy": "Copy HTML",
594
600
  "tooltip.id.copy": "Copy unique identifier",
@@ -596,6 +602,7 @@
596
602
  "tooltip.url.open": "Open URL",
597
603
  "ui.readLess": "Read less",
598
604
  "ui.readMore": "Read more",
605
+ "wfs.aggregations.notsupported": "Aggregations are currently not supported for WFS services",
599
606
  "wfs.feature.limit": "Too many features to display the WFS layer!",
600
607
  "wfs.featuretype.notfound": "No matching feature type was found in the service",
601
608
  "wfs.geojsongml.notsupported": "This service does not support the GeoJSON or GML format",
@@ -589,6 +589,12 @@
589
589
  "share.tab.webComponent": "",
590
590
  "table.loading.data": "",
591
591
  "table.object.count": "",
592
+ "table.paginator.firstPage": "Primera página",
593
+ "table.paginator.itemsPerPage": "Elementos por página",
594
+ "table.paginator.lastPage": "Última página",
595
+ "table.paginator.nextPage": "Página siguiente",
596
+ "table.paginator.previousPage": "Página anterior",
597
+ "table.paginator.rangeLabel": "{startIndex} - {endIndex} de {length}",
592
598
  "table.select.data": "",
593
599
  "tooltip.html.copy": "",
594
600
  "tooltip.id.copy": "",
@@ -596,6 +602,7 @@
596
602
  "tooltip.url.open": "",
597
603
  "ui.readLess": "",
598
604
  "ui.readMore": "",
605
+ "wfs.aggregations.notsupported": "",
599
606
  "wfs.feature.limit": "",
600
607
  "wfs.featuretype.notfound": "",
601
608
  "wfs.geojsongml.notsupported": "",
@@ -589,6 +589,12 @@
589
589
  "share.tab.webComponent": "Intégrer",
590
590
  "table.loading.data": "Chargement des données...",
591
591
  "table.object.count": "enregistrements dans ces données",
592
+ "table.paginator.firstPage": "Première page",
593
+ "table.paginator.itemsPerPage": "Éléments par page",
594
+ "table.paginator.lastPage": "Dernière page",
595
+ "table.paginator.nextPage": "Page suivante",
596
+ "table.paginator.previousPage": "Page précédente",
597
+ "table.paginator.rangeLabel": "{startIndex} - {endIndex} sur {length}",
592
598
  "table.select.data": "Source de données",
593
599
  "tooltip.html.copy": "Copier le HTML",
594
600
  "tooltip.id.copy": "Copier l'identifiant unique",
@@ -596,6 +602,7 @@
596
602
  "tooltip.url.open": "Ouvrir l'URL",
597
603
  "ui.readLess": "Réduire",
598
604
  "ui.readMore": "Lire la suite",
605
+ "wfs.aggregations.notsupported": "Agrégations non supportées pour les services WFS",
599
606
  "wfs.feature.limit": "Trop d'objets pour afficher la couche WFS !",
600
607
  "wfs.featuretype.notfound": "La classe d'objets n'a pas été trouvée dans le service",
601
608
  "wfs.geojsongml.notsupported": "Le service ne supporte pas le format GeoJSON ou GML",
@@ -589,6 +589,12 @@
589
589
  "share.tab.webComponent": "Incorporare",
590
590
  "table.loading.data": "Caricamento dei dati...",
591
591
  "table.object.count": "record in questi dati",
592
+ "table.paginator.firstPage": "Prima pagina",
593
+ "table.paginator.itemsPerPage": "Elementi per pagina",
594
+ "table.paginator.lastPage": "Ultima pagina",
595
+ "table.paginator.nextPage": "Pagina successiva",
596
+ "table.paginator.previousPage": "Pagina precedente",
597
+ "table.paginator.rangeLabel": "{startIndex} - {endIndex} di {total}",
592
598
  "table.select.data": "Sorgente dati",
593
599
  "tooltip.html.copy": "Copiare il HTML",
594
600
  "tooltip.id.copy": "Copiare l'identificatore unico",
@@ -596,6 +602,7 @@
596
602
  "tooltip.url.open": "Aprire l'URL",
597
603
  "ui.readLess": "Ridurre",
598
604
  "ui.readMore": "Leggere di più",
605
+ "wfs.aggregations.notsupported": "",
599
606
  "wfs.feature.limit": "Troppi oggetti per visualizzare il WFS layer!",
600
607
  "wfs.featuretype.notfound": "La classe di oggetto non è stata trovata nel servizio",
601
608
  "wfs.geojsongml.notsupported": "Il servizio non supporta il formato GeoJSON o GML",