geonetwork-ui 2.4.1-dev.9ee0df3df → 2.4.1-dev.a28bdabc1

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 (121) hide show
  1. package/esm2022/libs/api/metadata-converter/src/lib/gn4/gn4.converter.mjs +4 -3
  2. package/esm2022/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.mjs +5 -2
  3. package/esm2022/libs/api/metadata-converter/src/lib/gn4/types/metadata.model.mjs +1 -1
  4. package/esm2022/libs/api/repository/src/lib/gn4/gn4-repository.mjs +27 -16
  5. package/esm2022/libs/common/domain/src/lib/repository/records-repository.interface.mjs +1 -1
  6. package/esm2022/libs/data-access/gn4/src/openapi/api/records.api.service.mjs +7 -1
  7. package/esm2022/libs/feature/editor/src/lib/+state/editor.actions.mjs +3 -1
  8. package/esm2022/libs/feature/editor/src/lib/+state/editor.effects.mjs +18 -14
  9. package/esm2022/libs/feature/editor/src/lib/+state/editor.facade.mjs +15 -5
  10. package/esm2022/libs/feature/editor/src/lib/+state/editor.reducer.mjs +10 -4
  11. package/esm2022/libs/feature/editor/src/lib/+state/editor.selectors.mjs +6 -5
  12. package/esm2022/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.mjs +57 -10
  13. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.mjs +36 -23
  14. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-link-resources/form-field-online-link-resources.component.mjs +7 -12
  15. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-resources/form-field-online-resources.component.mjs +8 -12
  16. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.mjs +6 -12
  17. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.mjs +3 -3
  18. package/esm2022/libs/feature/editor/src/lib/services/editor.service.mjs +9 -5
  19. package/esm2022/libs/feature/search/src/lib/results-table/results-table-container.component.mjs +3 -4
  20. package/esm2022/libs/ui/dataviz/src/lib/figure/figure.component.mjs +3 -3
  21. package/esm2022/libs/ui/inputs/src/lib/file-input/file-input.component.mjs +4 -4
  22. package/esm2022/libs/ui/layout/src/lib/interactive-table/interactive-table.component.mjs +9 -4
  23. package/esm2022/libs/ui/search/src/lib/results-table/results-table.component.mjs +10 -10
  24. package/esm2022/libs/util/shared/src/lib/links/link-utils.mjs +40 -1
  25. package/esm2022/translations/de.json +29 -6
  26. package/esm2022/translations/en.json +13 -9
  27. package/esm2022/translations/es.json +27 -4
  28. package/esm2022/translations/fr.json +13 -9
  29. package/esm2022/translations/it.json +243 -218
  30. package/esm2022/translations/nl.json +27 -4
  31. package/esm2022/translations/pt.json +27 -4
  32. package/fesm2022/geonetwork-ui.mjs +883 -616
  33. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  34. package/libs/api/metadata-converter/src/lib/gn4/gn4.converter.d.ts.map +1 -1
  35. package/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.d.ts.map +1 -1
  36. package/libs/api/metadata-converter/src/lib/gn4/types/metadata.model.d.ts +1 -0
  37. package/libs/api/metadata-converter/src/lib/gn4/types/metadata.model.d.ts.map +1 -1
  38. package/libs/api/repository/src/lib/gn4/gn4-repository.d.ts +4 -3
  39. package/libs/api/repository/src/lib/gn4/gn4-repository.d.ts.map +1 -1
  40. package/libs/common/domain/src/lib/repository/records-repository.interface.d.ts +4 -3
  41. package/libs/common/domain/src/lib/repository/records-repository.interface.d.ts.map +1 -1
  42. package/libs/data-access/gn4/src/openapi/api/records.api.service.d.ts +3 -0
  43. package/libs/data-access/gn4/src/openapi/api/records.api.service.d.ts.map +1 -1
  44. package/libs/feature/editor/src/lib/+state/editor.actions.d.ts +10 -2
  45. package/libs/feature/editor/src/lib/+state/editor.actions.d.ts.map +1 -1
  46. package/libs/feature/editor/src/lib/+state/editor.effects.d.ts +6 -2
  47. package/libs/feature/editor/src/lib/+state/editor.effects.d.ts.map +1 -1
  48. package/libs/feature/editor/src/lib/+state/editor.facade.d.ts +5 -2
  49. package/libs/feature/editor/src/lib/+state/editor.facade.d.ts.map +1 -1
  50. package/libs/feature/editor/src/lib/+state/editor.reducer.d.ts +2 -1
  51. package/libs/feature/editor/src/lib/+state/editor.reducer.d.ts.map +1 -1
  52. package/libs/feature/editor/src/lib/+state/editor.selectors.d.ts +2 -1
  53. package/libs/feature/editor/src/lib/+state/editor.selectors.d.ts.map +1 -1
  54. package/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.d.ts +16 -5
  55. package/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.d.ts.map +1 -1
  56. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.d.ts +4 -4
  57. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.d.ts.map +1 -1
  58. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-link-resources/form-field-online-link-resources.component.d.ts +1 -4
  59. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-link-resources/form-field-online-link-resources.component.d.ts.map +1 -1
  60. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-resources/form-field-online-resources.component.d.ts +2 -5
  61. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-resources/form-field-online-resources.component.d.ts.map +1 -1
  62. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.d.ts +1 -4
  63. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.d.ts.map +1 -1
  64. package/libs/feature/editor/src/lib/services/editor.service.d.ts +1 -1
  65. package/libs/feature/editor/src/lib/services/editor.service.d.ts.map +1 -1
  66. package/libs/feature/search/src/lib/results-table/results-table-container.component.d.ts +0 -1
  67. package/libs/feature/search/src/lib/results-table/results-table-container.component.d.ts.map +1 -1
  68. package/libs/ui/elements/src/lib/record-api-form/record-api-form.component.d.ts +1 -1
  69. package/libs/ui/inputs/src/lib/file-input/file-input.component.d.ts +1 -1
  70. package/libs/ui/inputs/src/lib/file-input/file-input.component.d.ts.map +1 -1
  71. package/libs/ui/layout/src/lib/interactive-table/interactive-table.component.d.ts +2 -1
  72. package/libs/ui/layout/src/lib/interactive-table/interactive-table.component.d.ts.map +1 -1
  73. package/libs/ui/search/src/lib/results-table/results-table.component.d.ts +3 -3
  74. package/libs/ui/search/src/lib/results-table/results-table.component.d.ts.map +1 -1
  75. package/libs/util/shared/src/lib/links/link-utils.d.ts +2 -1
  76. package/libs/util/shared/src/lib/links/link-utils.d.ts.map +1 -1
  77. package/package.json +1 -1
  78. package/src/libs/api/metadata-converter/src/lib/gn4/gn4.converter.ts +4 -3
  79. package/src/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts +8 -1
  80. package/src/libs/api/metadata-converter/src/lib/gn4/types/metadata.model.ts +1 -0
  81. package/src/libs/api/repository/src/lib/gn4/gn4-repository.ts +53 -27
  82. package/src/libs/common/domain/src/lib/repository/records-repository.interface.ts +5 -4
  83. package/src/libs/common/fixtures/src/lib/elasticsearch/full-response.fixtures.ts +2 -2
  84. package/src/libs/common/fixtures/src/lib/elasticsearch/search-responses.fixtures.ts +16 -16
  85. package/src/libs/common/fixtures/src/lib/records.fixtures.ts +163 -0
  86. package/src/libs/data-access/gn4/src/openapi/api/records.api.service.ts +24 -4
  87. package/src/libs/feature/editor/src/lib/+state/editor.actions.ts +10 -1
  88. package/src/libs/feature/editor/src/lib/+state/editor.effects.ts +57 -31
  89. package/src/libs/feature/editor/src/lib/+state/editor.facade.ts +15 -9
  90. package/src/libs/feature/editor/src/lib/+state/editor.reducer.ts +18 -12
  91. package/src/libs/feature/editor/src/lib/+state/editor.selectors.ts +13 -8
  92. package/src/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.html +38 -7
  93. package/src/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.ts +62 -3
  94. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.html +1 -1
  95. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.ts +31 -19
  96. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-link-resources/form-field-online-link-resources.component.html +1 -10
  97. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-link-resources/form-field-online-link-resources.component.ts +1 -7
  98. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-resources/form-field-online-resources.component.html +11 -20
  99. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-resources/form-field-online-resources.component.ts +5 -10
  100. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.html +0 -9
  101. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.ts +2 -8
  102. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html +2 -2
  103. package/src/libs/feature/editor/src/lib/services/editor.service.ts +18 -16
  104. package/src/libs/feature/search/src/lib/results-table/results-table-container.component.html +0 -1
  105. package/src/libs/feature/search/src/lib/results-table/results-table-container.component.ts +0 -3
  106. package/src/libs/ui/dataviz/src/lib/figure/figure.component.html +1 -0
  107. package/src/libs/ui/inputs/src/lib/file-input/file-input.component.ts +1 -1
  108. package/src/libs/ui/layout/src/lib/interactive-table/interactive-table.component.html +12 -1
  109. package/src/libs/ui/layout/src/lib/interactive-table/interactive-table.component.ts +4 -6
  110. package/src/libs/ui/search/src/lib/results-table/results-table.component.html +23 -6
  111. package/src/libs/ui/search/src/lib/results-table/results-table.component.ts +6 -6
  112. package/src/libs/util/shared/src/lib/links/link-utils.ts +51 -1
  113. package/tailwind.base.config.js +2 -0
  114. package/translations/de.json +29 -6
  115. package/translations/en.json +13 -9
  116. package/translations/es.json +27 -4
  117. package/translations/fr.json +13 -9
  118. package/translations/it.json +243 -218
  119. package/translations/nl.json +27 -4
  120. package/translations/pt.json +27 -4
  121. package/translations/sk.json +27 -4
@@ -32,11 +32,10 @@ import {
32
32
  SortableListComponent,
33
33
  } from '../../../../../../../../../libs/ui/layout/src'
34
34
  import { TranslateModule, TranslateService } from '@ngx-translate/core'
35
- import { map, Subscription } from 'rxjs'
35
+ import { Subscription } from 'rxjs'
36
36
  import { MAX_UPLOAD_SIZE_MB } from '../../../../fields.config'
37
37
  import { OnlineResourceCardComponent } from '../../../online-resource-card/online-resource-card.component'
38
38
  import { OnlineServiceResourceInputComponent } from '../../../online-service-resource-input/online-service-resource-input.component'
39
- import { EditorFacade } from '../../../../+state/editor.facade'
40
39
 
41
40
  type OnlineNotLinkResource =
42
41
  | DatasetDownloadDistribution
@@ -93,25 +92,21 @@ export class FormFieldOnlineResourcesComponent {
93
92
  notLinkResources: OnlineNotLinkResource[] = []
94
93
  uploadProgress = undefined
95
94
  uploadSubscription: Subscription = null
96
- newService = {
95
+ newService = <DatasetServiceDistribution>{
97
96
  type: 'service',
98
97
  accessServiceProtocol: 'ogcFeatures',
99
98
  identifierInService: '',
100
- } as Omit<DatasetServiceDistribution, 'url'>
99
+ url: undefined,
100
+ }
101
101
 
102
102
  protected MAX_UPLOAD_SIZE_MB = MAX_UPLOAD_SIZE_MB
103
103
 
104
- disabled$ = this.editorFacade.alreadySavedOnce$.pipe(
105
- map((alreadySavedOnce) => !alreadySavedOnce)
106
- )
107
-
108
104
  constructor(
109
105
  private notificationsService: NotificationsService,
110
106
  private translateService: TranslateService,
111
107
  private platformService: PlatformServiceInterface,
112
108
  private cd: ChangeDetectorRef,
113
- private dialog: MatDialog,
114
- private editorFacade: EditorFacade
109
+ private dialog: MatDialog
115
110
  ) {}
116
111
 
117
112
  onSelectedTypeChange(selectedType: unknown) {
@@ -9,14 +9,5 @@
9
9
  (delete)="handleDelete()"
10
10
  [uploadProgress]="uploadProgress"
11
11
  (uploadCancel)="handleUploadCancel()"
12
- [disabled]="disabled$ | async"
13
12
  ></gn-ui-image-input>
14
- <div
15
- *ngIf="disabled$ | async"
16
- class="p-4 text-sm border border-primary bg-primary-lightest rounded-lg"
17
- translate
18
- data-test="disabled-message"
19
- >
20
- editor.record.form.field.draft.only.disabled
21
- </div>
22
13
  </div>
@@ -12,9 +12,8 @@ import { ImageInputComponent } from '../../../../../../../../../libs/ui/elements
12
12
  import { PlatformServiceInterface } from '../../../../../../../../../libs/common/domain/src/lib/platform.service.interface'
13
13
  import { NotificationsService } from '../../../../../../../../../libs/feature/notifications/src'
14
14
  import { TranslateModule, TranslateService } from '@ngx-translate/core'
15
- import { map, Subscription } from 'rxjs'
15
+ import { Subscription } from 'rxjs'
16
16
  import { MAX_UPLOAD_SIZE_MB } from '../../../../fields.config'
17
- import { EditorFacade } from '../../../../+state/editor.facade'
18
17
 
19
18
  @Component({
20
19
  selector: 'gn-ui-form-field-overviews',
@@ -30,10 +29,6 @@ export class FormFieldOverviewsComponent {
30
29
  @Output() valueChange: EventEmitter<Array<GraphicOverview>> =
31
30
  new EventEmitter()
32
31
 
33
- disabled$ = this.editorFacade.alreadySavedOnce$.pipe(
34
- map((alreadySavedOnce) => !alreadySavedOnce)
35
- )
36
-
37
32
  uploadProgress = undefined
38
33
  uploadSubscription: Subscription = null
39
34
 
@@ -52,8 +47,7 @@ export class FormFieldOverviewsComponent {
52
47
  private platformService: PlatformServiceInterface,
53
48
  private notificationsService: NotificationsService,
54
49
  private translateService: TranslateService,
55
- private cd: ChangeDetectorRef,
56
- private editorFacade: EditorFacade
50
+ private cd: ChangeDetectorRef
57
51
  ) {}
58
52
 
59
53
  handleFileChange(file: File) {
@@ -112,8 +112,8 @@
112
112
  <ng-container *ngSwitchCase="'licenses'">
113
113
  <gn-ui-form-field-license
114
114
  [label]="config.labelKey! | translate"
115
- [recordConstraints]="valueAsConstraints"
116
- (recordConstraintsChange)="valueChange.emit($event)"
115
+ [recordLicences]="valueAsConstraints"
116
+ (recordLicencesChange)="valueChange.emit($event)"
117
117
  ></gn-ui-form-field-license>
118
118
  </ng-container>
119
119
 
@@ -1,5 +1,5 @@
1
1
  import { Injectable } from '@angular/core'
2
- import { Observable, switchMap } from 'rxjs'
2
+ import { forkJoin, Observable, of, switchMap } from 'rxjs'
3
3
  import { map, tap } from 'rxjs/operators'
4
4
  import { CatalogRecord } from '../../../../../../libs/common/domain/src/lib/model/record'
5
5
  import { EditorConfig } from '../models/'
@@ -16,8 +16,7 @@ export class EditorService {
16
16
  saveRecord(
17
17
  record: CatalogRecord,
18
18
  recordSource: string,
19
- fieldsConfig: EditorConfig,
20
- generateNewUniqueIdentifier = false
19
+ fieldsConfig: EditorConfig
21
20
  ): Observable<[CatalogRecord, string]> {
22
21
  const savedRecord = { ...record }
23
22
 
@@ -35,22 +34,25 @@ export class EditorService {
35
34
  })
36
35
  }
37
36
  }
38
-
39
- // if we want a new unique identifier, clear the existing one
40
- if (generateNewUniqueIdentifier) {
37
+ let publishToAll = true
38
+ // if the record is new, generate a new unique identifier and pass publishToAll as false
39
+ if (!record.uniqueIdentifier) {
41
40
  savedRecord.uniqueIdentifier = null
41
+ publishToAll = false
42
42
  }
43
43
 
44
- return this.recordsRepository.saveRecord(savedRecord, recordSource).pipe(
45
- switchMap((uniqueIdentifier) =>
46
- this.recordsRepository.openRecordForEdition(uniqueIdentifier)
47
- ),
48
- tap(() => {
49
- // if saving was successful, the original draft can be discarded
50
- this.recordsRepository.clearRecordDraft(record.uniqueIdentifier)
51
- }),
52
- map(([record, recordSource]) => [record, recordSource])
53
- )
44
+ return this.recordsRepository
45
+ .saveRecord(savedRecord, recordSource, publishToAll)
46
+ .pipe(
47
+ switchMap((uniqueIdentifier) =>
48
+ this.recordsRepository.openRecordForEdition(uniqueIdentifier)
49
+ ),
50
+ tap(() => {
51
+ // if saving was successful, the original draft can be discarded
52
+ this.recordsRepository.clearRecordDraft(record.uniqueIdentifier)
53
+ }),
54
+ map(([record, recordSource]) => [record, recordSource])
55
+ )
54
56
  }
55
57
 
56
58
  // emits and completes once saving is done
@@ -4,7 +4,6 @@
4
4
  [hasDraft]="hasDraft"
5
5
  [selectedRecordsIdentifiers]="selectedRecords$ | async"
6
6
  [sortOrder]="sortBy$ | async"
7
- [isUnsavedDraft]="isUnsavedDraft"
8
7
  [canDelete]="canDelete"
9
8
  [canDuplicate]="canDuplicate"
10
9
  (recordClick)="handleRecordClick($event)"
@@ -38,9 +38,6 @@ export class ResultsTableContainerComponent implements OnDestroy {
38
38
  hasDraft = (record: CatalogRecord): boolean =>
39
39
  this.recordsRepository.recordHasDraft(record.uniqueIdentifier)
40
40
 
41
- isUnsavedDraft = (record: CatalogRecord): boolean =>
42
- this.recordsRepository.isRecordNotYetSaved(record.uniqueIdentifier)
43
-
44
41
  constructor(
45
42
  protected searchFacade: SearchFacade,
46
43
  private searchService: SearchService,
@@ -10,6 +10,7 @@
10
10
  "
11
11
  >
12
12
  <div
13
+ data-test="icon-container"
13
14
  class="{{ bgClass }} {{
14
15
  textClass
15
16
  }} text-[1.875em] rounded-full mr-[0.55em] flex justify-center items-center w-[2.2em] h-[2.2em] shrink-0"
@@ -48,10 +48,10 @@ import { iconoirCloudUpload, iconoirFramePlusIn } from '@ng-icons/iconoir'
48
48
  export class FileInputComponent {
49
49
  @Input() maxSizeMB: number
50
50
  @Input() uploadProgress?: number
51
- @Input() disabled? = false
52
51
  @Output() fileChange: EventEmitter<File> = new EventEmitter()
53
52
  @Output() urlChange: EventEmitter<string> = new EventEmitter()
54
53
  @Output() uploadCancel: EventEmitter<void> = new EventEmitter()
54
+ @Input() disabled? = false
55
55
 
56
56
  dragFilesOver = false
57
57
 
@@ -31,6 +31,11 @@
31
31
  *ngFor="let item of items"
32
32
  (click)="handleRowClick(item)"
33
33
  data-cy="table-row"
34
+ [title]="
35
+ !item.extras?.edit && !isDraftPage
36
+ ? ('editor.record.lock.reason' | translate)
37
+ : ''
38
+ "
34
39
  >
35
40
  <div
36
41
  class="relative h-0"
@@ -44,7 +49,13 @@
44
49
  </div>
45
50
  <ng-container *ngFor="let column of columns">
46
51
  <div
47
- class="table-row-cell px-3 py-1.5 flex items-center bg-white transition-colors duration-75 truncate group-hover:text-main group-hover:bg-gray-50 border-b border-gray-200"
52
+ class="table-row-cell px-3 py-1.5 flex items-center bg-white transition-colors duration-75 truncate border-b border-gray-200"
53
+ [ngClass]="{
54
+ 'text-purple-light cursor-default':
55
+ !item.extras?.edit && !isDraftPage,
56
+ 'group-hover:text-main group-hover:bg-gray-50':
57
+ item.extras?.edit || isDraftPage,
58
+ }"
48
59
  >
49
60
  <ng-container
50
61
  *ngTemplateOutlet="column.cell; context: { $implicit: item }"
@@ -9,12 +9,9 @@ import {
9
9
  } from '@angular/core'
10
10
  import { InteractiveTableColumnComponent } from './interactive-table-column/interactive-table-column.component'
11
11
  import { CommonModule } from '@angular/common'
12
- import {
13
- NgIconComponent,
14
- provideIcons,
15
- provideNgIconsConfig,
16
- } from '@ng-icons/core'
12
+ import { NgIconComponent, provideIcons } from '@ng-icons/core'
17
13
  import { iconoirNavArrowDown, iconoirNavArrowUp } from '@ng-icons/iconoir'
14
+ import { TranslateModule } from '@ngx-translate/core'
18
15
 
19
16
  @Component({
20
17
  selector: 'gn-ui-interactive-table',
@@ -22,7 +19,7 @@ import { iconoirNavArrowDown, iconoirNavArrowUp } from '@ng-icons/iconoir'
22
19
  styleUrls: ['./interactive-table.component.css'],
23
20
  changeDetection: ChangeDetectionStrategy.OnPush,
24
21
  standalone: true,
25
- imports: [CommonModule, InteractiveTableColumnComponent, NgIconComponent],
22
+ imports: [CommonModule, NgIconComponent, TranslateModule],
26
23
  providers: [provideIcons({ iconoirNavArrowDown, iconoirNavArrowUp })],
27
24
  })
28
25
  export class InteractiveTableComponent {
@@ -30,6 +27,7 @@ export class InteractiveTableComponent {
30
27
  columns: QueryList<InteractiveTableColumnComponent>
31
28
 
32
29
  @Input() items: unknown[] = []
30
+ @Input() isDraftPage = false
33
31
  @Output() itemClick = new EventEmitter<unknown>()
34
32
 
35
33
  get gridStyle() {
@@ -1,11 +1,18 @@
1
1
  <gn-ui-interactive-table
2
2
  [items]="records"
3
+ [isDraftPage]="isDraftPage"
3
4
  (itemClick)="handleRecordClick($event)"
4
5
  >
5
6
  <!-- SELECTED COLUMN -->
6
7
  <gn-ui-interactive-table-column [width]="'3rem'">
7
- <ng-template #cell let-item>
8
+ <ng-template #cell let-item let-i="index">
9
+ <ng-icon
10
+ name="iconoirLock"
11
+ class="text-purple"
12
+ *ngIf="!item.extras?.edit && !isDraftPage"
13
+ ></ng-icon>
8
14
  <gn-ui-checkbox
15
+ *ngIf="item.extras?.edit || isDraftPage"
9
16
  [checked]="isChecked(item)"
10
17
  (changed)="handleRecordSelectedChange($event, item)"
11
18
  class="-m-2"
@@ -102,9 +109,9 @@
102
109
  <ng-template #cell let-item>
103
110
  <span class="text-xs">
104
111
  {{
105
- (isUnsavedDraft(item)
106
- ? 'record.metadata.status.notPublished'
107
- : 'record.metadata.status.published'
112
+ (item.extras?.['isPublishedToAll']
113
+ ? 'record.metadata.status.published'
114
+ : 'record.metadata.status.notPublished'
108
115
  ) | translate
109
116
  }}</span
110
117
  >
@@ -123,7 +130,11 @@
123
130
  </ng-template>
124
131
  <ng-template #cell let-item>
125
132
  <div class="flex text-left w-full text-xs">
126
- {{ isUnsavedDraft(item) ? '-' : dateToString(item.recordUpdated) }}
133
+ {{
134
+ item.extras?.['isPublishedToAll']
135
+ ? dateToString(item.recordUpdated)
136
+ : '-'
137
+ }}
127
138
  </div>
128
139
  </ng-template>
129
140
  </gn-ui-interactive-table-column>
@@ -138,8 +149,14 @@
138
149
  (buttonClick)="openActionMenu(item, template)"
139
150
  type="light"
140
151
  data-test="record-menu-button"
152
+ [disabled]="!item.extras?.edit && !isDraftPage"
141
153
  >
142
- <ng-icon name="matMoreVert"></ng-icon>
154
+ <ng-icon
155
+ [ngClass]="{
156
+ 'text-purple-light': !item.extras?.edit && !isDraftPage,
157
+ }"
158
+ name="matMoreVert"
159
+ ></ng-icon>
143
160
  </gn-ui-button>
144
161
  <ng-template #template>
145
162
  <gn-ui-action-menu
@@ -30,7 +30,7 @@ import {
30
30
  import { TranslateModule } from '@ngx-translate/core'
31
31
  import { ActionMenuComponent } from './action-menu/action-menu.component'
32
32
  import { NgIconComponent, provideIcons } from '@ng-icons/core'
33
- import { iconoirUser } from '@ng-icons/iconoir'
33
+ import { iconoirUser, iconoirLock } from '@ng-icons/iconoir'
34
34
  import {
35
35
  CdkConnectedOverlay,
36
36
  CdkOverlayOrigin,
@@ -55,9 +55,8 @@ import { matMoreVert } from '@ng-icons/material-icons/baseline'
55
55
  ActionMenuComponent,
56
56
  NgIconComponent,
57
57
  CdkOverlayOrigin,
58
- CdkConnectedOverlay,
59
58
  ],
60
- providers: [provideIcons({ iconoirUser, matMoreVert })],
59
+ providers: [provideIcons({ iconoirUser, iconoirLock, matMoreVert })],
61
60
  })
62
61
  export class ResultsTableComponent {
63
62
  @Input() records: CatalogRecord[] = []
@@ -65,8 +64,8 @@ export class ResultsTableComponent {
65
64
  @Input() sortOrder: SortByField = null
66
65
  @Input() hasDraft: (record: CatalogRecord) => boolean = () => false
67
66
  @Input() canDuplicate: (record: CatalogRecord) => boolean = () => true
68
- @Input() isUnsavedDraft: (record: CatalogRecord) => boolean = () => true
69
67
  @Input() canDelete: (record: CatalogRecord) => boolean = () => true
68
+ @Input() isDraftPage = false
70
69
 
71
70
  // emits the column (field) as well as the order
72
71
  @Output() sortByChange = new EventEmitter<[string, 'asc' | 'desc']>()
@@ -170,8 +169,9 @@ export class ResultsTableComponent {
170
169
  return getBadgeColor(format)
171
170
  }
172
171
 
173
- handleRecordClick(item: unknown) {
174
- this.recordClick.emit(item as CatalogRecord)
172
+ handleRecordClick(item: CatalogRecord) {
173
+ if (item?.extras?.edit || this.isDraftPage)
174
+ this.recordClick.emit(item as CatalogRecord)
175
175
  }
176
176
 
177
177
  handleDuplicate(item: unknown) {
@@ -1,5 +1,14 @@
1
1
  import { marker } from '@biesbjerg/ngx-translate-extract-marker'
2
- import { DatasetOnlineResource } from '../../../../../../libs/common/domain/src/lib/model/record'
2
+ import {
3
+ DatasetOnlineResource,
4
+ ServiceProtocol,
5
+ } from '../../../../../../libs/common/domain/src/lib/model/record'
6
+ import {
7
+ OgcApiEndpoint,
8
+ WfsEndpoint,
9
+ WmsEndpoint,
10
+ WmtsEndpoint,
11
+ } from '@camptocamp/ogc-client'
3
12
 
4
13
  marker('downloads.wfs.featuretype.not.found')
5
14
 
@@ -242,6 +251,47 @@ export function getLinkLabel(link: DatasetOnlineResource): string {
242
251
  return format ? `${label} (${format})` : label
243
252
  }
244
253
 
254
+ export async function getLayers(url: string, serviceProtocol: ServiceProtocol) {
255
+ switch (serviceProtocol) {
256
+ case 'ogcFeatures': {
257
+ const layers = await new OgcApiEndpoint(url).allCollections
258
+ return layers
259
+ }
260
+ case 'wfs': {
261
+ const endpointWfs = new WfsEndpoint(url)
262
+ await endpointWfs.isReady()
263
+ return endpointWfs.getFeatureTypes()
264
+ }
265
+ case 'wms': {
266
+ const endpointWms = new WmsEndpoint(url)
267
+ await endpointWms.isReady()
268
+ return endpointWms
269
+ .getLayers()
270
+ .flatMap(wmsLayerFlatten)
271
+ .filter((l) => l.name)
272
+ }
273
+ case 'wmts': {
274
+ const endpointWmts = new WmtsEndpoint(url)
275
+ await endpointWmts.isReady()
276
+ return endpointWmts.getLayers()
277
+ }
278
+ default:
279
+ return undefined
280
+ }
281
+ }
282
+
283
+ function wmsLayerFlatten(layerFull) {
284
+ const layer = {
285
+ title: layerFull.title,
286
+ name: layerFull.name,
287
+ abstract: layerFull.abstract,
288
+ }
289
+
290
+ return 'children' in layerFull && Array.isArray(layerFull.children)
291
+ ? [layer, ...layerFull.children.flatMap(wmsLayerFlatten)]
292
+ : [layer]
293
+ }
294
+
245
295
  export function getMimeTypeForFormat(format: FileFormat): string | null {
246
296
  return format in FORMATS ? FORMATS[format.toLowerCase()].mimeTypes[0] : null
247
297
  }
@@ -44,6 +44,8 @@ module.exports = {
44
44
  800: '#8a2c0d',
45
45
  900: '#73230d',
46
46
  },
47
+ purple: '#9747FF',
48
+ 'purple-light': '#DDC3FF',
47
49
  },
48
50
  fontFamily: {
49
51
  sans: 'var(--font-family-main, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji")',
@@ -139,6 +139,7 @@
139
139
  "datahub.search.back": "Zurück",
140
140
  "datahub.search.filter.all": "Alle",
141
141
  "datahub.search.filter.generatedByAPI": "Generiert durch eine API",
142
+ "datahub.search.filter.generatedByWfs": "",
142
143
  "datahub.search.filter.others": "Andere",
143
144
  "dataset.error.http": "Die Daten konnten aufgrund eines HTTP-Fehlers nicht geladen werden: \"{ info }\"",
144
145
  "dataset.error.network": "Die Daten konnten aufgrund eines Netzwerkfehlers oder CORS-Beschränkungen nicht geladen werden: \"{ info }\"",
@@ -204,6 +205,9 @@
204
205
  "editor.record.deleteError.title": "Fehler beim Löschen des Datensatzes",
205
206
  "editor.record.deleteSuccess.body": "",
206
207
  "editor.record.deleteSuccess.title": "",
208
+ "editor.record.error.back": "",
209
+ "editor.record.error.explanation": "",
210
+ "editor.record.error.message": "",
207
211
  "editor.record.form.bottomButtons.comeBackLater": "",
208
212
  "editor.record.form.bottomButtons.next": "",
209
213
  "editor.record.form.bottomButtons.previous": "",
@@ -225,7 +229,6 @@
225
229
  "editor.record.form.field.constraintsShortcuts": "",
226
230
  "editor.record.form.field.contacts.noContact": "",
227
231
  "editor.record.form.field.contactsForResource.noContact": "",
228
- "editor.record.form.field.draft.only.disabled": "Dieses Feld wird aktiviert, sobald die Daten veröffentlicht wurden.",
229
232
  "editor.record.form.field.keywords": "Schlagwörter",
230
233
  "editor.record.form.field.legalConstraints": "Rechtliche Einschränkung",
231
234
  "editor.record.form.field.license": "Lizenz",
@@ -235,8 +238,10 @@
235
238
  "editor.record.form.field.onlineResource.dialogTitle": "",
236
239
  "editor.record.form.field.onlineResource.edit.description": "",
237
240
  "editor.record.form.field.onlineResource.edit.protocol": "",
241
+ "editor.record.form.field.onlineResource.edit.identifier.error": "Schichten konnten nicht vom Protokoll abgerufen werden",
238
242
  "editor.record.form.field.onlineResource.edit.identifier.placeholder": "Ebenenname",
239
243
  "editor.record.form.field.onlineResource.edit.identifier.placeholder.wps": "Prozessname",
244
+ "editor.record.form.field.onlineResource.edit.identifier.select.label": "Wählen Sie eine Ebene",
240
245
  "editor.record.form.field.onlineResource.edit.identifier.submit": "Link zum Dienst",
241
246
  "editor.record.form.field.onlineResource.edit.title": "",
242
247
  "editor.record.form.field.onlineResource.fileSize": "",
@@ -295,6 +300,7 @@
295
300
  "editor.record.loadError.body": "Der Datensatz konnte nicht geladen werden:",
296
301
  "editor.record.loadError.closeMessage": "Verstanden",
297
302
  "editor.record.loadError.title": "Fehler beim Laden des Datensatzes",
303
+ "editor.record.lock.reason": "",
298
304
  "editor.record.onlineResource.protocol.other": "",
299
305
  "editor.record.onlineResourceError.body": "",
300
306
  "editor.record.onlineResourceError.closeMessage": "",
@@ -315,9 +321,9 @@
315
321
  "editor.record.resourceError.body": "",
316
322
  "editor.record.resourceError.closeMessage": "",
317
323
  "editor.record.resourceError.title": "",
318
- "editor.record.saveStatus.asDraftOnly": "Nur als Entwurf gespeichert - noch nicht veröffentlicht",
319
- "editor.record.saveStatus.draftWithChangesPending": "Als Entwurf gespeichert - Änderungen stehen aus",
320
- "editor.record.saveStatus.recordUpToDate": "Datensatz ist auf dem neuesten Stand",
324
+ "editor.record.saveStatus.draftWithChangesPending": "Gespeichert - nicht publizierte Unterschiede",
325
+ "editor.record.saveStatus.recordNotPublished": "",
326
+ "editor.record.saveStatus.recordUpToDate": "Gespeichert - auf dem neuesten Stand",
321
327
  "editor.record.undo.confirmation.cancelText": "",
322
328
  "editor.record.undo.confirmation.confirmText": "",
323
329
  "editor.record.undo.confirmation.message": "",
@@ -421,14 +427,32 @@
421
427
  "record.metadata.api.form.closeButton": "Schließen",
422
428
  "record.metadata.api.form.closeForm": "Formular schließen",
423
429
  "record.metadata.api.form.create": "Ihre Anfrage erstellen",
430
+ "record.metadata.api.form.crsTitle": "",
431
+ "record.metadata.api.form.crsTooltip": "",
424
432
  "record.metadata.api.form.customUrl": "Benutzerdefinierte URL",
433
+ "record.metadata.api.form.filter": "",
434
+ "record.metadata.api.form.filterDescription": "",
435
+ "record.metadata.api.form.formatTitle": "",
436
+ "record.metadata.api.form.formatTooltip": "",
437
+ "record.metadata.api.form.items": "",
438
+ "record.metadata.api.form.itemsDescription": "",
439
+ "record.metadata.api.form.itemsTooltip": "",
425
440
  "record.metadata.api.form.limit": "Anzahl der Datensätze",
426
441
  "record.metadata.api.form.limit.all": "Alle",
442
+ "record.metadata.api.form.nextPage": "",
443
+ "record.metadata.api.form.nextPageTooltip": "",
427
444
  "record.metadata.api.form.offset": "Anzahl des ersten Datensatzes",
428
445
  "record.metadata.api.form.openForm": "Formular öffnen",
446
+ "record.metadata.api.form.paginationDescription": "",
447
+ "record.metadata.api.form.previousPage": "",
448
+ "record.metadata.api.form.previousPageTooltip": "",
449
+ "record.metadata.api.form.productTooltip": "",
429
450
  "record.metadata.api.form.reset": "Zurücksetzen",
430
- "record.metadata.api.form.title": "Benutzerdefinierte URL generieren",
451
+ "record.metadata.api.form.resetTooltip": "",
431
452
  "record.metadata.api.form.type": "Ausgabeformat",
453
+ "record.metadata.api.form.zoneTitle": "",
454
+ "record.metadata.api.form.zoneTooltip": "",
455
+ "record.metadata.api.gpfdl": "",
432
456
  "record.metadata.catalog": "Katalog",
433
457
  "record.metadata.contact": "Kontakt",
434
458
  "record.metadata.creation": "Erstellungsdatum",
@@ -493,7 +517,6 @@
493
517
  "record.tab.chart": "Diagramm",
494
518
  "record.tab.data": "Tabelle",
495
519
  "record.tab.map": "Karte",
496
- "record.was.created.time": "erstellte diesen Datensatz {time}",
497
520
  "records": "Datensätze",
498
521
  "results.layout.selectOne": "Layout auswählen",
499
522
  "results.records.hits.displayedOn": "{displayed, plural, =0{Kein Datensatz.} one{1 Datensatz} other{{displayed} Datensätze }} {hits, plural, other{angezeigt von {hits} insgesamt.}}",
@@ -139,6 +139,7 @@
139
139
  "datahub.search.back": "Back",
140
140
  "datahub.search.filter.all": "All",
141
141
  "datahub.search.filter.generatedByAPI": "Generated by an API",
142
+ "datahub.search.filter.generatedByWfs": "",
142
143
  "datahub.search.filter.others": "Others",
143
144
  "dataset.error.http": "The data could not be loaded because of an HTTP error: \"{ info }\"",
144
145
  "dataset.error.network": "The data could not be loaded because of a network error or CORS limitations: \"{ info }\"",
@@ -204,6 +205,9 @@
204
205
  "editor.record.deleteError.title": "Error deleting dataset",
205
206
  "editor.record.deleteSuccess.body": "The dataset was successfully deleted!",
206
207
  "editor.record.deleteSuccess.title": "Delete success",
208
+ "editor.record.error.back": "Go back to the catalog",
209
+ "editor.record.error.explanation": "You might not have access to this record,<br> Or this link might not be valid.",
210
+ "editor.record.error.message": "Something went wrong",
207
211
  "editor.record.form.bottomButtons.comeBackLater": "Come back later",
208
212
  "editor.record.form.bottomButtons.next": "Next",
209
213
  "editor.record.form.bottomButtons.previous": "Previous",
@@ -225,7 +229,6 @@
225
229
  "editor.record.form.field.constraintsShortcuts": "",
226
230
  "editor.record.form.field.contacts.noContact": "Please provide at least one point of contact.",
227
231
  "editor.record.form.field.contactsForResource.noContact": "Please provide at least one point of contact responsible for the data.",
228
- "editor.record.form.field.draft.only.disabled": "This field will be enabled once the dataset has been published",
229
232
  "editor.record.form.field.keywords": "Keywords",
230
233
  "editor.record.form.field.legalConstraints": "Legal constraint",
231
234
  "editor.record.form.field.license": "License",
@@ -235,8 +238,10 @@
235
238
  "editor.record.form.field.onlineResource.dialogTitle": "Modify the dataset preview",
236
239
  "editor.record.form.field.onlineResource.edit.description": "Description",
237
240
  "editor.record.form.field.onlineResource.edit.protocol": "Protocol",
241
+ "editor.record.form.field.onlineResource.edit.identifier.error": "Unable to retrieve layers from protocol",
238
242
  "editor.record.form.field.onlineResource.edit.identifier.placeholder": "Layer name",
239
243
  "editor.record.form.field.onlineResource.edit.identifier.placeholder.wps": "Process name",
244
+ "editor.record.form.field.onlineResource.edit.identifier.select.label": "Select a layer",
240
245
  "editor.record.form.field.onlineResource.edit.identifier.submit": "Link to the service",
241
246
  "editor.record.form.field.onlineResource.edit.title": "Title",
242
247
  "editor.record.form.field.onlineResource.fileSize": "{sizeMB}MB",
@@ -295,6 +300,7 @@
295
300
  "editor.record.loadError.body": "The dataset could not be loaded:",
296
301
  "editor.record.loadError.closeMessage": "Understood",
297
302
  "editor.record.loadError.title": "Error loading dataset",
303
+ "editor.record.lock.reason": "You are not an editor of the allowed groups",
298
304
  "editor.record.onlineResource.protocol.other": "Other",
299
305
  "editor.record.onlineResourceError.body": "An error happened while adding the resource:",
300
306
  "editor.record.onlineResourceError.closeMessage": "Understood",
@@ -315,9 +321,9 @@
315
321
  "editor.record.resourceError.body": "There was an issue with the dataset attachments:",
316
322
  "editor.record.resourceError.closeMessage": "Understood",
317
323
  "editor.record.resourceError.title": "Error with the dataset attachments",
318
- "editor.record.saveStatus.asDraftOnly": "Saved as draft only - not published yet",
319
- "editor.record.saveStatus.draftWithChangesPending": "Saved as draft - changes are pending",
320
- "editor.record.saveStatus.recordUpToDate": "Dataset is up to date",
324
+ "editor.record.saveStatus.draftWithChangesPending": "Saved - Unpublished differences",
325
+ "editor.record.saveStatus.recordNotPublished": "Saved - not published",
326
+ "editor.record.saveStatus.recordUpToDate": "Saved - Record up to date",
321
327
  "editor.record.undo.confirmation.cancelText": "Keep the changes",
322
328
  "editor.record.undo.confirmation.confirmText": "Discard the changes",
323
329
  "editor.record.undo.confirmation.message": "Are you sure you want to cancel the pending changes on this dataset ?",
@@ -421,13 +427,13 @@
421
427
  "record.metadata.api.form.closeButton": "Close",
422
428
  "record.metadata.api.form.closeForm": "Close the form",
423
429
  "record.metadata.api.form.create": "Create your request",
430
+ "record.metadata.api.form.crsTitle": "Coordinate System",
431
+ "record.metadata.api.form.crsTooltip": "Dropdown for selecting a coordinate reference system",
424
432
  "record.metadata.api.form.customUrl": "Custom URL",
425
433
  "record.metadata.api.form.filter": "Filters",
426
434
  "record.metadata.api.form.filterDescription": "Section for refining displayed elements",
427
435
  "record.metadata.api.form.formatTitle": "Format",
428
436
  "record.metadata.api.form.formatTooltip": "Dropdown for selecting a element format",
429
- "record.metadata.api.form.crsTitle": "Coordinate System",
430
- "record.metadata.api.form.crsTooltip": "Dropdown for selecting a coordinate reference system",
431
437
  "record.metadata.api.form.items": "Available Items",
432
438
  "record.metadata.api.form.itemsDescription": "List of items",
433
439
  "record.metadata.api.form.itemsTooltip": "Scroll to view all available items",
@@ -440,10 +446,9 @@
440
446
  "record.metadata.api.form.paginationDescription": "Pagination of displayed items",
441
447
  "record.metadata.api.form.previousPage": "Previous",
442
448
  "record.metadata.api.form.previousPageTooltip": "Go to the previous page",
449
+ "record.metadata.api.form.productTooltip": "",
443
450
  "record.metadata.api.form.reset": "Reset",
444
451
  "record.metadata.api.form.resetTooltip": "Reset all filters",
445
- "record.metadata.api.form.title": "Generate a custom URL",
446
- "record.metadata.api.form.title.gpf": "Download data",
447
452
  "record.metadata.api.form.type": "Output format",
448
453
  "record.metadata.api.form.zoneTitle": "Zone",
449
454
  "record.metadata.api.form.zoneTooltip": "Dropdown for selecting a geographic zone",
@@ -512,7 +517,6 @@
512
517
  "record.tab.chart": "Chart",
513
518
  "record.tab.data": "Table",
514
519
  "record.tab.map": "Map",
515
- "record.was.created.time": "created this dataset {time}",
516
520
  "records": "datasets",
517
521
  "results.layout.selectOne": "Results layout",
518
522
  "results.records.hits.displayedOn": "{displayed, plural, =0{No dataset.} one{1 } other{{displayed} }} {hits, plural, other{displayed on {hits} total.}}",