geonetwork-ui 2.4.0-dev.e7ff1d25 → 2.4.0-dev.e97caaf2

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 (165) hide show
  1. package/esm2022/libs/api/metadata-converter/src/lib/gn4/types/keywords.model.mjs +1 -1
  2. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.mjs +4 -2
  3. package/esm2022/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.mjs +11 -1
  4. package/esm2022/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.mjs +11 -1
  5. package/esm2022/libs/common/domain/src/lib/model/record/metadata.model.mjs +1 -1
  6. package/esm2022/libs/common/domain/src/lib/model/user/user.model.mjs +1 -1
  7. package/esm2022/libs/common/domain/src/lib/platform.service.interface.mjs +1 -1
  8. package/esm2022/libs/feature/editor/src/lib/+state/editor.actions.mjs +2 -1
  9. package/esm2022/libs/feature/editor/src/lib/+state/editor.effects.mjs +6 -1
  10. package/esm2022/libs/feature/editor/src/lib/+state/editor.facade.mjs +4 -1
  11. package/esm2022/libs/feature/editor/src/lib/components/contact-card/contact-card.component.mjs +3 -3
  12. package/esm2022/libs/feature/editor/src/lib/components/generic-keywords/generic-keywords.component.mjs +78 -0
  13. package/esm2022/libs/feature/editor/src/lib/components/overview-upload/overview-upload.component.mjs +44 -79
  14. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts-for-resource/form-field-contacts-for-resource.component.mjs +35 -41
  15. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-keywords/form-field-keywords.component.mjs +19 -41
  16. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.mjs +10 -8
  17. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-map-container/form-field-map-container.component.mjs +101 -0
  18. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-open-data/form-field-open-data.component.mjs +22 -25
  19. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.mjs +14 -7
  20. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-resource-updated/form-field-resource-updated.component.mjs +10 -6
  21. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.mjs +11 -11
  22. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-simple/form-field-simple.component.mjs +9 -8
  23. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-spatial-extent/form-field-spatial-extent.component.mjs +111 -5
  24. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-temporal-extents/form-field-temporal-extents.component.mjs +49 -53
  25. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.mjs +16 -14
  26. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.mjs +34 -64
  27. package/esm2022/libs/feature/editor/src/lib/components/record-form/record-form.component.mjs +5 -3
  28. package/esm2022/libs/feature/editor/src/lib/fields.config.mjs +8 -2
  29. package/esm2022/libs/feature/editor/src/lib/services/editor.service.mjs +5 -1
  30. package/esm2022/libs/ui/elements/src/lib/sortable-list/sortable-list.component.mjs +3 -11
  31. package/esm2022/libs/ui/inputs/src/index.mjs +2 -1
  32. package/esm2022/libs/ui/inputs/src/lib/editable-label/editable-label.directive.mjs +26 -24
  33. package/esm2022/libs/ui/inputs/src/lib/switch-toggle/switch-toggle.component.mjs +32 -0
  34. package/esm2022/libs/ui/map/src/lib/ui-map.module.mjs +3 -3
  35. package/esm2022/translations/de.json +12 -0
  36. package/esm2022/translations/en.json +12 -0
  37. package/esm2022/translations/es.json +12 -0
  38. package/esm2022/translations/fr.json +14 -2
  39. package/esm2022/translations/it.json +12 -0
  40. package/esm2022/translations/nl.json +12 -0
  41. package/esm2022/translations/pt.json +12 -0
  42. package/fesm2022/geonetwork-ui.mjs +846 -521
  43. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  44. package/libs/api/metadata-converter/src/lib/gn4/types/keywords.model.d.ts +2 -6
  45. package/libs/api/metadata-converter/src/lib/gn4/types/keywords.model.d.ts.map +1 -1
  46. package/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.d.ts.map +1 -1
  47. package/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.d.ts.map +1 -1
  48. package/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.d.ts +1 -0
  49. package/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.d.ts.map +1 -1
  50. package/libs/common/domain/src/lib/model/record/metadata.model.d.ts +1 -0
  51. package/libs/common/domain/src/lib/model/record/metadata.model.d.ts.map +1 -1
  52. package/libs/common/domain/src/lib/model/user/user.model.d.ts +1 -1
  53. package/libs/common/domain/src/lib/model/user/user.model.d.ts.map +1 -1
  54. package/libs/common/domain/src/lib/platform.service.interface.d.ts +1 -0
  55. package/libs/common/domain/src/lib/platform.service.interface.d.ts.map +1 -1
  56. package/libs/feature/editor/src/lib/+state/editor.actions.d.ts +1 -0
  57. package/libs/feature/editor/src/lib/+state/editor.actions.d.ts.map +1 -1
  58. package/libs/feature/editor/src/lib/+state/editor.effects.d.ts +5 -0
  59. package/libs/feature/editor/src/lib/+state/editor.effects.d.ts.map +1 -1
  60. package/libs/feature/editor/src/lib/+state/editor.facade.d.ts +1 -0
  61. package/libs/feature/editor/src/lib/+state/editor.facade.d.ts.map +1 -1
  62. package/libs/feature/editor/src/lib/components/generic-keywords/generic-keywords.component.d.ts +32 -0
  63. package/libs/feature/editor/src/lib/components/generic-keywords/generic-keywords.component.d.ts.map +1 -0
  64. package/libs/feature/editor/src/lib/components/overview-upload/overview-upload.component.d.ts +13 -13
  65. package/libs/feature/editor/src/lib/components/overview-upload/overview-upload.component.d.ts.map +1 -1
  66. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts-for-resource/form-field-contacts-for-resource.component.d.ts +10 -13
  67. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts-for-resource/form-field-contacts-for-resource.component.d.ts.map +1 -1
  68. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-keywords/form-field-keywords.component.d.ts +8 -19
  69. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-keywords/form-field-keywords.component.d.ts.map +1 -1
  70. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.d.ts +6 -4
  71. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.d.ts.map +1 -1
  72. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-map-container/form-field-map-container.component.d.ts +22 -0
  73. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-map-container/form-field-map-container.component.d.ts.map +1 -0
  74. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-open-data/form-field-open-data.component.d.ts +10 -12
  75. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-open-data/form-field-open-data.component.d.ts.map +1 -1
  76. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.d.ts +5 -3
  77. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.d.ts.map +1 -1
  78. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-resource-updated/form-field-resource-updated.component.d.ts +4 -3
  79. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-resource-updated/form-field-resource-updated.component.d.ts.map +1 -1
  80. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.d.ts +4 -4
  81. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.d.ts.map +1 -1
  82. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-simple/form-field-simple.component.d.ts +4 -3
  83. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-simple/form-field-simple.component.d.ts.map +1 -1
  84. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-spatial-extent/form-field-spatial-extent.component.d.ts +23 -0
  85. 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
  86. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-temporal-extents/form-field-temporal-extents.component.d.ts +15 -17
  87. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-temporal-extents/form-field-temporal-extents.component.d.ts.map +1 -1
  88. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.d.ts +5 -5
  89. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.d.ts.map +1 -1
  90. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts +15 -27
  91. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts.map +1 -1
  92. package/libs/feature/editor/src/lib/components/record-form/record-form.component.d.ts +3 -2
  93. package/libs/feature/editor/src/lib/components/record-form/record-form.component.d.ts.map +1 -1
  94. package/libs/feature/editor/src/lib/fields.config.d.ts +1 -0
  95. package/libs/feature/editor/src/lib/fields.config.d.ts.map +1 -1
  96. package/libs/feature/editor/src/lib/services/editor.service.d.ts +1 -0
  97. package/libs/feature/editor/src/lib/services/editor.service.d.ts.map +1 -1
  98. package/libs/ui/elements/src/lib/sortable-list/sortable-list.component.d.ts +1 -6
  99. package/libs/ui/elements/src/lib/sortable-list/sortable-list.component.d.ts.map +1 -1
  100. package/libs/ui/inputs/src/index.d.ts +1 -0
  101. package/libs/ui/inputs/src/index.d.ts.map +1 -1
  102. package/libs/ui/inputs/src/lib/editable-label/editable-label.directive.d.ts +5 -3
  103. package/libs/ui/inputs/src/lib/editable-label/editable-label.directive.d.ts.map +1 -1
  104. package/libs/ui/inputs/src/lib/switch-toggle/switch-toggle.component.d.ts +17 -0
  105. package/libs/ui/inputs/src/lib/switch-toggle/switch-toggle.component.d.ts.map +1 -0
  106. package/package.json +1 -1
  107. package/src/libs/api/metadata-converter/src/lib/fixtures/generic.records.ts +6 -1
  108. package/src/libs/api/metadata-converter/src/lib/gn4/types/keywords.model.ts +2 -6
  109. package/src/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.ts +3 -1
  110. package/src/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.ts +12 -1
  111. package/src/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.ts +43 -12
  112. package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +1 -0
  113. package/src/libs/common/domain/src/lib/model/user/user.model.ts +1 -1
  114. package/src/libs/common/domain/src/lib/platform.service.interface.ts +4 -0
  115. package/src/libs/common/fixtures/src/lib/organisations.fixture.ts +10 -0
  116. package/src/libs/feature/editor/src/lib/+state/editor.actions.ts +2 -0
  117. package/src/libs/feature/editor/src/lib/+state/editor.effects.ts +15 -0
  118. package/src/libs/feature/editor/src/lib/+state/editor.facade.ts +4 -0
  119. package/src/libs/feature/editor/src/lib/components/contact-card/contact-card.component.html +4 -2
  120. package/src/libs/feature/editor/src/lib/components/generic-keywords/generic-keywords.component.css +0 -0
  121. package/src/libs/feature/editor/src/lib/components/generic-keywords/generic-keywords.component.html +26 -0
  122. package/src/libs/feature/editor/src/lib/components/generic-keywords/generic-keywords.component.ts +89 -0
  123. package/src/libs/feature/editor/src/lib/components/overview-upload/overview-upload.component.html +1 -1
  124. package/src/libs/feature/editor/src/lib/components/overview-upload/overview-upload.component.ts +46 -94
  125. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts-for-resource/form-field-contacts-for-resource.component.ts +63 -85
  126. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-keywords/form-field-keywords.component.html +7 -17
  127. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-keywords/form-field-keywords.component.ts +18 -51
  128. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.ts +13 -5
  129. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-map-container/form-field-map-container.component.css +0 -0
  130. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-map-container/form-field-map-container.component.html +4 -0
  131. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-map-container/form-field-map-container.component.ts +128 -0
  132. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-open-data/form-field-open-data.component.html +1 -1
  133. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-open-data/form-field-open-data.component.ts +18 -29
  134. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.html +1 -1
  135. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.ts +16 -5
  136. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-resource-updated/form-field-resource-updated.component.html +2 -2
  137. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-resource-updated/form-field-resource-updated.component.ts +9 -3
  138. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.html +2 -2
  139. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.ts +13 -7
  140. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-simple/form-field-simple.component.html +5 -3
  141. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-simple/form-field-simple.component.ts +11 -4
  142. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-spatial-extent/form-field-spatial-extent.component.html +15 -1
  143. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-spatial-extent/form-field-spatial-extent.component.ts +156 -1
  144. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-temporal-extents/form-field-temporal-extents.component.html +9 -2
  145. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-temporal-extents/form-field-temporal-extents.component.ts +59 -71
  146. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.ts +17 -15
  147. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html +99 -81
  148. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts +37 -66
  149. package/src/libs/feature/editor/src/lib/components/record-form/record-form.component.html +1 -0
  150. package/src/libs/feature/editor/src/lib/components/record-form/record-form.component.ts +7 -2
  151. package/src/libs/feature/editor/src/lib/fields.config.ts +8 -1
  152. package/src/libs/feature/editor/src/lib/services/editor.service.ts +7 -0
  153. package/src/libs/ui/elements/src/lib/sortable-list/sortable-list.component.html +0 -9
  154. package/src/libs/ui/elements/src/lib/sortable-list/sortable-list.component.ts +0 -4
  155. package/src/libs/ui/inputs/src/index.ts +1 -0
  156. package/src/libs/ui/inputs/src/lib/editable-label/editable-label.directive.ts +40 -26
  157. package/src/libs/ui/map/src/lib/ui-map.module.ts +1 -1
  158. package/translations/de.json +12 -0
  159. package/translations/en.json +12 -0
  160. package/translations/es.json +12 -0
  161. package/translations/fr.json +14 -2
  162. package/translations/it.json +12 -0
  163. package/translations/nl.json +12 -0
  164. package/translations/pt.json +12 -0
  165. package/translations/sk.json +12 -0
@@ -1,4 +1,29 @@
1
+ import { CommonModule } from '@angular/common'
1
2
  import { ChangeDetectionStrategy, Component } from '@angular/core'
3
+ import {
4
+ DatasetSpatialExtent,
5
+ Keyword,
6
+ } from '../../../../../../../../../libs/common/domain/src/lib/model/record'
7
+ import { GenericKeywordsComponent } from '../../../generic-keywords/generic-keywords.component'
8
+ import { PlatformServiceInterface } from '../../../../../../../../../libs/common/domain/src/lib/platform.service.interface'
9
+ import { firstValueFrom, map, shareReplay } from 'rxjs'
10
+ import { EditorFacade } from '../../../../+state/editor.facade'
11
+ import { switchMap } from 'rxjs/operators'
12
+ import { FormFieldMapContainerComponent } from '../form-field-map-container/form-field-map-container.component'
13
+ import { TranslateService } from '@ngx-translate/core'
14
+
15
+ // This intermediary type will let us keep track of which keyword is bound to
16
+ // which extent; these properties will not be persisted
17
+ type KeywordWithExtent = Keyword & {
18
+ _linkedExtent: DatasetSpatialExtent
19
+ _doNotSave: boolean
20
+ }
21
+
22
+ /**
23
+ * This form field is not like the others, as it will read directly from the state to handle both spatial extents
24
+ * and place keywords.
25
+ * Other types of keywords will not be touched by this field.
26
+ */
2
27
 
3
28
  @Component({
4
29
  selector: 'gn-ui-form-field-spatial-extent',
@@ -6,5 +31,135 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'
6
31
  styleUrls: ['./form-field-spatial-extent.component.css'],
7
32
  changeDetection: ChangeDetectionStrategy.OnPush,
8
33
  standalone: true,
34
+ imports: [
35
+ CommonModule,
36
+ GenericKeywordsComponent,
37
+ FormFieldMapContainerComponent,
38
+ ],
9
39
  })
10
- export class FormFieldSpatialExtentComponent {}
40
+ export class FormFieldSpatialExtentComponent {
41
+ spatialExtents$ = this.editorFacade.record$.pipe(
42
+ map((record) => ('spatialExtents' in record ? record?.spatialExtents : []))
43
+ )
44
+
45
+ shownKeywords$ = this.editorFacade.record$.pipe(
46
+ map((record) => record?.keywords.filter((k) => k.type === 'place')),
47
+ // look for full keywords in the thesauri
48
+ switchMap((keywords) =>
49
+ Promise.all(
50
+ keywords.map(async (keyword) => {
51
+ if (!keyword.thesaurus) return keyword
52
+ const allKeywords = await firstValueFrom(
53
+ this.platformService.searchKeywordsInThesaurus(
54
+ keyword.label,
55
+ keyword.thesaurus.id
56
+ )
57
+ )
58
+ const found = allKeywords.find((k) => k.label === keyword.label)
59
+ return found ?? keyword
60
+ })
61
+ )
62
+ ),
63
+ // add additional "unnamed" keywords for extents without a matching keyword
64
+ switchMap(async (keywords) => {
65
+ const spatialExtents = await firstValueFrom(this.spatialExtents$)
66
+ const keywordsFromExtents = await Promise.all(
67
+ spatialExtents.map(async (extent) => {
68
+ const existingKeyword =
69
+ extent.description &&
70
+ (keywords.find(
71
+ (k) => k.key === extent.description
72
+ ) as KeywordWithExtent)
73
+ if (existingKeyword) {
74
+ existingKeyword._linkedExtent = extent
75
+ return null
76
+ }
77
+ let bbox = null
78
+ if ('geometry' in extent) {
79
+ bbox = extent.geometry // FIXME: this should be a bbox too but for now it works...
80
+ } else if ('bbox' in extent) {
81
+ bbox = extent.bbox
82
+ }
83
+ const label = await firstValueFrom(
84
+ this.translateService.get('editor.record.placeKeywordWithoutLabel')
85
+ )
86
+ return {
87
+ label,
88
+ type: 'place',
89
+ ...(bbox && { bbox }),
90
+ _linkedExtent: extent,
91
+ _doNotSave: true,
92
+ } as KeywordWithExtent
93
+ })
94
+ ).then((keywords) => keywords.filter((k) => !!k))
95
+
96
+ return [...keywords, ...keywordsFromExtents]
97
+ }),
98
+ shareReplay(1)
99
+ )
100
+
101
+ constructor(
102
+ private platformService: PlatformServiceInterface,
103
+ private editorFacade: EditorFacade,
104
+ private translateService: TranslateService
105
+ ) {}
106
+
107
+ async handleKeywordDelete(keyword: Keyword) {
108
+ const spatialExtents = await firstValueFrom(this.spatialExtents$)
109
+ const shownKeywords = (await firstValueFrom(
110
+ this.shownKeywords$
111
+ )) as KeywordWithExtent[]
112
+ const newKeywords = shownKeywords.filter((k) => k !== keyword)
113
+ const linkedExtent =
114
+ '_linkedExtent' in keyword ? keyword._linkedExtent : null
115
+ const newExtents = linkedExtent
116
+ ? spatialExtents.filter((extent) => linkedExtent !== extent)
117
+ : spatialExtents
118
+ return this.emitChanges(newKeywords, newExtents)
119
+ }
120
+
121
+ async handleKeywordAdd(keyword: Keyword) {
122
+ const spatialExtents = await firstValueFrom(this.spatialExtents$)
123
+ const shownKeywords = await firstValueFrom(this.shownKeywords$)
124
+ const newKeywords = [...shownKeywords, keyword] as KeywordWithExtent[]
125
+ let newExtents = spatialExtents
126
+ if (keyword.bbox) {
127
+ newExtents = [
128
+ ...spatialExtents,
129
+ {
130
+ bbox: keyword.bbox,
131
+ description: keyword.key ?? undefined,
132
+ },
133
+ ]
134
+ }
135
+ return this.emitChanges(newKeywords, newExtents)
136
+ }
137
+
138
+ async emitChanges(
139
+ placeKeywords: KeywordWithExtent[],
140
+ spatialExtents: DatasetSpatialExtent[]
141
+ ) {
142
+ // some keywords are only present to allow control over extents; they **should not** be saved!
143
+ const filteredPlaceKeywords = placeKeywords
144
+ .filter((keyword) => !keyword._doNotSave)
145
+ .map(
146
+ ({ label, thesaurus, type }) =>
147
+ ({
148
+ label,
149
+ type,
150
+ ...(thesaurus && { thesaurus }),
151
+ } as Keyword)
152
+ )
153
+ const notPlaceKeywords = await firstValueFrom(
154
+ this.editorFacade.record$.pipe(
155
+ map((record) => record.keywords.filter((k) => k.type !== 'place'))
156
+ )
157
+ )
158
+
159
+ this.editorFacade.updateRecordField('keywords', [
160
+ ...notPlaceKeywords,
161
+ ...filteredPlaceKeywords,
162
+ ])
163
+ this.editorFacade.updateRecordField('spatialExtents', spatialExtents)
164
+ }
165
+ }
@@ -1,6 +1,13 @@
1
+ <div class="flex gap-2 mb-2">
2
+ <gn-ui-button
3
+ *ngFor="let addOption of addOptions$ | async"
4
+ (buttonClick)="onAdd(addOption.eventName)"
5
+ >
6
+ <span class="material-symbols-outlined gn-ui-icon-small"> add </span>
7
+ &nbsp;{{ addOption.buttonLabel }}</gn-ui-button
8
+ >
9
+ </div>
1
10
  <gn-ui-sortable-list
2
11
  [elements]="elements"
3
12
  (elementsChange)="onElementsChange($event)"
4
- [addOptions]="addOptions$ | async"
5
- (add)="onAdd($event)"
6
13
  ></gn-ui-sortable-list>
@@ -1,18 +1,22 @@
1
+ import { CommonModule } from '@angular/common'
1
2
  import {
2
3
  ChangeDetectionStrategy,
3
4
  Component,
4
5
  Input,
5
- OnDestroy,
6
- OnInit,
7
- Type,
6
+ OnChanges,
7
+ Output,
8
8
  } from '@angular/core'
9
9
  import { FormArray, FormControl } from '@angular/forms'
10
- import { SortableListComponent } from '../../../../../../../../../libs/ui/elements/src'
11
- import { Subscription, combineLatest, map } from 'rxjs'
10
+ import { DatasetTemporalExtent } from '../../../../../../../../../libs/common/domain/src/lib/model/record'
11
+ import {
12
+ DynamicElement,
13
+ SortableListComponent,
14
+ } from '../../../../../../../../../libs/ui/elements/src'
15
+ import { ButtonComponent } from '../../../../../../../../../libs/ui/inputs/src'
16
+ import { TranslateService } from '@ngx-translate/core'
17
+ import { Observable, combineLatest, map } from 'rxjs'
12
18
  import { FormFieldTemporalExtentsDateComponent } from './form-field-temporal-extents-date/form-field-temporal-extents-date.component'
13
19
  import { FormFieldTemporalExtentsRangeComponent } from './form-field-temporal-extents-range/form-field-temporal-extents-range.component'
14
- import { TranslateService } from '@ngx-translate/core'
15
- import { CommonModule } from '@angular/common'
16
20
 
17
21
  @Component({
18
22
  selector: 'gn-ui-form-field-temporal-extents',
@@ -20,18 +24,14 @@ import { CommonModule } from '@angular/common'
20
24
  styleUrls: ['./form-field-temporal-extents.component.css'],
21
25
  changeDetection: ChangeDetectionStrategy.OnPush,
22
26
  standalone: true,
23
- imports: [CommonModule, SortableListComponent],
27
+ imports: [CommonModule, ButtonComponent, SortableListComponent],
24
28
  })
25
- export class FormFieldTemporalExtentsComponent implements OnInit, OnDestroy {
26
- @Input() control!: FormControl
27
-
28
- subscription: Subscription
29
+ export class FormFieldTemporalExtentsComponent implements OnChanges {
30
+ @Input() value: Array<DatasetTemporalExtent>
31
+ @Output() valueChange: Observable<Array<DatasetTemporalExtent>>
29
32
 
30
33
  array: FormArray = new FormArray([])
31
- elements: Array<{
32
- component: Type<any>
33
- inputs: Record<string, any>
34
- }>
34
+ elements: DynamicElement[] = []
35
35
 
36
36
  addOptions$ = combineLatest([
37
37
  this.translateService
@@ -42,29 +42,19 @@ export class FormFieldTemporalExtentsComponent implements OnInit, OnDestroy {
42
42
  .pipe(map((buttonLabel) => ({ buttonLabel, eventName: 'range' }))),
43
43
  ])
44
44
 
45
- constructor(private translateService: TranslateService) {}
46
-
47
- ngOnInit() {
48
- this.resetValueFromInput(this.control.value)
49
-
50
- this.subscription = new Subscription()
51
-
52
- this.subscription.add(
53
- this.control.valueChanges.subscribe((value) => {
54
- this.resetValueFromInput(value)
55
- })
56
- )
45
+ constructor(private translateService: TranslateService) {
46
+ this.valueChange = this.array.valueChanges
47
+ }
57
48
 
58
- this.subscription.add(
59
- this.array.valueChanges.subscribe((value) => {
60
- this.control.setValue(value)
61
- })
62
- )
49
+ ngOnChanges() {
50
+ this.resetValueFromInput(this.value)
63
51
  }
64
52
 
65
- onElementsChange(elements: { inputs: Record<string, unknown> }[]) {
53
+ onElementsChange(elements: DynamicElement[]) {
54
+ this.elements = elements
66
55
  this.array.clear({ emitEvent: false })
67
- elements.forEach((e, i) =>
56
+
57
+ this.elements.forEach((e: DynamicElement, i: number) =>
68
58
  this.array.push(e.inputs.control, {
69
59
  emitEvent: i === elements.length - 1,
70
60
  })
@@ -74,58 +64,56 @@ export class FormFieldTemporalExtentsComponent implements OnInit, OnDestroy {
74
64
  onAdd(eventName: string) {
75
65
  switch (eventName) {
76
66
  case 'date': {
77
- const dateControl = new FormControl({ start: new Date() })
78
- this.array.push(dateControl)
67
+ const instant = { start: new Date() }
68
+ this.pushDate(instant, this.elements, true)
79
69
  break
80
70
  }
81
71
  case 'range': {
82
- const rangeControl = new FormControl({
72
+ const range = {
83
73
  start: new Date(),
84
74
  end: new Date(),
85
- })
86
- this.array.push(rangeControl)
75
+ }
76
+ this.pushRange(range, this.elements, true)
87
77
  break
88
78
  }
89
79
  }
90
80
  }
91
81
 
92
- ngOnDestroy(): void {
93
- this.subscription.unsubscribe()
94
- }
95
-
96
82
  private resetValueFromInput(value) {
97
83
  this.array.clear({ emitEvent: false })
98
- let newElements = []
99
- value.forEach((v: any) => {
84
+ this.elements = []
85
+ if (!value) return
86
+
87
+ const newElements = []
88
+ value.forEach((v: DatasetTemporalExtent) => {
100
89
  if ('start' in v && 'end' in v) {
101
- const rangeControl = new FormControl({
102
- start: v.start,
103
- end: v.end,
104
- })
105
- this.array.push(rangeControl, { emitEvent: false })
106
- newElements = [
107
- ...newElements,
108
- {
109
- component: FormFieldTemporalExtentsRangeComponent,
110
- inputs: {
111
- control: rangeControl,
112
- },
113
- },
114
- ]
90
+ this.pushRange(v, newElements, false)
115
91
  } else {
116
- const dateControl = new FormControl({ start: v.start })
117
- this.array.push(dateControl, { emitEvent: false })
118
- newElements = [
119
- ...newElements,
120
- {
121
- component: FormFieldTemporalExtentsDateComponent,
122
- inputs: {
123
- control: dateControl,
124
- },
125
- },
126
- ]
92
+ this.pushDate(v, newElements, false)
127
93
  }
128
94
  })
129
95
  this.elements = newElements
130
96
  }
97
+
98
+ private pushDate(instant, elements, emitEvent) {
99
+ const dateControl = new FormControl(instant)
100
+ this.array.push(dateControl, { emitEvent })
101
+ elements.push({
102
+ component: FormFieldTemporalExtentsDateComponent,
103
+ inputs: {
104
+ control: dateControl,
105
+ },
106
+ })
107
+ }
108
+
109
+ private pushRange(period, elements, emitEvent) {
110
+ const rangeControl = new FormControl(period)
111
+ this.array.push(rangeControl, { emitEvent })
112
+ elements.push({
113
+ component: FormFieldTemporalExtentsRangeComponent,
114
+ inputs: {
115
+ control: rangeControl,
116
+ },
117
+ })
118
+ }
131
119
  }
@@ -1,20 +1,21 @@
1
1
  import {
2
2
  ChangeDetectionStrategy,
3
3
  Component,
4
+ EventEmitter,
4
5
  Input,
5
6
  OnInit,
7
+ Output,
6
8
  } from '@angular/core'
7
- import { FormControl } from '@angular/forms'
9
+ import {
10
+ UpdateFrequency,
11
+ UpdateFrequencyCustom,
12
+ } from '../../../../../../../../../libs/common/domain/src/lib/model/record'
8
13
  import {
9
14
  CheckToggleComponent,
10
15
  DropdownChoice,
11
16
  DropdownSelectorComponent,
12
17
  } from '../../../../../../../../../libs/ui/inputs/src'
13
18
  import { TranslateModule, TranslateService } from '@ngx-translate/core'
14
- import {
15
- UpdateFrequency,
16
- UpdateFrequencyCustom,
17
- } from '../../../../../../../../../libs/common/domain/src/lib/model/record'
18
19
  import { firstValueFrom } from 'rxjs'
19
20
 
20
21
  @Component({
@@ -26,23 +27,24 @@ import { firstValueFrom } from 'rxjs'
26
27
  imports: [CheckToggleComponent, DropdownSelectorComponent, TranslateModule],
27
28
  })
28
29
  export class FormFieldUpdateFrequencyComponent implements OnInit {
29
- @Input() control: FormControl<UpdateFrequency>
30
+ @Input() value: UpdateFrequency
31
+ @Output() valueChange: EventEmitter<UpdateFrequency> = new EventEmitter()
30
32
 
31
33
  protected choices: DropdownChoice[] = []
32
34
 
33
35
  get planned() {
34
- return typeof this.control.value !== 'string'
36
+ return typeof this.value !== 'string'
35
37
  }
36
38
 
37
39
  constructor(private translateService: TranslateService) {}
38
40
 
39
41
  async ngOnInit() {
40
42
  this.choices = await this.getInitialChoices()
41
- if (typeof this.control.value === 'string') {
43
+ if (typeof this.value === 'string') {
42
44
  return
43
45
  }
44
- const updatedTimes = this.control.value.updatedTimes
45
- const per = this.control.value.per
46
+ const updatedTimes = this.value.updatedTimes
47
+ const per = this.value.per
46
48
  // the update frequency is not in the list; make it appear there
47
49
  if (updatedTimes && updatedTimes !== 1 && updatedTimes !== 2) {
48
50
  this.choices = [
@@ -61,21 +63,21 @@ export class FormFieldUpdateFrequencyComponent implements OnInit {
61
63
 
62
64
  onPlannedToggled() {
63
65
  if (this.planned) {
64
- this.control.setValue('notPlanned')
66
+ this.valueChange.emit('notPlanned')
65
67
  } else {
66
- this.control.setValue({ updatedTimes: 1, per: 'day' })
68
+ this.valueChange.emit({ updatedTimes: 1, per: 'day' })
67
69
  }
68
70
  }
69
71
 
70
72
  get selectedFrequency(): string {
71
- if (typeof this.control.value === 'string') return null
72
- const { updatedTimes, per } = this.control.value
73
+ if (typeof this.value === 'string') return null
74
+ const { updatedTimes, per } = this.value
73
75
  return `${per}.${updatedTimes}`
74
76
  }
75
77
 
76
78
  onSelectFrequencyValue(value: unknown) {
77
79
  const split = (value as string).split('.')
78
- this.control.setValue({
80
+ this.valueChange.emit({
79
81
  updatedTimes: Number(split[1]),
80
82
  per: split[0] as UpdateFrequencyCustom['per'],
81
83
  })
@@ -1,7 +1,8 @@
1
- <ng-container *ngIf="isOpenData">
1
+ <ng-container *ngIf="model === 'licenses'">
2
2
  <gn-ui-form-field-open-data
3
- [control]="formControl"
4
- (visibilityChange)="onVisibilityChange($event)"
3
+ [value]="valueAsConstraints"
4
+ (valueChange)="valueChange.emit($event)"
5
+ (openDataChange)="isHidden = $event"
5
6
  ></gn-ui-form-field-open-data>
6
7
  </ng-container>
7
8
  <div class="flex flex-col h-full" *ngIf="!isHidden">
@@ -19,83 +20,100 @@
19
20
  </div>
20
21
 
21
22
  <ng-template #fieldContent>
22
- <ng-container *ngIf="isTitle">
23
- <div class="flex justify-between items-center gap-3">
24
- <span
25
- #titleInput
26
- class="grow font-title text-3xl font-normal"
27
- [gnUiEditableLabel]="true"
28
- (editableLabelChanged)="formControl.setValue($event)"
29
- >
30
- {{ formControl.value }}
31
- </span>
32
- <span
33
- class="material-symbols-outlined gn-ui-icon-small m-2 cursor-pointer"
34
- (click)="focusTitleInput()"
35
- >edit</span
36
- >
37
- <span
38
- class="material-symbols-outlined gn-ui-icon-small m-2"
39
- [matTooltip]="config.hintKey! | translate"
40
- matTooltipPosition="above"
41
- >
42
- help
43
- </span>
44
- </div>
45
- </ng-container>
46
- <ng-container *ngIf="isAbstract">
47
- <gn-ui-form-field-rich
48
- class="h-[8rem]"
49
- [control]="formControl"
50
- [label]="config.labelKey! | translate"
51
- [hint]="config.hintKey! | translate"
52
- ></gn-ui-form-field-rich>
53
- </ng-container>
54
- <ng-container *ngIf="isLicenses">
55
- <gn-ui-form-field-license
56
- [control]="formControl"
57
- [label]="config.labelKey! | translate"
58
- ></gn-ui-form-field-license>
59
- </ng-container>
60
- <ng-container *ngIf="isResourceUpdated">
61
- <gn-ui-form-field-resource-updated
62
- [control]="formControl"
63
- ></gn-ui-form-field-resource-updated>
64
- </ng-container>
65
- <ng-container *ngIf="isUpdateFrequency">
66
- <gn-ui-form-field-update-frequency
67
- [control]="formControl"
68
- ></gn-ui-form-field-update-frequency>
69
- </ng-container>
70
- <ng-container *ngIf="isTemporalExtents">
71
- <gn-ui-form-field-temporal-extents
72
- [control]="formControl"
73
- ></gn-ui-form-field-temporal-extents>
74
- </ng-container>
75
- <ng-container *ngIf="isSimpleField">
76
- <gn-ui-form-field-simple
77
- type="text"
78
- [control]="formControl"
79
- [readonly]="isReadOnly"
80
- ></gn-ui-form-field-simple>
81
- </ng-container>
82
- <ng-container *ngIf="isSpatialExtentField">
83
- <gn-ui-form-field-spatial-extent></gn-ui-form-field-spatial-extent>
84
- </ng-container>
85
- <ng-container *ngIf="isGraphicOverview">
86
- <gn-ui-form-field-overviews
87
- [control]="formControl"
88
- [metadataUuid]="metadataUuid$ | async"
89
- ></gn-ui-form-field-overviews>
90
- </ng-container>
91
- <ng-container *ngIf="isKeywords">
92
- <gn-ui-form-field-keywords
93
- [control]="formControl"
94
- ></gn-ui-form-field-keywords>
95
- </ng-container>
96
- <ng-container *ngIf="isContactsForResource">
97
- <gn-ui-form-field-contacts-for-resource
98
- [control]="formControl"
99
- ></gn-ui-form-field-contacts-for-resource>
23
+ <ng-container [ngSwitch]="model">
24
+ <ng-container *ngSwitchCase="'title'">
25
+ <div class="flex justify-between items-center gap-3">
26
+ <span
27
+ #titleInput
28
+ class="grow font-title text-3xl font-normal"
29
+ [gnUiEditableLabel]="valueAsString"
30
+ (editableLabelChanged)="valueChange.emit($event)"
31
+ ></span>
32
+ <span
33
+ class="material-symbols-outlined gn-ui-icon-small m-2 cursor-pointer"
34
+ (click)="focusTitleInput()"
35
+ >edit</span
36
+ >
37
+ <span
38
+ class="material-symbols-outlined gn-ui-icon-small m-2"
39
+ [matTooltip]="config.hintKey! | translate"
40
+ matTooltipPosition="above"
41
+ >
42
+ help
43
+ </span>
44
+ </div>
45
+ </ng-container>
46
+ <ng-container *ngSwitchCase="'abstract'">
47
+ <gn-ui-form-field-rich
48
+ class="h-[8rem]"
49
+ [label]="config.labelKey! | translate"
50
+ [hint]="config.hintKey! | translate"
51
+ [value]="valueAsString"
52
+ (valueChange)="valueChange.emit($event)"
53
+ ></gn-ui-form-field-rich>
54
+ </ng-container>
55
+ <ng-container *ngSwitchCase="'overviews'">
56
+ <gn-ui-form-field-overviews
57
+ [metadataUuid]="uniqueIdentifier"
58
+ [value]="valueAsOverviews"
59
+ (valueChange)="valueChange.emit($event)"
60
+ ></gn-ui-form-field-overviews>
61
+ </ng-container>
62
+ <ng-container *ngSwitchCase="'uniqueIdentifier'">
63
+ <gn-ui-form-field-simple
64
+ type="text"
65
+ [readonly]="true"
66
+ [value]="valueAsString"
67
+ (valueChange)="valueChange.emit($event)"
68
+ ></gn-ui-form-field-simple>
69
+ </ng-container>
70
+ <ng-container *ngSwitchCase="'resourceUpdated'">
71
+ <gn-ui-form-field-resource-updated
72
+ [value]="valueAsDate"
73
+ (valueChange)="valueChange.emit($event)"
74
+ ></gn-ui-form-field-resource-updated>
75
+ </ng-container>
76
+ <ng-container *ngSwitchCase="'recordUpdated'">
77
+ <gn-ui-form-field-simple
78
+ type="date"
79
+ [readonly]="true"
80
+ [value]="valueAsDate"
81
+ (valueChange)="valueChange.emit($event)"
82
+ ></gn-ui-form-field-simple>
83
+ </ng-container>
84
+ <ng-container *ngSwitchCase="'updateFrequency'">
85
+ <gn-ui-form-field-update-frequency
86
+ [value]="valueAsUpdateFrequency"
87
+ (valueChange)="valueChange.emit($event)"
88
+ ></gn-ui-form-field-update-frequency>
89
+ </ng-container>
90
+ <ng-container *ngSwitchCase="'temporalExtents'">
91
+ <gn-ui-form-field-temporal-extents
92
+ [value]="valueAsTemporalExtents"
93
+ (valueChange)="valueChange.emit($event)"
94
+ ></gn-ui-form-field-temporal-extents>
95
+ </ng-container>
96
+ <ng-container *ngSwitchCase="'spatialExtents'">
97
+ <gn-ui-form-field-spatial-extent></gn-ui-form-field-spatial-extent>
98
+ </ng-container>
99
+ <ng-container *ngSwitchCase="'keywords'">
100
+ <gn-ui-form-field-keywords
101
+ [value]="valueAsKeywords"
102
+ (valueChange)="valueChange.emit($event)"
103
+ ></gn-ui-form-field-keywords>
104
+ </ng-container>
105
+ <ng-container *ngSwitchCase="'licenses'">
106
+ <gn-ui-form-field-license
107
+ [label]="config.labelKey! | translate"
108
+ [value]="valueAsConstraints"
109
+ (valueChange)="valueChange.emit($event)"
110
+ ></gn-ui-form-field-license>
111
+ </ng-container>
112
+ <ng-container *ngSwitchCase="'contactsForResource'">
113
+ <gn-ui-form-field-contacts-for-resource
114
+ [value]="valueAsIndividuals"
115
+ (valueChange)="valueChange.emit($event)"
116
+ ></gn-ui-form-field-contacts-for-resource>
117
+ </ng-container>
100
118
  </ng-container>
101
119
  </ng-template>