geonetwork-ui 2.4.2-dev.ff0aab388 → 2.4.2
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/iso19139/read-parts.mjs +2 -3
- package/esm2022/libs/api/metadata-converter/src/lib/iso19139/write-parts.mjs +4 -1
- package/esm2022/libs/common/domain/src/lib/model/record/metadata.model.mjs +1 -1
- package/esm2022/libs/feature/dataviz/src/lib/service/data.service.mjs +4 -14
- package/esm2022/libs/feature/editor/src/lib/components/contact-card/contact-card.component.mjs +3 -3
- package/esm2022/libs/feature/editor/src/lib/components/generic-keywords/generic-keywords.component.mjs +3 -3
- package/esm2022/libs/feature/editor/src/lib/components/import-record/import-record.component.mjs +3 -4
- package/esm2022/libs/feature/editor/src/lib/components/online-resource-card/online-resource-card.component.mjs +3 -3
- package/esm2022/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.mjs +31 -40
- package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts/form-field-contacts.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 +3 -3
- package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-keywords/form-field-keywords.component.mjs +3 -3
- package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-link-resources/form-field-online-link-resources.component.mjs +8 -9
- package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-resources/form-field-online-resources.component.mjs +5 -25
- package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-spatial-extent/form-field-spatial-extent.component.mjs +5 -4
- package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.mjs +3 -3
- package/esm2022/libs/feature/editor/src/lib/fields.config.mjs +10 -2
- package/esm2022/libs/feature/record/src/lib/data-view/data-view.component.mjs +6 -3
- package/esm2022/libs/feature/record/src/lib/data-view-share/data-view-share.component.mjs +3 -3
- package/esm2022/libs/feature/record/src/lib/map-view/map-view.component.mjs +6 -3
- package/esm2022/libs/ui/search/src/lib/record-preview-feed/record-preview-feed.component.mjs +3 -1
- package/esm2022/libs/ui/search/src/lib/results-table/results-table.component.mjs +3 -3
- package/esm2022/libs/util/data-fetcher/src/lib/data-fetcher.mjs +5 -1
- package/esm2022/libs/util/data-fetcher/src/lib/headers.mjs +3 -2
- package/esm2022/libs/util/data-fetcher/src/lib/model.mjs +2 -1
- package/esm2022/libs/util/data-fetcher/src/lib/readers/wfs.mjs +79 -0
- package/esm2022/translations/de.json +13 -5
- package/esm2022/translations/en.json +22 -14
- package/esm2022/translations/es.json +13 -5
- package/esm2022/translations/fr.json +23 -15
- package/esm2022/translations/it.json +32 -26
- package/esm2022/translations/nl.json +13 -5
- package/esm2022/translations/pt.json +13 -5
- package/fesm2022/geonetwork-ui.mjs +293 -182
- package/fesm2022/geonetwork-ui.mjs.map +1 -1
- package/libs/api/metadata-converter/src/lib/iso19139/read-parts.d.ts.map +1 -1
- package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts.map +1 -1
- package/libs/feature/dataviz/src/lib/service/data.service.d.ts.map +1 -1
- package/libs/feature/editor/src/lib/components/import-record/import-record.component.d.ts +0 -1
- package/libs/feature/editor/src/lib/components/import-record/import-record.component.d.ts.map +1 -1
- package/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.d.ts +7 -14
- package/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.d.ts.map +1 -1
- package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-link-resources/form-field-online-link-resources.component.d.ts +2 -2
- package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-link-resources/form-field-online-link-resources.component.d.ts.map +1 -1
- package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-resources/form-field-online-resources.component.d.ts +1 -6
- package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-resources/form-field-online-resources.component.d.ts.map +1 -1
- package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-spatial-extent/form-field-spatial-extent.component.d.ts.map +1 -1
- package/libs/feature/editor/src/lib/fields.config.d.ts.map +1 -1
- package/libs/feature/record/src/lib/data-view/data-view.component.d.ts +2 -1
- 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 +2 -1
- package/libs/feature/record/src/lib/map-view/map-view.component.d.ts.map +1 -1
- package/libs/ui/search/src/lib/record-preview-feed/record-preview-feed.component.d.ts.map +1 -1
- package/libs/util/data-fetcher/src/lib/data-fetcher.d.ts +3 -2
- package/libs/util/data-fetcher/src/lib/data-fetcher.d.ts.map +1 -1
- package/libs/util/data-fetcher/src/lib/headers.d.ts.map +1 -1
- package/libs/util/data-fetcher/src/lib/model.d.ts +1 -1
- package/libs/util/data-fetcher/src/lib/model.d.ts.map +1 -1
- package/libs/util/data-fetcher/src/lib/readers/wfs.d.ts +21 -0
- package/libs/util/data-fetcher/src/lib/readers/wfs.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/libs/api/metadata-converter/src/lib/fixtures/geocat-ch.records.ts +1 -0
- package/src/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts +1 -2
- package/src/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts +3 -0
- package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +1 -1
- package/src/libs/feature/dataviz/src/lib/service/data.service.ts +4 -14
- package/src/libs/feature/editor/src/lib/components/contact-card/contact-card.component.html +1 -1
- package/src/libs/feature/editor/src/lib/components/generic-keywords/generic-keywords.component.html +1 -1
- package/src/libs/feature/editor/src/lib/components/import-record/import-record.component.html +4 -1
- package/src/libs/feature/editor/src/lib/components/import-record/import-record.component.ts +0 -4
- package/src/libs/feature/editor/src/lib/components/online-resource-card/online-resource-card.component.ts +2 -2
- package/src/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.html +8 -8
- package/src/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.ts +32 -45
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts/form-field-contacts.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.html +3 -1
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-keywords/form-field-keywords.component.html +1 -1
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-link-resources/form-field-online-link-resources.component.html +0 -1
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-link-resources/form-field-online-link-resources.component.ts +6 -6
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-resources/form-field-online-resources.component.html +24 -17
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-resources/form-field-online-resources.component.ts +2 -27
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-spatial-extent/form-field-spatial-extent.component.html +1 -1
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-spatial-extent/form-field-spatial-extent.component.ts +2 -1
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.html +1 -1
- package/src/libs/feature/editor/src/lib/fields.config.ts +9 -1
- package/src/libs/feature/record/src/lib/data-view/data-view.component.html +1 -0
- package/src/libs/feature/record/src/lib/data-view/data-view.component.ts +1 -0
- package/src/libs/feature/record/src/lib/data-view-share/data-view-share.component.html +1 -1
- package/src/libs/feature/record/src/lib/map-view/map-view.component.html +1 -0
- package/src/libs/feature/record/src/lib/map-view/map-view.component.ts +1 -0
- package/src/libs/ui/search/src/lib/record-preview-feed/record-preview-feed.component.ts +3 -0
- package/src/libs/ui/search/src/lib/results-table/results-table.component.html +1 -1
- package/src/libs/util/data-fetcher/src/lib/data-fetcher.ts +9 -1
- package/src/libs/util/data-fetcher/src/lib/headers.ts +4 -3
- package/src/libs/util/data-fetcher/src/lib/model.ts +1 -0
- package/src/libs/util/data-fetcher/src/lib/readers/wfs.ts +112 -0
- package/translations/de.json +13 -5
- package/translations/en.json +22 -14
- package/translations/es.json +13 -5
- package/translations/fr.json +23 -15
- package/translations/it.json +32 -26
- package/translations/nl.json +13 -5
- package/translations/pt.json +13 -5
- package/translations/sk.json +14 -6
|
@@ -5,8 +5,6 @@ import {
|
|
|
5
5
|
Component,
|
|
6
6
|
EventEmitter,
|
|
7
7
|
Input,
|
|
8
|
-
OnChanges,
|
|
9
|
-
OnInit,
|
|
10
8
|
Output,
|
|
11
9
|
} from '@angular/core'
|
|
12
10
|
import { FormsModule } from '@angular/forms'
|
|
@@ -23,23 +21,27 @@ import {
|
|
|
23
21
|
TextInputComponent,
|
|
24
22
|
UrlInputComponent,
|
|
25
23
|
} from '../../../../../../../libs/ui/inputs/src'
|
|
26
|
-
import {
|
|
24
|
+
import { createFuzzyFilter, getLayers } from '../../../../../../../libs/util/shared/src'
|
|
27
25
|
import {
|
|
28
26
|
NgIconComponent,
|
|
29
27
|
provideIcons,
|
|
30
28
|
provideNgIconsConfig,
|
|
31
29
|
} from '@ng-icons/core'
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
30
|
+
import { iconoirRefresh } from '@ng-icons/iconoir'
|
|
31
|
+
import { TranslateModule } from '@ngx-translate/core'
|
|
34
32
|
import {
|
|
35
33
|
BehaviorSubject,
|
|
36
34
|
debounceTime,
|
|
37
35
|
distinctUntilChanged,
|
|
38
|
-
map,
|
|
39
36
|
Observable,
|
|
40
37
|
switchMap,
|
|
41
38
|
} from 'rxjs'
|
|
42
39
|
|
|
40
|
+
marker('editor.record.form.field.onlineResource.edit.identifier.placeholder')
|
|
41
|
+
marker(
|
|
42
|
+
'editor.record.form.field.onlineResource.edit.identifier.placeholder.wps'
|
|
43
|
+
)
|
|
44
|
+
|
|
43
45
|
@Component({
|
|
44
46
|
selector: 'gn-ui-online-service-resource-input',
|
|
45
47
|
templateUrl: './online-service-resource-input.component.html',
|
|
@@ -59,26 +61,25 @@ import {
|
|
|
59
61
|
UrlInputComponent,
|
|
60
62
|
],
|
|
61
63
|
providers: [
|
|
62
|
-
provideIcons({
|
|
64
|
+
provideIcons({ iconoirRefresh }),
|
|
63
65
|
provideNgIconsConfig({
|
|
64
66
|
size: '1.5em',
|
|
65
67
|
}),
|
|
66
68
|
],
|
|
67
69
|
})
|
|
68
|
-
export class OnlineServiceResourceInputComponent
|
|
69
|
-
|
|
70
|
+
export class OnlineServiceResourceInputComponent {
|
|
71
|
+
_service: DatasetServiceDistribution
|
|
72
|
+
@Input() set service(service: DatasetServiceDistribution) {
|
|
73
|
+
this._service = { ...service }
|
|
74
|
+
}
|
|
70
75
|
@Input() protocolHint?: string
|
|
71
76
|
@Input() disabled? = false
|
|
72
77
|
@Input() modifyMode? = false
|
|
73
|
-
@Output()
|
|
74
|
-
|
|
75
|
-
url: string
|
|
76
|
-
identifier: string
|
|
77
|
-
}> = new EventEmitter()
|
|
78
|
+
@Output() serviceChange: EventEmitter<DatasetServiceDistribution> =
|
|
79
|
+
new EventEmitter()
|
|
78
80
|
|
|
79
81
|
errorMessage = false
|
|
80
|
-
|
|
81
|
-
url = ''
|
|
82
|
+
|
|
82
83
|
layersSubject = new BehaviorSubject<{ name: string; title: string }[]>([])
|
|
83
84
|
layers$: Observable<{ name: string; title: string }[]> =
|
|
84
85
|
this.layersSubject.asObservable()
|
|
@@ -121,35 +122,18 @@ export class OnlineServiceResourceInputComponent implements OnChanges, OnInit {
|
|
|
121
122
|
|
|
122
123
|
get activeLayerSuggestion() {
|
|
123
124
|
return !['wps', 'GPFDL', 'esriRest', 'other'].includes(
|
|
124
|
-
this.
|
|
125
|
+
this._service.accessServiceProtocol
|
|
125
126
|
)
|
|
126
127
|
}
|
|
127
128
|
|
|
128
|
-
ngOnChanges() {
|
|
129
|
-
this.selectedProtocol =
|
|
130
|
-
this.protocolOptions.find(
|
|
131
|
-
(option) => option.value === this.service.accessServiceProtocol
|
|
132
|
-
)?.value ?? 'other'
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
ngOnInit() {
|
|
136
|
-
if (this.service.url) {
|
|
137
|
-
this.url = this.service.url.toString()
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
129
|
handleUrlValueChange(url: string) {
|
|
142
|
-
this.url = url
|
|
143
|
-
this.service.url = url ? new URL(url) : undefined
|
|
130
|
+
this._service.url = url ? new URL(url) : undefined
|
|
144
131
|
this.resetLayersSuggestion()
|
|
145
|
-
this.urlChange.emit(this.url)
|
|
146
132
|
}
|
|
147
133
|
|
|
148
134
|
async handleUploadClick(url: string) {
|
|
149
|
-
this.url = url
|
|
150
|
-
|
|
151
135
|
try {
|
|
152
|
-
const layers = await getLayers(url, this.
|
|
136
|
+
const layers = await getLayers(url, this._service.accessServiceProtocol)
|
|
153
137
|
|
|
154
138
|
if (layers.length === 0) {
|
|
155
139
|
throw new Error('No layers found')
|
|
@@ -165,27 +149,29 @@ export class OnlineServiceResourceInputComponent implements OnChanges, OnInit {
|
|
|
165
149
|
}
|
|
166
150
|
|
|
167
151
|
resetAllFormFields() {
|
|
168
|
-
this.url =
|
|
169
|
-
this.service.url = null
|
|
152
|
+
this._service.url = null
|
|
170
153
|
this.resetLayersSuggestion()
|
|
171
154
|
}
|
|
172
155
|
|
|
173
156
|
resetLayersSuggestion() {
|
|
174
157
|
this.errorMessage = false
|
|
175
158
|
this.layersSubject.next([])
|
|
176
|
-
this.
|
|
159
|
+
this._service.identifierInService = null
|
|
177
160
|
}
|
|
178
161
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
162
|
+
submit() {
|
|
163
|
+
this.serviceChange.emit({
|
|
164
|
+
...this._service,
|
|
165
|
+
name: this._service.identifierInService, // should we keep the identifierInService? read-write duplicate with name
|
|
166
|
+
})
|
|
167
|
+
this._service.accessServiceProtocol = 'ogcFeatures'
|
|
168
|
+
this.resetAllFormFields()
|
|
183
169
|
}
|
|
184
170
|
|
|
185
171
|
getIdentifierPlaceholder(): string {
|
|
186
172
|
const baseKey =
|
|
187
173
|
'editor.record.form.field.onlineResource.edit.identifier.placeholder'
|
|
188
|
-
return this.
|
|
174
|
+
return this._service.accessServiceProtocol === 'wps'
|
|
189
175
|
? `${baseKey}.wps`
|
|
190
176
|
: baseKey
|
|
191
177
|
}
|
|
@@ -217,6 +203,7 @@ export class OnlineServiceResourceInputComponent implements OnChanges, OnInit {
|
|
|
217
203
|
* gn-ui-autocomplete
|
|
218
204
|
*/
|
|
219
205
|
handleSelectValue(val: { name: string; title: string }) {
|
|
220
|
-
this.
|
|
206
|
+
this._service.identifierInService = val.name // should we keep the identifierInService? read-write duplicate with name
|
|
207
|
+
this._service.description = val.title
|
|
221
208
|
}
|
|
222
209
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<div class="flex flex-col gap-3">
|
|
2
2
|
<gn-ui-autocomplete
|
|
3
|
-
[placeholder]="'
|
|
3
|
+
[placeholder]="'editor.record.form.field.contacts.placeholder' | translate"
|
|
4
4
|
[action]="autoCompleteAction"
|
|
5
5
|
(itemSelected)="addContact($event)"
|
|
6
6
|
[displayWithFn]="displayWithFn"
|
|
@@ -31,7 +31,9 @@
|
|
|
31
31
|
</div>
|
|
32
32
|
|
|
33
33
|
<gn-ui-autocomplete
|
|
34
|
-
[placeholder]="
|
|
34
|
+
[placeholder]="
|
|
35
|
+
'editor.record.form.field.contactsForResource.placeholder' | translate
|
|
36
|
+
"
|
|
35
37
|
[action]="autoCompleteAction"
|
|
36
38
|
(itemSelected)="addContact($event, role)"
|
|
37
39
|
[displayWithFn]="displayWithFn"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<gn-ui-generic-keywords
|
|
3
3
|
[keywords]="filteredKeywords"
|
|
4
4
|
[keywordTypes]="keywordTypes"
|
|
5
|
-
[placeholder]="'editor.form.keywords.placeholder' | translate"
|
|
5
|
+
[placeholder]="'editor.record.form.keywords.placeholder' | translate"
|
|
6
6
|
(changedKeywords)="handleKeywordsChange($event)"
|
|
7
7
|
[allowSubmit]="false"
|
|
8
8
|
>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common'
|
|
1
2
|
import {
|
|
2
3
|
ChangeDetectionStrategy,
|
|
3
4
|
ChangeDetectorRef,
|
|
@@ -8,28 +9,27 @@ import {
|
|
|
8
9
|
TemplateRef,
|
|
9
10
|
ViewChild,
|
|
10
11
|
} from '@angular/core'
|
|
12
|
+
import { MatDialog } from '@angular/material/dialog'
|
|
11
13
|
import {
|
|
12
14
|
OnlineLinkResource,
|
|
13
15
|
OnlineResource,
|
|
14
16
|
} from '../../../../../../../../../libs/common/domain/src/lib/model/record'
|
|
17
|
+
import { PlatformServiceInterface } from '../../../../../../../../../libs/common/domain/src/lib/platform.service.interface'
|
|
18
|
+
import { NotificationsService } from '../../../../../../../../../libs/feature/notifications/src'
|
|
15
19
|
import {
|
|
16
20
|
FileInputComponent,
|
|
17
21
|
TextAreaComponent,
|
|
18
22
|
TextInputComponent,
|
|
19
23
|
UrlInputComponent,
|
|
20
24
|
} from '../../../../../../../../../libs/ui/inputs/src'
|
|
21
|
-
import { CommonModule } from '@angular/common'
|
|
22
|
-
import { OnlineResourceCardComponent } from '../../../online-resource-card/online-resource-card.component'
|
|
23
25
|
import {
|
|
24
26
|
ModalDialogComponent,
|
|
25
27
|
SortableListComponent,
|
|
26
28
|
} from '../../../../../../../../../libs/ui/layout/src'
|
|
27
|
-
import { NotificationsService } from '../../../../../../../../../libs/feature/notifications/src'
|
|
28
29
|
import { TranslateModule, TranslateService } from '@ngx-translate/core'
|
|
29
|
-
import {
|
|
30
|
-
import { map, Subscription } from 'rxjs'
|
|
31
|
-
import { MatDialog } from '@angular/material/dialog'
|
|
30
|
+
import { Subscription } from 'rxjs'
|
|
32
31
|
import { MAX_UPLOAD_SIZE_MB } from '../../../../fields.config'
|
|
32
|
+
import { OnlineResourceCardComponent } from '../../../online-resource-card/online-resource-card.component'
|
|
33
33
|
|
|
34
34
|
@Component({
|
|
35
35
|
selector: 'gn-ui-form-field-online-link-resources',
|
|
@@ -20,8 +20,7 @@
|
|
|
20
20
|
>
|
|
21
21
|
<gn-ui-online-service-resource-input
|
|
22
22
|
[service]="newService"
|
|
23
|
-
|
|
24
|
-
(identifierSubmit)="handleIdentifierSubmit($event)"
|
|
23
|
+
(serviceChange)="handleServiceChange($event)"
|
|
25
24
|
></gn-ui-online-service-resource-input>
|
|
26
25
|
</div>
|
|
27
26
|
<div class="h-[8px]"></div>
|
|
@@ -40,28 +39,36 @@
|
|
|
40
39
|
|
|
41
40
|
<ng-template #dialogTemplate let-onlineResource>
|
|
42
41
|
<div class="flex flex-col gap-[16px]">
|
|
43
|
-
<div>
|
|
44
|
-
<h3 class="text-[16px] font-bold text-main mb-[12px]" translate>
|
|
45
|
-
editor.record.form.field.onlineResource.edit.title
|
|
46
|
-
</h3>
|
|
47
|
-
<gn-ui-text-input [(value)]="onlineResource.name"></gn-ui-text-input>
|
|
48
|
-
</div>
|
|
49
|
-
<div>
|
|
50
|
-
<h3 class="text-[16px] font-bold text-main mb-[12px]" translate>
|
|
51
|
-
editor.record.form.field.onlineResource.edit.description
|
|
52
|
-
</h3>
|
|
53
|
-
<gn-ui-text-area
|
|
54
|
-
[(value)]="onlineResource.description"
|
|
55
|
-
></gn-ui-text-area>
|
|
56
|
-
</div>
|
|
57
42
|
<ng-container *ngIf="onlineResource.type === 'service'; else urlInput">
|
|
58
|
-
<span class="w-full border-b border-gray-300"></span>
|
|
59
43
|
<gn-ui-online-service-resource-input
|
|
60
44
|
[service]="onlineResource"
|
|
61
45
|
[modifyMode]="true"
|
|
46
|
+
[disabled]="true"
|
|
62
47
|
></gn-ui-online-service-resource-input>
|
|
48
|
+
<div>
|
|
49
|
+
<h3 class="text-[16px] font-bold text-main mb-[12px]" translate>
|
|
50
|
+
editor.record.form.field.onlineResource.edit.description
|
|
51
|
+
</h3>
|
|
52
|
+
<gn-ui-text-area
|
|
53
|
+
[(value)]="onlineResource.description"
|
|
54
|
+
></gn-ui-text-area>
|
|
55
|
+
</div>
|
|
63
56
|
</ng-container>
|
|
64
57
|
<ng-template #urlInput>
|
|
58
|
+
<div>
|
|
59
|
+
<h3 class="text-[16px] font-bold text-main mb-[12px]" translate>
|
|
60
|
+
editor.record.form.field.onlineResource.edit.title
|
|
61
|
+
</h3>
|
|
62
|
+
<gn-ui-text-input [(value)]="onlineResource.name"></gn-ui-text-input>
|
|
63
|
+
</div>
|
|
64
|
+
<div>
|
|
65
|
+
<h3 class="text-[16px] font-bold text-main mb-[12px]" translate>
|
|
66
|
+
editor.record.form.field.onlineResource.edit.description
|
|
67
|
+
</h3>
|
|
68
|
+
<gn-ui-text-area
|
|
69
|
+
[(value)]="onlineResource.description"
|
|
70
|
+
></gn-ui-text-area>
|
|
71
|
+
</div>
|
|
65
72
|
<span class="w-full border-b border-gray-300"></span>
|
|
66
73
|
<gn-ui-url-input
|
|
67
74
|
class="w-full"
|
|
@@ -159,33 +159,8 @@ export class FormFieldOnlineResourcesComponent {
|
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
-
|
|
163
|
-
this.valueChange.emit([
|
|
164
|
-
...this.allResources,
|
|
165
|
-
{
|
|
166
|
-
...this.newService,
|
|
167
|
-
url: new URL(url),
|
|
168
|
-
},
|
|
169
|
-
])
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
handleIdentifierSubmit(payload: { url: string; identifier: string }) {
|
|
173
|
-
this.valueChange.emit([
|
|
174
|
-
...this.allResources,
|
|
175
|
-
{
|
|
176
|
-
...this.newService,
|
|
177
|
-
url: new URL(payload.url),
|
|
178
|
-
},
|
|
179
|
-
])
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
handleServiceModify(
|
|
183
|
-
oldService: DatasetServiceDistribution,
|
|
184
|
-
newService: DatasetServiceDistribution
|
|
185
|
-
) {
|
|
186
|
-
oldService.accessServiceProtocol = newService.accessServiceProtocol
|
|
187
|
-
oldService.identifierInService = newService.identifierInService
|
|
188
|
-
oldService.url = newService.url
|
|
162
|
+
handleServiceChange(service: DatasetServiceDistribution) {
|
|
163
|
+
this.valueChange.emit([...this.allResources, service])
|
|
189
164
|
}
|
|
190
165
|
|
|
191
166
|
handleResourcesChange(items: unknown[]) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<div class="flex flex-col gap-3">
|
|
2
2
|
<gn-ui-generic-keywords
|
|
3
|
-
[placeholder]="'
|
|
3
|
+
[placeholder]="'editor.record.form.keywords.place.placeholder' | translate"
|
|
4
4
|
[keywords]="shownKeywords$ | async"
|
|
5
5
|
[keywordTypes]="['place']"
|
|
6
6
|
(deletedKeyword)="handleKeywordDelete($event)"
|
|
@@ -10,7 +10,7 @@ import { firstValueFrom, map, shareReplay } from 'rxjs'
|
|
|
10
10
|
import { EditorFacade } from '../../../../+state/editor.facade'
|
|
11
11
|
import { switchMap } from 'rxjs/operators'
|
|
12
12
|
import { FormFieldMapContainerComponent } from '../form-field-map-container/form-field-map-container.component'
|
|
13
|
-
import { TranslateService } from '@ngx-translate/core'
|
|
13
|
+
import { TranslateModule, TranslateService } from '@ngx-translate/core'
|
|
14
14
|
import { SPATIAL_SCOPES } from '../../../../fields.config'
|
|
15
15
|
|
|
16
16
|
// This intermediary type will let us keep track of which keyword is bound to
|
|
@@ -36,6 +36,7 @@ type KeywordWithExtent = Keyword & {
|
|
|
36
36
|
CommonModule,
|
|
37
37
|
GenericKeywordsComponent,
|
|
38
38
|
FormFieldMapContainerComponent,
|
|
39
|
+
TranslateModule,
|
|
39
40
|
],
|
|
40
41
|
})
|
|
41
42
|
export class FormFieldSpatialExtentComponent {
|
|
@@ -63,6 +63,8 @@ export const RECORD_KEYWORDS_FIELD: EditorField = {
|
|
|
63
63
|
model: 'keywords',
|
|
64
64
|
formFieldConfig: {},
|
|
65
65
|
}
|
|
66
|
+
// keeping track of the label to not lose existing translation
|
|
67
|
+
marker('editor.record.form.field.keywords')
|
|
66
68
|
|
|
67
69
|
export const RECORD_RESOURCE_CREATED_FIELD: EditorField = {
|
|
68
70
|
model: 'resourceCreated',
|
|
@@ -156,18 +158,24 @@ export const RECORD_SPATIAL_EXTENTS_FIELD: EditorField = {
|
|
|
156
158
|
model: 'spatialExtents',
|
|
157
159
|
formFieldConfig: {},
|
|
158
160
|
}
|
|
161
|
+
// keeping track of the label to not lose existing translation
|
|
162
|
+
marker('editor.record.form.field.spatialExtents')
|
|
159
163
|
|
|
160
164
|
export const RECORD_ONLINE_RESOURCES: EditorField = {
|
|
161
165
|
model: 'onlineResources',
|
|
162
166
|
modelSpecifier: 'onlineResourceType:!link',
|
|
163
167
|
formFieldConfig: {},
|
|
164
168
|
}
|
|
169
|
+
// keeping track of the label to not lose existing translation
|
|
170
|
+
marker('editor.record.form.field.onlineResources')
|
|
165
171
|
|
|
166
172
|
export const RECORD_ONLINE_LINK_RESOURCES: EditorField = {
|
|
167
173
|
model: 'onlineResources',
|
|
168
174
|
modelSpecifier: 'onlineResourceType:link',
|
|
169
175
|
formFieldConfig: {},
|
|
170
176
|
}
|
|
177
|
+
// keeping track of the label to not lose existing translation
|
|
178
|
+
marker('editor.record.form.field.onlineLinkResources')
|
|
171
179
|
|
|
172
180
|
/************************************************************
|
|
173
181
|
*************** SECTIONS *****************
|
|
@@ -273,7 +281,7 @@ export const DEFAULT_CONFIGURATION: EditorConfig = {
|
|
|
273
281
|
],
|
|
274
282
|
},
|
|
275
283
|
{
|
|
276
|
-
labelKey: marker('editor.record.form.page.
|
|
284
|
+
labelKey: marker('editor.record.form.page.resources'),
|
|
277
285
|
sections: [ASSOCIATED_RESOURCES_SECTION, ANNEXES_SECTION],
|
|
278
286
|
},
|
|
279
287
|
{
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<div class="w-full h-full flex flex-col p-1">
|
|
2
2
|
<gn-ui-dropdown-selector
|
|
3
3
|
*ngIf="dropdownChoices$ | async as choices"
|
|
4
|
+
[ngClass]="{ hidden: !displaySource }"
|
|
4
5
|
[title]="'table.select.data' | translate"
|
|
5
6
|
class="truncate p-1 -mx-1 self-end mb-1"
|
|
6
7
|
extraBtnClass="!text-primary font-sans font-medium"
|
|
@@ -34,6 +34,7 @@ import { TranslateModule } from '@ngx-translate/core'
|
|
|
34
34
|
})
|
|
35
35
|
export class DataViewComponent {
|
|
36
36
|
@Input() mode: 'table' | 'chart'
|
|
37
|
+
@Input() displaySource = true
|
|
37
38
|
@Output() chartConfig$ = new BehaviorSubject<DatavizConfigurationModel>(null)
|
|
38
39
|
compatibleDataLinks$ = combineLatest([
|
|
39
40
|
this.mdViewFacade.dataLinks$,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<div class="w-full h-full flex flex-col p-1">
|
|
2
2
|
<div class="w-full flex justify-end">
|
|
3
3
|
<gn-ui-dropdown-selector
|
|
4
|
+
[ngClass]="{ hidden: !displaySource }"
|
|
4
5
|
class="truncate p-1 -mx-1 mb-1"
|
|
5
6
|
extraBtnClass="!text-primary font-sans font-medium"
|
|
6
7
|
[title]="'map.select.layer' | translate"
|
|
@@ -85,6 +85,7 @@ export class MapViewComponent implements AfterViewInit {
|
|
|
85
85
|
@Input() set excludeWfs(value: boolean) {
|
|
86
86
|
this.excludeWfs$.next(value)
|
|
87
87
|
}
|
|
88
|
+
@Input() displaySource = true
|
|
88
89
|
@ViewChild('mapContainer') mapContainer: MapContainerComponent
|
|
89
90
|
|
|
90
91
|
excludeWfs$ = new BehaviorSubject(false)
|
|
@@ -2,6 +2,9 @@ import { ChangeDetectionStrategy, Component, ElementRef } from '@angular/core'
|
|
|
2
2
|
import { RecordPreviewComponent } from '../record-preview/record-preview.component'
|
|
3
3
|
import { TranslateService } from '@ngx-translate/core'
|
|
4
4
|
import Duration from 'duration-relativetimeformat'
|
|
5
|
+
import { marker } from '@biesbjerg/ngx-translate-extract-marker'
|
|
6
|
+
|
|
7
|
+
marker('record.was.created.time')
|
|
5
8
|
|
|
6
9
|
@Component({
|
|
7
10
|
selector: 'gn-ui-record-preview-feed',
|
|
@@ -8,11 +8,16 @@ import { inferDatasetType } from './utils'
|
|
|
8
8
|
import { BaseReader } from './readers/base'
|
|
9
9
|
import { GmlReader } from './readers/gml'
|
|
10
10
|
import { WfsVersion } from '@camptocamp/ogc-client'
|
|
11
|
+
import { WfsReader } from './readers/wfs'
|
|
11
12
|
|
|
12
13
|
export async function openDataset(
|
|
13
14
|
url: string,
|
|
14
15
|
typeHint?: SupportedType,
|
|
15
|
-
options?: {
|
|
16
|
+
options?: {
|
|
17
|
+
namespace?: string
|
|
18
|
+
wfsVersion?: WfsVersion
|
|
19
|
+
wfsFeatureType?: string
|
|
20
|
+
}
|
|
16
21
|
): Promise<BaseReader> {
|
|
17
22
|
const fileType = await inferDatasetType(url, typeHint)
|
|
18
23
|
let reader: BaseReader
|
|
@@ -33,6 +38,9 @@ export async function openDataset(
|
|
|
33
38
|
case 'gml':
|
|
34
39
|
reader = new GmlReader(url, options.namespace, options.wfsVersion)
|
|
35
40
|
break
|
|
41
|
+
case 'wfs':
|
|
42
|
+
reader = await WfsReader.createReader(url, options.wfsFeatureType)
|
|
43
|
+
break
|
|
36
44
|
}
|
|
37
45
|
reader.load()
|
|
38
46
|
return reader
|
|
@@ -5,9 +5,10 @@ export function parseHeaders(httpHeaders: Headers): DatasetHeaders {
|
|
|
5
5
|
if (httpHeaders.has('Content-Type')) {
|
|
6
6
|
result.mimeType = httpHeaders.get('Content-Type').split(';')[0]
|
|
7
7
|
const supported =
|
|
8
|
-
SupportedTypes.filter(
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
SupportedTypes.filter((type) => type !== 'wfs') // Ignore wfs type as it is not a file type
|
|
9
|
+
.filter(
|
|
10
|
+
(type) => AllMimeTypes[type].indexOf(result.mimeType as never) > -1
|
|
11
|
+
)[0] || null
|
|
11
12
|
if (supported !== null) result.supportedType = supported
|
|
12
13
|
}
|
|
13
14
|
if (httpHeaders.has('Content-Length')) {
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { WfsEndpoint, WfsVersion } from '@camptocamp/ogc-client'
|
|
2
|
+
import { DataItem, DatasetInfo, PropertyInfo } from '../model'
|
|
3
|
+
import { fetchDataAsText } from '../utils'
|
|
4
|
+
import { BaseReader } from './base'
|
|
5
|
+
import { GmlReader, parseGml } from './gml'
|
|
6
|
+
import { GeojsonReader, parseGeojson } from './geojson'
|
|
7
|
+
|
|
8
|
+
export class WfsReader extends BaseReader {
|
|
9
|
+
endpoint: WfsEndpoint
|
|
10
|
+
featureTypeName: string
|
|
11
|
+
version: WfsVersion
|
|
12
|
+
|
|
13
|
+
constructor(url: string, wfsEndpoint: WfsEndpoint, featureTypeName: string) {
|
|
14
|
+
super(url)
|
|
15
|
+
this.endpoint = wfsEndpoint
|
|
16
|
+
this.featureTypeName = featureTypeName
|
|
17
|
+
this.version = this.endpoint.getVersion()
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
get properties(): Promise<PropertyInfo[]> {
|
|
21
|
+
return this.getData().then((result) => result.properties)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
get info(): Promise<DatasetInfo> {
|
|
25
|
+
return this.endpoint.getFeatureTypeFull(this.featureTypeName).then(
|
|
26
|
+
(result) =>
|
|
27
|
+
({
|
|
28
|
+
itemsCount: result.objectCount,
|
|
29
|
+
}) as DatasetInfo
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
static async createReader(wfsUrlEndpoint: string, featureTypeName?: string) {
|
|
34
|
+
const wfsEndpoint = await new WfsEndpoint(wfsUrlEndpoint).isReady()
|
|
35
|
+
const featureTypes = wfsEndpoint.getFeatureTypes()
|
|
36
|
+
const featureType = wfsEndpoint.getFeatureTypeSummary(
|
|
37
|
+
featureTypes.length === 1 && !featureTypeName
|
|
38
|
+
? featureTypes[0].name
|
|
39
|
+
: featureTypeName
|
|
40
|
+
)
|
|
41
|
+
if (!featureType) {
|
|
42
|
+
throw new Error('wfs.featuretype.notfound')
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (wfsEndpoint.supportsStartIndex()) {
|
|
46
|
+
return new WfsReader(wfsUrlEndpoint, wfsEndpoint, featureType.name)
|
|
47
|
+
} else if (wfsEndpoint.supportsJson(featureType.name)) {
|
|
48
|
+
return new GeojsonReader(
|
|
49
|
+
wfsEndpoint.getFeatureUrl(featureType.name, {
|
|
50
|
+
asJson: true,
|
|
51
|
+
outputCrs: 'EPSG:4326',
|
|
52
|
+
})
|
|
53
|
+
)
|
|
54
|
+
} else {
|
|
55
|
+
if (
|
|
56
|
+
featureType.outputFormats.find((f) =>
|
|
57
|
+
f.toLowerCase().includes('gml')
|
|
58
|
+
) &&
|
|
59
|
+
(featureType.defaultCrs === 'EPSG:4326' ||
|
|
60
|
+
featureType.otherCrs?.includes('EPSG:4326'))
|
|
61
|
+
) {
|
|
62
|
+
return new GmlReader(
|
|
63
|
+
wfsEndpoint.getFeatureUrl(featureType.name, {
|
|
64
|
+
outputFormat: featureType.outputFormats.find((f) =>
|
|
65
|
+
f.toLowerCase().includes('gml')
|
|
66
|
+
),
|
|
67
|
+
outputCrs: 'EPSG:4326',
|
|
68
|
+
}),
|
|
69
|
+
featureType.name,
|
|
70
|
+
wfsEndpoint.getVersion()
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
throw new Error('wfs.geojsongml.notsupported')
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
protected getData() {
|
|
78
|
+
const asJson = this.endpoint.supportsJson(this.featureTypeName)
|
|
79
|
+
let url = this.endpoint.getFeatureUrl(this.featureTypeName, {
|
|
80
|
+
...(this.startIndex !== null && { startIndex: this.startIndex }),
|
|
81
|
+
...(this.count !== null && { maxFeatures: this.count }),
|
|
82
|
+
asJson,
|
|
83
|
+
outputCrs: 'EPSG:4326',
|
|
84
|
+
// sortBy: this.sort // TODO: no sort in ogc-client?
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
if (Array.isArray(this.sort) && this.sort.length > 0) {
|
|
88
|
+
const finalUrl = new URL(url)
|
|
89
|
+
const sorts = this.sort
|
|
90
|
+
.map(
|
|
91
|
+
(fieldSort) => `${fieldSort[1]}+${fieldSort[0] === 'asc' ? 'A' : 'D'}`
|
|
92
|
+
)
|
|
93
|
+
.join(',')
|
|
94
|
+
// Direct update on string url to prevent encoding of +A and +D
|
|
95
|
+
url = `${url}${finalUrl.search ? '&' : ''}SORTBY=${sorts}`
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return fetchDataAsText(url).then((text) =>
|
|
99
|
+
asJson
|
|
100
|
+
? parseGeojson(text)
|
|
101
|
+
: parseGml(text, this.featureTypeName, this.version)
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
load() {
|
|
106
|
+
// Nothing to load for Wfs
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async read(): Promise<DataItem[]> {
|
|
110
|
+
return (await this.getData()).items
|
|
111
|
+
}
|
|
112
|
+
}
|