geonetwork-ui 2.5.0-dev.da7bc314b → 2.5.0-dev.ed99f2ef4
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 +20 -17
- 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 +8 -8
- 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/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 +310 -195
- 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/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 +22 -16
- 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 +22 -9
- 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/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
|
@@ -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
|
+
)
|
|
@@ -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([])
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
>
|
|
7
7
|
<ul class="flex flex-col gap-2 w-full">
|
|
8
8
|
<gn-ui-button
|
|
9
|
+
*ngIf="!isDraftPage"
|
|
9
10
|
type="light"
|
|
10
11
|
extraClass="flex flex-row items-center gap-2 w-full justify-start"
|
|
11
12
|
(buttonClick)="duplicate.emit()"
|
|
@@ -23,7 +24,10 @@
|
|
|
23
24
|
(buttonClick)="displayDeleteMenu()"
|
|
24
25
|
[disabled]="!canDelete"
|
|
25
26
|
data-test="record-menu-delete-button"
|
|
26
|
-
><span translate>record.action.delete</span
|
|
27
|
+
><span *ngIf="!isDraftPage" translate>record.action.delete</span>
|
|
28
|
+
<span *ngIf="isDraftPage" translate
|
|
29
|
+
>record.action.rollback</span
|
|
30
|
+
></gn-ui-button
|
|
27
31
|
>
|
|
28
32
|
</ul>
|
|
29
33
|
</div>
|
|
@@ -60,4 +64,36 @@
|
|
|
60
64
|
</div>
|
|
61
65
|
</div>
|
|
62
66
|
</ng-container>
|
|
67
|
+
<ng-container *ngSwitchCase="'rollbackMenu'">
|
|
68
|
+
<div
|
|
69
|
+
data-test="rollbackMenuSection"
|
|
70
|
+
class="w-80 p-6 flex flex-col gap-3 mt-2 border border-gray-100 bg-white shadow-2xl rounded-2xl"
|
|
71
|
+
>
|
|
72
|
+
<span class="text-lg font-bold text-center">{{
|
|
73
|
+
'editor.record.undo.confirmation.title' | translate
|
|
74
|
+
}}</span>
|
|
75
|
+
<span class="text-center">{{
|
|
76
|
+
'editor.record.undo.confirmation.message' | translate
|
|
77
|
+
}}</span>
|
|
78
|
+
<div class="flex flex-row gap-8 justify-center">
|
|
79
|
+
<gn-ui-button
|
|
80
|
+
(buttonClick)="rollback.emit()"
|
|
81
|
+
cdkFocusInitial
|
|
82
|
+
type="primary"
|
|
83
|
+
data-cy="confirm-button"
|
|
84
|
+
[style.--gn-ui-button-width]="'120px'"
|
|
85
|
+
>{{
|
|
86
|
+
'editor.record.undo.confirmation.confirmText' | translate
|
|
87
|
+
}}</gn-ui-button
|
|
88
|
+
>
|
|
89
|
+
<gn-ui-button
|
|
90
|
+
[style.--gn-ui-button-width]="'120px'"
|
|
91
|
+
(buttonClick)="closeActionMenu.emit()"
|
|
92
|
+
>{{
|
|
93
|
+
'editor.record.undo.confirmation.cancelText' | translate
|
|
94
|
+
}}</gn-ui-button
|
|
95
|
+
>
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
</ng-container>
|
|
63
99
|
</ng-container>
|
|
@@ -13,7 +13,7 @@ import { ConfirmationDialogComponent } from '../../../../../../../libs/ui/elemen
|
|
|
13
13
|
import { ButtonComponent } from '../../../../../../../libs/ui/inputs/src'
|
|
14
14
|
import { TranslateModule } from '@ngx-translate/core'
|
|
15
15
|
|
|
16
|
-
type ActionMenuPage = 'mainMenu' | 'deleteMenu'
|
|
16
|
+
type ActionMenuPage = 'mainMenu' | 'deleteMenu' | 'rollbackMenu'
|
|
17
17
|
|
|
18
18
|
@Component({
|
|
19
19
|
selector: 'gn-ui-action-menu',
|
|
@@ -32,9 +32,11 @@ type ActionMenuPage = 'mainMenu' | 'deleteMenu'
|
|
|
32
32
|
export class ActionMenuComponent {
|
|
33
33
|
@Input() canDuplicate: boolean
|
|
34
34
|
@Input() canDelete: boolean
|
|
35
|
+
@Input() isDraftPage: boolean
|
|
35
36
|
@Output() duplicate = new EventEmitter<void>()
|
|
36
37
|
@Output() delete = new EventEmitter<void>()
|
|
37
38
|
@Output() closeActionMenu = new EventEmitter<void>()
|
|
39
|
+
@Output() rollback = new EventEmitter<void>()
|
|
38
40
|
|
|
39
41
|
@ViewChild(MatMenuTrigger) trigger: MatMenuTrigger
|
|
40
42
|
|
|
@@ -55,7 +57,11 @@ export class ActionMenuComponent {
|
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
displayDeleteMenu() {
|
|
58
|
-
this.
|
|
60
|
+
if (this.isDraftPage) {
|
|
61
|
+
this.sectionDisplayed = 'rollbackMenu'
|
|
62
|
+
} else {
|
|
63
|
+
this.sectionDisplayed = 'deleteMenu'
|
|
64
|
+
}
|
|
59
65
|
this.cdr.markForCheck()
|
|
60
66
|
}
|
|
61
67
|
}
|
|
@@ -162,9 +162,11 @@
|
|
|
162
162
|
<gn-ui-action-menu
|
|
163
163
|
[canDuplicate]="canDuplicate(item) && !isDuplicating"
|
|
164
164
|
[canDelete]="canDelete(item)"
|
|
165
|
+
[isDraftPage]="isDraftPage"
|
|
165
166
|
(duplicate)="handleDuplicate(item)"
|
|
166
167
|
(delete)="handleDelete(item)"
|
|
167
168
|
(closeActionMenu)="closeActionMenu()"
|
|
169
|
+
(rollback)="handleRollback(item)"
|
|
168
170
|
>
|
|
169
171
|
</gn-ui-action-menu>
|
|
170
172
|
</ng-template>
|
|
@@ -74,6 +74,7 @@ export class ResultsTableComponent {
|
|
|
74
74
|
@Output() recordClick = new EventEmitter<CatalogRecord>()
|
|
75
75
|
@Output() duplicateRecord = new EventEmitter<CatalogRecord>()
|
|
76
76
|
@Output() deleteRecord = new EventEmitter<CatalogRecord>()
|
|
77
|
+
@Output() rollbackDraft = new EventEmitter<CatalogRecord>()
|
|
77
78
|
@Output() recordsSelectedChange = new EventEmitter<
|
|
78
79
|
[CatalogRecord[], boolean]
|
|
79
80
|
>()
|
|
@@ -186,6 +187,11 @@ export class ResultsTableComponent {
|
|
|
186
187
|
this.closeActionMenu()
|
|
187
188
|
}
|
|
188
189
|
|
|
190
|
+
handleRollback(item: unknown) {
|
|
191
|
+
this.rollbackDraft.emit(item as CatalogRecord)
|
|
192
|
+
this.closeActionMenu()
|
|
193
|
+
}
|
|
194
|
+
|
|
189
195
|
setSortBy(col: string, order: 'asc' | 'desc') {
|
|
190
196
|
this.sortByChange.emit([col, order])
|
|
191
197
|
}
|
|
@@ -17,10 +17,17 @@ export async function openDataset(
|
|
|
17
17
|
namespace?: string
|
|
18
18
|
wfsVersion?: WfsVersion
|
|
19
19
|
wfsFeatureType?: string
|
|
20
|
-
}
|
|
20
|
+
},
|
|
21
|
+
cacheActive?: boolean
|
|
21
22
|
): Promise<BaseReader> {
|
|
22
23
|
const fileType = await inferDatasetType(url, typeHint)
|
|
23
|
-
let reader:
|
|
24
|
+
let reader:
|
|
25
|
+
| CsvReader
|
|
26
|
+
| JsonReader
|
|
27
|
+
| GeojsonReader
|
|
28
|
+
| ExcelReader
|
|
29
|
+
| GmlReader
|
|
30
|
+
| WfsReader
|
|
24
31
|
try {
|
|
25
32
|
switch (fileType) {
|
|
26
33
|
case 'csv':
|
|
@@ -42,6 +49,7 @@ export async function openDataset(
|
|
|
42
49
|
reader = await WfsReader.createReader(url, options.wfsFeatureType)
|
|
43
50
|
break
|
|
44
51
|
}
|
|
52
|
+
reader.setCacheActive(cacheActive)
|
|
45
53
|
reader.load()
|
|
46
54
|
return reader
|
|
47
55
|
} catch (e: any) {
|
|
@@ -61,9 +69,10 @@ export async function openDataset(
|
|
|
61
69
|
export async function readDataset(
|
|
62
70
|
url: string,
|
|
63
71
|
typeHint?: SupportedType,
|
|
64
|
-
options?: any
|
|
72
|
+
options?: any,
|
|
73
|
+
cacheActive = true
|
|
65
74
|
): Promise<DataItem[]> {
|
|
66
|
-
const reader = await openDataset(url, typeHint, options)
|
|
75
|
+
const reader = await openDataset(url, typeHint, options, cacheActive)
|
|
67
76
|
try {
|
|
68
77
|
return await reader.read()
|
|
69
78
|
} catch (e: any) {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { BaseReader } from './base'
|
|
2
|
+
|
|
3
|
+
export abstract class BaseCacheReader extends BaseReader {
|
|
4
|
+
constructor(
|
|
5
|
+
protected url: string,
|
|
6
|
+
protected cacheActive = true
|
|
7
|
+
) {
|
|
8
|
+
super(url)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
setCacheActive(value: boolean) {
|
|
12
|
+
this.cacheActive = value
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -2,13 +2,14 @@ import { BaseReader } from './base'
|
|
|
2
2
|
import { DataItem, DatasetInfo, PropertyInfo } from '../model'
|
|
3
3
|
import { getJsonDataItemsProxy, jsonToGeojsonFeature } from '../utils'
|
|
4
4
|
import { generateSqlQuery } from '../sql-utils'
|
|
5
|
+
import { BaseCacheReader } from './base-cache'
|
|
5
6
|
|
|
6
7
|
type ParseResult = {
|
|
7
8
|
items: DataItem[]
|
|
8
9
|
properties: PropertyInfo[]
|
|
9
10
|
}
|
|
10
11
|
|
|
11
|
-
export class BaseFileReader extends
|
|
12
|
+
export class BaseFileReader extends BaseCacheReader {
|
|
12
13
|
private parseResult_: Promise<ParseResult>
|
|
13
14
|
|
|
14
15
|
protected getData(): Promise<ParseResult> {
|
|
@@ -11,8 +11,8 @@ import {
|
|
|
11
11
|
|
|
12
12
|
export class BaseReader {
|
|
13
13
|
protected selected: FieldName[] = null
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
public groupedBy: FieldGroupBy[] = null
|
|
15
|
+
public aggregations: FieldAggregation[] = null
|
|
16
16
|
protected filter: FieldFilter = null
|
|
17
17
|
protected sort: FieldSort[] = null
|
|
18
18
|
protected startIndex: number = null
|
|
@@ -28,6 +28,6 @@ export function parseExcel(buffer: ArrayBuffer): Promise<{
|
|
|
28
28
|
|
|
29
29
|
export class ExcelReader extends BaseFileReader {
|
|
30
30
|
getData() {
|
|
31
|
-
return fetchDataAsArrayBuffer(this.url).then(parseExcel)
|
|
31
|
+
return fetchDataAsArrayBuffer(this.url, this.cacheActive).then(parseExcel)
|
|
32
32
|
}
|
|
33
33
|
}
|
|
@@ -37,17 +37,17 @@ export function parseGml(
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export class GmlReader extends BaseFileReader {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
constructor(
|
|
41
|
+
protected url: string,
|
|
42
|
+
protected namespace: string,
|
|
43
|
+
protected version: WfsVersion,
|
|
44
|
+
protected cacheActive = true
|
|
45
|
+
) {
|
|
44
46
|
super(url)
|
|
45
|
-
this.namespace = namespace
|
|
46
|
-
this.version = version
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
protected getData() {
|
|
50
|
-
return fetchDataAsText(this.url).then((text) =>
|
|
50
|
+
return fetchDataAsText(this.url, this.cacheActive).then((text) =>
|
|
51
51
|
parseGml(text, this.namespace, this.version)
|
|
52
52
|
)
|
|
53
53
|
}
|
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
import { WfsEndpoint, WfsVersion } from '@camptocamp/ogc-client'
|
|
2
2
|
import { DataItem, DatasetInfo, PropertyInfo } from '../model'
|
|
3
3
|
import { fetchDataAsText } from '../utils'
|
|
4
|
-
import { BaseReader } from './base'
|
|
5
4
|
import { GmlReader, parseGml } from './gml'
|
|
6
5
|
import { GeojsonReader, parseGeojson } from './geojson'
|
|
7
|
-
import {
|
|
6
|
+
import { BaseCacheReader } from './base-cache'
|
|
7
|
+
import { getJsonDataItemsProxy, jsonToGeojsonFeature } from '../utils'
|
|
8
|
+
import { generateSqlQuery } from '../sql-utils'
|
|
8
9
|
|
|
9
|
-
export class WfsReader extends
|
|
10
|
+
export class WfsReader extends BaseCacheReader {
|
|
10
11
|
endpoint: WfsEndpoint
|
|
11
12
|
featureTypeName: string
|
|
12
13
|
version: WfsVersion
|
|
13
14
|
|
|
14
|
-
constructor(
|
|
15
|
-
|
|
15
|
+
constructor(
|
|
16
|
+
url: string,
|
|
17
|
+
wfsEndpoint: WfsEndpoint,
|
|
18
|
+
featureTypeName: string,
|
|
19
|
+
cacheActive?: boolean
|
|
20
|
+
) {
|
|
21
|
+
super(url, cacheActive)
|
|
16
22
|
this.endpoint = wfsEndpoint
|
|
17
23
|
this.featureTypeName = featureTypeName
|
|
18
24
|
this.version = this.endpoint.getVersion()
|
|
@@ -90,11 +96,10 @@ export class WfsReader extends BaseReader {
|
|
|
90
96
|
}
|
|
91
97
|
}
|
|
92
98
|
|
|
93
|
-
|
|
94
|
-
if (
|
|
95
|
-
|
|
99
|
+
public async getData(aggregation?, groupedBy?) {
|
|
100
|
+
if (aggregation || groupedBy) {
|
|
101
|
+
return { items: await this.getQueryData() }
|
|
96
102
|
}
|
|
97
|
-
|
|
98
103
|
const asJson = this.endpoint.supportsJson(this.featureTypeName)
|
|
99
104
|
const attributes = this.selected ?? undefined
|
|
100
105
|
let url = this.endpoint.getFeatureUrl(this.featureTypeName, {
|
|
@@ -117,18 +122,36 @@ export class WfsReader extends BaseReader {
|
|
|
117
122
|
url = `${url}${finalUrl.search ? '&' : ''}SORTBY=${sorts}`
|
|
118
123
|
}
|
|
119
124
|
|
|
120
|
-
return fetchDataAsText(url).then((text) =>
|
|
125
|
+
return fetchDataAsText(url, this.cacheActive).then((text) =>
|
|
121
126
|
asJson
|
|
122
127
|
? parseGeojson(text)
|
|
123
128
|
: parseGml(text, this.featureTypeName, this.version)
|
|
124
129
|
)
|
|
125
130
|
}
|
|
126
131
|
|
|
132
|
+
public async getQueryData() {
|
|
133
|
+
const items = (await this.getData()).items
|
|
134
|
+
const jsonItems = getJsonDataItemsProxy(items)
|
|
135
|
+
const query = generateSqlQuery(
|
|
136
|
+
this.selected,
|
|
137
|
+
this.filter,
|
|
138
|
+
this.sort,
|
|
139
|
+
this.startIndex,
|
|
140
|
+
this.count,
|
|
141
|
+
this.groupedBy,
|
|
142
|
+
this.aggregations
|
|
143
|
+
)
|
|
144
|
+
const result = await import('alasql').then((module) =>
|
|
145
|
+
module.default(query, [jsonItems])
|
|
146
|
+
)
|
|
147
|
+
return result.map(jsonToGeojsonFeature)
|
|
148
|
+
}
|
|
149
|
+
|
|
127
150
|
load() {
|
|
128
151
|
// Nothing to load for Wfs
|
|
129
152
|
}
|
|
130
153
|
|
|
131
154
|
async read(): Promise<DataItem[]> {
|
|
132
|
-
return (await this.getData()).items
|
|
155
|
+
return (await this.getData(this.aggregations, this.groupedBy)).items
|
|
133
156
|
}
|
|
134
157
|
}
|
|
@@ -51,39 +51,43 @@ export function fetchHeaders(url: string): Promise<DatasetHeaders> {
|
|
|
51
51
|
})
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
export function fetchDataAsText(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
54
|
+
export function fetchDataAsText(
|
|
55
|
+
url: string,
|
|
56
|
+
cacheActive: boolean
|
|
57
|
+
): Promise<string> {
|
|
58
|
+
const fetchFactory = () =>
|
|
59
|
+
sharedFetch(url)
|
|
60
|
+
.catch((error) => {
|
|
61
|
+
throw FetchError.corsOrNetwork(error.message)
|
|
62
|
+
})
|
|
63
|
+
.then(async (response) => {
|
|
64
|
+
if (!response.ok) {
|
|
65
|
+
throw FetchError.http(response.status, await response.text())
|
|
66
|
+
}
|
|
67
|
+
return response.text()
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
return cacheActive ? useCache(fetchFactory, url, 'asText') : fetchFactory()
|
|
70
71
|
}
|
|
71
|
-
export function fetchDataAsArrayBuffer(
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
72
|
+
export function fetchDataAsArrayBuffer(
|
|
73
|
+
url: string,
|
|
74
|
+
cacheActive: boolean
|
|
75
|
+
): Promise<ArrayBuffer> {
|
|
76
|
+
const fetchFactory = () =>
|
|
77
|
+
sharedFetch(url)
|
|
78
|
+
.catch((error) => {
|
|
79
|
+
throw FetchError.corsOrNetwork(error.message)
|
|
80
|
+
})
|
|
81
|
+
.then(async (response) => {
|
|
82
|
+
if (!response.ok) {
|
|
83
|
+
throw FetchError.http(response.status, await response.text())
|
|
84
|
+
}
|
|
85
|
+
// convert to a numeric array so that we can store the response in cache
|
|
86
|
+
return Array.from(new Uint8Array(await response.arrayBuffer()))
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
return (
|
|
90
|
+
cacheActive ? useCache(fetchFactory, url, 'asArrayBuffer') : fetchFactory()
|
|
87
91
|
).then((array) => {
|
|
88
92
|
return new Uint8Array(array).buffer
|
|
89
93
|
})
|
package/translations/de.json
CHANGED
|
@@ -20,8 +20,6 @@
|
|
|
20
20
|
"chart.type.lineSmooth": "Geglättes Liniendiagramm",
|
|
21
21
|
"chart.type.pie": "Kreisdiagramm",
|
|
22
22
|
"dashboard.catalog.allRecords": "Metadatenkatalog",
|
|
23
|
-
"dashboard.catalog.contacts": "Kontakte",
|
|
24
|
-
"dashboard.catalog.thesaurus": "Thesaurus",
|
|
25
23
|
"dashboard.createRecord": "Neuer Eintrag",
|
|
26
24
|
"dashboard.importRecord": "",
|
|
27
25
|
"dashboard.importRecord.importExternal": "",
|
|
@@ -34,7 +32,6 @@
|
|
|
34
32
|
"dashboard.records.myDraft": "Meine Entwürfe",
|
|
35
33
|
"dashboard.records.myRecords": "Meine Datensätze",
|
|
36
34
|
"dashboard.records.search": "Suche nach \"{searchText}\"",
|
|
37
|
-
"dashboard.records.templates": "Vorlagen",
|
|
38
35
|
"dashboard.records.userDetail": "Name",
|
|
39
36
|
"dashboard.records.userEmail": "E-Mail",
|
|
40
37
|
"dashboard.records.username": "Benutzername",
|
|
@@ -425,6 +422,7 @@
|
|
|
425
422
|
"record.action.download": "Herunterladen",
|
|
426
423
|
"record.action.duplicate": "",
|
|
427
424
|
"record.action.duplicating": "",
|
|
425
|
+
"record.action.rollback": "",
|
|
428
426
|
"record.action.view": "Anzeigen",
|
|
429
427
|
"record.externalViewer.open": "In externem Kartenviewer öffnen",
|
|
430
428
|
"record.feature.limit": "Die Ressource enthält mehr als {count} Features und kann hier nicht angezeigt werden.",
|
|
@@ -547,6 +545,8 @@
|
|
|
547
545
|
"search.error.recordNotFound": "Der Datensatz mit der Kennung \"{ id }\" konnte nicht gefunden werden.",
|
|
548
546
|
"search.field.any.placeholder": "Suche Datensätze ...",
|
|
549
547
|
"search.field.sortBy": "Sortieren nach:",
|
|
548
|
+
"search.filters.availableServices.download": "",
|
|
549
|
+
"search.filters.availableServices.view": "",
|
|
550
550
|
"search.filters.changeDate": "Letzte Aktualisierung",
|
|
551
551
|
"search.filters.clear": "Zurücksetzen",
|
|
552
552
|
"search.filters.contact": "Kontakte",
|
|
@@ -602,7 +602,6 @@
|
|
|
602
602
|
"tooltip.url.open": "URL öffnen",
|
|
603
603
|
"ui.readLess": "Weniger lesen",
|
|
604
604
|
"ui.readMore": "Weiterlesen",
|
|
605
|
-
"wfs.aggregations.notsupported": "",
|
|
606
605
|
"wfs.feature.limit": "Zu viele Features, um den WFS-Layer anzuzeigen!",
|
|
607
606
|
"wfs.featuretype.notfound": "Kein passender Feature-Typ wurde im Dienst gefunden",
|
|
608
607
|
"wfs.geojsongml.notsupported": "Dieser Dienst unterstützt das GeoJSON- oder GML-Format nicht",
|