geonetwork-ui 2.4.0-dev.db93b4c4 → 2.4.0-dev.dd042cec

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 (186) hide show
  1. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.mjs +5 -5
  2. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/read-parts.mjs +30 -2
  3. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/utils/geometry.mjs +31 -0
  4. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/write-parts.mjs +23 -1
  5. package/esm2022/libs/api/metadata-converter/src/lib/xml-utils.mjs +10 -3
  6. package/esm2022/libs/api/repository/src/lib/gn4/gn4-repository.mjs +31 -3
  7. package/esm2022/libs/common/domain/src/lib/model/record/contact.model.mjs +28 -1
  8. package/esm2022/libs/common/domain/src/lib/model/record/metadata.model.mjs +1 -1
  9. package/esm2022/libs/common/domain/src/lib/repository/records-repository.interface.mjs +1 -1
  10. package/esm2022/libs/data-access/gn4/src/openapi/api/records.api.service.mjs +2 -6
  11. package/esm2022/libs/feature/editor/src/lib/components/contact-card/contact-card.component.mjs +29 -0
  12. package/esm2022/libs/feature/editor/src/lib/components/overview-upload/overview-upload.component.mjs +131 -0
  13. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts-for-resource/form-field-contacts-for-resource.component.mjs +170 -0
  14. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-keywords/form-field-keywords.component.mjs +3 -3
  15. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-open-data/form-field-open-data.component.mjs +47 -0
  16. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.mjs +21 -0
  17. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-temporal-extents/form-field-temporal-extents.component.mjs +7 -6
  18. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.mjs +33 -9
  19. package/esm2022/libs/feature/editor/src/lib/components/record-form/record-form.component.mjs +3 -3
  20. package/esm2022/libs/feature/editor/src/lib/fields.config.mjs +30 -3
  21. package/esm2022/libs/feature/map/src/lib/utils/map-utils.service.mjs +10 -5
  22. package/esm2022/libs/feature/search/src/lib/fuzzy-search/fuzzy-search.component.mjs +3 -3
  23. package/esm2022/libs/feature/search/src/lib/results-table/results-table-container.component.mjs +46 -7
  24. package/esm2022/libs/feature/search/src/lib/state/search.facade.mjs +6 -2
  25. package/esm2022/libs/ui/elements/src/index.mjs +2 -1
  26. package/esm2022/libs/ui/elements/src/lib/confirmation-dialog/confirmation-dialog.component.mjs +27 -0
  27. package/esm2022/libs/ui/elements/src/lib/markdown-editor/markdown-editor.component.mjs +4 -3
  28. package/esm2022/libs/ui/elements/src/lib/markdown-parser/markdown-parser.component.mjs +2 -2
  29. package/esm2022/libs/ui/elements/src/lib/metadata-info/metadata-info.component.mjs +3 -3
  30. package/esm2022/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.mjs +5 -11
  31. package/esm2022/libs/ui/elements/src/lib/metadata-quality-item/metadata-quality-item.component.mjs +3 -3
  32. package/esm2022/libs/ui/elements/src/lib/sortable-list/sortable-list.component.mjs +7 -3
  33. package/esm2022/libs/ui/elements/src/lib/ui-elements.module.mjs +5 -2
  34. package/esm2022/libs/ui/elements/src/lib/user-preview/user-preview.component.mjs +3 -3
  35. package/esm2022/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.mjs +19 -5
  36. package/esm2022/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.mjs +3 -3
  37. package/esm2022/libs/ui/layout/src/lib/interactive-table/interactive-table.component.mjs +3 -3
  38. package/esm2022/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.mjs +67 -0
  39. package/esm2022/libs/ui/search/src/lib/results-table/results-table.component.mjs +28 -8
  40. package/esm2022/libs/ui/widgets/src/index.mjs +2 -1
  41. package/esm2022/libs/ui/widgets/src/lib/popover/popover.component.mjs +68 -0
  42. package/esm2022/translations/de.json +44 -17
  43. package/esm2022/translations/en.json +37 -10
  44. package/esm2022/translations/es.json +36 -9
  45. package/esm2022/translations/fr.json +47 -20
  46. package/esm2022/translations/it.json +37 -10
  47. package/esm2022/translations/nl.json +36 -9
  48. package/esm2022/translations/pt.json +36 -9
  49. package/fesm2022/geonetwork-ui.mjs +1266 -279
  50. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  51. package/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.d.ts.map +1 -1
  52. package/libs/api/metadata-converter/src/lib/iso19139/read-parts.d.ts +8 -1
  53. package/libs/api/metadata-converter/src/lib/iso19139/read-parts.d.ts.map +1 -1
  54. package/libs/api/metadata-converter/src/lib/iso19139/utils/geometry.d.ts +5 -0
  55. package/libs/api/metadata-converter/src/lib/iso19139/utils/geometry.d.ts.map +1 -0
  56. package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts +3 -1
  57. package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts.map +1 -1
  58. package/libs/api/metadata-converter/src/lib/xml-utils.d.ts +1 -0
  59. package/libs/api/metadata-converter/src/lib/xml-utils.d.ts.map +1 -1
  60. package/libs/api/repository/src/lib/gn4/gn4-repository.d.ts +7 -1
  61. package/libs/api/repository/src/lib/gn4/gn4-repository.d.ts.map +1 -1
  62. package/libs/common/domain/src/lib/model/record/contact.model.d.ts +1 -0
  63. package/libs/common/domain/src/lib/model/record/contact.model.d.ts.map +1 -1
  64. package/libs/common/domain/src/lib/model/record/metadata.model.d.ts +2 -1
  65. package/libs/common/domain/src/lib/model/record/metadata.model.d.ts.map +1 -1
  66. package/libs/common/domain/src/lib/repository/records-repository.interface.d.ts +17 -0
  67. package/libs/common/domain/src/lib/repository/records-repository.interface.d.ts.map +1 -1
  68. package/libs/data-access/gn4/src/openapi/api/records.api.service.d.ts.map +1 -1
  69. package/libs/feature/editor/src/lib/components/contact-card/contact-card.component.d.ts +12 -0
  70. package/libs/feature/editor/src/lib/components/contact-card/contact-card.component.d.ts.map +1 -0
  71. package/libs/feature/editor/src/lib/components/overview-upload/overview-upload.component.d.ts +27 -0
  72. package/libs/feature/editor/src/lib/components/overview-upload/overview-upload.component.d.ts.map +1 -0
  73. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts-for-resource/form-field-contacts-for-resource.component.d.ts +47 -0
  74. 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 -0
  75. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-open-data/form-field-open-data.component.d.ts +17 -0
  76. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-open-data/form-field-open-data.component.d.ts.map +1 -0
  77. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.d.ts +11 -0
  78. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.d.ts.map +1 -0
  79. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-temporal-extents/form-field-temporal-extents.component.d.ts +3 -1
  80. 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
  81. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts +9 -1
  82. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts.map +1 -1
  83. package/libs/feature/editor/src/lib/fields.config.d.ts +7 -0
  84. package/libs/feature/editor/src/lib/fields.config.d.ts.map +1 -1
  85. package/libs/feature/map/src/lib/utils/map-utils.service.d.ts.map +1 -1
  86. package/libs/feature/search/src/lib/results-table/results-table-container.component.d.ts +14 -4
  87. package/libs/feature/search/src/lib/results-table/results-table-container.component.d.ts.map +1 -1
  88. package/libs/feature/search/src/lib/state/search.facade.d.ts +1 -0
  89. package/libs/feature/search/src/lib/state/search.facade.d.ts.map +1 -1
  90. package/libs/ui/elements/src/index.d.ts +1 -0
  91. package/libs/ui/elements/src/index.d.ts.map +1 -1
  92. package/libs/ui/elements/src/lib/confirmation-dialog/confirmation-dialog.component.d.ts +18 -0
  93. package/libs/ui/elements/src/lib/confirmation-dialog/confirmation-dialog.component.d.ts.map +1 -0
  94. package/libs/ui/elements/src/lib/downloads-list/downloads-list.component.d.ts +1 -1
  95. package/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.d.ts +0 -3
  96. package/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.d.ts.map +1 -1
  97. package/libs/ui/elements/src/lib/record-api-form/record-api-form.component.d.ts +1 -1
  98. package/libs/ui/elements/src/lib/sortable-list/sortable-list.component.d.ts +4 -4
  99. package/libs/ui/elements/src/lib/sortable-list/sortable-list.component.d.ts.map +1 -1
  100. package/libs/ui/elements/src/lib/ui-elements.module.d.ts +7 -6
  101. package/libs/ui/elements/src/lib/ui-elements.module.d.ts.map +1 -1
  102. package/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.d.ts +9 -1
  103. package/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.d.ts.map +1 -1
  104. package/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.d.ts +20 -0
  105. package/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.d.ts.map +1 -0
  106. package/libs/ui/search/src/lib/results-table/results-table.component.d.ts +9 -3
  107. package/libs/ui/search/src/lib/results-table/results-table.component.d.ts.map +1 -1
  108. package/libs/ui/widgets/src/index.d.ts +1 -0
  109. package/libs/ui/widgets/src/index.d.ts.map +1 -1
  110. package/libs/ui/widgets/src/lib/popover/popover.component.d.ts +19 -0
  111. package/libs/ui/widgets/src/lib/popover/popover.component.d.ts.map +1 -0
  112. package/package.json +1 -1
  113. package/src/libs/api/metadata-converter/src/lib/fixtures/geo2france.records.ts +5 -1
  114. package/src/libs/api/metadata-converter/src/lib/fixtures/geocat-ch.records.ts +37 -12
  115. package/src/libs/api/metadata-converter/src/lib/fixtures/metawal.records.ts +5 -1
  116. package/src/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.ts +4 -2
  117. package/src/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts +72 -2
  118. package/src/libs/api/metadata-converter/src/lib/iso19139/utils/geometry.ts +39 -0
  119. package/src/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts +70 -1
  120. package/src/libs/api/metadata-converter/src/lib/xml-utils.ts +13 -5
  121. package/src/libs/api/repository/src/lib/gn4/gn4-repository.ts +42 -2
  122. package/src/libs/common/domain/src/lib/model/record/contact.model.ts +28 -0
  123. package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +2 -1
  124. package/src/libs/common/domain/src/lib/repository/records-repository.interface.ts +22 -0
  125. package/src/libs/data-access/gn4/src/openapi/api/records.api.service.ts +1 -5
  126. package/src/libs/data-access/gn4/src/spec.yaml +0 -8
  127. package/src/libs/feature/editor/src/lib/components/contact-card/contact-card.component.css +0 -0
  128. package/src/libs/feature/editor/src/lib/components/contact-card/contact-card.component.html +25 -0
  129. package/src/libs/feature/editor/src/lib/components/contact-card/contact-card.component.ts +30 -0
  130. package/src/libs/feature/editor/src/lib/components/overview-upload/overview-upload.component.html +2 -1
  131. package/src/libs/feature/editor/src/lib/components/overview-upload/overview-upload.component.ts +110 -19
  132. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts-for-resource/form-field-contacts-for-resource.component.css +0 -0
  133. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts-for-resource/form-field-contacts-for-resource.component.html +76 -0
  134. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts-for-resource/form-field-contacts-for-resource.component.ts +271 -0
  135. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-keywords/form-field-keywords.component.html +1 -1
  136. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-open-data/form-field-open-data.component.css +0 -0
  137. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-open-data/form-field-open-data.component.html +6 -0
  138. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-open-data/form-field-open-data.component.ts +59 -0
  139. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.css +0 -0
  140. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.html +5 -0
  141. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.ts +22 -0
  142. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-temporal-extents/form-field-temporal-extents.component.ts +8 -7
  143. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html +18 -1
  144. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts +30 -1
  145. package/src/libs/feature/editor/src/lib/components/record-form/record-form.component.html +1 -1
  146. package/src/libs/feature/editor/src/lib/fields.config.ts +32 -2
  147. package/src/libs/feature/map/src/lib/utils/map-utils.service.ts +8 -4
  148. package/src/libs/feature/search/src/lib/fuzzy-search/fuzzy-search.component.html +1 -1
  149. package/src/libs/feature/search/src/lib/results-table/results-table-container.component.html +3 -1
  150. package/src/libs/feature/search/src/lib/results-table/results-table-container.component.ts +57 -3
  151. package/src/libs/feature/search/src/lib/state/search.facade.ts +6 -0
  152. package/src/libs/ui/elements/src/index.ts +1 -0
  153. package/src/libs/ui/elements/src/lib/confirmation-dialog/confirmation-dialog.component.css +0 -0
  154. package/src/libs/ui/elements/src/lib/confirmation-dialog/confirmation-dialog.component.html +12 -0
  155. package/src/libs/ui/elements/src/lib/confirmation-dialog/confirmation-dialog.component.ts +37 -0
  156. package/src/libs/ui/elements/src/lib/markdown-editor/markdown-editor.component.html +4 -1
  157. package/src/libs/ui/elements/src/lib/markdown-parser/markdown-parser.component.css +2 -1
  158. package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.html +12 -8
  159. package/src/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.html +14 -20
  160. package/src/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.ts +0 -10
  161. package/src/libs/ui/elements/src/lib/metadata-quality-item/metadata-quality-item.component.html +1 -1
  162. package/src/libs/ui/elements/src/lib/sortable-list/sortable-list.component.html +3 -1
  163. package/src/libs/ui/elements/src/lib/sortable-list/sortable-list.component.ts +8 -4
  164. package/src/libs/ui/elements/src/lib/ui-elements.module.ts +2 -1
  165. package/src/libs/ui/elements/src/lib/user-preview/user-preview.component.html +1 -1
  166. package/src/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.ts +15 -3
  167. package/src/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.html +1 -1
  168. package/src/libs/ui/layout/src/lib/interactive-table/interactive-table.component.html +1 -0
  169. package/src/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.css +0 -0
  170. package/src/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.html +26 -0
  171. package/src/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.ts +74 -0
  172. package/src/libs/ui/search/src/lib/results-table/results-table.component.html +15 -1
  173. package/src/libs/ui/search/src/lib/results-table/results-table.component.ts +26 -12
  174. package/src/libs/ui/widgets/src/index.ts +1 -0
  175. package/src/libs/ui/widgets/src/lib/popover/popover.component.css +0 -0
  176. package/src/libs/ui/widgets/src/lib/popover/popover.component.html +3 -0
  177. package/src/libs/ui/widgets/src/lib/popover/popover.component.ts +85 -0
  178. package/tailwind.base.css +2 -1
  179. package/translations/de.json +44 -17
  180. package/translations/en.json +37 -10
  181. package/translations/es.json +36 -9
  182. package/translations/fr.json +47 -20
  183. package/translations/it.json +37 -10
  184. package/translations/nl.json +36 -9
  185. package/translations/pt.json +36 -9
  186. package/translations/sk.json +37 -10
@@ -1,4 +1,10 @@
1
- <div class="flex flex-col h-full">
1
+ <ng-container *ngIf="isOpenData">
2
+ <gn-ui-form-field-open-data
3
+ [control]="formControl"
4
+ (visibilityChange)="onVisibilityChange($event)"
5
+ ></gn-ui-form-field-open-data>
6
+ </ng-container>
7
+ <div class="flex flex-col h-full" *ngIf="!isHidden">
2
8
  <ng-container *ngIf="withoutWrapper; else withGenericWrapper">
3
9
  <ng-container *ngTemplateOutlet="fieldContent"></ng-container>
4
10
  </ng-container>
@@ -76,9 +82,20 @@
76
82
  <ng-container *ngIf="isSpatialExtentField">
77
83
  <gn-ui-form-field-spatial-extent></gn-ui-form-field-spatial-extent>
78
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>
79
91
  <ng-container *ngIf="isKeywords">
80
92
  <gn-ui-form-field-keywords
81
93
  [control]="formControl"
82
94
  ></gn-ui-form-field-keywords>
83
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>
100
+ </ng-container>
84
101
  </ng-template>
@@ -3,6 +3,7 @@ import {
3
3
  ChangeDetectionStrategy,
4
4
  Component,
5
5
  ElementRef,
6
+ EventEmitter,
6
7
  Input,
7
8
  Output,
8
9
  ViewChild,
@@ -28,7 +29,12 @@ import { FormFieldSpatialExtentComponent } from './form-field-spatial-extent/for
28
29
  import { FormFieldUpdateFrequencyComponent } from './form-field-update-frequency/form-field-update-frequency.component'
29
30
  import { CatalogRecordKeys } from '../../../../../../../../libs/common/domain/src/lib/model/record'
30
31
  import { FormFieldKeywordsComponent } from './form-field-keywords/form-field-keywords.component'
32
+ import { FormFieldOverviewsComponent } from './form-field-overviews/form-field-overviews.component'
33
+ import { map, take } from 'rxjs/operators'
34
+ import { EditorFacade } from '../../../+state/editor.facade'
31
35
  import { FormFieldConfig } from '../../../models'
36
+ import { FormFieldContactsForResourceComponent } from './form-field-contacts-for-resource/form-field-contacts-for-resource.component'
37
+ import { FormFieldOpenDataComponent } from './form-field-open-data/form-field-open-data.component'
32
38
 
33
39
  @Component({
34
40
  selector: 'gn-ui-form-field',
@@ -55,6 +61,9 @@ import { FormFieldConfig } from '../../../models'
55
61
  FormFieldArrayComponent,
56
62
  FormFieldKeywordsComponent,
57
63
  TranslateModule,
64
+ FormFieldOverviewsComponent,
65
+ FormFieldContactsForResourceComponent,
66
+ FormFieldOpenDataComponent,
58
67
  ],
59
68
  })
60
69
  export class FormFieldComponent {
@@ -67,12 +76,18 @@ export class FormFieldComponent {
67
76
  }
68
77
 
69
78
  @Output() valueChange: Observable<unknown>
79
+ isHidden = false
70
80
 
71
81
  @ViewChild('titleInput') titleInput: ElementRef
72
82
 
83
+ metadataUuid$ = this.facade.record$.pipe(
84
+ take(1),
85
+ map((record) => record.uniqueIdentifier)
86
+ )
87
+
73
88
  formControl = new FormControl()
74
89
 
75
- constructor() {
90
+ constructor(private facade: EditorFacade) {
76
91
  this.valueChange = this.formControl.valueChanges
77
92
  }
78
93
 
@@ -80,6 +95,10 @@ export class FormFieldComponent {
80
95
  this.titleInput.nativeElement.children[0].focus()
81
96
  }
82
97
 
98
+ onVisibilityChange(visibility: boolean) {
99
+ this.isHidden = visibility
100
+ }
101
+
83
102
  get isTitle() {
84
103
  return this.model === 'title'
85
104
  }
@@ -101,6 +120,9 @@ export class FormFieldComponent {
101
120
  get isSpatialExtentField() {
102
121
  return this.model === 'spatialExtents'
103
122
  }
123
+ get isGraphicOverview() {
124
+ return this.model === 'overviews'
125
+ }
104
126
  get isSimpleField() {
105
127
  return this.model === 'uniqueIdentifier' || this.model === 'recordUpdated'
106
128
  }
@@ -110,8 +132,15 @@ export class FormFieldComponent {
110
132
  get isKeywords() {
111
133
  return this.model === 'keywords'
112
134
  }
135
+ get isContactsForResource() {
136
+ return this.model === 'contactsForResource'
137
+ }
113
138
 
114
139
  get withoutWrapper() {
115
140
  return this.model === 'title' || this.model === 'abstract'
116
141
  }
142
+
143
+ get isOpenData() {
144
+ return this.model === 'licenses'
145
+ }
117
146
  }
@@ -14,7 +14,7 @@
14
14
  >
15
15
  <div
16
16
  *ngIf="section.labelKey"
17
- class="text-2xl font-petrona text-secondary"
17
+ class="text-2xl font-title text-secondary"
18
18
  translate
19
19
  >
20
20
  {{ section.labelKey }}
@@ -83,6 +83,20 @@ export const RECORD_ABSTRACT_FIELD: EditorField = {
83
83
  },
84
84
  }
85
85
 
86
+ export const CONTACTS_FOR_RESOURCE_FIELD: EditorField = {
87
+ model: 'contactsForResource',
88
+ formFieldConfig: {
89
+ labelKey: '',
90
+ },
91
+ }
92
+
93
+ export const RECORD_GRAPHICAL_OVERVIEW_FIELD: EditorField = {
94
+ model: 'overviews',
95
+ formFieldConfig: {
96
+ labelKey: marker('editor.record.form.field.overviews'),
97
+ },
98
+ }
99
+
86
100
  /************************************************************
87
101
  *************** SECTIONS *****************
88
102
  ************************************************************
@@ -90,7 +104,11 @@ export const RECORD_ABSTRACT_FIELD: EditorField = {
90
104
 
91
105
  export const TITLE_SECTION: EditorSection = {
92
106
  hidden: false,
93
- fields: [RECORD_TITLE_FIELD, RECORD_ABSTRACT_FIELD],
107
+ fields: [
108
+ RECORD_TITLE_FIELD,
109
+ RECORD_ABSTRACT_FIELD,
110
+ RECORD_GRAPHICAL_OVERVIEW_FIELD,
111
+ ],
94
112
  }
95
113
 
96
114
  export const ABOUT_SECTION: EditorSection = {
@@ -146,7 +164,7 @@ export const DATA_MANAGERS_SECTION: EditorSection = {
146
164
  labelKey: marker('editor.record.form.section.dataManagers.label'),
147
165
  descriptionKey: marker('editor.record.form.section.dataManagers.description'),
148
166
  hidden: false,
149
- fields: [],
167
+ fields: [CONTACTS_FOR_RESOURCE_FIELD],
150
168
  }
151
169
 
152
170
  export const DATA_POINT_OF_CONTACT_SECTION: EditorSection = {
@@ -183,3 +201,15 @@ export const DEFAULT_CONFIGURATION: EditorConfig = {
183
201
  },
184
202
  ],
185
203
  }
204
+
205
+ /************************************************************
206
+ *************** LICENSES *****************
207
+ ************************************************************
208
+ */
209
+ export const OPEN_DATA_LICENSES: string[] = [
210
+ 'etalab',
211
+ 'etalab-v2',
212
+ 'odbl',
213
+ 'odc-by',
214
+ 'pddl',
215
+ ]
@@ -32,7 +32,7 @@ import { ProxyService } from '../../../../../../libs/util/shared/src'
32
32
  import { WmsEndpoint, WmtsEndpoint } from '@camptocamp/ogc-client'
33
33
  import { LONLAT_CRS_CODES } from '../constant/projections'
34
34
  import { fromEPSGCode, register } from 'ol/proj/proj4'
35
- import proj4 from 'proj4/dist/proj4'
35
+ import proj4 from 'proj4'
36
36
  import { defaults as defaultControls } from 'ol/control/defaults'
37
37
 
38
38
  const FEATURE_PROJECTION = 'EPSG:3857'
@@ -220,11 +220,15 @@ export class MapUtilsService {
220
220
  if (!('spatialExtents' in record) || record.spatialExtents.length === 0) {
221
221
  return null
222
222
  }
223
- // transform an array of geojson geometries into a bbox
223
+ // extend all the spatial extents into an including bbox
224
224
  const totalExtent = record.spatialExtents.reduce(
225
225
  (prev, curr) => {
226
- const geom = GEOJSON.readGeometry(curr.geometry)
227
- return extend(prev, geom.getExtent())
226
+ if ('bbox' in curr) return extend(prev, curr.bbox)
227
+ else if ('geometry' in curr) {
228
+ const geom = GEOJSON.readGeometry(curr.geometry)
229
+ return extend(prev, geom.getExtent())
230
+ }
231
+ return prev
228
232
  },
229
233
  [Infinity, Infinity, -Infinity, -Infinity]
230
234
  )
@@ -6,6 +6,6 @@
6
6
  (inputSubmitted)="handleInputSubmission($event)"
7
7
  (inputCleared)="handleInputCleared()"
8
8
  [value]="searchInputValue$ | async"
9
- [clearOnSelection]="true"
9
+ [preventCompleteOnSelection]="true"
10
10
  [autoFocus]="autoFocus"
11
11
  ></gn-ui-autocomplete>
@@ -1,9 +1,11 @@
1
1
  <gn-ui-results-table
2
2
  [records]="records$ | async"
3
- [recordHasDraft]="hasDraft"
3
+ [hasDraft]="hasDraft"
4
4
  [selectedRecordsIdentifiers]="selectedRecords$ | async"
5
5
  [sortOrder]="sortBy$ | async"
6
6
  (recordClick)="handleRecordClick($event)"
7
+ (duplicateRecord)="handleDuplicateRecord($event)"
8
+ (deleteRecord)="handleDeleteRecord($event)"
7
9
  (recordsSelectedChange)="handleRecordsSelectedChange($event[0], $event[1])"
8
10
  (sortByChange)="handleSortByChange($event[0], $event[1])"
9
11
  ></gn-ui-results-table>
@@ -1,4 +1,4 @@
1
- import { Component, EventEmitter, Output } from '@angular/core'
1
+ import { Component, EventEmitter, OnDestroy, Output } from '@angular/core'
2
2
  import { CatalogRecord } from '../../../../../../libs/common/domain/src/lib/model/record'
3
3
  import { SearchFacade } from '../state/search.facade'
4
4
  import { SelectionService } from '../../../../../../libs/api/repository/src'
@@ -6,6 +6,9 @@ import { SearchService } from '../utils/service/search.service'
6
6
  import { RecordsRepositoryInterface } from '../../../../../../libs/common/domain/src/lib/repository/records-repository.interface'
7
7
  import { ResultsTableComponent } from '../../../../../../libs/ui/search/src'
8
8
  import { CommonModule } from '@angular/common'
9
+ import { Subscription } from 'rxjs'
10
+ import { NotificationsService } from '../../../../../../libs/feature/notifications/src'
11
+ import { TranslateService } from '@ngx-translate/core'
9
12
 
10
13
  @Component({
11
14
  selector: 'gn-ui-results-table-container',
@@ -14,8 +17,11 @@ import { CommonModule } from '@angular/common'
14
17
  standalone: true,
15
18
  imports: [CommonModule, ResultsTableComponent],
16
19
  })
17
- export class ResultsTableContainerComponent {
20
+ export class ResultsTableContainerComponent implements OnDestroy {
18
21
  @Output() recordClick = new EventEmitter<CatalogRecord>()
22
+ @Output() duplicateRecord = new EventEmitter<CatalogRecord>()
23
+
24
+ subscription = new Subscription()
19
25
 
20
26
  records$ = this.searchFacade.results$
21
27
  selectedRecords$ = this.selectionService.selectedRecordsIdentifiers$
@@ -28,13 +34,57 @@ export class ResultsTableContainerComponent {
28
34
  private searchFacade: SearchFacade,
29
35
  private searchService: SearchService,
30
36
  private selectionService: SelectionService,
31
- private recordsRepository: RecordsRepositoryInterface
37
+ private recordsRepository: RecordsRepositoryInterface,
38
+ private notificationsService: NotificationsService,
39
+ private translateService: TranslateService
32
40
  ) {}
33
41
 
34
42
  handleRecordClick(item: unknown) {
35
43
  this.recordClick.emit(item as CatalogRecord)
36
44
  }
37
45
 
46
+ handleDuplicateRecord(item: unknown) {
47
+ this.duplicateRecord.emit(item as CatalogRecord)
48
+ }
49
+
50
+ async handleDeleteRecord(item: unknown) {
51
+ const uniqueIdentifier = (item as CatalogRecord).uniqueIdentifier
52
+ this.subscription.add(
53
+ this.recordsRepository.deleteRecord(uniqueIdentifier).subscribe({
54
+ next: () => {
55
+ this.recordsRepository.clearRecordDraft(uniqueIdentifier)
56
+ this.searchFacade.requestNewResults()
57
+ this.notificationsService.showNotification(
58
+ {
59
+ type: 'success',
60
+ title: this.translateService.instant(
61
+ 'editor.record.deleteSuccess.title'
62
+ ),
63
+ text: `${this.translateService.instant(
64
+ 'editor.record.deleteSuccess.body'
65
+ )}`,
66
+ },
67
+ 2500
68
+ )
69
+ },
70
+ error: (error) => {
71
+ this.notificationsService.showNotification({
72
+ type: 'error',
73
+ title: this.translateService.instant(
74
+ 'editor.record.deleteError.title'
75
+ ),
76
+ text: `${this.translateService.instant(
77
+ 'editor.record.deleteError.body'
78
+ )} ${error}`,
79
+ closeMessage: this.translateService.instant(
80
+ 'editor.record.deleteError.closeMessage'
81
+ ),
82
+ })
83
+ },
84
+ })
85
+ )
86
+ }
87
+
38
88
  handleSortByChange(col: string, order: 'asc' | 'desc') {
39
89
  this.searchService.setSortBy([order, col])
40
90
  }
@@ -46,4 +96,8 @@ export class ResultsTableContainerComponent {
46
96
  this.selectionService.selectRecords(records)
47
97
  }
48
98
  }
99
+
100
+ ngOnDestroy() {
101
+ this.subscription.unsubscribe()
102
+ }
49
103
  }
@@ -8,6 +8,7 @@ import {
8
8
  Paginate,
9
9
  RequestMoreOnAggregation,
10
10
  RequestMoreResults,
11
+ RequestNewResults,
11
12
  SetConfigAggregations,
12
13
  SetConfigFilters,
13
14
  SetConfigRequestFields,
@@ -151,6 +152,11 @@ export class SearchFacade {
151
152
  return this
152
153
  }
153
154
 
155
+ requestNewResults(): SearchFacade {
156
+ this.store.dispatch(new RequestNewResults(this.searchId))
157
+ return this
158
+ }
159
+
154
160
  requestMoreOnAggregation(key: string, increment: number): SearchFacade {
155
161
  this.store.dispatch(
156
162
  new RequestMoreOnAggregation(key, increment, this.searchId)
@@ -1,5 +1,6 @@
1
1
  export * from './lib/api-card/api-card.component'
2
2
  export * from './lib/avatar/avatar.component'
3
+ export * from './lib/confirmation-dialog/confirmation-dialog.component'
3
4
  export * from './lib/content-ghost/content-ghost.component'
4
5
  export * from './lib/download-item/download-item.component'
5
6
  export * from './lib/downloads-list/downloads-list.component'
@@ -0,0 +1,12 @@
1
+ <h1 mat-dialog-title>{{ data.title }}</h1>
2
+ <div mat-dialog-content>{{ data.message }}</div>
3
+ <div mat-dialog-actions>
4
+ <gn-ui-button (buttonClick)="onCancel()">{{ data.cancelText }}</gn-ui-button>
5
+ <gn-ui-button
6
+ (buttonClick)="onConfirm()"
7
+ cdkFocusInitial
8
+ class="ml-2"
9
+ data-cy="confirm-button"
10
+ >{{ data.confirmText }}</gn-ui-button
11
+ >
12
+ </div>
@@ -0,0 +1,37 @@
1
+ import { ChangeDetectionStrategy, Component, Inject } from '@angular/core'
2
+ import {
3
+ MAT_DIALOG_DATA,
4
+ MatDialogModule,
5
+ MatDialogRef,
6
+ } from '@angular/material/dialog'
7
+ import { ButtonComponent } from '../../../../../../libs/ui/inputs/src'
8
+
9
+ export interface ConfirmationDialogData {
10
+ title: string
11
+ message: string
12
+ confirmText: string
13
+ cancelText: string
14
+ }
15
+
16
+ @Component({
17
+ selector: 'gn-ui-confirmation-dialog',
18
+ templateUrl: './confirmation-dialog.component.html',
19
+ styleUrls: ['./confirmation-dialog.component.css'],
20
+ changeDetection: ChangeDetectionStrategy.OnPush,
21
+ standalone: true,
22
+ imports: [MatDialogModule, ButtonComponent],
23
+ })
24
+ export class ConfirmationDialogComponent {
25
+ constructor(
26
+ public dialogRef: MatDialogRef<ConfirmationDialogComponent>,
27
+ @Inject(MAT_DIALOG_DATA) public data: ConfirmationDialogData
28
+ ) {}
29
+
30
+ onConfirm() {
31
+ this.dialogRef.close(true)
32
+ }
33
+
34
+ onCancel() {
35
+ this.dialogRef.close(false)
36
+ }
37
+ }
@@ -1,5 +1,8 @@
1
1
  <div class="h-full flex flex-col">
2
- <p class="flex-none mb-2 font-medium text-sm text-gray-900">
2
+ <p
3
+ *ngIf="helperText"
4
+ class="flex-none mb-2 font-medium text-sm text-gray-900"
5
+ >
3
6
  {{ helperText }}
4
7
  </p>
5
8
  <div class="flex-1" [hidden]="preview">
@@ -2,9 +2,10 @@
2
2
  :host ::ng-deep .markdown-body {
3
3
  -ms-text-size-adjust: 100%;
4
4
  -webkit-text-size-adjust: 100%;
5
- margin: 0px 0px 1.5rem 0px;
5
+ margin: 0;
6
6
  line-height: 1.5;
7
7
  word-wrap: break-word;
8
+ height: 100%;
8
9
  }
9
10
 
10
11
  /** Emphasis **/
@@ -1,7 +1,7 @@
1
1
  <div class="mb-6 md-description sm:mb-4 sm:pr-16">
2
2
  <gn-ui-content-ghost ghostClass="h-32" [showContent]="fieldReady('abstract')">
3
3
  <gn-ui-max-lines [maxLines]="6" *ngIf="metadata.abstract">
4
- <div>
4
+ <div class="mb-6">
5
5
  <gn-ui-markdown-parser
6
6
  [textContent]="metadata.abstract"
7
7
  ></gn-ui-markdown-parser>
@@ -47,19 +47,23 @@
47
47
  </ng-template>
48
48
  </ng-container>
49
49
  <ng-container *ngIf="legalConstraints.length">
50
- <gn-ui-markdown-parser
51
- *ngFor="let constraint of legalConstraints"
52
- [textContent]="constraint"
53
- >
54
- </gn-ui-markdown-parser>
50
+ <div class="mb-6">
51
+ <gn-ui-markdown-parser
52
+ *ngFor="let constraint of legalConstraints"
53
+ [textContent]="constraint"
54
+ >
55
+ </gn-ui-markdown-parser>
56
+ </div>
55
57
  </ng-container>
56
58
  <ng-container *ngIf="otherConstraints.length">
57
59
  <div gnUiLinkify *ngFor="let constraint of otherConstraints">
58
60
  <h5 translate class="font-medium text-black text-sm mb-[2px] mt-[16px]">
59
61
  record.metadata.otherConstraints
60
62
  </h5>
61
- <gn-ui-markdown-parser [textContent]="constraint">
62
- </gn-ui-markdown-parser>
63
+ <div class="mb-6">
64
+ <gn-ui-markdown-parser [textContent]="constraint">
65
+ </gn-ui-markdown-parser>
66
+ </div>
63
67
  </div>
64
68
  </ng-container>
65
69
 
@@ -1,22 +1,16 @@
1
- <div
2
- *ngIf="metadataQualityDisplay"
3
- class="mb-6 metadata-quality"
4
- (mouseenter)="showMenu()"
5
- (mouseleave)="hideMenu()"
6
- >
7
- <div class="min-w-[200px]" [class]="smaller ? 'leading-[8px]' : ''">
8
- <gn-ui-progress-bar
9
- (focus)="showMenu()"
10
- (blur)="hideMenu()"
11
- tabindex="0"
12
- [value]="qualityScore"
13
- type="primary"
14
- ></gn-ui-progress-bar>
15
- </div>
16
- <div
17
- class="absolute z-10 bg-white border border-black border-opacity-35 rounded-lg shadow-lg p-5 whitespace-nowrap"
18
- [class]="isMenuShown ? 'block' : 'hidden'"
19
- >
1
+ <div *ngIf="metadataQualityDisplay" class="mb-6 metadata-quality">
2
+ <gn-ui-popover [content]="popoverItems" theme="light-border">
3
+ <div class="min-w-[200px]" [class]="smaller ? 'leading-[8px]' : ''">
4
+ <gn-ui-progress-bar
5
+ tabindex="0"
6
+ [value]="qualityScore"
7
+ type="primary"
8
+ ></gn-ui-progress-bar>
9
+ </div>
10
+ </gn-ui-popover>
11
+ </div>
12
+ <ng-template #popoverItems>
13
+ <div class="p-2 py-4">
20
14
  <div class="mb-4 font-bold" translate>record.metadata.quality.details</div>
21
15
  <gn-ui-metadata-quality-item
22
16
  *ngFor="let e of items"
@@ -24,4 +18,4 @@
24
18
  [value]="e.value"
25
19
  ></gn-ui-metadata-quality-item>
26
20
  </div>
27
- </div>
21
+ </ng-template>
@@ -21,8 +21,6 @@ export class MetadataQualityComponent implements OnChanges {
21
21
 
22
22
  items: MetadataQualityItem[] = []
23
23
 
24
- isMenuShown = false
25
-
26
24
  get qualityScore() {
27
25
  const qualityScore = this.metadata?.extras?.qualityScore
28
26
  return typeof qualityScore === 'number'
@@ -36,14 +34,6 @@ export class MetadataQualityComponent implements OnChanges {
36
34
  )
37
35
  }
38
36
 
39
- showMenu() {
40
- this.isMenuShown = true
41
- }
42
-
43
- hideMenu() {
44
- this.isMenuShown = false
45
- }
46
-
47
37
  private add(name: string, value: boolean) {
48
38
  if (this.metadataQualityDisplay?.[name] !== false) {
49
39
  this.items.push({ name, value })
@@ -1,4 +1,4 @@
1
1
  <div class="ml-4 flex flex-row">
2
- <mat-icon class="material-symbols-outlined">{{ icon }}</mat-icon>
2
+ <mat-icon class="material-symbols-outlined min-w-fit">{{ icon }}</mat-icon>
3
3
  <p class="ml-2 text">{{ labelKey | translate }}</p>
4
4
  </div>
@@ -12,7 +12,9 @@
12
12
  class="sortable-list flex flex-col gap-3 p-2"
13
13
  (cdkDropListDropped)="drop($event)"
14
14
  >
15
- <ng-container *ngFor="let element of elements; index as index">
15
+ <ng-container
16
+ *ngFor="let element of elements; index as index; trackBy: trackByFn"
17
+ >
16
18
  <div class="sortable-box bg-white flex items-center" cdkDrag>
17
19
  <span
18
20
  cdkDragHandle
@@ -17,9 +17,9 @@ import {
17
17
  import { MatIconModule } from '@angular/material/icon'
18
18
  import { ButtonComponent } from '../../../../../../libs/ui/inputs/src'
19
19
 
20
- type DynamicElement = {
21
- component: Type<any>
22
- inputs: Record<string, any>
20
+ export type DynamicElement = {
21
+ component: Type<unknown>
22
+ inputs: Record<string, unknown>
23
23
  }
24
24
 
25
25
  @Component({
@@ -40,7 +40,7 @@ type DynamicElement = {
40
40
  })
41
41
  export class SortableListComponent {
42
42
  @Input() elements: Array<DynamicElement>
43
- @Input() addOptions: Array<{ buttonLabel: string; eventName: string }>
43
+ @Input() addOptions: Array<{ buttonLabel: string; eventName: string }> = []
44
44
  @Output() elementsChange = new EventEmitter<Array<DynamicElement>>()
45
45
  @Output() add = new EventEmitter<string>()
46
46
 
@@ -53,4 +53,8 @@ export class SortableListComponent {
53
53
  this.elements = this.elements.filter((_, i) => i !== index)
54
54
  this.elementsChange.emit(this.elements)
55
55
  }
56
+
57
+ trackByFn(index: number) {
58
+ return index
59
+ }
56
60
  }
@@ -9,7 +9,7 @@ import { ContentGhostComponent } from './content-ghost/content-ghost.component'
9
9
  import { DownloadItemComponent } from './download-item/download-item.component'
10
10
  import { DownloadsListComponent } from './downloads-list/downloads-list.component'
11
11
  import { ApiCardComponent } from './api-card/api-card.component'
12
- import { UiWidgetsModule } from '../../../../../libs/ui/widgets/src'
12
+ import { PopoverComponent, UiWidgetsModule } from '../../../../../libs/ui/widgets/src'
13
13
  import { MaxLinesComponent, UiLayoutModule } from '../../../../../libs/ui/layout/src'
14
14
  import { TranslateModule } from '@ngx-translate/core'
15
15
  import { RelatedRecordCardComponent } from './related-record-card/related-record-card.component'
@@ -45,6 +45,7 @@ import { TimeSincePipe } from './user-feedback-item/time-since.pipe'
45
45
  UiInputsModule,
46
46
  FormsModule,
47
47
  NgOptimizedImage,
48
+ PopoverComponent,
48
49
  MarkdownParserComponent,
49
50
  ThumbnailComponent,
50
51
  TimeSincePipe,
@@ -1,6 +1,6 @@
1
1
  <figure class="text-center">
2
2
  <div
3
- class="w-12 h-12 border border-primary rounded-full capitalize"
3
+ class="w-10 h-10 border border-primary rounded-full capitalize"
4
4
  [matTooltip]="userFullName"
5
5
  >
6
6
  <gn-ui-avatar
@@ -61,6 +61,7 @@ export class AutocompleteComponent
61
61
  @Input() action: (value: string) => Observable<AutocompleteItem[]>
62
62
  @Input() value?: AutocompleteItem
63
63
  @Input() clearOnSelection = false
64
+ @Input() preventCompleteOnSelection = false
64
65
  @Input() autoFocus = false
65
66
  @Input() minCharacterCount? = 3
66
67
  @Input() allowSubmit = true
@@ -206,13 +207,24 @@ export class AutocompleteComponent
206
207
  this.inputSubmitted.emit(this.inputRef.nativeElement.value)
207
208
  }
208
209
 
210
+ /**
211
+ * This function is triggered when an item is selected in the list of displayed items.
212
+ * If preventCompleteOnSelection is true then the input will be left as entered by the user.
213
+ * If preventCompleteOnSelection is false (by default) then the input will be completed with the item selected by the user.
214
+ * If clearOnSelection is true then the input will be cleared upon selection.
215
+ * @param event
216
+ */
209
217
  handleSelection(event: MatAutocompleteSelectedEvent) {
210
218
  this.cancelEnter = true
211
219
  this.itemSelected.emit(event.option.value)
212
- if (this.clearOnSelection) {
213
- this.lastInputValue$.pipe(first()).subscribe((any) => {
214
- this.inputRef.nativeElement.value = any
220
+ if (this.preventCompleteOnSelection) {
221
+ this.lastInputValue$.pipe(first()).subscribe((lastInputValue) => {
222
+ this.inputRef.nativeElement.value = lastInputValue
215
223
  })
224
+ return
225
+ }
226
+ if (this.clearOnSelection) {
227
+ this.inputRef.nativeElement.value = ''
216
228
  }
217
229
  }
218
230
  }