geonetwork-ui 2.4.0-dev.aa5f997e → 2.4.0-dev.b0bcda82

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 (161) hide show
  1. package/esm2022/libs/api/metadata-converter/src/index.mjs +1 -2
  2. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.mjs +5 -5
  3. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/read-parts.mjs +30 -2
  4. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/utils/geometry.mjs +31 -0
  5. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/write-parts.mjs +23 -1
  6. package/esm2022/libs/api/metadata-converter/src/lib/xml-utils.mjs +10 -3
  7. package/esm2022/libs/api/repository/src/lib/gn4/gn4-repository.mjs +21 -4
  8. package/esm2022/libs/common/domain/src/lib/model/record/contact.model.mjs +28 -1
  9. package/esm2022/libs/common/domain/src/lib/model/record/metadata.model.mjs +1 -1
  10. package/esm2022/libs/common/domain/src/lib/repository/records-repository.interface.mjs +1 -1
  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 +40 -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/sortable-list/sortable-list.component.mjs +7 -3
  31. package/esm2022/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.mjs +19 -5
  32. package/esm2022/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.mjs +3 -3
  33. package/esm2022/libs/ui/layout/src/lib/interactive-table/interactive-table.component.mjs +3 -3
  34. package/esm2022/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.mjs +49 -11
  35. package/esm2022/libs/ui/search/src/lib/results-table/results-table.component.mjs +18 -6
  36. package/esm2022/translations/de.json +41 -16
  37. package/esm2022/translations/en.json +34 -9
  38. package/esm2022/translations/es.json +34 -9
  39. package/esm2022/translations/fr.json +44 -19
  40. package/esm2022/translations/it.json +34 -9
  41. package/esm2022/translations/nl.json +34 -9
  42. package/esm2022/translations/pt.json +34 -9
  43. package/fesm2022/geonetwork-ui.mjs +1134 -263
  44. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  45. package/libs/api/metadata-converter/src/index.d.ts +0 -1
  46. package/libs/api/metadata-converter/src/index.d.ts.map +1 -1
  47. package/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.d.ts.map +1 -1
  48. package/libs/api/metadata-converter/src/lib/iso19139/read-parts.d.ts +8 -1
  49. package/libs/api/metadata-converter/src/lib/iso19139/read-parts.d.ts.map +1 -1
  50. package/libs/api/metadata-converter/src/lib/iso19139/utils/geometry.d.ts +5 -0
  51. package/libs/api/metadata-converter/src/lib/iso19139/utils/geometry.d.ts.map +1 -0
  52. package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts +3 -1
  53. package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts.map +1 -1
  54. package/libs/api/metadata-converter/src/lib/xml-utils.d.ts +1 -0
  55. package/libs/api/metadata-converter/src/lib/xml-utils.d.ts.map +1 -1
  56. package/libs/api/repository/src/lib/gn4/gn4-repository.d.ts +6 -1
  57. package/libs/api/repository/src/lib/gn4/gn4-repository.d.ts.map +1 -1
  58. package/libs/common/domain/src/lib/model/record/contact.model.d.ts +1 -0
  59. package/libs/common/domain/src/lib/model/record/contact.model.d.ts.map +1 -1
  60. package/libs/common/domain/src/lib/model/record/metadata.model.d.ts +2 -1
  61. package/libs/common/domain/src/lib/model/record/metadata.model.d.ts.map +1 -1
  62. package/libs/common/domain/src/lib/repository/records-repository.interface.d.ts +8 -0
  63. package/libs/common/domain/src/lib/repository/records-repository.interface.d.ts.map +1 -1
  64. package/libs/feature/editor/src/lib/components/contact-card/contact-card.component.d.ts +12 -0
  65. package/libs/feature/editor/src/lib/components/contact-card/contact-card.component.d.ts.map +1 -0
  66. package/libs/feature/editor/src/lib/components/overview-upload/overview-upload.component.d.ts +27 -0
  67. package/libs/feature/editor/src/lib/components/overview-upload/overview-upload.component.d.ts.map +1 -0
  68. 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
  69. 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
  70. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-open-data/form-field-open-data.component.d.ts +17 -0
  71. 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
  72. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.d.ts +11 -0
  73. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.d.ts.map +1 -0
  74. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-temporal-extents/form-field-temporal-extents.component.d.ts +3 -1
  75. 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
  76. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts +9 -1
  77. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts.map +1 -1
  78. package/libs/feature/editor/src/lib/fields.config.d.ts +7 -0
  79. package/libs/feature/editor/src/lib/fields.config.d.ts.map +1 -1
  80. package/libs/feature/map/src/lib/utils/map-utils.service.d.ts.map +1 -1
  81. package/libs/feature/search/src/lib/results-table/results-table-container.component.d.ts +11 -3
  82. package/libs/feature/search/src/lib/results-table/results-table-container.component.d.ts.map +1 -1
  83. package/libs/feature/search/src/lib/state/search.facade.d.ts +1 -0
  84. package/libs/feature/search/src/lib/state/search.facade.d.ts.map +1 -1
  85. package/libs/ui/elements/src/index.d.ts +1 -0
  86. package/libs/ui/elements/src/index.d.ts.map +1 -1
  87. package/libs/ui/elements/src/lib/confirmation-dialog/confirmation-dialog.component.d.ts +18 -0
  88. package/libs/ui/elements/src/lib/confirmation-dialog/confirmation-dialog.component.d.ts.map +1 -0
  89. package/libs/ui/elements/src/lib/downloads-list/downloads-list.component.d.ts +1 -1
  90. package/libs/ui/elements/src/lib/record-api-form/record-api-form.component.d.ts +1 -1
  91. package/libs/ui/elements/src/lib/sortable-list/sortable-list.component.d.ts +4 -4
  92. package/libs/ui/elements/src/lib/sortable-list/sortable-list.component.d.ts.map +1 -1
  93. package/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.d.ts +9 -1
  94. package/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.d.ts.map +1 -1
  95. package/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.d.ts +10 -1
  96. package/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.d.ts.map +1 -1
  97. package/libs/ui/search/src/lib/results-table/results-table.component.d.ts +6 -2
  98. package/libs/ui/search/src/lib/results-table/results-table.component.d.ts.map +1 -1
  99. package/package.json +1 -1
  100. package/src/libs/api/metadata-converter/src/index.ts +0 -1
  101. package/src/libs/api/metadata-converter/src/lib/fixtures/geo2france.records.ts +5 -1
  102. package/src/libs/api/metadata-converter/src/lib/fixtures/geocat-ch.records.ts +37 -12
  103. package/src/libs/api/metadata-converter/src/lib/fixtures/metawal.records.ts +5 -1
  104. package/src/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.ts +4 -2
  105. package/src/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts +72 -2
  106. package/src/libs/api/metadata-converter/src/lib/iso19139/utils/geometry.ts +39 -0
  107. package/src/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts +70 -1
  108. package/src/libs/api/metadata-converter/src/lib/xml-utils.ts +13 -5
  109. package/src/libs/api/repository/src/lib/gn4/gn4-repository.ts +24 -4
  110. package/src/libs/common/domain/src/lib/model/record/contact.model.ts +28 -0
  111. package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +2 -1
  112. package/src/libs/common/domain/src/lib/repository/records-repository.interface.ts +10 -0
  113. package/src/libs/feature/editor/src/lib/components/contact-card/contact-card.component.css +0 -0
  114. package/src/libs/feature/editor/src/lib/components/contact-card/contact-card.component.html +25 -0
  115. package/src/libs/feature/editor/src/lib/components/contact-card/contact-card.component.ts +30 -0
  116. package/src/libs/feature/editor/src/lib/components/overview-upload/overview-upload.component.html +2 -1
  117. package/src/libs/feature/editor/src/lib/components/overview-upload/overview-upload.component.ts +110 -19
  118. 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
  119. 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
  120. 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
  121. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-keywords/form-field-keywords.component.html +1 -1
  122. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-open-data/form-field-open-data.component.css +0 -0
  123. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-open-data/form-field-open-data.component.html +6 -0
  124. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-open-data/form-field-open-data.component.ts +59 -0
  125. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.css +0 -0
  126. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.html +5 -0
  127. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.ts +22 -0
  128. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-temporal-extents/form-field-temporal-extents.component.ts +8 -7
  129. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html +18 -1
  130. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts +30 -1
  131. package/src/libs/feature/editor/src/lib/components/record-form/record-form.component.html +1 -1
  132. package/src/libs/feature/editor/src/lib/fields.config.ts +32 -2
  133. package/src/libs/feature/map/src/lib/utils/map-utils.service.ts +8 -4
  134. package/src/libs/feature/search/src/lib/fuzzy-search/fuzzy-search.component.html +1 -1
  135. package/src/libs/feature/search/src/lib/results-table/results-table-container.component.html +2 -1
  136. package/src/libs/feature/search/src/lib/results-table/results-table-container.component.ts +52 -3
  137. package/src/libs/feature/search/src/lib/state/search.facade.ts +6 -0
  138. package/src/libs/ui/elements/src/index.ts +1 -0
  139. package/src/libs/ui/elements/src/lib/confirmation-dialog/confirmation-dialog.component.css +0 -0
  140. package/src/libs/ui/elements/src/lib/confirmation-dialog/confirmation-dialog.component.html +12 -0
  141. package/src/libs/ui/elements/src/lib/confirmation-dialog/confirmation-dialog.component.ts +37 -0
  142. package/src/libs/ui/elements/src/lib/markdown-editor/markdown-editor.component.html +4 -1
  143. package/src/libs/ui/elements/src/lib/markdown-parser/markdown-parser.component.css +2 -1
  144. package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.html +12 -8
  145. package/src/libs/ui/elements/src/lib/sortable-list/sortable-list.component.html +3 -1
  146. package/src/libs/ui/elements/src/lib/sortable-list/sortable-list.component.ts +8 -4
  147. package/src/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.ts +15 -3
  148. package/src/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.html +1 -1
  149. package/src/libs/ui/layout/src/lib/interactive-table/interactive-table.component.html +1 -0
  150. package/src/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.html +10 -1
  151. package/src/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.ts +55 -3
  152. package/src/libs/ui/search/src/lib/results-table/results-table.component.html +7 -2
  153. package/src/libs/ui/search/src/lib/results-table/results-table.component.ts +9 -9
  154. package/translations/de.json +41 -16
  155. package/translations/en.json +34 -9
  156. package/translations/es.json +34 -9
  157. package/translations/fr.json +44 -19
  158. package/translations/it.json +34 -9
  159. package/translations/nl.json +34 -9
  160. package/translations/pt.json +34 -9
  161. package/translations/sk.json +34 -9
@@ -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,10 +17,12 @@ 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>()
19
22
  @Output() duplicateRecord = new EventEmitter<CatalogRecord>()
20
23
 
24
+ subscription = new Subscription()
25
+
21
26
  records$ = this.searchFacade.results$
22
27
  selectedRecords$ = this.selectionService.selectedRecordsIdentifiers$
23
28
  sortBy$ = this.searchFacade.sortBy$
@@ -29,7 +34,9 @@ export class ResultsTableContainerComponent {
29
34
  private searchFacade: SearchFacade,
30
35
  private searchService: SearchService,
31
36
  private selectionService: SelectionService,
32
- private recordsRepository: RecordsRepositoryInterface
37
+ private recordsRepository: RecordsRepositoryInterface,
38
+ private notificationsService: NotificationsService,
39
+ private translateService: TranslateService
33
40
  ) {}
34
41
 
35
42
  handleRecordClick(item: unknown) {
@@ -40,6 +47,44 @@ export class ResultsTableContainerComponent {
40
47
  this.duplicateRecord.emit(item as CatalogRecord)
41
48
  }
42
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
+
43
88
  handleSortByChange(col: string, order: 'asc' | 'desc') {
44
89
  this.searchService.setSortBy([order, col])
45
90
  }
@@ -51,4 +96,8 @@ export class ResultsTableContainerComponent {
51
96
  this.selectionService.selectRecords(records)
52
97
  }
53
98
  }
99
+
100
+ ngOnDestroy() {
101
+ this.subscription.unsubscribe()
102
+ }
54
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
 
@@ -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
  }
@@ -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
  }
@@ -12,7 +12,7 @@
12
12
  </span>
13
13
  </div>
14
14
  </div>
15
- <div class="flex-1">
15
+ <div class="flex-1 overflow-y-auto">
16
16
  <ng-content></ng-content>
17
17
  </div>
18
18
  </div>
@@ -30,6 +30,7 @@
30
30
  class="contents text-gray-900 cursor-pointer group"
31
31
  *ngFor="let item of items"
32
32
  (click)="handleRowClick(item)"
33
+ data-cy="table-row"
33
34
  >
34
35
  <div
35
36
  class="relative h-0"
@@ -1,5 +1,5 @@
1
1
  <gn-ui-button
2
- type="outline"
2
+ type="light"
3
3
  [matMenuTriggerFor]="menu"
4
4
  (buttonClick)="openMenu()"
5
5
  data-test="record-menu-button"
@@ -9,9 +9,18 @@
9
9
  <mat-menu #menu="matMenu">
10
10
  <button
11
11
  mat-menu-item
12
+ [disabled]="!canDuplicate"
12
13
  (click)="duplicate.emit()"
13
14
  data-test="record-menu-duplicate-button"
14
15
  >
15
16
  <span translate>record.action.duplicate</span>
16
17
  </button>
18
+ <button
19
+ mat-menu-item
20
+ [disabled]="!canDelete"
21
+ (click)="openDeleteConfirmationDialog()"
22
+ data-test="record-menu-delete-button"
23
+ >
24
+ <span translate>record.action.delete</span>
25
+ </button>
17
26
  </mat-menu>
@@ -1,22 +1,74 @@
1
- import { Component, EventEmitter, Output, ViewChild } from '@angular/core'
1
+ import {
2
+ Component,
3
+ EventEmitter,
4
+ Input,
5
+ Output,
6
+ ViewChild,
7
+ } from '@angular/core'
8
+ import { MatDialog, MatDialogModule } from '@angular/material/dialog'
2
9
  import { MatIconModule } from '@angular/material/icon'
3
10
  import { MatMenuModule, MatMenuTrigger } from '@angular/material/menu'
11
+ import { ConfirmationDialogComponent } from '../../../../../../../libs/ui/elements/src'
4
12
  import { ButtonComponent } from '../../../../../../../libs/ui/inputs/src'
5
- import { TranslateModule } from '@ngx-translate/core'
13
+ import { TranslateModule, TranslateService } from '@ngx-translate/core'
6
14
 
7
15
  @Component({
8
16
  selector: 'gn-ui-action-menu',
9
17
  templateUrl: './action-menu.component.html',
10
18
  styleUrls: ['./action-menu.component.css'],
11
19
  standalone: true,
12
- imports: [MatIconModule, ButtonComponent, MatMenuModule, TranslateModule],
20
+ imports: [
21
+ MatIconModule,
22
+ ButtonComponent,
23
+ MatMenuModule,
24
+ MatDialogModule,
25
+ ConfirmationDialogComponent,
26
+ TranslateModule,
27
+ ],
13
28
  })
14
29
  export class ActionMenuComponent {
30
+ @Input() canDuplicate: boolean
31
+ @Input() canDelete: boolean
15
32
  @Output() duplicate = new EventEmitter<void>()
33
+ @Output() delete = new EventEmitter<void>()
16
34
 
17
35
  @ViewChild(MatMenuTrigger) trigger: MatMenuTrigger
18
36
 
37
+ constructor(
38
+ public dialog: MatDialog,
39
+ private translateService: TranslateService
40
+ ) {}
41
+
19
42
  openMenu() {
20
43
  this.trigger.openMenu()
21
44
  }
45
+
46
+ openDeleteConfirmationDialog() {
47
+ const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
48
+ data: {
49
+ title: this.translateService.instant(
50
+ 'editor.record.delete.confirmation.title'
51
+ ),
52
+ message: this.translateService.instant(
53
+ 'editor.record.delete.confirmation.message'
54
+ ),
55
+ confirmText: this.translateService.instant(
56
+ 'editor.record.delete.confirmation.confirmText'
57
+ ),
58
+ cancelText: this.translateService.instant(
59
+ 'editor.record.delete.confirmation.cancelText'
60
+ ),
61
+ },
62
+ restoreFocus: false,
63
+ })
64
+
65
+ // Manually restore focus to the menu trigger since the element that
66
+ // opens the dialog won't be in the DOM any more when the dialog closes.
67
+ dialogRef.afterClosed().subscribe((confirmed) => {
68
+ this.trigger.focus()
69
+ if (confirmed) {
70
+ this.delete.emit()
71
+ }
72
+ })
73
+ }
22
74
  }
@@ -37,7 +37,7 @@
37
37
  <div class="flex flex-row items-center gap-2 max-w-full">
38
38
  <span class="overflow-hidden text-ellipsis">{{ item.title }}</span>
39
39
  <gn-ui-badge
40
- *ngIf="recordHasDraft(item)"
40
+ *ngIf="hasDraft(item)"
41
41
  [style.--gn-ui-badge-padding]="'0.4em 0.6em'"
42
42
  [style.--gn-ui-badge-text-color]="'#3d2006'"
43
43
  [style.--gn-ui-badge-background-color]="'#ffbc7b'"
@@ -125,7 +125,12 @@
125
125
  <gn-ui-interactive-table-column>
126
126
  <ng-template #header> </ng-template>
127
127
  <ng-template #cell let-item>
128
- <gn-ui-action-menu (duplicate)="handleDuplicate(item)">
128
+ <gn-ui-action-menu
129
+ [canDuplicate]="canDuplicate(item)"
130
+ [canDelete]="canDelete(item)"
131
+ (duplicate)="handleDuplicate(item)"
132
+ (delete)="handleDelete(item)"
133
+ >
129
134
  </gn-ui-action-menu>
130
135
  </ng-template>
131
136
  </gn-ui-interactive-table-column>
@@ -1,13 +1,6 @@
1
1
  import { CommonModule } from '@angular/common'
2
- import {
3
- Component,
4
- EventEmitter,
5
- Input,
6
- Output,
7
- ViewChild,
8
- } from '@angular/core'
2
+ import { Component, EventEmitter, Input, Output } from '@angular/core'
9
3
  import { MatIconModule } from '@angular/material/icon'
10
- import { MatMenuModule, MatMenuTrigger } from '@angular/material/menu'
11
4
  import { CatalogRecord } from '../../../../../../libs/common/domain/src/lib/model/record'
12
5
  import {
13
6
  FieldSort,
@@ -47,12 +40,15 @@ export class ResultsTableComponent {
47
40
  @Input() records: CatalogRecord[] = []
48
41
  @Input() selectedRecordsIdentifiers: string[] = []
49
42
  @Input() sortOrder: SortByField = null
50
- @Input() recordHasDraft: (record: CatalogRecord) => boolean = () => false
43
+ @Input() hasDraft: (record: CatalogRecord) => boolean = () => false
44
+ @Input() canDuplicate: (record: CatalogRecord) => boolean = () => true
45
+ @Input() canDelete: (record: CatalogRecord) => boolean = () => true
51
46
 
52
47
  // emits the column (field) as well as the order
53
48
  @Output() sortByChange = new EventEmitter<[string, 'asc' | 'desc']>()
54
49
  @Output() recordClick = new EventEmitter<CatalogRecord>()
55
50
  @Output() duplicateRecord = new EventEmitter<CatalogRecord>()
51
+ @Output() deleteRecord = new EventEmitter<CatalogRecord>()
56
52
  @Output() recordsSelectedChange = new EventEmitter<
57
53
  [CatalogRecord[], boolean]
58
54
  >()
@@ -103,6 +99,10 @@ export class ResultsTableComponent {
103
99
  this.duplicateRecord.emit(item as CatalogRecord)
104
100
  }
105
101
 
102
+ handleDelete(item: unknown) {
103
+ this.deleteRecord.emit(item as CatalogRecord)
104
+ }
105
+
106
106
  setSortBy(col: string, order: 'asc' | 'desc') {
107
107
  this.sortByChange.emit([col, order])
108
108
  }
@@ -147,6 +147,27 @@
147
147
  "dataset.error.parse": "Die Daten wurden geladen, konnten aber nicht gelesen werden: \"{ info }\"",
148
148
  "dataset.error.unknown": "Die Daten können nicht angezeigt werden: \"{ info }\"",
149
149
  "dataset.error.unsupportedType": "Der folgende Inhaltstyp wird nicht unterstützt: \"{ info }\"",
150
+ "domain.contact.role.author": "",
151
+ "domain.contact.role.collaborator": "",
152
+ "domain.contact.role.contributor": "",
153
+ "domain.contact.role.custodian": "",
154
+ "domain.contact.role.distributor": "",
155
+ "domain.contact.role.editor": "",
156
+ "domain.contact.role.funder": "",
157
+ "domain.contact.role.mediator": "",
158
+ "domain.contact.role.originator": "",
159
+ "domain.contact.role.other": "",
160
+ "domain.contact.role.owner": "",
161
+ "domain.contact.role.point_of_contact": "",
162
+ "domain.contact.role.principal_investigator": "",
163
+ "domain.contact.role.processor": "",
164
+ "domain.contact.role.publisher": "",
165
+ "domain.contact.role.resource_provider": "",
166
+ "domain.contact.role.rights_holder": "",
167
+ "domain.contact.role.sponsor": "",
168
+ "domain.contact.role.stakeholder": "",
169
+ "domain.contact.role.unspecified": "",
170
+ "domain.contact.role.user": "",
150
171
  "domain.record.status.completed": "Abgeschlossen",
151
172
  "domain.record.status.deprecated": "Veraltet",
152
173
  "domain.record.status.ongoing": "Kontinuierliche Aktualisierung",
@@ -165,21 +186,30 @@
165
186
  "downloads.format.unknown": "unbekannt",
166
187
  "downloads.wfs.featuretype.not.found": "Der Layer wurde nicht gefunden",
167
188
  "dropFile": "Datei ablegen",
189
+ "editor.record.delete.confirmation.cancelText": "Stornieren",
190
+ "editor.record.delete.confirmation.confirmText": "Löschen",
191
+ "editor.record.delete.confirmation.message": "Sind Sie sicher, dass Sie diesen Datensatz löschen möchten?",
192
+ "editor.record.delete.confirmation.title": "Datensatz löschen?",
193
+ "editor.record.deleteError.body": "Der Datensatz konnte nicht gelöscht werden:",
194
+ "editor.record.deleteError.closeMessage": "Verstanden",
195
+ "editor.record.deleteError.title": "Fehler beim Löschen des Datensatzes",
196
+ "editor.record.deleteSuccess.body": "",
197
+ "editor.record.deleteSuccess.title": "",
168
198
  "editor.record.form.bottomButtons.comeBackLater": "",
169
199
  "editor.record.form.bottomButtons.next": "",
170
200
  "editor.record.form.bottomButtons.previous": "",
171
- "editor.record.form.field.abstract": "",
201
+ "editor.record.form.field.abstract": "Kurzbeschreibung",
202
+ "editor.record.form.field.contactsForResource.noContact": "",
172
203
  "editor.record.form.field.keywords": "Schlagwörter",
173
204
  "editor.record.form.field.license": "Lizenz",
174
- "editor.record.form.field.recordUpdated": "",
175
- "editor.record.form.field.resourceUpdated": "",
176
- "editor.record.form.field.temporalExtents": "",
177
- "editor.record.form.field.title": "",
178
- "editor.record.form.field.uniqueIdentifier": "",
179
- "editor.record.form.field.updateFrequency": "",
180
- "editor.record.form.abstract": "Kurzbeschreibung",
181
- "editor.record.form.keywords": "Schlüsselwörter",
182
- "editor.record.form.license": "Lizenz",
205
+ "editor.record.form.field.overviews": "",
206
+ "editor.record.form.field.recordUpdated": "Datensatz zuletzt aktualisiert",
207
+ "editor.record.form.field.resourceUpdated": "Letztes Aktualisierungsdatum",
208
+ "editor.record.form.field.temporalExtents": "Zeitlicher Umfang",
209
+ "editor.record.form.field.title": "Metadaten-Titel",
210
+ "editor.record.form.field.uniqueIdentifier": "Eindeutige Kennung (ID)",
211
+ "editor.record.form.field.updateFrequency": "Aktualisierungshäufigkeit",
212
+ "editor.record.form.classification.opendata": "",
183
213
  "editor.record.form.license.cc-by": "Creative Commons CC-BY",
184
214
  "editor.record.form.license.cc-by-sa": "Creative Commons CC-BY-SA",
185
215
  "editor.record.form.license.cc-zero": "Creative Commons CC-0",
@@ -205,16 +235,10 @@
205
235
  "editor.record.form.section.dataPointOfContact.label": "",
206
236
  "editor.record.form.section.geographicalCoverage.label": "",
207
237
  "editor.record.form.section.useAndAccessConditions.label": "",
208
- "editor.record.form.metadata.title": "Metadaten-Titel",
209
- "editor.record.form.record.updated": "Datensatz zuletzt aktualisiert",
210
- "editor.record.form.resourceUpdated": "Letztes Aktualisierungsdatum",
211
- "editor.record.form.temporalExtents": "Zeitlicher Umfang",
212
238
  "editor.record.form.temporalExtents.addDate": "Zeitpunkt",
213
239
  "editor.record.form.temporalExtents.addRange": "Zeitraum",
214
240
  "editor.record.form.temporalExtents.date": "Datum",
215
241
  "editor.record.form.temporalExtents.range": "Datumsbereich",
216
- "editor.record.form.unique.identifier": "Eindeutige Kennung (ID)",
217
- "editor.record.form.updateFrequency": "Aktualisierungshäufigkeit",
218
242
  "editor.record.form.updateFrequency.planned": "Die Daten sollten regelmäßig aktualisiert werden.",
219
243
  "editor.record.loadError.body": "Der Datensatz konnte nicht geladen werden:",
220
244
  "editor.record.loadError.closeMessage": "Verstanden",
@@ -306,6 +330,7 @@
306
330
  "pagination.page": "Seite",
307
331
  "pagination.pageOf": "von",
308
332
  "previous": "zurück",
333
+ "record.action.delete": "Löschen",
309
334
  "record.action.download": "Herunterladen",
310
335
  "record.action.duplicate": "",
311
336
  "record.action.view": "Anzeigen",