geonetwork-ui 2.3.0-dev.a26c0b88 → 2.3.0-dev.aef43725

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/read-parts.mjs +2 -2
  2. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/write-parts.mjs +2 -2
  3. package/esm2022/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.mjs +9 -7
  4. package/esm2022/libs/feature/dataviz/src/lib/chart-view/chart-view.component.mjs +1 -1
  5. package/esm2022/libs/feature/dataviz/src/lib/service/data.service.mjs +14 -2
  6. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.mjs +1 -1
  7. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.mjs +104 -0
  8. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.mjs +8 -3
  9. package/esm2022/libs/feature/editor/src/lib/components/wizard-field/wizard-field.component.mjs +1 -1
  10. package/esm2022/libs/feature/editor/src/lib/fields.config.mjs +8 -1
  11. package/esm2022/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.mjs +1 -1
  12. package/esm2022/libs/feature/map/src/lib/map-context/map-context.model.mjs +1 -1
  13. package/esm2022/libs/feature/map/src/lib/map-context/map-context.service.mjs +30 -10
  14. package/esm2022/libs/feature/map/src/lib/utils/map-utils.service.mjs +7 -3
  15. package/esm2022/libs/feature/record/src/lib/data-view/data-view.component.mjs +1 -1
  16. package/esm2022/libs/feature/record/src/lib/map-view/map-view.component.mjs +11 -7
  17. package/esm2022/libs/feature/record/src/lib/state/mdview.facade.mjs +34 -5
  18. package/esm2022/libs/feature/record/src/lib/state/mdview.reducer.mjs +1 -3
  19. package/esm2022/libs/feature/search/src/index.mjs +2 -1
  20. package/esm2022/libs/feature/search/src/lib/results-layout/results-layout.component.mjs +1 -1
  21. package/esm2022/libs/feature/search/src/lib/results-list/results-list.container.component.mjs +4 -4
  22. package/esm2022/libs/feature/search/src/lib/sort-by/sort-by.component.mjs +1 -1
  23. package/esm2022/libs/ui/catalog/src/lib/language-switcher/language-switcher.component.mjs +1 -1
  24. package/esm2022/libs/ui/catalog/src/lib/organisations-filter/organisations-filter.component.mjs +1 -1
  25. package/esm2022/libs/ui/elements/src/index.mjs +2 -2
  26. package/esm2022/libs/ui/elements/src/lib/error/error.component.mjs +30 -0
  27. package/esm2022/libs/ui/elements/src/lib/record-api-form/record-api-form.component.mjs +69 -69
  28. package/esm2022/libs/ui/elements/src/lib/ui-elements.module.mjs +6 -6
  29. package/esm2022/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.mjs +3 -5
  30. package/esm2022/libs/ui/inputs/src/lib/check-toggle/check-toggle.component.mjs +4 -3
  31. package/esm2022/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.mjs +5 -3
  32. package/esm2022/libs/ui/inputs/src/lib/ui-inputs.module.mjs +6 -5
  33. package/esm2022/libs/util/app-config/src/lib/app-config.mjs +3 -1
  34. package/esm2022/libs/util/app-config/src/lib/fixtures.mjs +2 -1
  35. package/esm2022/libs/util/app-config/src/lib/model.mjs +1 -1
  36. package/esm2022/translations/de.json +3 -0
  37. package/esm2022/translations/en.json +3 -0
  38. package/esm2022/translations/es.json +3 -0
  39. package/esm2022/translations/fr.json +3 -0
  40. package/esm2022/translations/it.json +3 -0
  41. package/esm2022/translations/nl.json +3 -0
  42. package/esm2022/translations/pt.json +3 -0
  43. package/fesm2022/geonetwork-ui.mjs +445 -245
  44. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  45. package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts.map +1 -1
  46. package/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.d.ts.map +1 -1
  47. package/libs/feature/dataviz/src/lib/service/data.service.d.ts +2 -1
  48. package/libs/feature/dataviz/src/lib/service/data.service.d.ts.map +1 -1
  49. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.d.ts +21 -0
  50. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.d.ts.map +1 -0
  51. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts +1 -0
  52. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts.map +1 -1
  53. package/libs/feature/editor/src/lib/fields.config.d.ts.map +1 -1
  54. package/libs/feature/map/src/lib/map-context/map-context.model.d.ts +6 -0
  55. package/libs/feature/map/src/lib/map-context/map-context.model.d.ts.map +1 -1
  56. package/libs/feature/map/src/lib/map-context/map-context.service.d.ts +1 -1
  57. package/libs/feature/map/src/lib/map-context/map-context.service.d.ts.map +1 -1
  58. package/libs/feature/map/src/lib/utils/map-utils.service.d.ts.map +1 -1
  59. package/libs/feature/record/src/lib/map-view/map-view.component.d.ts +2 -2
  60. package/libs/feature/record/src/lib/map-view/map-view.component.d.ts.map +1 -1
  61. package/libs/feature/record/src/lib/state/mdview.facade.d.ts +5 -2
  62. package/libs/feature/record/src/lib/state/mdview.facade.d.ts.map +1 -1
  63. package/libs/feature/record/src/lib/state/mdview.reducer.d.ts.map +1 -1
  64. package/libs/feature/search/src/index.d.ts +1 -0
  65. package/libs/feature/search/src/index.d.ts.map +1 -1
  66. package/libs/ui/elements/src/index.d.ts +1 -1
  67. package/libs/ui/elements/src/index.d.ts.map +1 -1
  68. package/libs/ui/elements/src/lib/error/error.component.d.ts +16 -0
  69. package/libs/ui/elements/src/lib/error/error.component.d.ts.map +1 -0
  70. package/libs/ui/elements/src/lib/record-api-form/record-api-form.component.d.ts +14 -3
  71. package/libs/ui/elements/src/lib/record-api-form/record-api-form.component.d.ts.map +1 -1
  72. package/libs/ui/elements/src/lib/ui-elements.module.d.ts +2 -2
  73. package/libs/ui/elements/src/lib/ui-elements.module.d.ts.map +1 -1
  74. package/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.d.ts +1 -2
  75. package/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.d.ts.map +1 -1
  76. package/libs/ui/inputs/src/lib/check-toggle/check-toggle.component.d.ts +1 -1
  77. package/libs/ui/inputs/src/lib/check-toggle/check-toggle.component.d.ts.map +1 -1
  78. package/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.d.ts +2 -1
  79. package/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.d.ts.map +1 -1
  80. package/libs/ui/inputs/src/lib/ui-inputs.module.d.ts +27 -27
  81. package/libs/util/app-config/src/lib/app-config.d.ts.map +1 -1
  82. package/libs/util/app-config/src/lib/fixtures.d.ts.map +1 -1
  83. package/libs/util/app-config/src/lib/model.d.ts +1 -0
  84. package/libs/util/app-config/src/lib/model.d.ts.map +1 -1
  85. package/package.json +2 -2
  86. package/src/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts +1 -1
  87. package/src/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts +1 -4
  88. package/src/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.ts +16 -10
  89. package/src/libs/common/fixtures/src/lib/records.fixtures.ts +8 -0
  90. package/src/libs/feature/dataviz/src/lib/service/data.service.ts +15 -1
  91. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.css +0 -0
  92. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.html +14 -0
  93. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.ts +143 -0
  94. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html +5 -0
  95. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts +5 -0
  96. package/src/libs/feature/editor/src/lib/fields.config.ts +7 -0
  97. package/src/libs/feature/map/src/lib/map-context/map-context.model.ts +6 -0
  98. package/src/libs/feature/map/src/lib/map-context/map-context.service.ts +31 -9
  99. package/src/libs/feature/map/src/lib/utils/map-utils.service.ts +6 -2
  100. package/src/libs/feature/record/src/lib/map-view/map-view.component.ts +10 -8
  101. package/src/libs/feature/record/src/lib/state/mdview.facade.ts +40 -3
  102. package/src/libs/feature/record/src/lib/state/mdview.reducer.ts +0 -2
  103. package/src/libs/feature/search/src/index.ts +1 -0
  104. package/src/libs/feature/search/src/lib/results-list/results-list.container.component.html +4 -4
  105. package/src/libs/ui/elements/src/index.ts +1 -1
  106. package/src/libs/ui/elements/src/lib/{search-results-error/search-results-error.component.html → error/error.component.html} +18 -3
  107. package/src/libs/ui/elements/src/lib/{search-results-error/search-results-error.component.ts → error/error.component.ts} +5 -4
  108. package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.ts +95 -79
  109. package/src/libs/ui/elements/src/lib/ui-elements.module.ts +3 -4
  110. package/src/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.html +1 -1
  111. package/src/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.ts +0 -1
  112. package/src/libs/ui/inputs/src/lib/check-toggle/check-toggle.component.ts +3 -0
  113. package/src/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.html +1 -0
  114. package/src/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.ts +1 -0
  115. package/src/libs/ui/inputs/src/lib/ui-inputs.module.ts +1 -1
  116. package/src/libs/util/app-config/src/lib/app-config.ts +2 -0
  117. package/src/libs/util/app-config/src/lib/fixtures.ts +1 -0
  118. package/src/libs/util/app-config/src/lib/model.ts +1 -0
  119. package/translations/de.json +3 -0
  120. package/translations/en.json +3 -0
  121. package/translations/es.json +3 -0
  122. package/translations/fr.json +3 -0
  123. package/translations/it.json +3 -0
  124. package/translations/nl.json +3 -0
  125. package/translations/pt.json +3 -0
  126. package/translations/sk.json +3 -0
  127. package/esm2022/libs/ui/elements/src/lib/search-results-error/search-results-error.component.mjs +0 -29
  128. package/libs/ui/elements/src/lib/search-results-error/search-results-error.component.d.ts +0 -15
  129. package/libs/ui/elements/src/lib/search-results-error/search-results-error.component.d.ts.map +0 -1
  130. /package/src/libs/ui/elements/src/lib/{search-results-error/search-results-error.component.css → error/error.component.css} +0 -0
@@ -82,7 +82,6 @@ const metadataViewReducer = createReducer(
82
82
  */
83
83
  on(MetadataViewActions.loadUserFeedbacks, (state) => ({
84
84
  ...state,
85
- error: null,
86
85
  allUserFeedbacksLoading: true,
87
86
  })),
88
87
  on(MetadataViewActions.addUserFeedback, (state) => ({
@@ -93,7 +92,6 @@ const metadataViewReducer = createReducer(
93
92
  MetadataViewActions.loadUserFeedbacksSuccess,
94
93
  (state, { userFeedbacks }) => ({
95
94
  ...state,
96
- error: null,
97
95
  userFeedbacks: userFeedbacks,
98
96
  addUserFeedbackLoading: false,
99
97
  allUserFeedbacksLoading: false,
@@ -8,6 +8,7 @@ export * from './lib/state/effects'
8
8
  export * from './lib/state/reducer'
9
9
  export * from './lib/utils/service/search.service'
10
10
  export * from './lib/utils/service/fields.service'
11
+ export * from './lib/utils/service/fields'
11
12
  export * from './lib/results-list/results-list.container.component'
12
13
  export * from './lib/filter-dropdown/filter-dropdown.component'
13
14
  export * from './lib/constants'
@@ -42,16 +42,16 @@
42
42
  </div>
43
43
 
44
44
  <div class="p-4 max-w-[600px] m-auto text-[13px]">
45
- <gn-ui-search-results-error
45
+ <gn-ui-error
46
46
  *ngIf="(errorCode$ | async) === 0"
47
47
  [type]="errorTypes.COULD_NOT_REACH_API"
48
48
  >
49
- </gn-ui-search-results-error>
50
- <gn-ui-search-results-error
49
+ </gn-ui-error>
50
+ <gn-ui-error
51
51
  *ngIf="(error$ | async) !== null && (errorCode$ | async) !== 0"
52
52
  [type]="errorTypes.RECEIVED_ERROR"
53
53
  [error]="errorMessage$ | async"
54
- ></gn-ui-search-results-error>
54
+ ></gn-ui-error>
55
55
  </div>
56
56
 
57
57
  <ng-template #favoriteToggle let-record>
@@ -17,7 +17,7 @@ export * from './lib/pagination-buttons/pagination-buttons.component'
17
17
  export * from './lib/pagination/pagination.component'
18
18
  export * from './lib/record-api-form/record-api-form.component'
19
19
  export * from './lib/related-record-card/related-record-card.component'
20
- export * from './lib/search-results-error/search-results-error.component'
20
+ export * from './lib/error/error.component'
21
21
  export * from './lib/thumbnail/thumbnail.component'
22
22
  export * from './lib/ui-elements.module'
23
23
  export * from './lib/user-preview/user-preview.component'
@@ -1,7 +1,10 @@
1
1
  <div
2
2
  class="p-[1.7em] bg-red-50 text-red-800 text-[1.5em] text-center rounded-lg"
3
3
  >
4
- <div *ngIf="type === types.COULD_NOT_REACH_API">
4
+ <div
5
+ *ngIf="type === types.COULD_NOT_REACH_API"
6
+ data-test="could-not-reach-api-error"
7
+ >
5
8
  <div class="relative opacity-40">
6
9
  <mat-icon class="material-symbols-outlined face">face</mat-icon>
7
10
  <mat-icon class="material-symbols-outlined question-mark1"
@@ -13,14 +16,26 @@
13
16
  </div>
14
17
  <div translate>search.error.couldNotReachApi</div>
15
18
  </div>
16
- <div *ngIf="type === types.RECEIVED_ERROR">
19
+ <div
20
+ *ngIf="type === types.DATASET_HAS_NO_LINK"
21
+ data-test="dataset-has-no-link-error"
22
+ >
23
+ <div class="relative opacity-40">
24
+ <mat-icon class="material-symbols-outlined face">computer</mat-icon>
25
+ </div>
26
+ <div translate>search.error.recordHasnolink</div>
27
+ </div>
28
+ <div *ngIf="type === types.RECEIVED_ERROR" data-test="received-error-error">
17
29
  <div class="relative opacity-40">
18
30
  <mat-icon class="material-symbols-outlined face">mood_bad</mat-icon>
19
31
  </div>
20
32
  <div translate>search.error.receivedError</div>
21
33
  <div *ngIf="error">{{ error }}</div>
22
34
  </div>
23
- <div *ngIf="type === types.RECORD_NOT_FOUND">
35
+ <div
36
+ *ngIf="type === types.RECORD_NOT_FOUND"
37
+ data-test="record-not-found-error"
38
+ >
24
39
  <div class="relative opacity-40">
25
40
  <mat-icon class="material-symbols-outlined computer">computer</mat-icon>
26
41
  <mat-icon class="material-symbols-outlined computer-question-mark"
@@ -4,15 +4,16 @@ export enum ErrorType {
4
4
  COULD_NOT_REACH_API,
5
5
  RECEIVED_ERROR,
6
6
  RECORD_NOT_FOUND,
7
+ DATASET_HAS_NO_LINK,
7
8
  }
8
9
 
9
10
  @Component({
10
- selector: 'gn-ui-search-results-error',
11
- templateUrl: './search-results-error.component.html',
12
- styleUrls: ['./search-results-error.component.css'],
11
+ selector: 'gn-ui-error',
12
+ templateUrl: './error.component.html',
13
+ styleUrls: ['./error.component.css'],
13
14
  changeDetection: ChangeDetectionStrategy.OnPush,
14
15
  })
15
- export class SearchResultsErrorComponent {
16
+ export class ErrorComponent {
16
17
  @Input() type!: ErrorType
17
18
  @Input() error?: string
18
19
  @Input() recordId?: string
@@ -5,13 +5,19 @@ import {
5
5
  ServiceProtocol,
6
6
  } from '../../../../../../libs/common/domain/src/lib/model/record'
7
7
  import { mimeTypeToFormat } from '../../../../../../libs/util/shared/src'
8
- import { BehaviorSubject, combineLatest, map, switchMap } from 'rxjs'
8
+ import { BehaviorSubject, combineLatest, filter, map, switchMap } from 'rxjs'
9
9
 
10
10
  const DEFAULT_PARAMS = {
11
11
  OFFSET: '',
12
12
  LIMIT: '-1',
13
13
  FORMAT: 'json',
14
14
  }
15
+
16
+ interface OutputFormats {
17
+ itemFormats?: any[]
18
+ outputFormats?: any[]
19
+ }
20
+
15
21
  @Component({
16
22
  selector: 'gn-ui-record-api-form',
17
23
  templateUrl: './record-api-form.component.html',
@@ -25,56 +31,40 @@ export class RecordApiFormComponent {
25
31
  this.apiFeatureType = value ? value.name : undefined
26
32
  if (value) {
27
33
  this.apiBaseUrl = value.url.href
28
- this.parseOutputFormats()
34
+ this.createEndpoint().then(() => this.parseOutputFormats())
29
35
  }
30
36
  this.resetUrl()
31
37
  }
32
38
 
33
- offset$ = new BehaviorSubject('')
34
- limit$ = new BehaviorSubject('')
35
- format$ = new BehaviorSubject('')
39
+ offset$ = new BehaviorSubject(DEFAULT_PARAMS.OFFSET)
40
+ limit$ = new BehaviorSubject(DEFAULT_PARAMS.LIMIT)
41
+ format$ = new BehaviorSubject(DEFAULT_PARAMS.FORMAT)
42
+ endpoint$ = new BehaviorSubject<WfsEndpoint | OgcApiEndpoint | undefined>(
43
+ undefined
44
+ )
36
45
  apiBaseUrl: string
37
46
  apiFeatureType: string
38
47
  supportOffset = true
39
48
  accessServiceProtocol: ServiceProtocol | undefined
40
49
  outputFormats = [{ value: 'json', label: 'JSON' }]
50
+ endpoint: WfsEndpoint | OgcApiEndpoint | undefined
51
+ firstCollection: string | undefined
41
52
 
42
- apiQueryUrl$ = combineLatest([this.offset$, this.limit$, this.format$]).pipe(
43
- switchMap(async ([offset, limit, format]) => {
44
- let outputUrl
45
- if (this.apiBaseUrl) {
46
- const url = new URL(this.apiBaseUrl)
47
- const params = { offset: offset, limit: limit, f: format }
48
- for (const [key, value] of Object.entries(params)) {
49
- if (value && value !== '0') {
50
- url.searchParams.set(key, value)
51
- } else {
52
- url.searchParams.delete(key)
53
- }
54
- }
55
- outputUrl = url.toString()
56
- }
57
-
58
- if (this.accessServiceProtocol === 'wfs') {
59
- const wfsEndpoint = new WfsEndpoint(this.apiBaseUrl)
60
- if (await wfsEndpoint.isReady()) {
61
- const options = {
62
- outputFormat: format,
63
- startIndex: Number(offset),
64
- }
65
- if (limit !== '-1') {
66
- options['maxFeatures'] = Number(limit)
67
- }
68
- outputUrl = wfsEndpoint.getFeatureUrl(this.apiFeatureType, options)
69
- }
70
- }
71
- return outputUrl
72
- })
53
+ apiQueryUrl$ = combineLatest([
54
+ this.offset$,
55
+ this.limit$,
56
+ this.format$,
57
+ // only compute the url if the endpoint was created
58
+ this.endpoint$.pipe(filter((endpoint) => !!endpoint)),
59
+ ]).pipe(
60
+ switchMap(([offset, limit, format]) =>
61
+ this.generateApiQueryUrl(offset, limit, format)
62
+ )
73
63
  )
64
+
74
65
  noLimitChecked$ = this.limit$.pipe(
75
66
  map((limit) => limit === '-1' || limit === '')
76
67
  )
77
-
78
68
  displayLimit$ = this.limit$.pipe(
79
69
  map((limit) => (limit !== '-1' ? limit : ''))
80
70
  )
@@ -84,8 +74,7 @@ export class RecordApiFormComponent {
84
74
  }
85
75
 
86
76
  setLimit(value: string) {
87
- const newLimit = value === '' ? '-1' : value
88
- this.limit$.next(newLimit)
77
+ this.limit$.next(value === '' ? '-1' : value)
89
78
  }
90
79
 
91
80
  setFormat(value: string | unknown) {
@@ -98,55 +87,82 @@ export class RecordApiFormComponent {
98
87
  this.format$.next(DEFAULT_PARAMS.FORMAT)
99
88
  }
100
89
 
101
- parseOutputFormats() {
102
- const apiUrl =
103
- this.apiBaseUrl.slice(-1) === '?'
104
- ? this.apiBaseUrl.slice(0, -1)
105
- : this.apiBaseUrl
106
-
107
- this.getOutputFormats(apiUrl, this.accessServiceProtocol).then(
108
- (outputFormats) => {
109
- let formatsList = []
110
- if ('itemFormats' in outputFormats) {
111
- formatsList = this.mapFormats(outputFormats.itemFormats)
112
- } else if ('outputFormats' in outputFormats) {
113
- formatsList = this.mapFormats(outputFormats.outputFormats)
114
- }
115
- this.outputFormats = this.outputFormats.concat(
116
- formatsList.filter(Boolean)
117
- )
118
- this.outputFormats = this.outputFormats
119
- .filter(
120
- (format, index, self) =>
121
- index === self.findIndex((t) => t.value === format.value)
122
- )
123
- .sort((a, b) => a.label.localeCompare(b.label))
124
- }
125
- )
90
+ async parseOutputFormats() {
91
+ if (!this.endpoint) return
92
+ const apiUrl = this.apiBaseUrl.endsWith('?')
93
+ ? this.apiBaseUrl.slice(0, -1)
94
+ : this.apiBaseUrl
95
+ const outputFormats = await this.getOutputFormats(apiUrl)
96
+
97
+ const formatsList = outputFormats.itemFormats
98
+ ? this.mapFormats(outputFormats.itemFormats)
99
+ : this.mapFormats(outputFormats.outputFormats || [])
100
+
101
+ this.outputFormats = this.outputFormats
102
+ .concat(formatsList.filter(Boolean))
103
+ .filter(
104
+ (format, index, self) =>
105
+ index === self.findIndex((t) => t.value === format.value)
106
+ )
107
+ .sort((a, b) => a.label.localeCompare(b.label))
126
108
  }
127
109
 
128
110
  mapFormats(formats: any[]) {
129
111
  return formats.map((format) => {
130
112
  const normalizedFormat = mimeTypeToFormat(format)
131
- if (normalizedFormat) {
132
- return {
133
- label: normalizedFormat.toUpperCase(),
134
- value: normalizedFormat,
135
- }
136
- }
137
- return null
113
+ return normalizedFormat
114
+ ? { label: normalizedFormat.toUpperCase(), value: normalizedFormat }
115
+ : null
138
116
  })
139
117
  }
140
118
 
141
- async getOutputFormats(url: string, accessServiceProtocol: string) {
142
- if (accessServiceProtocol === 'wfs') {
143
- const endpoint = await new WfsEndpoint(url).isReady()
144
- this.supportOffset = endpoint.supportsStartIndex()
145
- return endpoint.getServiceInfo()
119
+ async getOutputFormats(url: string): Promise<OutputFormats> {
120
+ if (!this.endpoint) return {}
121
+ if (this.endpoint instanceof WfsEndpoint) {
122
+ this.supportOffset = this.endpoint.supportsStartIndex()
123
+ return this.endpoint.getServiceInfo() as OutputFormats
124
+ } else {
125
+ return (await this.endpoint.getCollectionInfo(
126
+ this.firstCollection
127
+ )) as OutputFormats
128
+ }
129
+ }
130
+
131
+ async createEndpoint() {
132
+ if (!this.apiBaseUrl || !this.accessServiceProtocol) return
133
+ if (this.accessServiceProtocol === 'wfs') {
134
+ this.endpoint = new WfsEndpoint(this.apiBaseUrl)
135
+ await (this.endpoint as WfsEndpoint).isReady()
136
+ } else {
137
+ this.endpoint = new OgcApiEndpoint(this.apiBaseUrl)
138
+ this.firstCollection = (await this.endpoint.allCollections)[0].name
139
+ }
140
+ this.endpoint$.next(this.endpoint)
141
+ }
142
+
143
+ async generateApiQueryUrl(
144
+ offset: string,
145
+ limit: string,
146
+ format: string
147
+ ): Promise<string> {
148
+ if (!this.apiBaseUrl || !this.endpoint || !this.apiFeatureType) return ''
149
+
150
+ const options = {
151
+ outputFormat: format,
152
+ startIndex: offset ? Number(offset) : undefined,
153
+ maxFeatures: limit !== '-1' ? Number(limit) : undefined,
154
+ limit: limit !== '-1' ? Number(limit) : limit === '-1' ? -1 : undefined,
155
+ offset: offset !== '' ? Number(offset) : undefined,
156
+ }
157
+
158
+ if (this.endpoint instanceof WfsEndpoint) {
159
+ options.maxFeatures = limit !== '-1' ? Number(limit) : undefined
160
+ return this.endpoint.getFeatureUrl(this.apiFeatureType, options)
146
161
  } else {
147
- const endpoint = await new OgcApiEndpoint(url)
148
- const firstCollection = (await endpoint.featureCollections)[0]
149
- return endpoint.getCollectionInfo(firstCollection)
162
+ return await this.endpoint.getCollectionItemsUrl(
163
+ this.firstCollection,
164
+ options
165
+ )
150
166
  }
151
167
  }
152
168
  }
@@ -12,13 +12,12 @@ import { ApiCardComponent } from './api-card/api-card.component'
12
12
  import { UiWidgetsModule } from '../../../../../libs/ui/widgets/src'
13
13
  import { UiLayoutModule } from '../../../../../libs/ui/layout/src'
14
14
  import { TranslateModule } from '@ngx-translate/core'
15
- import { LinkCardComponent } from './link-card/link-card.component'
16
15
  import { RelatedRecordCardComponent } from './related-record-card/related-record-card.component'
17
16
  import { MetadataContactComponent } from './metadata-contact/metadata-contact.component'
18
17
  import { MetadataCatalogComponent } from './metadata-catalog/metadata-catalog.component'
19
18
  import { MetadataQualityComponent } from './metadata-quality/metadata-quality.component'
20
19
  import { MetadataQualityItemComponent } from './metadata-quality-item/metadata-quality-item.component'
21
- import { SearchResultsErrorComponent } from './search-results-error/search-results-error.component'
20
+ import { ErrorComponent } from './error/error.component'
22
21
  import { PaginationComponent } from './pagination/pagination.component'
23
22
  import { ThumbnailComponent } from './thumbnail/thumbnail.component'
24
23
  import { UiInputsModule } from '../../../../../libs/ui/inputs/src'
@@ -62,7 +61,7 @@ import { TimeSincePipe } from './user-feedback-item/time-since.pipe'
62
61
  MetadataCatalogComponent,
63
62
  MetadataQualityComponent,
64
63
  MetadataQualityItemComponent,
65
- SearchResultsErrorComponent,
64
+ ErrorComponent,
66
65
  PaginationComponent,
67
66
  AvatarComponent,
68
67
  UserPreviewComponent,
@@ -84,7 +83,7 @@ import { TimeSincePipe } from './user-feedback-item/time-since.pipe'
84
83
  MetadataCatalogComponent,
85
84
  MetadataQualityComponent,
86
85
  MetadataQualityItemComponent,
87
- SearchResultsErrorComponent,
86
+ ErrorComponent,
88
87
  PaginationComponent,
89
88
  ThumbnailComponent,
90
89
  AvatarComponent,
@@ -30,7 +30,7 @@
30
30
  ></gn-ui-user-feedback-item>
31
31
  </div>
32
32
 
33
- <div *ngIf="isActiveUserEditor" class="mt-2 flex flex-col">
33
+ <div *ngIf="activeUser" class="mt-2 flex flex-col">
34
34
  <hr class="-mx-4 my-4" />
35
35
  <div
36
36
  id="new-comment-buttons"
@@ -21,7 +21,6 @@ import { UserModel } from '../../../../../../libs/common/domain/src/lib/model/us
21
21
  export class UserFeedbackItemComponent implements OnInit {
22
22
  @Input() userFeedbackParent: UserFeedbackViewModel
23
23
  @Input() userFeedBacksAnswers: UserFeedbackViewModel[]
24
- @Input() isActiveUserEditor: boolean
25
24
  @Input() activeUser: UserModel
26
25
  @Input() isLastComment: boolean
27
26
  @Input() isAddUserFeedbackLoading: boolean
@@ -5,12 +5,15 @@ import {
5
5
  Input,
6
6
  Output,
7
7
  } from '@angular/core'
8
+ import { FormsModule } from '@angular/forms'
8
9
 
9
10
  @Component({
10
11
  selector: 'gn-ui-check-toggle',
11
12
  templateUrl: './check-toggle.component.html',
12
13
  styleUrls: ['./check-toggle.component.css'],
13
14
  changeDetection: ChangeDetectionStrategy.OnPush,
15
+ standalone: true,
16
+ imports: [FormsModule],
14
17
  })
15
18
  export class CheckToggleComponent {
16
19
  @Input() title: string
@@ -18,6 +18,7 @@
18
18
  cdkOverlayOrigin
19
19
  #overlayOrigin="cdkOverlayOrigin"
20
20
  (keydown)="handleTriggerKeydown($event)"
21
+ [disabled]="disabled"
21
22
  >
22
23
  <div class="grow font-medium truncate py-1 mr-2 text-left">
23
24
  {{ getChoiceLabel() | translate }}
@@ -48,6 +48,7 @@ export class DropdownSelectorComponent implements OnInit {
48
48
  @Input() maxRows: number
49
49
  @Input() extraBtnClass = ''
50
50
  @Input() minWidth = ''
51
+ @Input() disabled: boolean
51
52
  @Output() selectValue = new EventEmitter<DropdownChoice['value']>()
52
53
  @ViewChild('overlayOrigin') overlayOrigin: CdkOverlayOrigin
53
54
  @ViewChild(CdkConnectedOverlay) overlay: CdkConnectedOverlay
@@ -44,7 +44,6 @@ import { ImageInputComponent } from './image-input/image-input.component'
44
44
  StarToggleComponent,
45
45
  DropdownMultiselectComponent,
46
46
  ViewportIntersectorComponent,
47
- CheckToggleComponent,
48
47
  CopyTextButtonComponent,
49
48
  CheckboxComponent,
50
49
  SearchInputComponent,
@@ -73,6 +72,7 @@ import { ImageInputComponent } from './image-input/image-input.component'
73
72
  ImageInputComponent,
74
73
  DropdownSelectorComponent,
75
74
  DateRangePickerComponent,
75
+ CheckToggleComponent,
76
76
  ],
77
77
  exports: [
78
78
  DropdownSelectorComponent,
@@ -144,6 +144,7 @@ export function loadAppConfig() {
144
144
  [],
145
145
  [
146
146
  'max_zoom',
147
+ 'do_not_tile_wms',
147
148
  'max_extent',
148
149
  'baselayer',
149
150
  'do_not_use_default_basemap',
@@ -158,6 +159,7 @@ export function loadAppConfig() {
158
159
  ? null
159
160
  : ({
160
161
  MAX_ZOOM: parsedMapSection.max_zoom,
162
+ DO_NOT_TILE_WMS: parsedMapSection.do_not_tile_wms,
161
163
  MAX_EXTENT: parsedMapSection.max_extent,
162
164
  EXTERNAL_VIEWER_URL_TEMPLATE:
163
165
  parsedMapSection.external_viewer_url_template,
@@ -81,6 +81,7 @@ export const MAP_CONFIG_FIXTURE: MapConfig = {
81
81
  MAX_ZOOM: 10,
82
82
  MAX_EXTENT: [-418263.418776, 5251529.591305, 961272.067714, 6706890.609855],
83
83
  DO_NOT_USE_DEFAULT_BASEMAP: false,
84
+ DO_NOT_TILE_WMS: false,
84
85
  EXTERNAL_VIEWER_URL_TEMPLATE:
85
86
  'https://example.com/myviewer/#/?actions=[{"type":"CATALOG:ADD_LAYERS_FROM_CATALOGS","layers":["${layer_name}"],"sources":[{"url":"${service_url}","type":"${service_type}"}]}]',
86
87
  EXTERNAL_VIEWER_OPEN_NEW_TAB: true,
@@ -20,6 +20,7 @@ export interface LayerConfig {
20
20
 
21
21
  export interface MapConfig {
22
22
  MAX_ZOOM?: number
23
+ DO_NOT_TILE_WMS: boolean
23
24
  MAX_EXTENT?: [number, number, number, number] // Expressed as [minx, miny, maxx, maxy]
24
25
  EXTERNAL_VIEWER_URL_TEMPLATE?: string
25
26
  EXTERNAL_VIEWER_OPEN_NEW_TAB?: boolean
@@ -156,6 +156,8 @@
156
156
  "editor.record.form.license.pddl": "",
157
157
  "editor.record.form.license.unknown": "Unbekannt oder nicht vorhanden",
158
158
  "editor.record.form.resourceUpdated": "",
159
+ "editor.record.form.updateFrequency": "",
160
+ "editor.record.form.updateFrequency.planned": "",
159
161
  "editor.record.loadError.body": "",
160
162
  "editor.record.loadError.closeMessage": "",
161
163
  "editor.record.loadError.title": "",
@@ -333,6 +335,7 @@
333
335
  "search.error.couldNotReachApi": "Die API konnte nicht erreicht werden",
334
336
  "search.error.receivedError": "Ein Fehler ist aufgetreten",
335
337
  "search.error.recordNotFound": "Der Datensatz mit der Kennung \"{ id }\" konnte nicht gefunden werden.",
338
+ "search.error.recordHasnolink": "",
336
339
  "search.field.any.placeholder": "Suche Datensätze ...",
337
340
  "search.field.sortBy": "Sortieren nach:",
338
341
  "search.filters.clear": "Zurücksetzen",
@@ -156,6 +156,8 @@
156
156
  "editor.record.form.license.pddl": "Open Data Commons PDDL",
157
157
  "editor.record.form.license.unknown": "Unknown or absent",
158
158
  "editor.record.form.resourceUpdated": "Last update date",
159
+ "editor.record.form.updateFrequency": "Update frequency",
160
+ "editor.record.form.updateFrequency.planned": "The data should be updated regularly.",
159
161
  "editor.record.loadError.body": "The record could not be loaded:",
160
162
  "editor.record.loadError.closeMessage": "Understood",
161
163
  "editor.record.loadError.title": "Error loading record",
@@ -333,6 +335,7 @@
333
335
  "search.error.couldNotReachApi": "The API could not be reached",
334
336
  "search.error.receivedError": "An error was received",
335
337
  "search.error.recordNotFound": "The record with identifier \"{ id }\" could not be found.",
338
+ "search.error.recordHasnolink": "This record currently has no link yet, please come back later.",
336
339
  "search.field.any.placeholder": "Search datasets ...",
337
340
  "search.field.sortBy": "Sort by:",
338
341
  "search.filters.clear": "Reset",
@@ -156,6 +156,8 @@
156
156
  "editor.record.form.license.pddl": "",
157
157
  "editor.record.form.license.unknown": "",
158
158
  "editor.record.form.resourceUpdated": "",
159
+ "editor.record.form.updateFrequency": "",
160
+ "editor.record.form.updateFrequency.planned": "",
159
161
  "editor.record.loadError.body": "",
160
162
  "editor.record.loadError.closeMessage": "",
161
163
  "editor.record.loadError.title": "",
@@ -333,6 +335,7 @@
333
335
  "search.error.couldNotReachApi": "",
334
336
  "search.error.receivedError": "",
335
337
  "search.error.recordNotFound": "",
338
+ "search.error.recordHasnolink": "",
336
339
  "search.field.any.placeholder": "",
337
340
  "search.field.sortBy": "",
338
341
  "search.filters.clear": "",
@@ -156,6 +156,8 @@
156
156
  "editor.record.form.license.pddl": "",
157
157
  "editor.record.form.license.unknown": "Non-reconnue ou absente",
158
158
  "editor.record.form.resourceUpdated": "Date de dernière révision",
159
+ "editor.record.form.updateFrequency": "Fréquence de mise à jour",
160
+ "editor.record.form.updateFrequency.planned": "Ces données doivent être mise à jour régulièrement.",
159
161
  "editor.record.loadError.body": "",
160
162
  "editor.record.loadError.closeMessage": "",
161
163
  "editor.record.loadError.title": "",
@@ -333,6 +335,7 @@
333
335
  "search.error.couldNotReachApi": "Problème de connexion à l'API",
334
336
  "search.error.receivedError": "Erreur retournée",
335
337
  "search.error.recordNotFound": "Cette donnée n'a pu être trouvée.",
338
+ "search.error.recordHasnolink": "Ce dataset n'a pas encore de lien, réessayez plus tard s'il vous plaît.",
336
339
  "search.field.any.placeholder": "Rechercher une donnée...",
337
340
  "search.field.sortBy": "Trier par :",
338
341
  "search.filters.clear": "Réinitialiser",
@@ -156,6 +156,8 @@
156
156
  "editor.record.form.license.pddl": "",
157
157
  "editor.record.form.license.unknown": "Non riconosciuta o assente",
158
158
  "editor.record.form.resourceUpdated": "",
159
+ "editor.record.form.updateFrequency": "",
160
+ "editor.record.form.updateFrequency.planned": "",
159
161
  "editor.record.loadError.body": "",
160
162
  "editor.record.loadError.closeMessage": "",
161
163
  "editor.record.loadError.title": "",
@@ -333,6 +335,7 @@
333
335
  "search.error.couldNotReachApi": "Problema di connessione all'API",
334
336
  "search.error.receivedError": "Errore ricevuto",
335
337
  "search.error.recordNotFound": "Impossibile trovare questo dato",
338
+ "search.error.recordHasnolink": "",
336
339
  "search.field.any.placeholder": "Cerca un dato...",
337
340
  "search.field.sortBy": "Ordina per:",
338
341
  "search.filters.clear": "Ripristina",
@@ -156,6 +156,8 @@
156
156
  "editor.record.form.license.pddl": "",
157
157
  "editor.record.form.license.unknown": "",
158
158
  "editor.record.form.resourceUpdated": "",
159
+ "editor.record.form.updateFrequency": "",
160
+ "editor.record.form.updateFrequency.planned": "",
159
161
  "editor.record.loadError.body": "",
160
162
  "editor.record.loadError.closeMessage": "",
161
163
  "editor.record.loadError.title": "",
@@ -333,6 +335,7 @@
333
335
  "search.error.couldNotReachApi": "",
334
336
  "search.error.receivedError": "",
335
337
  "search.error.recordNotFound": "",
338
+ "search.error.recordHasnolink": "",
336
339
  "search.field.any.placeholder": "",
337
340
  "search.field.sortBy": "",
338
341
  "search.filters.clear": "",
@@ -156,6 +156,8 @@
156
156
  "editor.record.form.license.pddl": "",
157
157
  "editor.record.form.license.unknown": "",
158
158
  "editor.record.form.resourceUpdated": "",
159
+ "editor.record.form.updateFrequency": "",
160
+ "editor.record.form.updateFrequency.planned": "",
159
161
  "editor.record.loadError.body": "",
160
162
  "editor.record.loadError.closeMessage": "",
161
163
  "editor.record.loadError.title": "",
@@ -333,6 +335,7 @@
333
335
  "search.error.couldNotReachApi": "",
334
336
  "search.error.receivedError": "",
335
337
  "search.error.recordNotFound": "",
338
+ "search.error.recordHasnolink": "",
336
339
  "search.field.any.placeholder": "",
337
340
  "search.field.sortBy": "",
338
341
  "search.filters.clear": "",
@@ -156,6 +156,8 @@
156
156
  "editor.record.form.license.pddl": "",
157
157
  "editor.record.form.license.unknown": "Neznáme alebo chýbajúce",
158
158
  "editor.record.form.resourceUpdated": "",
159
+ "editor.record.form.updateFrequency": "",
160
+ "editor.record.form.updateFrequency.planned": "",
159
161
  "editor.record.loadError.body": "",
160
162
  "editor.record.loadError.closeMessage": "",
161
163
  "editor.record.loadError.title": "",
@@ -333,6 +335,7 @@
333
335
  "search.error.couldNotReachApi": "K rozhraniu API sa nepodarilo pripojiť",
334
336
  "search.error.receivedError": "Bola zaznamenaná chyba",
335
337
  "search.error.recordNotFound": "Záznam s identifikátorom \"{ id }\" sa nepodarilo nájsť.",
338
+ "search.error.recordHasnolink": "",
336
339
  "search.field.any.placeholder": "Hľadať datasety ...",
337
340
  "search.field.sortBy": "Zoradiť podľa:",
338
341
  "search.filters.clear": "Obnoviť",