geonetwork-ui 2.3.0-dev.139106e0 → 2.3.0-dev.287bf00c

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 (166) hide show
  1. package/esm2022/libs/api/repository/src/lib/gn4/auth/avatar.service.interface.mjs +1 -1
  2. package/esm2022/libs/api/repository/src/lib/gn4/auth/gravatar.service.mjs +12 -1
  3. package/esm2022/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.mjs +36 -3
  4. package/esm2022/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.mjs +19 -7
  5. package/esm2022/libs/common/domain/src/lib/model/record/index.mjs +2 -1
  6. package/esm2022/libs/common/domain/src/lib/model/record/user-feedbacks.model.mjs +2 -0
  7. package/esm2022/libs/common/domain/src/lib/model/user/index.mjs +2 -0
  8. package/esm2022/libs/common/domain/src/lib/platform.service.interface.mjs +1 -1
  9. package/esm2022/libs/feature/dataviz/src/lib/service/data.service.mjs +53 -2
  10. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.mjs +64 -0
  11. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-resource-updated/form-field-resource-updated.component.mjs +15 -0
  12. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.mjs +20 -6
  13. package/esm2022/libs/feature/editor/src/lib/components/wizard-field/wizard-field.component.mjs +1 -1
  14. package/esm2022/libs/feature/editor/src/lib/fields.config.mjs +16 -1
  15. package/esm2022/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.mjs +1 -1
  16. package/esm2022/libs/feature/map/src/lib/add-layer-from-wfs/add-layer-from-wfs.component.mjs +1 -1
  17. package/esm2022/libs/feature/map/src/lib/add-layer-from-wms/add-layer-from-wms.component.mjs +1 -1
  18. package/esm2022/libs/feature/record/src/lib/feature-record.module.mjs +4 -4
  19. package/esm2022/libs/feature/record/src/lib/map-view/map-view.component.mjs +3 -2
  20. package/esm2022/libs/feature/record/src/lib/state/mdview.actions.mjs +22 -4
  21. package/esm2022/libs/feature/record/src/lib/state/mdview.effects.mjs +37 -10
  22. package/esm2022/libs/feature/record/src/lib/state/mdview.facade.mjs +22 -7
  23. package/esm2022/libs/feature/record/src/lib/state/mdview.reducer.mjs +52 -17
  24. package/esm2022/libs/feature/record/src/lib/state/mdview.selectors.mjs +18 -3
  25. package/esm2022/libs/feature/router/src/lib/default/state/router.effects.mjs +2 -2
  26. package/esm2022/libs/ui/elements/src/lib/markdown-editor/markdown-editor.component.mjs +2 -2
  27. package/esm2022/libs/ui/elements/src/lib/record-api-form/record-api-form.component.mjs +34 -7
  28. package/esm2022/libs/ui/elements/src/lib/ui-elements.module.mjs +10 -2
  29. package/esm2022/libs/ui/elements/src/lib/user-feedback-item/time-since.pipe.mjs +59 -0
  30. package/esm2022/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.mjs +62 -0
  31. package/esm2022/libs/ui/inputs/src/index.mjs +15 -15
  32. package/esm2022/libs/ui/inputs/src/lib/date-picker/date-picker.component.mjs +22 -0
  33. package/esm2022/libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.mjs +7 -5
  34. package/esm2022/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.mjs +17 -8
  35. package/esm2022/libs/ui/inputs/src/lib/text-area/text-area.component.mjs +27 -4
  36. package/esm2022/libs/ui/inputs/src/lib/text-input/text-input.component.mjs +19 -3
  37. package/esm2022/libs/ui/inputs/src/lib/ui-inputs.module.mjs +11 -9
  38. package/esm2022/libs/util/shared/src/lib/links/link-classifier.service.mjs +2 -2
  39. package/esm2022/libs/util/shared/src/lib/links/link-utils.mjs +22 -1
  40. package/esm2022/translations/de.json +26 -0
  41. package/esm2022/translations/en.json +26 -0
  42. package/esm2022/translations/es.json +26 -0
  43. package/esm2022/translations/fr.json +26 -0
  44. package/esm2022/translations/it.json +26 -0
  45. package/esm2022/translations/nl.json +26 -0
  46. package/esm2022/translations/pt.json +26 -0
  47. package/fesm2022/geonetwork-ui.mjs +1436 -717
  48. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  49. package/libs/api/repository/src/lib/gn4/auth/avatar.service.interface.d.ts +1 -0
  50. package/libs/api/repository/src/lib/gn4/auth/avatar.service.interface.d.ts.map +1 -1
  51. package/libs/api/repository/src/lib/gn4/auth/gravatar.service.d.ts +1 -0
  52. package/libs/api/repository/src/lib/gn4/auth/gravatar.service.d.ts.map +1 -1
  53. package/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.d.ts +6 -2
  54. package/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.d.ts.map +1 -1
  55. package/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.d.ts +9 -6
  56. package/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.d.ts.map +1 -1
  57. package/libs/common/domain/src/lib/model/record/index.d.ts +1 -0
  58. package/libs/common/domain/src/lib/model/record/index.d.ts.map +1 -1
  59. package/libs/common/domain/src/lib/model/record/user-feedbacks.model.d.ts +15 -0
  60. package/libs/common/domain/src/lib/model/record/user-feedbacks.model.d.ts.map +1 -0
  61. package/libs/common/domain/src/lib/model/user/index.d.ts +2 -0
  62. package/libs/common/domain/src/lib/model/user/index.d.ts.map +1 -0
  63. package/libs/common/domain/src/lib/platform.service.interface.d.ts +3 -0
  64. package/libs/common/domain/src/lib/platform.service.interface.d.ts.map +1 -1
  65. package/libs/feature/dataviz/src/lib/service/data.service.d.ts +3 -1
  66. package/libs/feature/dataviz/src/lib/service/data.service.d.ts.map +1 -1
  67. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.d.ts +39 -0
  68. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.d.ts.map +1 -0
  69. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-resource-updated/form-field-resource-updated.component.d.ts +8 -0
  70. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-resource-updated/form-field-resource-updated.component.d.ts.map +1 -0
  71. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts +4 -1
  72. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts.map +1 -1
  73. package/libs/feature/editor/src/lib/fields.config.d.ts.map +1 -1
  74. package/libs/feature/record/src/lib/feature-record.module.d.ts.map +1 -1
  75. package/libs/feature/record/src/lib/map-view/map-view.component.d.ts.map +1 -1
  76. package/libs/feature/record/src/lib/state/mdview.actions.d.ts +40 -6
  77. package/libs/feature/record/src/lib/state/mdview.actions.d.ts.map +1 -1
  78. package/libs/feature/record/src/lib/state/mdview.effects.d.ts +24 -4
  79. package/libs/feature/record/src/lib/state/mdview.effects.d.ts.map +1 -1
  80. package/libs/feature/record/src/lib/state/mdview.facade.d.ts +14 -4
  81. package/libs/feature/record/src/lib/state/mdview.facade.d.ts.map +1 -1
  82. package/libs/feature/record/src/lib/state/mdview.reducer.d.ts +8 -5
  83. package/libs/feature/record/src/lib/state/mdview.reducer.d.ts.map +1 -1
  84. package/libs/feature/record/src/lib/state/mdview.selectors.d.ts +12 -9
  85. package/libs/feature/record/src/lib/state/mdview.selectors.d.ts.map +1 -1
  86. package/libs/ui/elements/src/lib/downloads-list/downloads-list.component.d.ts +1 -1
  87. package/libs/ui/elements/src/lib/record-api-form/record-api-form.component.d.ts +4 -2
  88. package/libs/ui/elements/src/lib/record-api-form/record-api-form.component.d.ts.map +1 -1
  89. package/libs/ui/elements/src/lib/ui-elements.module.d.ts +16 -14
  90. package/libs/ui/elements/src/lib/ui-elements.module.d.ts.map +1 -1
  91. package/libs/ui/elements/src/lib/user-feedback-item/time-since.pipe.d.ts +11 -0
  92. package/libs/ui/elements/src/lib/user-feedback-item/time-since.pipe.d.ts.map +1 -0
  93. package/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.d.ts +22 -0
  94. package/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.d.ts.map +1 -0
  95. package/libs/ui/inputs/src/index.d.ts +14 -14
  96. package/libs/ui/inputs/src/index.d.ts.map +1 -1
  97. package/libs/ui/inputs/src/lib/date-picker/date-picker.component.d.ts +9 -0
  98. package/libs/ui/inputs/src/lib/date-picker/date-picker.component.d.ts.map +1 -0
  99. package/libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.d.ts +1 -1
  100. package/libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.d.ts.map +1 -1
  101. package/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.d.ts +1 -1
  102. package/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.d.ts.map +1 -1
  103. package/libs/ui/inputs/src/lib/text-area/text-area.component.d.ts +7 -1
  104. package/libs/ui/inputs/src/lib/text-area/text-area.component.d.ts.map +1 -1
  105. package/libs/ui/inputs/src/lib/text-input/text-input.component.d.ts +4 -1
  106. package/libs/ui/inputs/src/lib/text-input/text-input.component.d.ts.map +1 -1
  107. package/libs/ui/inputs/src/lib/ui-inputs.module.d.ts +35 -35
  108. package/libs/util/shared/src/lib/links/link-utils.d.ts +18 -0
  109. package/libs/util/shared/src/lib/links/link-utils.d.ts.map +1 -1
  110. package/package.json +1 -1
  111. package/src/libs/api/repository/src/lib/gn4/auth/avatar.service.interface.ts +1 -0
  112. package/src/libs/api/repository/src/lib/gn4/auth/gravatar.service.ts +12 -1
  113. package/src/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.ts +51 -1
  114. package/src/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.ts +34 -7
  115. package/src/libs/common/domain/src/lib/model/record/index.ts +1 -0
  116. package/src/libs/common/domain/src/lib/model/record/user-feedbacks.model.ts +15 -0
  117. package/src/libs/common/domain/src/lib/platform.service.interface.ts +3 -0
  118. package/src/libs/common/fixtures/src/index.ts +8 -6
  119. package/src/libs/common/fixtures/src/lib/records.fixtures.ts +3 -3
  120. package/src/libs/common/fixtures/src/lib/user-feedbacks.fixtures.ts +83 -0
  121. package/src/libs/feature/dataviz/src/lib/service/data.service.ts +68 -1
  122. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.css +0 -0
  123. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.html +8 -0
  124. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.ts +64 -0
  125. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-resource-updated/form-field-resource-updated.component.css +0 -0
  126. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-resource-updated/form-field-resource-updated.component.html +4 -0
  127. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-resource-updated/form-field-resource-updated.component.ts +15 -0
  128. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html +33 -33
  129. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts +16 -0
  130. package/src/libs/feature/editor/src/lib/fields.config.ts +15 -0
  131. package/src/libs/feature/record/src/lib/feature-record.module.ts +5 -2
  132. package/src/libs/feature/record/src/lib/map-view/map-view.component.ts +2 -1
  133. package/src/libs/feature/record/src/lib/state/mdview.actions.ts +51 -6
  134. package/src/libs/feature/record/src/lib/state/mdview.effects.ts +82 -7
  135. package/src/libs/feature/record/src/lib/state/mdview.facade.ts +49 -8
  136. package/src/libs/feature/record/src/lib/state/mdview.reducer.ts +81 -24
  137. package/src/libs/feature/record/src/lib/state/mdview.selectors.ts +40 -10
  138. package/src/libs/feature/router/src/lib/default/state/router.effects.ts +2 -2
  139. package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.html +1 -1
  140. package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.ts +40 -4
  141. package/src/libs/ui/elements/src/lib/ui-elements.module.ts +5 -0
  142. package/src/libs/ui/elements/src/lib/user-feedback-item/time-since.pipe.ts +54 -0
  143. package/src/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.css +0 -0
  144. package/src/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.html +75 -0
  145. package/src/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.ts +63 -0
  146. package/src/libs/ui/inputs/src/index.ts +14 -14
  147. package/src/libs/ui/inputs/src/lib/date-picker/date-picker.component.css +3 -0
  148. package/src/libs/ui/inputs/src/lib/date-picker/date-picker.component.html +11 -0
  149. package/src/libs/ui/inputs/src/lib/date-picker/date-picker.component.ts +16 -0
  150. package/src/libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.ts +8 -1
  151. package/src/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.ts +13 -0
  152. package/src/libs/ui/inputs/src/lib/text-area/text-area.component.html +2 -1
  153. package/src/libs/ui/inputs/src/lib/text-area/text-area.component.ts +29 -0
  154. package/src/libs/ui/inputs/src/lib/text-input/text-input.component.html +1 -1
  155. package/src/libs/ui/inputs/src/lib/text-input/text-input.component.ts +16 -1
  156. package/src/libs/ui/inputs/src/lib/ui-inputs.module.ts +2 -2
  157. package/src/libs/util/shared/src/lib/links/link-classifier.service.ts +1 -1
  158. package/src/libs/util/shared/src/lib/links/link-utils.ts +21 -0
  159. package/translations/de.json +26 -0
  160. package/translations/en.json +26 -0
  161. package/translations/es.json +26 -0
  162. package/translations/fr.json +26 -0
  163. package/translations/it.json +26 -0
  164. package/translations/nl.json +26 -0
  165. package/translations/pt.json +26 -0
  166. package/translations/sk.json +26 -0
@@ -6,11 +6,15 @@ import {
6
6
  RegistriesApiService,
7
7
  SiteApiService,
8
8
  ToolsApiService,
9
+ UserfeedbackApiService,
9
10
  UsersApiService,
10
11
  } from '../../../../../../../libs/data-access/gn4/src'
11
12
  import { PlatformServiceInterface } from '../../../../../../../libs/common/domain/src/lib/platform.service.interface'
12
13
  import { UserModel } from '../../../../../../../libs/common/domain/src/lib/model/user/user.model'
13
- import { Organization } from '../../../../../../../libs/common/domain/src/lib/model/record'
14
+ import {
15
+ Organization,
16
+ UserFeedback,
17
+ } from '../../../../../../../libs/common/domain/src/lib/model/record'
14
18
  import { Gn4PlatformMapper } from './gn4-platform.mapper'
15
19
  import { ltr } from 'semver'
16
20
  import { ThesaurusModel } from '../../../../../../../libs/common/domain/src/lib/model/thesaurus/thesaurus.model'
@@ -21,9 +25,9 @@ const minApiVersion = '4.2.2'
21
25
  @Injectable()
22
26
  export class Gn4PlatformService implements PlatformServiceInterface {
23
27
  private readonly type = 'GeoNetwork'
24
- private me$: Observable<UserModel>
25
- private users$: Observable<UserModel[]>
26
- private isAnonymous$: Observable<boolean>
28
+ private readonly me$: Observable<UserModel>
29
+ private readonly users$: Observable<UserModel[]>
30
+ private readonly isUserAnonymous$: Observable<boolean>
27
31
 
28
32
  private keyTranslations$ = this.toolsApiService
29
33
  .getTranslationsPackage1('gnui')
@@ -65,13 +69,18 @@ export class Gn4PlatformService implements PlatformServiceInterface {
65
69
  private mapper: Gn4PlatformMapper,
66
70
  private toolsApiService: ToolsApiService,
67
71
  private registriesApiService: RegistriesApiService,
68
- private langService: LangService
72
+ private langService: LangService,
73
+ private userfeedbackApiService: UserfeedbackApiService
69
74
  ) {
70
75
  this.me$ = this.meApi.getMe().pipe(
71
76
  switchMap((apiUser) => this.mapper.userFromMeApi(apiUser)),
72
77
  shareReplay({ bufferSize: 1, refCount: true })
73
78
  )
74
- this.isAnonymous$ = this.me$.pipe(map((user) => !user || !('id' in user)))
79
+
80
+ this.isUserAnonymous$ = this.me$.pipe(
81
+ map((user) => !user || !('id' in user))
82
+ )
83
+
75
84
  this.users$ = this.usersApi.getUsers().pipe(
76
85
  map((users) => users.map((user) => this.mapper.userFromApi(user))),
77
86
  shareReplay()
@@ -91,7 +100,7 @@ export class Gn4PlatformService implements PlatformServiceInterface {
91
100
  }
92
101
 
93
102
  isAnonymous(): Observable<boolean> {
94
- return this.isAnonymous$
103
+ return this.isUserAnonymous$
95
104
  }
96
105
 
97
106
  getOrganizations(): Observable<Organization[]> {
@@ -148,6 +157,24 @@ export class Gn4PlatformService implements PlatformServiceInterface {
148
157
  ),
149
158
  shareReplay(1)
150
159
  )
160
+
151
161
  return this.thesauri[uri]
152
162
  }
163
+
164
+ getUserFeedbacks(uuid: string): Observable<UserFeedback[]> {
165
+ return this.userfeedbackApiService
166
+ .getUserComments(uuid)
167
+ .pipe(
168
+ map((userFeedbacks) =>
169
+ userFeedbacks.map(this.mapper.userFeedbacksFromApi)
170
+ )
171
+ )
172
+ }
173
+
174
+ postUserFeedbacks(userFeedback: UserFeedback): Observable<void> {
175
+ const mappedUserFeedBack = this.mapper.userFeedbacksToApi(userFeedback)
176
+ return this.userfeedbackApiService
177
+ .newUserFeedback(mappedUserFeedBack)
178
+ .pipe(map(() => undefined))
179
+ }
153
180
  }
@@ -1,3 +1,4 @@
1
1
  export * from './contact.model'
2
2
  export * from './organization.model'
3
3
  export * from './metadata.model'
4
+ export * from './user-feedbacks.model'
@@ -0,0 +1,15 @@
1
+ export interface UserFeedback {
2
+ uuid: string
3
+ comment: string
4
+ metadataUUID: string
5
+ authorUserId: string
6
+ authorName: string
7
+ authorEmail: string
8
+ published: boolean
9
+ parentUuid?: string
10
+ date: Date
11
+ }
12
+
13
+ export interface UserFeedbackViewModel extends UserFeedback {
14
+ avatarUrl: string
15
+ }
@@ -2,6 +2,7 @@ import type { Observable } from 'rxjs'
2
2
  import type { UserModel } from './model/user/user.model'
3
3
  import type { Organization } from './model/record/organization.model'
4
4
  import type { ThesaurusModel } from './model/thesaurus/'
5
+ import { UserFeedback } from './model/record'
5
6
 
6
7
  export abstract class PlatformServiceInterface {
7
8
  abstract getType(): string
@@ -16,4 +17,6 @@ export abstract class PlatformServiceInterface {
16
17
  abstract getOrganizations(): Observable<Organization[]>
17
18
  abstract translateKey(key: string): Observable<string>
18
19
  abstract getThesaurusByUri(uri: string): Observable<ThesaurusModel>
20
+ abstract getUserFeedbacks(recordUuid: string): Observable<UserFeedback[]>
21
+ abstract postUserFeedbacks(recordUuid: UserFeedback): Observable<void>
19
22
  }
@@ -1,11 +1,13 @@
1
+ export * from './lib/elasticsearch'
2
+ export * from './lib/gn4'
3
+ export * from './lib/search'
4
+
1
5
  export * from './lib/geojson.fixtures'
6
+ export * from './lib/link.fixtures'
2
7
  export * from './lib/ol-feature.fixture'
8
+ export * from './lib/organisations.fixture'
3
9
  export * from './lib/record-link.fixtures'
4
- export * from './lib/link.fixtures'
5
10
  export * from './lib/records.fixtures'
6
- export * from './lib/organisations.fixture'
7
- export * from './lib/elasticsearch'
8
- export * from './lib/search'
9
- export * from './lib/user.fixtures'
10
11
  export * from './lib/repository.fixtures'
11
- export * from './lib/gn4'
12
+ export * from './lib/user.fixtures'
13
+ export * from './lib/user-feedbacks.fixtures'
@@ -1,5 +1,5 @@
1
1
  import { DatasetRecord } from '../../../../../libs/common/domain/src/lib/model/record'
2
- import { deepFreeze } from './utils/freeze'
2
+ import { deepFreeze } from './utils'
3
3
 
4
4
  export const DATASET_RECORDS: DatasetRecord[] = deepFreeze([
5
5
  {
@@ -49,8 +49,8 @@ export const DATASET_RECORDS: DatasetRecord[] = deepFreeze([
49
49
  status: 'ongoing',
50
50
  recordCreated: new Date('2022-02-01T15:12:00'),
51
51
  recordUpdated: new Date('2022-02-01T15:12:00'),
52
- datasetCreated: new Date('2022-09-01T14:18:19'),
53
- datasetUpdated: new Date('2022-12-04T15:12:00'),
52
+ resourceCreated: new Date('2022-09-01T14:18:19'),
53
+ resourceUpdated: new Date('2022-12-04T15:12:00'),
54
54
  title: 'A very interesting dataset (un jeu de données très intéressant)',
55
55
  abstract: `# Introduction
56
56
  This dataset has been established for testing purposes.
@@ -0,0 +1,83 @@
1
+ import { UserFeedback } from '../../../../../libs/common/domain/src/lib/model/record'
2
+ import { deepFreeze } from './utils'
3
+
4
+ export const SOME_USER_FEEDBACKS: UserFeedback[] = deepFreeze([
5
+ {
6
+ uuid: '4ad03fb7-1728-424c-bdaa-aedd531b07a8',
7
+ comment: 'A nice comment.',
8
+ metadataUUID: 'my-dataset-001',
9
+ authorUserId: '46798',
10
+ authorName: 'Arnaud De Maison',
11
+ authorEmail: 'a.demaison@geo2france.fr',
12
+ published: true,
13
+ parentUuid: undefined,
14
+ date: new Date('2023-01-01T08:00:00Z'),
15
+ },
16
+ {
17
+ uuid: '52cbd0f1-9cb9-4409-8e85-bc608f049af4',
18
+ comment: 'A very nice comment that is a reply.',
19
+ metadataUUID: 'my-dataset-001',
20
+ authorUserId: '46798',
21
+ authorName: 'Arnaud De Maison',
22
+ authorEmail: 'a.demaison@geo2france.fr',
23
+ published: true,
24
+ parentUuid: '4ad03fb7-1728-424c-bdaa-aedd531b07a8',
25
+ date: new Date('2023-01-01T09:00:00Z'),
26
+ },
27
+ {
28
+ uuid: 'b48f62ec-b5e6-4d27-a396-2c2b44f6dcb5',
29
+ comment: 'Another nice comment.',
30
+ metadataUUID: 'my-dataset-001',
31
+ authorUserId: '46798',
32
+ authorName: 'Arnaud De Maison',
33
+ authorEmail: 'a.demaison@geo2france.fr',
34
+ published: true,
35
+ parentUuid: undefined,
36
+ date: new Date('2023-01-01T10:00:00Z'),
37
+ },
38
+ {
39
+ uuid: '1f12a3be-fc8a-4e83-968f-9b88ffbcab02',
40
+ comment: 'Another very nice reply.',
41
+ metadataUUID: 'my-dataset-001',
42
+ authorUserId: '46798',
43
+ authorName: 'Arnaud De Maison',
44
+ authorEmail: 'a.demaison@geo2france.fr',
45
+ published: true,
46
+ parentUuid: '4ad03fb7-1728-424c-bdaa-aedd531b07a8',
47
+ date: new Date('2023-01-01T11:00:00Z'),
48
+ },
49
+ {
50
+ uuid: 'f8dd778d-e93c-4b3c-ba9b-9574be070f46',
51
+ comment: 'Another nice comment.',
52
+ metadataUUID: 'my-dataset-001',
53
+ authorUserId: '46798',
54
+ authorName: 'Arnaud De Maison',
55
+ authorEmail: 'a.demaison@geo2france.fr',
56
+ published: true,
57
+ parentUuid: undefined,
58
+ date: new Date('2023-01-01T10:00:00Z'),
59
+ },
60
+ {
61
+ uuid: 'df3b8872-61d1-4ae9-8822-bb070b94d7d1',
62
+ comment: 'Another nice comment.',
63
+ metadataUUID: 'my-dataset-001',
64
+ authorUserId: '46798',
65
+ authorName: 'Arnaud De Maison',
66
+ authorEmail: 'a.demaison@geo2france.fr',
67
+ published: true,
68
+ parentUuid: undefined,
69
+ date: new Date('2023-01-01T11:00:00Z'),
70
+ },
71
+ ])
72
+
73
+ export const A_USER_FEEDBACK: UserFeedback = deepFreeze({
74
+ uuid: '4ad03fb7-1728-424c-bdaa-aedd531b07a8',
75
+ comment: 'A nice comment.',
76
+ metadataUUID: 'my-dataset-001',
77
+ authorUserId: '46798',
78
+ authorName: 'Arnaud De Maison',
79
+ authorEmail: 'a.demaison@geo2france.fr',
80
+ published: true,
81
+ parentUuid: undefined,
82
+ date: new Date('2023-01-01T08:00:00Z'),
83
+ })
@@ -1,6 +1,11 @@
1
1
  import { Injectable } from '@angular/core'
2
2
  import { marker } from '@biesbjerg/ngx-translate-extract-marker'
3
- import { WfsEndpoint, WfsVersion } from '@camptocamp/ogc-client'
3
+ import {
4
+ OgcApiCollectionInfo,
5
+ OgcApiEndpoint,
6
+ WfsEndpoint,
7
+ WfsVersion,
8
+ } from '@camptocamp/ogc-client'
4
9
  import {
5
10
  BaseReader,
6
11
  FetchError,
@@ -148,6 +153,53 @@ export class DataService {
148
153
  )
149
154
  }
150
155
 
156
+ async getDownloadLinksFromOgcApiFeatures(
157
+ ogcApiLink: DatasetServiceDistribution
158
+ ): Promise<DatasetDistribution[]> {
159
+ const collectionInfo = await this.getDownloadUrlsFromOgcApi(
160
+ ogcApiLink.url.href
161
+ )
162
+
163
+ return Object.keys(collectionInfo.bulkDownloadLinks).map((downloadLink) => {
164
+ return {
165
+ ...ogcApiLink,
166
+ type: 'download',
167
+ url: new URL(collectionInfo.bulkDownloadLinks[downloadLink]),
168
+ mimeType: getMimeTypeForFormat(
169
+ getFileFormatFromServiceOutput(downloadLink)
170
+ ),
171
+ }
172
+ })
173
+ }
174
+
175
+ async getDownloadUrlsFromOgcApi(url: string): Promise<OgcApiCollectionInfo> {
176
+ const endpoint = new OgcApiEndpoint(this.proxy.getProxiedUrl(url))
177
+ return await endpoint.featureCollections
178
+ .then((collections) => {
179
+ return endpoint.getCollectionInfo(collections[0])
180
+ })
181
+ .catch((error) => {
182
+ if (error instanceof Error) {
183
+ throw new Error(`wfs.unreachable.unknown`)
184
+ } else {
185
+ if (error.type === 'network') {
186
+ throw new Error(`wfs.unreachable.cors`)
187
+ }
188
+ if (error.type === 'http') {
189
+ throw new Error(`wfs.unreachable.http`)
190
+ }
191
+ if (error.type === 'parse') {
192
+ throw new Error(`wfs.unreachable.parse`)
193
+ }
194
+ if (error.type === 'unsupportedType') {
195
+ throw new Error(`wfs.unreachable.unsupportedType`)
196
+ } else {
197
+ throw new Error(`wfs.unreachable.unknown`)
198
+ }
199
+ }
200
+ })
201
+ }
202
+
151
203
  getDownloadLinksFromEsriRest(
152
204
  esriRestLink: DatasetServiceDistribution
153
205
  ): DatasetDistribution[] {
@@ -205,6 +257,21 @@ export class DataService {
205
257
  'geojson'
206
258
  )
207
259
  return from(openDataset(url, 'geojson')).pipe()
260
+ } else if (
261
+ link.type === 'service' &&
262
+ link.accessServiceProtocol === 'ogcFeatures'
263
+ ) {
264
+ return from(this.getDownloadUrlsFromOgcApi(link.url.href)).pipe(
265
+ switchMap((collectionInfo) => {
266
+ const geojsonUrl = collectionInfo.jsonDownloadLink
267
+ return openDataset(geojsonUrl, 'geojson')
268
+ }),
269
+ tap((url) => {
270
+ if (url === null) {
271
+ throw new Error('wfs.geojsongml.notsupported')
272
+ }
273
+ })
274
+ )
208
275
  }
209
276
  return throwError(() => 'protocol not supported')
210
277
  }
@@ -0,0 +1,8 @@
1
+ <gn-ui-dropdown-selector
2
+ [title]="label"
3
+ [showTitle]="false"
4
+ [choices]="choices"
5
+ [selected]="selected"
6
+ (selectValue)="onSelectValue($event)"
7
+ >
8
+ </gn-ui-dropdown-selector>
@@ -0,0 +1,64 @@
1
+ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
2
+ import { FormControl } from '@angular/forms'
3
+ import { marker } from '@biesbjerg/ngx-translate-extract-marker'
4
+ import { DropdownSelectorComponent } from '../../../../../../../../../libs/ui/inputs/src'
5
+
6
+ @Component({
7
+ selector: 'gn-ui-form-field-license',
8
+ templateUrl: './form-field-license.component.html',
9
+ styleUrls: ['./form-field-license.component.css'],
10
+ changeDetection: ChangeDetectionStrategy.OnPush,
11
+ standalone: true,
12
+ imports: [DropdownSelectorComponent],
13
+ })
14
+ export class FormFieldLicenseComponent {
15
+ @Input() control!: FormControl
16
+ @Input() label: string
17
+
18
+ get selected() {
19
+ return this.control.value[0]?.text
20
+ }
21
+
22
+ onSelectValue(value: unknown) {
23
+ this.control.setValue([{ text: value }])
24
+ }
25
+
26
+ choices = [
27
+ {
28
+ value: 'cc-by',
29
+ label: marker('editor.record.form.license.cc-by'),
30
+ },
31
+ {
32
+ value: 'cc-by-sa',
33
+ label: marker('editor.record.form.license.cc-by-sa'),
34
+ },
35
+ {
36
+ value: 'cc-zero',
37
+ label: marker('editor.record.form.license.cc-zero'),
38
+ },
39
+ {
40
+ value: 'etalab',
41
+ label: marker('editor.record.form.license.etalab'),
42
+ },
43
+ {
44
+ value: 'etalab-v2',
45
+ label: marker('editor.record.form.license.etalab-v2'),
46
+ },
47
+ {
48
+ value: 'odbl',
49
+ label: marker('editor.record.form.license.odbl'),
50
+ },
51
+ {
52
+ value: 'odc-by',
53
+ label: marker('editor.record.form.license.odc-by'),
54
+ },
55
+ {
56
+ value: 'pddl',
57
+ label: marker('editor.record.form.license.pddl'),
58
+ },
59
+ {
60
+ value: 'unknown',
61
+ label: marker('editor.record.form.license.unknown'),
62
+ },
63
+ ]
64
+ }
@@ -0,0 +1,4 @@
1
+ <gn-ui-date-picker
2
+ [date]="control.value"
3
+ (dateChange)="control.setValue($event)"
4
+ ></gn-ui-date-picker>
@@ -0,0 +1,15 @@
1
+ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
2
+ import { FormControl } from '@angular/forms'
3
+ import { DatePickerComponent } from '../../../../../../../../../libs/ui/inputs/src'
4
+
5
+ @Component({
6
+ selector: 'gn-ui-form-field-resource-updated',
7
+ templateUrl: './form-field-resource-updated.component.html',
8
+ styleUrls: ['./form-field-resource-updated.component.css'],
9
+ changeDetection: ChangeDetectionStrategy.OnPush,
10
+ standalone: true,
11
+ imports: [DatePickerComponent],
12
+ })
13
+ export class FormFieldResourceUpdatedComponent {
14
+ @Input() control!: FormControl
15
+ }
@@ -1,29 +1,18 @@
1
1
  <div class="flex flex-col h-full">
2
- <div class="mb-2 flex flex-row">
3
- <label class="grow">
4
- <span class="font-medium field-label">{{
5
- config.labelKey | translate
6
- }}</span>
7
- <span *ngIf="config.hintKey" class="text-gray-900 text-sm">
8
- - {{ config.hintKey | translate }}
9
- </span>
10
- </label>
11
- <mat-icon
12
- *ngIf="isFieldOk"
13
- class="material-symbols-outlined text-[#c6d950] icon-ok"
14
- >check_circle</mat-icon
15
- >
16
- <mat-icon
17
- *ngIf="isFieldLocked"
18
- class="material-symbols-outlined text-blue-400 icon-locked"
19
- >lock</mat-icon
20
- >
21
- <mat-icon
22
- *ngIf="isFieldInvalid"
23
- class="material-symbols-outlined text-pink-500 icon-invalid"
24
- >cancel</mat-icon
2
+ <ng-container *ngIf="withoutWrapper; else withGenericWrapper">
3
+ <ng-container *ngTemplateOutlet="fieldContent"></ng-container>
4
+ </ng-container>
5
+ <ng-template #withGenericWrapper>
6
+ <gn-ui-form-field-wrapper
7
+ [label]="config.labelKey | translate"
8
+ [hint]="config.hintKey | translate"
25
9
  >
26
- </div>
10
+ <ng-container *ngTemplateOutlet="fieldContent"></ng-container>
11
+ </gn-ui-form-field-wrapper>
12
+ </ng-template>
13
+ </div>
14
+
15
+ <ng-template #fieldContent>
27
16
  <ng-container *ngIf="isTitle">
28
17
  <div class="flex justify-between items-center gap-3">
29
18
  <h2
@@ -48,6 +37,25 @@
48
37
  </span>
49
38
  </div>
50
39
  </ng-container>
40
+ <ng-container *ngIf="isAbstract">
41
+ <gn-ui-form-field-rich
42
+ class="h-[8rem]"
43
+ [control]="formControl"
44
+ [label]="config.labelKey | translate"
45
+ [hint]="config.hintKey | translate"
46
+ ></gn-ui-form-field-rich>
47
+ </ng-container>
48
+ <ng-container *ngIf="isLicenses">
49
+ <gn-ui-form-field-license
50
+ [control]="formControl"
51
+ [label]="config.labelKey | translate"
52
+ ></gn-ui-form-field-license>
53
+ </ng-container>
54
+ <ng-container *ngIf="isResourceUpdated">
55
+ <gn-ui-form-field-resource-updated
56
+ [control]="formControl"
57
+ ></gn-ui-form-field-resource-updated>
58
+ </ng-container>
51
59
  <ng-container *ngIf="isSimpleField">
52
60
  <gn-ui-form-field-simple
53
61
  [type]="simpleType"
@@ -63,14 +71,6 @@
63
71
  [invalid]="isFieldInvalid"
64
72
  ></gn-ui-form-field-file>
65
73
  </ng-container>
66
- <ng-container *ngIf="isAbstract">
67
- <gn-ui-form-field-rich
68
- class="h-[8rem]"
69
- [control]="formControl"
70
- [label]="config.labelKey | translate"
71
- [hint]="config.hintKey | translate"
72
- ></gn-ui-form-field-rich>
73
- </ng-container>
74
74
  <ng-container *ngIf="isArrayField">
75
75
  <gn-ui-form-field-array></gn-ui-form-field-array>
76
76
  </ng-container>
@@ -89,4 +89,4 @@
89
89
  >
90
90
  {{ config.invalidHintKey | translate }}
91
91
  </div>
92
- </div>
92
+ </ng-template>
@@ -11,11 +11,14 @@ import { FormControl, ReactiveFormsModule } from '@angular/forms'
11
11
  import { MatIconModule } from '@angular/material/icon'
12
12
  import { MatTooltipModule } from '@angular/material/tooltip'
13
13
  import { EditableLabelDirective } from '../../../../../../../../libs/ui/inputs/src'
14
+ import { FormFieldWrapperComponent } from '../../../../../../../../libs/ui/layout/src'
14
15
  import { TranslateModule } from '@ngx-translate/core'
15
16
  import { Observable } from 'rxjs'
16
17
  import { FormFieldArrayComponent } from './form-field-array/form-field-array.component'
17
18
  import { FormFieldFileComponent } from './form-field-file/form-field-file.component'
19
+ import { FormFieldLicenseComponent } from './form-field-license/form-field-license.component'
18
20
  import { FormFieldObjectComponent } from './form-field-object/form-field-object.component'
21
+ import { FormFieldResourceUpdatedComponent } from './form-field-resource-updated/form-field-resource-updated.component'
19
22
  import { FormFieldRichComponent } from './form-field-rich/form-field-rich.component'
20
23
  import { FormFieldSimpleComponent } from './form-field-simple/form-field-simple.component'
21
24
  import { FormFieldSpatialExtentComponent } from './form-field-spatial-extent/form-field-spatial-extent.component'
@@ -34,6 +37,9 @@ import { FormFieldConfig } from './form-field.model'
34
37
  EditableLabelDirective,
35
38
  MatIconModule,
36
39
  MatTooltipModule,
40
+ FormFieldWrapperComponent,
41
+ FormFieldLicenseComponent,
42
+ FormFieldResourceUpdatedComponent,
37
43
  FormFieldSimpleComponent,
38
44
  FormFieldRichComponent,
39
45
  FormFieldObjectComponent,
@@ -118,4 +124,14 @@ export class FormFieldComponent {
118
124
  get isAbstract() {
119
125
  return this.model === 'abstract'
120
126
  }
127
+ get isLicenses() {
128
+ return this.model === 'licenses'
129
+ }
130
+ get isResourceUpdated() {
131
+ return this.model === 'resourceUpdated'
132
+ }
133
+
134
+ get withoutWrapper() {
135
+ return this.model === 'title' || this.model === 'abstract'
136
+ }
121
137
  }
@@ -1,3 +1,4 @@
1
+ import { marker } from '@biesbjerg/ngx-translate-extract-marker'
1
2
  import { EditorFieldsConfig } from './models/fields.model'
2
3
 
3
4
  export const DEFAULT_FIELDS: EditorFieldsConfig = [
@@ -32,4 +33,18 @@ export const DEFAULT_FIELDS: EditorFieldsConfig = [
32
33
  },
33
34
  onSaveProcess: '${dateNow()}',
34
35
  },
36
+ {
37
+ model: 'licenses',
38
+ formFieldConfig: {
39
+ labelKey: marker('editor.record.form.license'),
40
+ type: 'list',
41
+ },
42
+ },
43
+ {
44
+ model: 'resourceUpdated',
45
+ formFieldConfig: {
46
+ labelKey: marker('editor.record.form.resourceUpdated'),
47
+ type: 'date',
48
+ },
49
+ },
35
50
  ]
@@ -11,7 +11,10 @@ import { MdViewFacade } from './state'
11
11
  import { MdViewEffects } from './state/mdview.effects'
12
12
  import { MapViewComponent } from './map-view/map-view.component'
13
13
  import { DataViewComponent } from './data-view/data-view.component'
14
- import { MD_VIEW_FEATURE_STATE_KEY, reducer } from './state/mdview.reducer'
14
+ import {
15
+ METADATA_VIEW_FEATURE_STATE_KEY,
16
+ reducer,
17
+ } from './state/mdview.reducer'
15
18
  import { MatTabsModule } from '@angular/material/tabs'
16
19
  import { MatIconModule } from '@angular/material/icon'
17
20
  import { UiWidgetsModule } from '../../../../../libs/ui/widgets/src'
@@ -35,7 +38,7 @@ import { DataViewShareComponent } from './data-view-share/data-view-share.compon
35
38
  ],
36
39
  imports: [
37
40
  CommonModule,
38
- StoreModule.forFeature(MD_VIEW_FEATURE_STATE_KEY, reducer),
41
+ StoreModule.forFeature(METADATA_VIEW_FEATURE_STATE_KEY, reducer),
39
42
  EffectsModule.forFeature([MdViewEffects]),
40
43
  UiLayoutModule,
41
44
  FeatureMapModule,
@@ -196,7 +196,8 @@ export class MapViewComponent implements OnInit, OnDestroy {
196
196
  } else if (
197
197
  (link.type === 'service' &&
198
198
  (link.accessServiceProtocol === 'wfs' ||
199
- link.accessServiceProtocol === 'esriRest')) ||
199
+ link.accessServiceProtocol === 'esriRest' ||
200
+ link.accessServiceProtocol === 'ogcFeatures')) ||
200
201
  link.type === 'download'
201
202
  ) {
202
203
  return this.dataService.readAsGeoJson(link).pipe(