geonetwork-ui 2.3.0-dev.c4b41b40 → 2.3.0-dev.cc25794c

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 (129) hide show
  1. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/read-parts.mjs +2 -2
  2. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/write-parts.mjs +2 -2
  3. package/esm2022/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.mjs +9 -7
  4. package/esm2022/libs/feature/dataviz/src/lib/chart-view/chart-view.component.mjs +1 -1
  5. package/esm2022/libs/feature/dataviz/src/lib/service/data.service.mjs +5 -23
  6. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.mjs +1 -1
  7. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.mjs +104 -0
  8. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.mjs +8 -3
  9. package/esm2022/libs/feature/editor/src/lib/components/wizard-field/wizard-field.component.mjs +1 -1
  10. package/esm2022/libs/feature/editor/src/lib/fields.config.mjs +8 -1
  11. package/esm2022/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.mjs +73 -20
  12. package/esm2022/libs/feature/map/src/lib/add-layer-from-wfs/add-layer-from-wfs.component.mjs +1 -1
  13. package/esm2022/libs/feature/map/src/lib/add-layer-from-wms/add-layer-from-wms.component.mjs +1 -1
  14. package/esm2022/libs/feature/map/src/lib/map-context/map-context.model.mjs +1 -1
  15. package/esm2022/libs/feature/map/src/lib/map-context/map-context.service.mjs +58 -17
  16. package/esm2022/libs/feature/map/src/lib/utils/map-utils.service.mjs +6 -2
  17. package/esm2022/libs/feature/record/src/lib/data-view/data-view.component.mjs +1 -1
  18. package/esm2022/libs/feature/record/src/lib/map-view/map-view.component.mjs +5 -3
  19. package/esm2022/libs/feature/record/src/lib/state/mdview.reducer.mjs +1 -3
  20. package/esm2022/libs/feature/search/src/index.mjs +2 -1
  21. package/esm2022/libs/feature/search/src/lib/results-layout/results-layout.component.mjs +1 -1
  22. package/esm2022/libs/feature/search/src/lib/sort-by/sort-by.component.mjs +1 -1
  23. package/esm2022/libs/feature/search/src/lib/utils/service/fields.service.mjs +1 -1
  24. package/esm2022/libs/ui/catalog/src/lib/language-switcher/language-switcher.component.mjs +1 -1
  25. package/esm2022/libs/ui/catalog/src/lib/organisations-filter/organisations-filter.component.mjs +1 -1
  26. package/esm2022/libs/ui/elements/src/lib/api-card/api-card.component.mjs +3 -2
  27. package/esm2022/libs/ui/elements/src/lib/downloads-list/downloads-list.component.mjs +2 -2
  28. package/esm2022/libs/ui/elements/src/lib/record-api-form/record-api-form.component.mjs +89 -54
  29. package/esm2022/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.mjs +3 -5
  30. package/esm2022/libs/ui/inputs/src/lib/check-toggle/check-toggle.component.mjs +4 -3
  31. package/esm2022/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.mjs +5 -3
  32. package/esm2022/libs/ui/inputs/src/lib/text-input/text-input.component.mjs +5 -3
  33. package/esm2022/libs/ui/inputs/src/lib/ui-inputs.module.mjs +6 -5
  34. package/esm2022/libs/ui/layout/src/lib/carousel/carousel.component.mjs +3 -3
  35. package/esm2022/libs/util/app-config/src/lib/app-config.mjs +3 -1
  36. package/esm2022/libs/util/app-config/src/lib/fixtures.mjs +2 -1
  37. package/esm2022/libs/util/app-config/src/lib/model.mjs +1 -1
  38. package/esm2022/translations/de.json +11 -14
  39. package/esm2022/translations/en.json +11 -14
  40. package/esm2022/translations/es.json +11 -14
  41. package/esm2022/translations/fr.json +11 -14
  42. package/esm2022/translations/it.json +11 -14
  43. package/esm2022/translations/nl.json +11 -14
  44. package/esm2022/translations/pt.json +11 -14
  45. package/fesm2022/geonetwork-ui.mjs +474 -266
  46. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  47. package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts.map +1 -1
  48. package/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.d.ts.map +1 -1
  49. package/libs/feature/dataviz/src/lib/service/data.service.d.ts.map +1 -1
  50. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.d.ts +21 -0
  51. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.d.ts.map +1 -0
  52. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts +1 -0
  53. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts.map +1 -1
  54. package/libs/feature/editor/src/lib/fields.config.d.ts.map +1 -1
  55. package/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.d.ts +10 -5
  56. package/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.d.ts.map +1 -1
  57. package/libs/feature/map/src/lib/map-context/map-context.model.d.ts +7 -0
  58. package/libs/feature/map/src/lib/map-context/map-context.model.d.ts.map +1 -1
  59. package/libs/feature/map/src/lib/map-context/map-context.service.d.ts +1 -1
  60. package/libs/feature/map/src/lib/map-context/map-context.service.d.ts.map +1 -1
  61. package/libs/feature/map/src/lib/utils/map-utils.service.d.ts.map +1 -1
  62. package/libs/feature/record/src/lib/map-view/map-view.component.d.ts.map +1 -1
  63. package/libs/feature/record/src/lib/state/mdview.reducer.d.ts.map +1 -1
  64. package/libs/feature/search/src/index.d.ts +1 -0
  65. package/libs/feature/search/src/index.d.ts.map +1 -1
  66. package/libs/feature/search/src/lib/utils/service/fields.service.d.ts +3 -3
  67. package/libs/feature/search/src/lib/utils/service/fields.service.d.ts.map +1 -1
  68. package/libs/ui/elements/src/lib/api-card/api-card.component.d.ts.map +1 -1
  69. package/libs/ui/elements/src/lib/record-api-form/record-api-form.component.d.ts +22 -4
  70. package/libs/ui/elements/src/lib/record-api-form/record-api-form.component.d.ts.map +1 -1
  71. package/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.d.ts +1 -2
  72. package/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.d.ts.map +1 -1
  73. package/libs/ui/inputs/src/lib/check-toggle/check-toggle.component.d.ts +1 -1
  74. package/libs/ui/inputs/src/lib/check-toggle/check-toggle.component.d.ts.map +1 -1
  75. package/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.d.ts +2 -1
  76. package/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.d.ts.map +1 -1
  77. package/libs/ui/inputs/src/lib/text-input/text-input.component.d.ts +2 -1
  78. package/libs/ui/inputs/src/lib/text-input/text-input.component.d.ts.map +1 -1
  79. package/libs/ui/inputs/src/lib/ui-inputs.module.d.ts +27 -27
  80. package/libs/util/app-config/src/lib/app-config.d.ts.map +1 -1
  81. package/libs/util/app-config/src/lib/fixtures.d.ts.map +1 -1
  82. package/libs/util/app-config/src/lib/model.d.ts +1 -0
  83. package/libs/util/app-config/src/lib/model.d.ts.map +1 -1
  84. package/package.json +2 -2
  85. package/src/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts +1 -1
  86. package/src/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts +1 -4
  87. package/src/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.ts +16 -10
  88. package/src/libs/common/fixtures/src/lib/link.fixtures.ts +8 -0
  89. package/src/libs/feature/dataviz/src/lib/service/data.service.ts +4 -21
  90. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.css +0 -0
  91. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.html +14 -0
  92. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.ts +143 -0
  93. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html +5 -0
  94. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts +5 -0
  95. package/src/libs/feature/editor/src/lib/fields.config.ts +7 -0
  96. package/src/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.css +7 -0
  97. package/src/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.html +32 -18
  98. package/src/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.ts +72 -17
  99. package/src/libs/feature/map/src/lib/map-context/map-context.model.ts +7 -0
  100. package/src/libs/feature/map/src/lib/map-context/map-context.service.ts +57 -17
  101. package/src/libs/feature/map/src/lib/utils/map-utils.service.ts +5 -1
  102. package/src/libs/feature/record/src/lib/map-view/map-view.component.ts +4 -4
  103. package/src/libs/feature/record/src/lib/state/mdview.reducer.ts +0 -2
  104. package/src/libs/feature/search/src/index.ts +1 -0
  105. package/src/libs/feature/search/src/lib/utils/service/fields.service.ts +2 -2
  106. package/src/libs/ui/elements/src/lib/api-card/api-card.component.ts +2 -1
  107. package/src/libs/ui/elements/src/lib/downloads-list/downloads-list.component.ts +1 -1
  108. package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.html +25 -9
  109. package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.ts +116 -57
  110. package/src/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.html +1 -1
  111. package/src/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.ts +0 -1
  112. package/src/libs/ui/inputs/src/lib/check-toggle/check-toggle.component.ts +3 -0
  113. package/src/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.html +1 -0
  114. package/src/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.ts +1 -0
  115. package/src/libs/ui/inputs/src/lib/text-input/text-input.component.html +1 -0
  116. package/src/libs/ui/inputs/src/lib/text-input/text-input.component.ts +1 -0
  117. package/src/libs/ui/inputs/src/lib/ui-inputs.module.ts +1 -1
  118. package/src/libs/ui/layout/src/lib/carousel/carousel.component.css +1 -0
  119. package/src/libs/util/app-config/src/lib/app-config.ts +2 -0
  120. package/src/libs/util/app-config/src/lib/fixtures.ts +1 -0
  121. package/src/libs/util/app-config/src/lib/model.ts +1 -0
  122. package/translations/de.json +11 -14
  123. package/translations/en.json +11 -14
  124. package/translations/es.json +11 -14
  125. package/translations/fr.json +11 -14
  126. package/translations/it.json +11 -14
  127. package/translations/nl.json +11 -14
  128. package/translations/pt.json +11 -14
  129. package/translations/sk.json +11 -14
@@ -24,10 +24,8 @@ import {
24
24
  findChildOrCreate,
25
25
  findChildrenElement,
26
26
  findNestedChildOrCreate,
27
- findNestedElement,
28
27
  findNestedElements,
29
28
  readAttribute,
30
- readText,
31
29
  removeAllChildren,
32
30
  removeChildren,
33
31
  removeChildrenByName,
@@ -36,7 +34,6 @@ import {
36
34
  } from '../xml-utils'
37
35
  import {
38
36
  ChainableFunction,
39
- combine,
40
37
  fallback,
41
38
  filterArray,
42
39
  getAtIndex,
@@ -220,7 +217,7 @@ export function getISODuration(updateFrequency: UpdateFrequencyCustom): string {
220
217
  else duration.hours = Math.round(24 / updateFrequency.updatedTimes)
221
218
  break
222
219
  case 'week':
223
- duration.days = Math.round(7 / updateFrequency.updatedTimes)
220
+ duration.days = Math.round(7 / updateFrequency.updatedTimes - 0.0001) // this is to make sure that '2 times per week' = 'every 3 days'
224
221
  break
225
222
  case 'month':
226
223
  if (updateFrequency.updatedTimes <= 1) duration.months = 1
@@ -162,19 +162,25 @@ export class Gn4PlatformService implements PlatformServiceInterface {
162
162
  }
163
163
 
164
164
  getUserFeedbacks(uuid: string): Observable<UserFeedback[]> {
165
- return this.userfeedbackApiService
166
- .getUserComments(uuid)
167
- .pipe(
168
- map((userFeedbacks) =>
169
- userFeedbacks.map(this.mapper.userFeedbacksFromApi)
170
- )
171
- )
165
+ return this.userfeedbackApiService.getUserComments(uuid).pipe(
166
+ map((userFeedbacks) =>
167
+ userFeedbacks.map(this.mapper.userFeedbacksFromApi)
168
+ ),
169
+ catchError((error) => {
170
+ console.error('Error fetching user feedbacks:', error)
171
+ return of(undefined)
172
+ })
173
+ )
172
174
  }
173
175
 
174
176
  postUserFeedbacks(userFeedback: UserFeedback): Observable<void> {
175
177
  const mappedUserFeedBack = this.mapper.userFeedbacksToApi(userFeedback)
176
- return this.userfeedbackApiService
177
- .newUserFeedback(mappedUserFeedBack)
178
- .pipe(map(() => undefined))
178
+ return this.userfeedbackApiService.newUserFeedback(mappedUserFeedBack).pipe(
179
+ map(() => undefined),
180
+ catchError((error) => {
181
+ console.error('Error posting user feedback:', error)
182
+ return of(undefined)
183
+ })
184
+ )
179
185
  }
180
186
  }
@@ -110,6 +110,14 @@ export const LINK_FIXTURES: Record<string, DatasetDistribution> = deepFreeze({
110
110
  url: new URL('https://my.ogc.server/wfs'),
111
111
  accessServiceProtocol: 'wfs',
112
112
  },
113
+ geodataWfsDownload: {
114
+ name: 'mylayer',
115
+ type: 'download',
116
+ url: new URL(
117
+ 'https://my.ogc.server/wfs?GetFeature&FeatureType=surval_parametre_ligne&format=csv'
118
+ ),
119
+ accessServiceProtocol: 'wfs',
120
+ },
113
121
  geodataWms2: {
114
122
  name: 'myotherlayer',
115
123
  type: 'service',
@@ -32,6 +32,7 @@ marker('wfs.unreachable.http')
32
32
  marker('wfs.unreachable.unknown')
33
33
  marker('wfs.featuretype.notfound')
34
34
  marker('wfs.geojsongml.notsupported')
35
+ marker('ogc.unreachable.unknown')
35
36
  marker('dataset.error.network')
36
37
  marker('dataset.error.http')
37
38
  marker('dataset.error.parse')
@@ -159,7 +160,6 @@ export class DataService {
159
160
  const collectionInfo = await this.getDownloadUrlsFromOgcApi(
160
161
  ogcApiLink.url.href
161
162
  )
162
-
163
163
  return Object.keys(collectionInfo.bulkDownloadLinks).map((downloadLink) => {
164
164
  return {
165
165
  ...ogcApiLink,
@@ -174,29 +174,12 @@ export class DataService {
174
174
 
175
175
  async getDownloadUrlsFromOgcApi(url: string): Promise<OgcApiCollectionInfo> {
176
176
  const endpoint = new OgcApiEndpoint(this.proxy.getProxiedUrl(url))
177
- return await endpoint.featureCollections
177
+ return await endpoint.allCollections
178
178
  .then((collections) => {
179
- return endpoint.getCollectionInfo(collections[0])
179
+ return endpoint.getCollectionInfo(collections[0].name)
180
180
  })
181
181
  .catch((error) => {
182
- if (error instanceof Error) {
183
- throw new Error(`wfs.unreachable.unknown`)
184
- } else {
185
- if (error.type === 'network') {
186
- throw new Error(`wfs.unreachable.cors`)
187
- }
188
- if (error.type === 'http') {
189
- throw new Error(`wfs.unreachable.http`)
190
- }
191
- if (error.type === 'parse') {
192
- throw new Error(`wfs.unreachable.parse`)
193
- }
194
- if (error.type === 'unsupportedType') {
195
- throw new Error(`wfs.unreachable.unsupportedType`)
196
- } else {
197
- throw new Error(`wfs.unreachable.unknown`)
198
- }
199
- }
182
+ throw new Error(`ogc.unreachable.unknown`)
200
183
  })
201
184
  }
202
185
 
@@ -0,0 +1,14 @@
1
+ <gn-ui-check-toggle
2
+ [label]="'editor.record.form.updateFrequency.planned' | translate"
3
+ [value]="planned"
4
+ (toggled)="onPlannedToggled()"
5
+ ></gn-ui-check-toggle>
6
+ <gn-ui-dropdown-selector
7
+ title="updateFrequency"
8
+ [showTitle]="false"
9
+ [choices]="choices"
10
+ [selected]="selectedFrequency"
11
+ (selectValue)="onSelectFrequencyValue($event)"
12
+ [disabled]="!planned"
13
+ >
14
+ </gn-ui-dropdown-selector>
@@ -0,0 +1,143 @@
1
+ import {
2
+ ChangeDetectionStrategy,
3
+ Component,
4
+ Input,
5
+ OnInit,
6
+ } from '@angular/core'
7
+ import { FormControl } from '@angular/forms'
8
+ import { marker } from '@biesbjerg/ngx-translate-extract-marker'
9
+ import {
10
+ CheckToggleComponent,
11
+ DropdownSelectorComponent,
12
+ } from '../../../../../../../../../libs/ui/inputs/src'
13
+ import { TranslateModule, TranslateService } from '@ngx-translate/core'
14
+
15
+ @Component({
16
+ selector: 'gn-ui-form-field-update-frequency',
17
+ templateUrl: './form-field-update-frequency.component.html',
18
+ styleUrls: ['./form-field-update-frequency.component.css'],
19
+ changeDetection: ChangeDetectionStrategy.OnPush,
20
+ standalone: true,
21
+ imports: [CheckToggleComponent, DropdownSelectorComponent, TranslateModule],
22
+ })
23
+ export class FormFieldUpdateFrequencyComponent implements OnInit {
24
+ @Input() control: FormControl
25
+
26
+ get planned() {
27
+ return this.control.value !== 'notPlanned'
28
+ }
29
+
30
+ constructor(private translateService: TranslateService) {}
31
+
32
+ ngOnInit() {
33
+ const updatedTimes = this.control.value?.updatedTimes
34
+ const per = this.control.value?.per
35
+ if (updatedTimes && updatedTimes !== 1 && updatedTimes !== 2) {
36
+ this.choices = [
37
+ {
38
+ value: `${per}.${updatedTimes}`,
39
+ label: this.translateService.instant(
40
+ `domain.record.updateFrequency.${per}`,
41
+ {
42
+ count: updatedTimes,
43
+ }
44
+ ),
45
+ },
46
+ ...this.choices,
47
+ ]
48
+ }
49
+ }
50
+
51
+ onPlannedToggled() {
52
+ if (this.planned) {
53
+ this.control.setValue('notPlanned')
54
+ } else {
55
+ this.control.setValue({ updatedTimes: 1, per: 'day' })
56
+ }
57
+ }
58
+
59
+ get selectedFrequency() {
60
+ const { updatedTimes, per } = this.control.value
61
+ return `${per}.${updatedTimes}`
62
+ }
63
+
64
+ onSelectFrequencyValue(value: unknown) {
65
+ const split = (value as string).split('.')
66
+ this.control.setValue({ updatedTimes: Number(split[1]), per: split[0] })
67
+ }
68
+
69
+ choices = [
70
+ {
71
+ value: 'day.1',
72
+ label: this.translateService.instant(
73
+ 'domain.record.updateFrequency.day',
74
+ {
75
+ count: 1,
76
+ }
77
+ ),
78
+ },
79
+ {
80
+ value: 'day.2',
81
+ label: this.translateService.instant(
82
+ 'domain.record.updateFrequency.day',
83
+ {
84
+ count: 2,
85
+ }
86
+ ),
87
+ },
88
+ {
89
+ value: 'week.1',
90
+ label: this.translateService.instant(
91
+ 'domain.record.updateFrequency.week',
92
+ {
93
+ count: 1,
94
+ }
95
+ ),
96
+ },
97
+ {
98
+ value: 'week.2',
99
+ label: this.translateService.instant(
100
+ 'domain.record.updateFrequency.week',
101
+ {
102
+ count: 2,
103
+ }
104
+ ),
105
+ },
106
+ {
107
+ value: 'month.1',
108
+ label: this.translateService.instant(
109
+ 'domain.record.updateFrequency.month',
110
+ {
111
+ count: 1,
112
+ }
113
+ ),
114
+ },
115
+ {
116
+ value: 'month.2',
117
+ label: this.translateService.instant(
118
+ 'domain.record.updateFrequency.month',
119
+ {
120
+ count: 2,
121
+ }
122
+ ),
123
+ },
124
+ {
125
+ value: 'year.1',
126
+ label: this.translateService.instant(
127
+ 'domain.record.updateFrequency.year',
128
+ {
129
+ count: 1,
130
+ }
131
+ ),
132
+ },
133
+ {
134
+ value: 'year.2',
135
+ label: this.translateService.instant(
136
+ 'domain.record.updateFrequency.year',
137
+ {
138
+ count: 2,
139
+ }
140
+ ),
141
+ },
142
+ ]
143
+ }
@@ -56,6 +56,11 @@
56
56
  [control]="formControl"
57
57
  ></gn-ui-form-field-resource-updated>
58
58
  </ng-container>
59
+ <ng-container *ngIf="isUpdateFrequency">
60
+ <gn-ui-form-field-update-frequency
61
+ [control]="formControl"
62
+ ></gn-ui-form-field-update-frequency>
63
+ </ng-container>
59
64
  <ng-container *ngIf="isSimpleField">
60
65
  <gn-ui-form-field-simple
61
66
  [type]="simpleType"
@@ -24,6 +24,7 @@ import { FormFieldSimpleComponent } from './form-field-simple/form-field-simple.
24
24
  import { FormFieldSpatialExtentComponent } from './form-field-spatial-extent/form-field-spatial-extent.component'
25
25
  import { FormFieldTemporalExtentComponent } from './form-field-temporal-extent/form-field-temporal-extent.component'
26
26
  import { FormFieldConfig } from './form-field.model'
27
+ import { FormFieldUpdateFrequencyComponent } from './form-field-update-frequency/form-field-update-frequency.component'
27
28
 
28
29
  @Component({
29
30
  selector: 'gn-ui-form-field',
@@ -40,6 +41,7 @@ import { FormFieldConfig } from './form-field.model'
40
41
  FormFieldWrapperComponent,
41
42
  FormFieldLicenseComponent,
42
43
  FormFieldResourceUpdatedComponent,
44
+ FormFieldUpdateFrequencyComponent,
43
45
  FormFieldSimpleComponent,
44
46
  FormFieldRichComponent,
45
47
  FormFieldObjectComponent,
@@ -130,6 +132,9 @@ export class FormFieldComponent {
130
132
  get isResourceUpdated() {
131
133
  return this.model === 'resourceUpdated'
132
134
  }
135
+ get isUpdateFrequency() {
136
+ return this.model === 'updateFrequency'
137
+ }
133
138
 
134
139
  get withoutWrapper() {
135
140
  return this.model === 'title' || this.model === 'abstract'
@@ -47,4 +47,11 @@ export const DEFAULT_FIELDS: EditorFieldsConfig = [
47
47
  type: 'date',
48
48
  },
49
49
  },
50
+ {
51
+ model: 'updateFrequency',
52
+ formFieldConfig: {
53
+ labelKey: marker('editor.record.form.updateFrequency'),
54
+ type: 'text',
55
+ },
56
+ },
50
57
  ]
@@ -0,0 +1,7 @@
1
+ .dropdown-content {
2
+ display: none;
3
+ }
4
+
5
+ .relative:hover .dropdown-content {
6
+ display: block;
7
+ }
@@ -4,8 +4,7 @@
4
4
  (valueChange)="urlChange.next($event)"
5
5
  [hint]="'map.ogc.urlInput.hint' | translate"
6
6
  class="w-96"
7
- >
8
- </gn-ui-text-input>
7
+ ></gn-ui-text-input>
9
8
  </div>
10
9
 
11
10
  <div *ngIf="errorMessage" class="text-red-500 mt-2">
@@ -16,21 +15,36 @@
16
15
  <p class="loading-message" translate>map.loading.service</p>
17
16
  </div>
18
17
 
19
- <div *ngIf="!loading && layers.length > 0">
20
- <h2 class="font-bold" translate>map.layers.available</h2>
21
- <ng-container *ngFor="let layer of layers">
22
- <div class="flex items-center justify-between my-2 layer-item-tree">
23
- <p class="max-w-xs overflow-hidden overflow-ellipsis whitespace-nowrap">
24
- {{ layer }}
25
- </p>
26
- <gn-ui-button
27
- class="layer-add-btn"
28
- type="primary"
29
- (buttonClick)="addLayer(layer)"
30
- extraClass="text-sm !px-2 !py-1"
31
- translate
32
- ><span translate> map.layer.add </span></gn-ui-button
18
+ <ng-container *ngFor="let layer of layers">
19
+ <div
20
+ *ngIf="shouldDisplayLayer(layer)"
21
+ class="flex items-center justify-between my-2 layer-item-tree"
22
+ >
23
+ <div class="flex flex-col items-start w-full">
24
+ <p
25
+ class="max-w-xs overflow-hidden overflow-ellipsis whitespace-nowrap"
26
+ [title]="layer.name"
33
27
  >
28
+ {{ layer.name }}
29
+ </p>
30
+ <div class="flex justify-between items-center w-full">
31
+ <gn-ui-dropdown-selector
32
+ [title]="'Add Layer As' | translate"
33
+ [choices]="getLayerChoices(layer)"
34
+ (selectValue)="onLayerTypeSelect(layer.name, $event)"
35
+ [selected]="selectedLayerTypes[layer.name]"
36
+ extraBtnClass="w-6 h-5 !text-sm !px-2 !py-1"
37
+ ></gn-ui-dropdown-selector>
38
+ <gn-ui-button
39
+ class="layer-add-btn"
40
+ type="primary"
41
+ (buttonClick)="addLayer(layer.name, selectedLayerTypes[layer.name])"
42
+ extraClass="text-sm !px-2 !py-1"
43
+ translate
44
+ >
45
+ <span translate>map.layer.add</span>
46
+ </gn-ui-button>
47
+ </div>
34
48
  </div>
35
- </ng-container>
36
- </div>
49
+ </div>
50
+ </ng-container>
@@ -14,7 +14,7 @@ import {
14
14
  MapContextLayerTypeEnum,
15
15
  } from '../map-context/map-context.model'
16
16
  import { TranslateModule } from '@ngx-translate/core'
17
- import { UiInputsModule } from '../../../../../../libs/ui/inputs/src'
17
+ import { DropdownChoice, UiInputsModule } from '../../../../../../libs/ui/inputs/src'
18
18
  import { CommonModule } from '@angular/common'
19
19
  import { MapLayer } from '../+state/map.models'
20
20
 
@@ -30,18 +30,16 @@ export class AddLayerFromOgcApiComponent implements OnInit {
30
30
  @Output() layerAdded = new EventEmitter<MapLayer>()
31
31
 
32
32
  urlChange = new Subject<string>()
33
- layerUrl = ''
34
33
  loading = false
35
- layers: string[] = []
36
- ogcEndpoint: OgcApiEndpoint = null
34
+ layers: any[] = []
37
35
  errorMessage: string | null = null
36
+ selectedLayerTypes: { [key: string]: DropdownChoice['value'] } = {}
38
37
 
39
38
  constructor(private changeDetectorRef: ChangeDetectorRef) {}
40
39
 
41
40
  ngOnInit() {
42
41
  this.urlChange.pipe(debounceTime(700)).subscribe(() => {
43
42
  this.loadLayers()
44
- this.changeDetectorRef.detectChanges() // manually trigger change detection
45
43
  })
46
44
  }
47
45
 
@@ -49,14 +47,13 @@ export class AddLayerFromOgcApiComponent implements OnInit {
49
47
  this.errorMessage = null
50
48
  try {
51
49
  this.loading = true
52
- if (this.ogcUrl.trim() === '') {
50
+ if (!this.ogcUrl.trim()) {
53
51
  this.layers = []
54
52
  return
55
53
  }
56
- this.ogcEndpoint = await new OgcApiEndpoint(this.ogcUrl)
57
-
58
- // Currently only supports feature collections
59
- this.layers = await this.ogcEndpoint.featureCollections
54
+ const ogcEndpoint = await new OgcApiEndpoint(this.ogcUrl)
55
+ this.layers = await ogcEndpoint.allCollections
56
+ this.setDefaultLayerTypes()
60
57
  } catch (error) {
61
58
  const err = error as Error
62
59
  this.layers = []
@@ -67,14 +64,72 @@ export class AddLayerFromOgcApiComponent implements OnInit {
67
64
  }
68
65
  }
69
66
 
70
- async addLayer(layer: string) {
71
- this.layerUrl = await this.ogcEndpoint.getCollectionItemsUrl(layer)
67
+ setDefaultLayerTypes() {
68
+ this.layers.forEach((layer) => {
69
+ const choices = this.getLayerChoices(layer)
70
+ if (choices.length > 0) {
71
+ this.selectedLayerTypes[layer.name] = choices[0].value
72
+ }
73
+ })
74
+ }
72
75
 
73
- const layerToAdd: MapContextLayerModel = {
74
- name: layer,
75
- url: this.layerUrl,
76
- type: MapContextLayerTypeEnum.OGCAPI,
76
+ getLayerChoices(layer: any) {
77
+ const choices = []
78
+ if (layer.hasRecords) {
79
+ choices.push({ label: 'Records', value: 'record' })
80
+ }
81
+ if (layer.hasFeatures) {
82
+ choices.push({ label: 'Features', value: 'features' })
83
+ }
84
+ if (layer.hasVectorTiles) {
85
+ choices.push({ label: 'Vector Tiles', value: 'vectorTiles' })
86
+ }
87
+ if (layer.hasMapTiles) {
88
+ choices.push({ label: 'Map Tiles', value: 'mapTiles' })
89
+ }
90
+ return choices
91
+ }
92
+
93
+ shouldDisplayLayer(layer: any) {
94
+ return (
95
+ layer.hasRecords ||
96
+ layer.hasFeatures ||
97
+ layer.hasVectorTiles ||
98
+ layer.hasMapTiles
99
+ )
100
+ }
101
+
102
+ onLayerTypeSelect(layerName: string, selectedType: any) {
103
+ this.selectedLayerTypes[layerName] = selectedType
104
+ ? selectedType
105
+ : this.getLayerChoices(layerName)[0]?.value
106
+ }
107
+
108
+ async addLayer(layer: string, layerType: any) {
109
+ try {
110
+ const ogcEndpoint = await new OgcApiEndpoint(this.ogcUrl)
111
+ let layerUrl: string
112
+
113
+ if (layerType === 'vectorTiles') {
114
+ layerUrl = await ogcEndpoint.getVectorTilesetUrl(layer)
115
+ } else if (layerType === 'mapTiles') {
116
+ layerUrl = await ogcEndpoint.getMapTilesetUrl(layer)
117
+ } else {
118
+ layerUrl = await ogcEndpoint.getCollectionItemsUrl(layer, {
119
+ outputFormat: 'json',
120
+ })
121
+ }
122
+
123
+ const layerToAdd: MapContextLayerModel = {
124
+ name: layer,
125
+ url: layerUrl,
126
+ type: MapContextLayerTypeEnum.OGCAPI,
127
+ layerType: layerType,
128
+ }
129
+ this.layerAdded.emit({ ...layerToAdd, title: layer })
130
+ } catch (error) {
131
+ const err = error as Error
132
+ console.error('Error adding layer:', err.message)
77
133
  }
78
- this.layerAdded.emit({ ...layerToAdd, title: layer })
79
134
  }
80
135
  }
@@ -20,29 +20,35 @@ export interface MapContextLayerWmsModel {
20
20
  type: 'wms'
21
21
  url: string
22
22
  name: string
23
+ attributions?: string
23
24
  }
24
25
 
25
26
  export interface MapContextLayerWmtsModel {
26
27
  type: 'wmts'
27
28
  url: string
28
29
  name: string
30
+ attributions?: string
29
31
  }
30
32
 
31
33
  interface MapContextLayerWfsModel {
32
34
  type: 'wfs'
33
35
  url: string
34
36
  name: string
37
+ attributions?: string
35
38
  }
36
39
 
37
40
  export interface MapContextLayerOgcapiModel {
38
41
  type: 'ogcapi'
39
42
  url: string
40
43
  name: string
44
+ layerType: 'feature' | 'vectorTiles' | 'mapTiles' | 'record'
45
+ attributions?: string
41
46
  }
42
47
 
43
48
  interface LayerXyzModel {
44
49
  type: 'xyz'
45
50
  name?: string
51
+ attributions?: string
46
52
  }
47
53
  interface LayerXyzModelWithUrl extends LayerXyzModel {
48
54
  url: string
@@ -58,6 +64,7 @@ export type MapContextLayerXyzModel =
58
64
 
59
65
  interface LayerGeojson {
60
66
  type: 'geojson'
67
+ attributions?: string
61
68
  }
62
69
  interface LayerGeojsonWithUrl extends LayerGeojson {
63
70
  url: string