geonetwork-ui 2.5.0-dev.b51c2cb0f → 2.5.0-dev.caf47b863
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.
- package/esm2022/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.mjs +11 -1
- package/esm2022/libs/api/metadata-converter/src/lib/gn4/types/metadata.model.mjs +1 -1
- package/esm2022/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.mjs +34 -28
- package/esm2022/libs/api/repository/src/lib/gn4/gn4-repository.mjs +22 -2
- package/esm2022/libs/common/domain/src/lib/model/record/metadata.model.mjs +1 -1
- package/esm2022/libs/common/domain/src/lib/repository/records-repository.interface.mjs +1 -1
- package/esm2022/libs/feature/dataviz/src/lib/chart-view/chart-view.component.mjs +7 -4
- package/esm2022/libs/feature/dataviz/src/lib/service/data.service.mjs +24 -14
- package/esm2022/libs/feature/dataviz/src/lib/table-view/table-view.component.mjs +7 -4
- package/esm2022/libs/feature/editor/src/lib/components/constraint-card/constraint-card.component.mjs +3 -3
- package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts-for-resource/form-field-contacts-for-resource.component.mjs +2 -1
- package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.mjs +2 -2
- package/esm2022/libs/feature/editor/src/lib/fields.config.mjs +2 -2
- package/esm2022/libs/feature/record/src/lib/data-view/data-view.component.mjs +4 -3
- package/esm2022/libs/feature/record/src/lib/map-view/map-view.component.mjs +3 -2
- package/esm2022/libs/feature/record/src/lib/state/mdview.actions.mjs +4 -1
- package/esm2022/libs/feature/record/src/lib/state/mdview.effects.mjs +7 -2
- package/esm2022/libs/feature/record/src/lib/state/mdview.facade.mjs +9 -1
- package/esm2022/libs/feature/record/src/lib/state/mdview.reducer.mjs +19 -1
- package/esm2022/libs/feature/record/src/lib/state/mdview.selectors.mjs +6 -1
- package/esm2022/libs/feature/search/src/lib/results-table/results-table-container.component.mjs +1 -1
- package/esm2022/libs/feature/search/src/lib/utils/service/fields.mjs +46 -1
- package/esm2022/libs/feature/search/src/lib/utils/service/fields.service.mjs +3 -2
- package/esm2022/libs/ui/elements/src/index.mjs +2 -1
- package/esm2022/libs/ui/elements/src/lib/application-banner/application-banner.component.mjs +78 -0
- package/esm2022/libs/ui/elements/src/lib/markdown-parser/markdown-parser.component.mjs +3 -3
- package/esm2022/libs/ui/elements/src/lib/record-api-form/record-api-form.component.mjs +2 -1
- package/esm2022/libs/ui/elements/src/lib/ui-elements.module.mjs +10 -4
- package/esm2022/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.mjs +7 -2
- package/esm2022/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.mjs +14 -4
- package/esm2022/libs/ui/search/src/lib/results-table/results-table.component.mjs +10 -3
- package/esm2022/libs/util/data-fetcher/src/lib/data-fetcher.mjs +5 -4
- package/esm2022/libs/util/data-fetcher/src/lib/readers/base-cache.mjs +12 -0
- package/esm2022/libs/util/data-fetcher/src/lib/readers/base-file.mjs +3 -3
- package/esm2022/libs/util/data-fetcher/src/lib/readers/base.mjs +1 -1
- package/esm2022/libs/util/data-fetcher/src/lib/readers/csv.mjs +2 -2
- package/esm2022/libs/util/data-fetcher/src/lib/readers/excel.mjs +2 -2
- package/esm2022/libs/util/data-fetcher/src/lib/readers/geojson.mjs +2 -2
- package/esm2022/libs/util/data-fetcher/src/lib/readers/gml.mjs +5 -3
- package/esm2022/libs/util/data-fetcher/src/lib/readers/json.mjs +2 -2
- package/esm2022/libs/util/data-fetcher/src/lib/readers/wfs.mjs +19 -11
- package/esm2022/libs/util/data-fetcher/src/lib/utils.mjs +9 -7
- package/esm2022/translations/de.json +3 -4
- package/esm2022/translations/en.json +4 -13
- package/esm2022/translations/es.json +3 -4
- package/esm2022/translations/fr.json +15 -16
- package/esm2022/translations/it.json +20 -20
- package/esm2022/translations/nl.json +3 -4
- package/esm2022/translations/pt.json +3 -4
- package/fesm2022/geonetwork-ui.mjs +469 -218
- package/fesm2022/geonetwork-ui.mjs.map +1 -1
- package/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.d.ts.map +1 -1
- package/libs/api/metadata-converter/src/lib/gn4/types/metadata.model.d.ts +3 -0
- package/libs/api/metadata-converter/src/lib/gn4/types/metadata.model.d.ts.map +1 -1
- package/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.d.ts +1 -0
- package/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.d.ts.map +1 -1
- package/libs/api/repository/src/lib/gn4/gn4-repository.d.ts +2 -1
- package/libs/api/repository/src/lib/gn4/gn4-repository.d.ts.map +1 -1
- package/libs/common/domain/src/lib/model/record/metadata.model.d.ts +6 -0
- package/libs/common/domain/src/lib/model/record/metadata.model.d.ts.map +1 -1
- package/libs/common/domain/src/lib/repository/records-repository.interface.d.ts +2 -1
- package/libs/common/domain/src/lib/repository/records-repository.interface.d.ts.map +1 -1
- package/libs/feature/dataviz/src/lib/chart-view/chart-view.component.d.ts +2 -1
- package/libs/feature/dataviz/src/lib/chart-view/chart-view.component.d.ts.map +1 -1
- package/libs/feature/dataviz/src/lib/service/data.service.d.ts +2 -2
- package/libs/feature/dataviz/src/lib/service/data.service.d.ts.map +1 -1
- package/libs/feature/dataviz/src/lib/table-view/table-view.component.d.ts +2 -1
- package/libs/feature/dataviz/src/lib/table-view/table-view.component.d.ts.map +1 -1
- package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts-for-resource/form-field-contacts-for-resource.component.d.ts.map +1 -1
- package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.d.ts.map +1 -1
- package/libs/feature/record/src/lib/data-view/data-view.component.d.ts +1 -0
- package/libs/feature/record/src/lib/data-view/data-view.component.d.ts.map +1 -1
- package/libs/feature/record/src/lib/map-view/map-view.component.d.ts.map +1 -1
- package/libs/feature/record/src/lib/state/mdview.actions.d.ts +16 -1
- package/libs/feature/record/src/lib/state/mdview.actions.d.ts.map +1 -1
- package/libs/feature/record/src/lib/state/mdview.effects.d.ts +5 -0
- package/libs/feature/record/src/lib/state/mdview.effects.d.ts.map +1 -1
- package/libs/feature/record/src/lib/state/mdview.facade.d.ts +2 -0
- package/libs/feature/record/src/lib/state/mdview.facade.d.ts.map +1 -1
- package/libs/feature/record/src/lib/state/mdview.reducer.d.ts +4 -1
- package/libs/feature/record/src/lib/state/mdview.reducer.d.ts.map +1 -1
- package/libs/feature/record/src/lib/state/mdview.selectors.d.ts +2 -0
- package/libs/feature/record/src/lib/state/mdview.selectors.d.ts.map +1 -1
- package/libs/feature/search/src/lib/utils/service/fields.d.ts +10 -0
- package/libs/feature/search/src/lib/utils/service/fields.d.ts.map +1 -1
- package/libs/feature/search/src/lib/utils/service/fields.service.d.ts.map +1 -1
- package/libs/ui/elements/src/index.d.ts +1 -0
- package/libs/ui/elements/src/index.d.ts.map +1 -1
- package/libs/ui/elements/src/lib/application-banner/application-banner.component.d.ts +16 -0
- package/libs/ui/elements/src/lib/application-banner/application-banner.component.d.ts.map +1 -0
- package/libs/ui/elements/src/lib/record-api-form/record-api-form.component.d.ts.map +1 -1
- package/libs/ui/elements/src/lib/ui-elements.module.d.ts +2 -1
- package/libs/ui/elements/src/lib/ui-elements.module.d.ts.map +1 -1
- package/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.d.ts.map +1 -1
- package/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.d.ts +4 -2
- package/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.d.ts.map +1 -1
- package/libs/ui/search/src/lib/results-table/results-table.component.d.ts +3 -1
- package/libs/ui/search/src/lib/results-table/results-table.component.d.ts.map +1 -1
- package/libs/util/data-fetcher/src/lib/data-fetcher.d.ts +2 -2
- package/libs/util/data-fetcher/src/lib/data-fetcher.d.ts.map +1 -1
- package/libs/util/data-fetcher/src/lib/readers/base-cache.d.ts +8 -0
- package/libs/util/data-fetcher/src/lib/readers/base-cache.d.ts.map +1 -0
- package/libs/util/data-fetcher/src/lib/readers/base-file.d.ts +2 -2
- package/libs/util/data-fetcher/src/lib/readers/base-file.d.ts.map +1 -1
- package/libs/util/data-fetcher/src/lib/readers/base.d.ts +2 -2
- package/libs/util/data-fetcher/src/lib/readers/base.d.ts.map +1 -1
- package/libs/util/data-fetcher/src/lib/readers/gml.d.ts +5 -3
- package/libs/util/data-fetcher/src/lib/readers/gml.d.ts.map +1 -1
- package/libs/util/data-fetcher/src/lib/readers/wfs.d.ts +7 -4
- package/libs/util/data-fetcher/src/lib/readers/wfs.d.ts.map +1 -1
- package/libs/util/data-fetcher/src/lib/utils.d.ts +2 -2
- package/libs/util/data-fetcher/src/lib/utils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts +25 -0
- package/src/libs/api/metadata-converter/src/lib/gn4/types/metadata.model.ts +4 -0
- package/src/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.ts +36 -27
- package/src/libs/api/repository/src/lib/gn4/gn4-repository.ts +41 -2
- package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +3 -1
- package/src/libs/common/domain/src/lib/repository/records-repository.interface.ts +4 -1
- package/src/libs/common/fixtures/src/lib/records.fixtures.ts +75 -0
- package/src/libs/feature/dataviz/src/lib/chart-view/chart-view.component.ts +4 -1
- package/src/libs/feature/dataviz/src/lib/service/data.service.ts +43 -20
- package/src/libs/feature/dataviz/src/lib/table-view/table-view.component.ts +2 -1
- package/src/libs/feature/editor/src/lib/components/constraint-card/constraint-card.component.html +1 -1
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts-for-resource/form-field-contacts-for-resource.component.ts +1 -0
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.ts +1 -1
- package/src/libs/feature/editor/src/lib/fields.config.ts +1 -1
- package/src/libs/feature/record/src/lib/data-view/data-view.component.html +2 -0
- package/src/libs/feature/record/src/lib/data-view/data-view.component.ts +3 -0
- package/src/libs/feature/record/src/lib/map-view/map-view.component.ts +2 -1
- package/src/libs/feature/record/src/lib/state/mdview.actions.ts +16 -0
- package/src/libs/feature/record/src/lib/state/mdview.effects.ts +21 -2
- package/src/libs/feature/record/src/lib/state/mdview.facade.ts +15 -0
- package/src/libs/feature/record/src/lib/state/mdview.reducer.ts +30 -1
- package/src/libs/feature/record/src/lib/state/mdview.selectors.ts +12 -0
- package/src/libs/feature/search/src/lib/utils/service/fields.service.ts +2 -0
- package/src/libs/feature/search/src/lib/utils/service/fields.ts +55 -0
- package/src/libs/ui/elements/src/index.ts +1 -0
- package/src/libs/ui/elements/src/lib/application-banner/application-banner.component.css +0 -0
- package/src/libs/ui/elements/src/lib/application-banner/application-banner.component.html +25 -0
- package/src/libs/ui/elements/src/lib/application-banner/application-banner.component.ts +70 -0
- package/src/libs/ui/elements/src/lib/markdown-parser/markdown-parser.component.ts +2 -2
- package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.ts +2 -0
- package/src/libs/ui/elements/src/lib/ui-elements.module.ts +3 -0
- package/src/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.ts +6 -0
- package/src/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.html +37 -1
- package/src/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.ts +8 -2
- package/src/libs/ui/search/src/lib/results-table/results-table.component.html +2 -0
- package/src/libs/ui/search/src/lib/results-table/results-table.component.ts +6 -0
- package/src/libs/util/data-fetcher/src/lib/data-fetcher.ts +13 -4
- package/src/libs/util/data-fetcher/src/lib/readers/base-cache.ts +14 -0
- package/src/libs/util/data-fetcher/src/lib/readers/base-file.ts +2 -1
- package/src/libs/util/data-fetcher/src/lib/readers/base.ts +2 -2
- package/src/libs/util/data-fetcher/src/lib/readers/csv.ts +1 -1
- package/src/libs/util/data-fetcher/src/lib/readers/excel.ts +1 -1
- package/src/libs/util/data-fetcher/src/lib/readers/geojson.ts +1 -1
- package/src/libs/util/data-fetcher/src/lib/readers/gml.ts +7 -7
- package/src/libs/util/data-fetcher/src/lib/readers/json.ts +1 -1
- package/src/libs/util/data-fetcher/src/lib/readers/wfs.ts +34 -11
- package/src/libs/util/data-fetcher/src/lib/utils.ts +36 -32
- package/translations/de.json +3 -4
- package/translations/en.json +4 -13
- package/translations/es.json +3 -4
- package/translations/fr.json +15 -16
- package/translations/it.json +20 -20
- package/translations/nl.json +3 -4
- package/translations/pt.json +3 -4
- package/translations/sk.json +3 -4
|
@@ -164,17 +164,26 @@ export class DataService {
|
|
|
164
164
|
wfsLink.url.toString(),
|
|
165
165
|
wfsLink.name
|
|
166
166
|
).pipe(
|
|
167
|
-
map((urls) =>
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
)
|
|
176
|
-
|
|
177
|
-
|
|
167
|
+
map((urls) => {
|
|
168
|
+
if (urls.geojson) {
|
|
169
|
+
urls.all['application/json'] = urls.geojson
|
|
170
|
+
}
|
|
171
|
+
return urls
|
|
172
|
+
}),
|
|
173
|
+
map((urls) => {
|
|
174
|
+
const resources: DatasetOnlineResource[] = Object.keys(urls.all).map(
|
|
175
|
+
(format) => ({
|
|
176
|
+
...wfsLink,
|
|
177
|
+
name: wfsLink.name,
|
|
178
|
+
type: 'download' as const,
|
|
179
|
+
url: new URL(urls.all[format]),
|
|
180
|
+
mimeType: getMimeTypeForFormat(
|
|
181
|
+
getFileFormatFromServiceOutput(format)
|
|
182
|
+
),
|
|
183
|
+
})
|
|
184
|
+
)
|
|
185
|
+
return resources
|
|
186
|
+
})
|
|
178
187
|
)
|
|
179
188
|
}
|
|
180
189
|
|
|
@@ -187,6 +196,7 @@ export class DataService {
|
|
|
187
196
|
return Object.keys(collectionInfo.bulkDownloadLinks).map((downloadLink) => {
|
|
188
197
|
return {
|
|
189
198
|
...ogcApiLink,
|
|
199
|
+
name: collectionInfo.id,
|
|
190
200
|
type: 'download',
|
|
191
201
|
url: new URL(collectionInfo.bulkDownloadLinks[downloadLink]),
|
|
192
202
|
mimeType: getMimeTypeForFormat(
|
|
@@ -232,8 +242,11 @@ export class DataService {
|
|
|
232
242
|
}))
|
|
233
243
|
}
|
|
234
244
|
|
|
235
|
-
readAsGeoJson(
|
|
236
|
-
|
|
245
|
+
readAsGeoJson(
|
|
246
|
+
link: DatasetOnlineResource,
|
|
247
|
+
cacheActive: boolean
|
|
248
|
+
): Observable<FeatureCollection> {
|
|
249
|
+
return this.getDataset(link, cacheActive).pipe(
|
|
237
250
|
switchMap((dataset) => dataset.selectAll().read()),
|
|
238
251
|
map((features) => ({
|
|
239
252
|
type: 'FeatureCollection',
|
|
@@ -242,13 +255,21 @@ export class DataService {
|
|
|
242
255
|
)
|
|
243
256
|
}
|
|
244
257
|
|
|
245
|
-
getDataset(
|
|
258
|
+
getDataset(
|
|
259
|
+
link: DatasetOnlineResource,
|
|
260
|
+
cacheActive: boolean
|
|
261
|
+
): Observable<BaseReader> {
|
|
246
262
|
if (link.type === 'service' && link.accessServiceProtocol === 'wfs') {
|
|
247
263
|
const wfsUrlEndpoint = this.proxy.getProxiedUrl(link.url.toString())
|
|
248
264
|
return from(
|
|
249
|
-
openDataset(
|
|
250
|
-
|
|
251
|
-
|
|
265
|
+
openDataset(
|
|
266
|
+
wfsUrlEndpoint,
|
|
267
|
+
'wfs',
|
|
268
|
+
{
|
|
269
|
+
wfsFeatureType: link.name,
|
|
270
|
+
},
|
|
271
|
+
cacheActive
|
|
272
|
+
)
|
|
252
273
|
)
|
|
253
274
|
} else if (link.type === 'download') {
|
|
254
275
|
const linkProxifiedUrl = this.proxy.getProxiedUrl(link.url.toString())
|
|
@@ -257,7 +278,9 @@ export class DataService {
|
|
|
257
278
|
SupportedTypes.indexOf(format as any) > -1
|
|
258
279
|
? (format as SupportedType)
|
|
259
280
|
: undefined
|
|
260
|
-
return from(
|
|
281
|
+
return from(
|
|
282
|
+
openDataset(linkProxifiedUrl, supportedType, undefined, cacheActive)
|
|
283
|
+
).pipe()
|
|
261
284
|
} else if (
|
|
262
285
|
link.type === 'service' &&
|
|
263
286
|
link.accessServiceProtocol === 'esriRest'
|
|
@@ -266,7 +289,7 @@ export class DataService {
|
|
|
266
289
|
link.url.toString(),
|
|
267
290
|
'geojson'
|
|
268
291
|
)
|
|
269
|
-
return from(openDataset(url, 'geojson')).pipe()
|
|
292
|
+
return from(openDataset(url, 'geojson', undefined, cacheActive)).pipe()
|
|
270
293
|
} else if (
|
|
271
294
|
link.type === 'service' &&
|
|
272
295
|
link.accessServiceProtocol === 'ogcFeatures'
|
|
@@ -274,7 +297,7 @@ export class DataService {
|
|
|
274
297
|
return from(this.getDownloadUrlsFromOgcApi(link.url.href)).pipe(
|
|
275
298
|
switchMap((collectionInfo) => {
|
|
276
299
|
const geojsonUrl = collectionInfo.jsonDownloadLink
|
|
277
|
-
return openDataset(geojsonUrl, 'geojson')
|
|
300
|
+
return openDataset(geojsonUrl, 'geojson', undefined, cacheActive)
|
|
278
301
|
}),
|
|
279
302
|
tap((url) => {
|
|
280
303
|
if (url === null) {
|
|
@@ -33,6 +33,7 @@ import { CommonModule } from '@angular/common'
|
|
|
33
33
|
standalone: true,
|
|
34
34
|
})
|
|
35
35
|
export class TableViewComponent {
|
|
36
|
+
@Input() cacheActive = true
|
|
36
37
|
@Input() set link(value: DatasetOnlineResource) {
|
|
37
38
|
this.currentLink$.next(value)
|
|
38
39
|
}
|
|
@@ -66,7 +67,7 @@ export class TableViewComponent {
|
|
|
66
67
|
) {}
|
|
67
68
|
|
|
68
69
|
getDatasetReader(link: DatasetOnlineResource): Observable<BaseReader> {
|
|
69
|
-
return this.dataService.getDataset(link)
|
|
70
|
+
return this.dataService.getDataset(link, this.cacheActive)
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
onTableSelect(event) {
|
|
@@ -28,7 +28,7 @@ import { FormFieldWrapperComponent } from '../../../../../../../../../libs/ui/la
|
|
|
28
28
|
export class FormFieldRichComponent {
|
|
29
29
|
@Input() label: string
|
|
30
30
|
@Input() hint: string
|
|
31
|
-
@Input() placeholder = '
|
|
31
|
+
@Input() placeholder = ''
|
|
32
32
|
@Input() value: string
|
|
33
33
|
|
|
34
34
|
@Output() valueChange: EventEmitter<string> = new EventEmitter()
|
|
@@ -275,8 +275,8 @@ export const DEFAULT_CONFIGURATION: EditorConfig = {
|
|
|
275
275
|
labelKey: marker('editor.record.form.page.description'),
|
|
276
276
|
sections: [
|
|
277
277
|
TITLE_SECTION,
|
|
278
|
-
ABOUT_SECTION,
|
|
279
278
|
CLASSIFICATION_SECTION,
|
|
279
|
+
ABOUT_SECTION,
|
|
280
280
|
GEOGRAPHICAL_COVERAGE_SECTION,
|
|
281
281
|
],
|
|
282
282
|
},
|
|
@@ -11,11 +11,13 @@
|
|
|
11
11
|
<div class="relative h-[460px]">
|
|
12
12
|
<gn-ui-table-view
|
|
13
13
|
*ngIf="mode === 'table'"
|
|
14
|
+
[cacheActive]="cacheActive$ | async"
|
|
14
15
|
[link]="selectedLink$ | async"
|
|
15
16
|
></gn-ui-table-view>
|
|
16
17
|
<gn-ui-chart-view
|
|
17
18
|
*ngIf="mode === 'chart'"
|
|
18
19
|
(chartConfig$)="setChartConfig($event)"
|
|
20
|
+
[cacheActive]="cacheActive$ | async"
|
|
19
21
|
[link]="selectedLink$ | async"
|
|
20
22
|
></gn-ui-chart-view>
|
|
21
23
|
</div>
|
|
@@ -36,6 +36,9 @@ export class DataViewComponent {
|
|
|
36
36
|
@Input() mode: 'table' | 'chart'
|
|
37
37
|
@Input() displaySource = true
|
|
38
38
|
@Output() chartConfig$ = new BehaviorSubject<DatavizConfigurationModel>(null)
|
|
39
|
+
cacheActive$ = this.mdViewFacade.isHighUpdateFrequency$.pipe(
|
|
40
|
+
map((highF) => !highF)
|
|
41
|
+
)
|
|
39
42
|
compatibleDataLinks$ = combineLatest([
|
|
40
43
|
this.mdViewFacade.dataLinks$,
|
|
41
44
|
this.mdViewFacade.geoDataLinks$,
|
|
@@ -239,7 +239,8 @@ export class MapViewComponent implements AfterViewInit {
|
|
|
239
239
|
link.accessServiceProtocol === 'ogcFeatures')) ||
|
|
240
240
|
link.type === 'download'
|
|
241
241
|
) {
|
|
242
|
-
|
|
242
|
+
const cacheActive = true // TODO implement whether should be true or false
|
|
243
|
+
return this.dataService.readAsGeoJson(link, cacheActive).pipe(
|
|
243
244
|
map((data) => ({
|
|
244
245
|
type: 'geojson',
|
|
245
246
|
data,
|
|
@@ -2,6 +2,7 @@ import { DatavizConfigurationModel } from '../../../../../../libs/common/domain/
|
|
|
2
2
|
import { createAction, props } from '@ngrx/store'
|
|
3
3
|
import {
|
|
4
4
|
CatalogRecord,
|
|
5
|
+
DatasetFeatureCatalog,
|
|
5
6
|
UserFeedback,
|
|
6
7
|
} from '../../../../../../libs/common/domain/src/lib/model/record'
|
|
7
8
|
|
|
@@ -28,6 +29,21 @@ export const loadFullMetadataFailure = createAction(
|
|
|
28
29
|
props<{ otherError?: string; notFound?: boolean }>()
|
|
29
30
|
)
|
|
30
31
|
|
|
32
|
+
export const loadFeatureCatalog = createAction(
|
|
33
|
+
"[Metadata view] Load metadata's feature catalog",
|
|
34
|
+
props<{ metadata: CatalogRecord }>()
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
export const loadFeatureCatalogSuccess = createAction(
|
|
38
|
+
'[Metadata view] Load metadata feature catalog success',
|
|
39
|
+
props<{ datasetCatalog: DatasetFeatureCatalog | null }>()
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
export const loadFeatureCatalogFailure = createAction(
|
|
43
|
+
'[Metadata view] Load metadata feature catalog failure',
|
|
44
|
+
props<{ error?: string }>()
|
|
45
|
+
)
|
|
46
|
+
|
|
31
47
|
export const closeMetadata = createAction('[Metadata view] close')
|
|
32
48
|
|
|
33
49
|
/*
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { Injectable } from '@angular/core'
|
|
2
2
|
import { Actions, createEffect, ofType } from '@ngrx/effects'
|
|
3
3
|
import { exhaustMap, mergeMap, of } from 'rxjs'
|
|
4
|
-
import { catchError, map, switchMap } from 'rxjs/operators'
|
|
4
|
+
import { catchError, filter, map, switchMap, take } from 'rxjs/operators'
|
|
5
5
|
import * as MdViewActions from './mdview.actions'
|
|
6
6
|
import { RecordsRepositoryInterface } from '../../../../../../libs/common/domain/src/lib/repository/records-repository.interface'
|
|
7
7
|
import { PlatformServiceInterface } from '../../../../../../libs/common/domain/src/lib/platform.service.interface'
|
|
8
|
-
|
|
9
8
|
@Injectable()
|
|
10
9
|
export class MdViewEffects {
|
|
11
10
|
constructor(
|
|
@@ -33,6 +32,26 @@ export class MdViewEffects {
|
|
|
33
32
|
)
|
|
34
33
|
)
|
|
35
34
|
|
|
35
|
+
loadFeatureCatalog$ = createEffect(() =>
|
|
36
|
+
this.actions$.pipe(
|
|
37
|
+
ofType(MdViewActions.loadFullMetadataSuccess),
|
|
38
|
+
filter(({ full }) => full !== undefined),
|
|
39
|
+
switchMap(({ full }) => this.recordsRepository.getFeatureCatalog(full)),
|
|
40
|
+
map((featureCatalog) =>
|
|
41
|
+
MdViewActions.loadFeatureCatalogSuccess({
|
|
42
|
+
datasetCatalog: featureCatalog,
|
|
43
|
+
})
|
|
44
|
+
),
|
|
45
|
+
catchError((error) =>
|
|
46
|
+
of(
|
|
47
|
+
MdViewActions.loadFeatureCatalogFailure({
|
|
48
|
+
error: error.message,
|
|
49
|
+
})
|
|
50
|
+
)
|
|
51
|
+
)
|
|
52
|
+
)
|
|
53
|
+
)
|
|
54
|
+
|
|
36
55
|
/*
|
|
37
56
|
Related effects
|
|
38
57
|
*/
|
|
@@ -52,11 +52,26 @@ export class MdViewFacade {
|
|
|
52
52
|
filter((md) => !!md)
|
|
53
53
|
)
|
|
54
54
|
|
|
55
|
+
featureCatalog$ = this.store.pipe(select(MdViewSelectors.getFeatureCatalog))
|
|
56
|
+
|
|
55
57
|
isIncomplete$ = this.store.pipe(
|
|
56
58
|
select(MdViewSelectors.getMetadataIsIncomplete),
|
|
57
59
|
filter((incomplete) => incomplete !== null)
|
|
58
60
|
)
|
|
59
61
|
|
|
62
|
+
isHighUpdateFrequency$ = this.metadata$.pipe(
|
|
63
|
+
map((record) => {
|
|
64
|
+
if (record.updateFrequency instanceof Object) {
|
|
65
|
+
return (
|
|
66
|
+
record.updateFrequency.per === 'day' &&
|
|
67
|
+
record.updateFrequency.updatedTimes > 1
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return record.updateFrequency === 'continual'
|
|
72
|
+
})
|
|
73
|
+
)
|
|
74
|
+
|
|
60
75
|
error$ = this.store.pipe(select(MdViewSelectors.getMetadataError))
|
|
61
76
|
|
|
62
77
|
related$ = this.store.pipe(select(MdViewSelectors.getRelated))
|
|
@@ -3,6 +3,7 @@ import * as MetadataViewActions from './mdview.actions'
|
|
|
3
3
|
import { DatavizConfigurationModel } from '../../../../../../libs/common/domain/src/lib/model/dataviz/dataviz-configuration.model'
|
|
4
4
|
import {
|
|
5
5
|
CatalogRecord,
|
|
6
|
+
DatasetFeatureCatalog,
|
|
6
7
|
UserFeedback,
|
|
7
8
|
} from '../../../../../../libs/common/domain/src/lib/model/record'
|
|
8
9
|
|
|
@@ -17,6 +18,9 @@ export interface MetadataViewState {
|
|
|
17
18
|
allUserFeedbacksLoading: boolean
|
|
18
19
|
addUserFeedbackLoading: boolean
|
|
19
20
|
chartConfig?: DatavizConfigurationModel
|
|
21
|
+
featureCatalog?: DatasetFeatureCatalog
|
|
22
|
+
featureCatalogLoading: boolean
|
|
23
|
+
featureCatalogError: string | null
|
|
20
24
|
}
|
|
21
25
|
|
|
22
26
|
export const initialMetadataViewState: MetadataViewState = {
|
|
@@ -24,6 +28,8 @@ export const initialMetadataViewState: MetadataViewState = {
|
|
|
24
28
|
loadingFull: false,
|
|
25
29
|
allUserFeedbacksLoading: false,
|
|
26
30
|
addUserFeedbackLoading: false,
|
|
31
|
+
featureCatalogLoading: false,
|
|
32
|
+
featureCatalogError: null,
|
|
27
33
|
}
|
|
28
34
|
|
|
29
35
|
const metadataViewReducer = createReducer(
|
|
@@ -105,7 +111,30 @@ const metadataViewReducer = createReducer(
|
|
|
105
111
|
addUserFeedbackLoading: false,
|
|
106
112
|
allUserFeedbacksLoading: false,
|
|
107
113
|
})
|
|
108
|
-
)
|
|
114
|
+
),
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* FeatureCatalog reducers
|
|
118
|
+
*/
|
|
119
|
+
|
|
120
|
+
on(MetadataViewActions.loadFeatureCatalog, (state) => ({
|
|
121
|
+
...state,
|
|
122
|
+
featureCatalogError: null,
|
|
123
|
+
featureCatalogLoading: true,
|
|
124
|
+
})),
|
|
125
|
+
on(
|
|
126
|
+
MetadataViewActions.loadFeatureCatalogSuccess,
|
|
127
|
+
(state, { datasetCatalog }) => ({
|
|
128
|
+
...state,
|
|
129
|
+
featureCatalog: datasetCatalog,
|
|
130
|
+
featureCatalogLoading: false,
|
|
131
|
+
})
|
|
132
|
+
),
|
|
133
|
+
on(MetadataViewActions.loadFeatureCatalogFailure, (state, { error }) => ({
|
|
134
|
+
...state,
|
|
135
|
+
featureCatalogError: error,
|
|
136
|
+
featureCatalogLoading: false,
|
|
137
|
+
}))
|
|
109
138
|
)
|
|
110
139
|
|
|
111
140
|
export function reducer(
|
|
@@ -64,3 +64,15 @@ export const getAddUserFeedbacksLoading = createSelector(
|
|
|
64
64
|
getMdViewState,
|
|
65
65
|
(state: MetadataViewState) => state.addUserFeedbackLoading
|
|
66
66
|
)
|
|
67
|
+
|
|
68
|
+
/*
|
|
69
|
+
Feature Catalog Selectors
|
|
70
|
+
*/
|
|
71
|
+
export const getFeatureCatalog = createSelector(
|
|
72
|
+
getMdViewState,
|
|
73
|
+
(state: MetadataViewState) => state.featureCatalog
|
|
74
|
+
)
|
|
75
|
+
export const getFeatureCatalogIsLoading = createSelector(
|
|
76
|
+
getMdViewState,
|
|
77
|
+
(state: MetadataViewState) => state.featureCatalogLoading
|
|
78
|
+
)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Injectable, Injector } from '@angular/core'
|
|
2
2
|
import {
|
|
3
3
|
AbstractSearchField,
|
|
4
|
+
AvailableServicesField,
|
|
4
5
|
DateRangeSearchField,
|
|
5
6
|
FieldValue,
|
|
6
7
|
FullTextSearchField,
|
|
@@ -91,6 +92,7 @@ export class FieldsService {
|
|
|
91
92
|
),
|
|
92
93
|
user: new UserSearchField(this.injector),
|
|
93
94
|
changeDate: new DateRangeSearchField('changeDate', this.injector, 'desc'),
|
|
95
|
+
availableServices: new AvailableServicesField(this.injector),
|
|
94
96
|
} as Record<string, AbstractSearchField>
|
|
95
97
|
|
|
96
98
|
get supportedFields() {
|
|
@@ -9,6 +9,7 @@ import { PlatformServiceInterface } from '../../../../../../../libs/common/domai
|
|
|
9
9
|
import {
|
|
10
10
|
AggregationBuckets,
|
|
11
11
|
AggregationsParams,
|
|
12
|
+
FieldFilter,
|
|
12
13
|
FieldFilterByExpression,
|
|
13
14
|
FieldFilters,
|
|
14
15
|
TermBucket,
|
|
@@ -425,3 +426,57 @@ export class DateRangeSearchField extends SimpleSearchField {
|
|
|
425
426
|
return 'dateRange'
|
|
426
427
|
}
|
|
427
428
|
}
|
|
429
|
+
|
|
430
|
+
marker('search.filters.availableServices.view')
|
|
431
|
+
marker('search.filters.availableServices.download')
|
|
432
|
+
|
|
433
|
+
export class AvailableServicesField extends SimpleSearchField {
|
|
434
|
+
private translateService = this.injector.get(TranslateService)
|
|
435
|
+
|
|
436
|
+
constructor(injector: Injector) {
|
|
437
|
+
super('availableServices', injector, 'asc')
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
linkProtocolViewFilter = '/OGC:WMT?S.*/'
|
|
441
|
+
linkProtocolDownloadFilter = '/OGC:WFS.*/'
|
|
442
|
+
|
|
443
|
+
protected async getBucketLabel(bucket: TermBucket) {
|
|
444
|
+
return firstValueFrom(
|
|
445
|
+
this.translateService.get(
|
|
446
|
+
`search.filters.availableServices.${bucket.term}`
|
|
447
|
+
)
|
|
448
|
+
)
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
protected getAggregations(): AggregationsParams {
|
|
452
|
+
return {
|
|
453
|
+
availableServices: {
|
|
454
|
+
type: 'filters',
|
|
455
|
+
filters: {
|
|
456
|
+
view: `+linkProtocol:${this.linkProtocolViewFilter}`,
|
|
457
|
+
download: `+linkProtocol:${this.linkProtocolDownloadFilter}`,
|
|
458
|
+
},
|
|
459
|
+
},
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
getFiltersForValues(values: FieldValue[]): Observable<FieldFilters> {
|
|
464
|
+
const filters: FieldFilter = {}
|
|
465
|
+
if (values.includes('view')) filters[this.linkProtocolViewFilter] = true
|
|
466
|
+
if (values.includes('download'))
|
|
467
|
+
filters[this.linkProtocolDownloadFilter] = true
|
|
468
|
+
|
|
469
|
+
return of({
|
|
470
|
+
linkProtocol: filters,
|
|
471
|
+
})
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
getValuesForFilter(filters: FieldFilters): Observable<FieldValue[]> {
|
|
475
|
+
const linkFilter = filters.linkProtocol
|
|
476
|
+
if (!linkFilter) return of([])
|
|
477
|
+
const values = []
|
|
478
|
+
if (linkFilter[this.linkProtocolViewFilter]) values.push('view')
|
|
479
|
+
if (linkFilter[this.linkProtocolDownloadFilter]) values.push('download')
|
|
480
|
+
return of(values)
|
|
481
|
+
}
|
|
482
|
+
}
|
|
@@ -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'
|
|
File without changes
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<div
|
|
2
|
+
*ngIf="message && bannerOpen"
|
|
3
|
+
class="absolute left-0 right-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]="message.length > 200 ? 'pt-5' : 'pt-1'">
|
|
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
|
|
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
|
}
|
|
@@ -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([])
|