geonetwork-ui 2.4.1-dev.7a0dc5e3f → 2.4.1-dev.89bb09dfa

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 (181) 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/metadata-converter/src/lib/iso19139/utils/update-frequency.mapper.mjs +6 -62
  5. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/write-parts.mjs +19 -1
  6. package/esm2022/libs/api/repository/src/lib/gn4/gn4-repository.mjs +27 -16
  7. package/esm2022/libs/common/domain/src/lib/model/record/metadata.model.mjs +27 -1
  8. package/esm2022/libs/common/domain/src/lib/repository/records-repository.interface.mjs +1 -1
  9. package/esm2022/libs/data-access/gn4/src/openapi/api/records.api.service.mjs +7 -1
  10. package/esm2022/libs/feature/editor/src/lib/+state/editor.actions.mjs +3 -1
  11. package/esm2022/libs/feature/editor/src/lib/+state/editor.effects.mjs +18 -14
  12. package/esm2022/libs/feature/editor/src/lib/+state/editor.facade.mjs +15 -5
  13. package/esm2022/libs/feature/editor/src/lib/+state/editor.reducer.mjs +10 -4
  14. package/esm2022/libs/feature/editor/src/lib/+state/editor.selectors.mjs +6 -5
  15. package/esm2022/libs/feature/editor/src/lib/components/constraint-card/constraint-card.component.mjs +3 -3
  16. package/esm2022/libs/feature/editor/src/lib/components/generic-keywords/generic-keywords.component.mjs +3 -3
  17. package/esm2022/libs/feature/editor/src/lib/components/import-record/import-record.component.mjs +2 -2
  18. package/esm2022/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.mjs +95 -12
  19. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.mjs +36 -23
  20. 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
  21. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-resources/form-field-online-resources.component.mjs +17 -12
  22. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.mjs +7 -13
  23. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-spatial-extent/form-field-spatial-extent.component.mjs +3 -3
  24. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.mjs +36 -60
  25. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.mjs +3 -3
  26. package/esm2022/libs/feature/editor/src/lib/components/record-form/record-form.component.mjs +3 -3
  27. package/esm2022/libs/feature/editor/src/lib/fields.config.mjs +11 -15
  28. package/esm2022/libs/feature/editor/src/lib/services/editor.service.mjs +9 -5
  29. package/esm2022/libs/feature/search/src/lib/results-table/results-table-container.component.mjs +3 -4
  30. package/esm2022/libs/ui/dataviz/src/lib/figure/figure.component.mjs +3 -3
  31. package/esm2022/libs/ui/elements/src/index.mjs +3 -2
  32. package/esm2022/libs/ui/elements/src/lib/image-input/image-input.component.mjs +213 -0
  33. package/esm2022/libs/ui/elements/src/lib/ui-elements.module.mjs +19 -13
  34. package/esm2022/libs/ui/inputs/src/index.mjs +5 -6
  35. package/esm2022/libs/ui/inputs/src/lib/button/button.component.mjs +2 -1
  36. package/esm2022/libs/ui/inputs/src/lib/file-input/file-input.component.mjs +5 -5
  37. package/esm2022/libs/ui/inputs/src/lib/ui-inputs.module.mjs +19 -25
  38. package/esm2022/libs/ui/inputs/src/lib/url-input/url-input.component.mjs +6 -6
  39. package/esm2022/libs/ui/layout/src/lib/interactive-table/interactive-table.component.mjs +9 -4
  40. package/esm2022/libs/ui/search/src/lib/results-table/results-table.component.mjs +10 -10
  41. package/esm2022/libs/util/shared/src/lib/links/link-utils.mjs +40 -1
  42. package/esm2022/translations/de.json +52 -17
  43. package/esm2022/translations/en.json +32 -16
  44. package/esm2022/translations/es.json +50 -15
  45. package/esm2022/translations/fr.json +36 -20
  46. package/esm2022/translations/it.json +265 -228
  47. package/esm2022/translations/nl.json +50 -15
  48. package/esm2022/translations/pt.json +50 -15
  49. package/fesm2022/geonetwork-ui.mjs +1774 -1420
  50. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  51. package/libs/api/metadata-converter/src/lib/gn4/gn4.converter.d.ts.map +1 -1
  52. package/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.d.ts.map +1 -1
  53. package/libs/api/metadata-converter/src/lib/gn4/types/metadata.model.d.ts +1 -0
  54. package/libs/api/metadata-converter/src/lib/gn4/types/metadata.model.d.ts.map +1 -1
  55. package/libs/api/metadata-converter/src/lib/iso19139/utils/update-frequency.mapper.d.ts.map +1 -1
  56. package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts.map +1 -1
  57. package/libs/api/repository/src/lib/gn4/gn4-repository.d.ts +4 -3
  58. package/libs/api/repository/src/lib/gn4/gn4-repository.d.ts.map +1 -1
  59. package/libs/common/domain/src/lib/model/record/metadata.model.d.ts +2 -1
  60. package/libs/common/domain/src/lib/model/record/metadata.model.d.ts.map +1 -1
  61. package/libs/common/domain/src/lib/repository/records-repository.interface.d.ts +4 -3
  62. package/libs/common/domain/src/lib/repository/records-repository.interface.d.ts.map +1 -1
  63. package/libs/data-access/gn4/src/openapi/api/records.api.service.d.ts +3 -0
  64. package/libs/data-access/gn4/src/openapi/api/records.api.service.d.ts.map +1 -1
  65. package/libs/feature/editor/src/lib/+state/editor.actions.d.ts +10 -2
  66. package/libs/feature/editor/src/lib/+state/editor.actions.d.ts.map +1 -1
  67. package/libs/feature/editor/src/lib/+state/editor.effects.d.ts +6 -2
  68. package/libs/feature/editor/src/lib/+state/editor.effects.d.ts.map +1 -1
  69. package/libs/feature/editor/src/lib/+state/editor.facade.d.ts +5 -2
  70. package/libs/feature/editor/src/lib/+state/editor.facade.d.ts.map +1 -1
  71. package/libs/feature/editor/src/lib/+state/editor.reducer.d.ts +2 -1
  72. package/libs/feature/editor/src/lib/+state/editor.reducer.d.ts.map +1 -1
  73. package/libs/feature/editor/src/lib/+state/editor.selectors.d.ts +2 -1
  74. package/libs/feature/editor/src/lib/+state/editor.selectors.d.ts.map +1 -1
  75. package/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.d.ts +24 -4
  76. package/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.d.ts.map +1 -1
  77. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.d.ts +4 -4
  78. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.d.ts.map +1 -1
  79. 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
  80. 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
  81. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-resources/form-field-online-resources.component.d.ts +6 -5
  82. 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
  83. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.d.ts +1 -4
  84. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.d.ts.map +1 -1
  85. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.d.ts +1 -1
  86. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.d.ts.map +1 -1
  87. package/libs/feature/editor/src/lib/fields.config.d.ts.map +1 -1
  88. package/libs/feature/editor/src/lib/services/editor.service.d.ts +1 -1
  89. package/libs/feature/editor/src/lib/services/editor.service.d.ts.map +1 -1
  90. package/libs/feature/search/src/lib/results-table/results-table-container.component.d.ts +0 -1
  91. package/libs/feature/search/src/lib/results-table/results-table-container.component.d.ts.map +1 -1
  92. package/libs/ui/elements/src/index.d.ts +2 -1
  93. package/libs/ui/elements/src/index.d.ts.map +1 -1
  94. package/libs/ui/elements/src/lib/image-input/image-input.component.d.ts.map +1 -0
  95. package/libs/ui/elements/src/lib/record-api-form/record-api-form.component.d.ts +1 -1
  96. package/libs/ui/elements/src/lib/ui-elements.module.d.ts +2 -1
  97. package/libs/ui/elements/src/lib/ui-elements.module.d.ts.map +1 -1
  98. package/libs/ui/inputs/src/index.d.ts +4 -5
  99. package/libs/ui/inputs/src/index.d.ts.map +1 -1
  100. package/libs/ui/inputs/src/lib/button/button.component.d.ts +1 -1
  101. package/libs/ui/inputs/src/lib/button/button.component.d.ts.map +1 -1
  102. package/libs/ui/inputs/src/lib/file-input/file-input.component.d.ts +1 -1
  103. package/libs/ui/inputs/src/lib/file-input/file-input.component.d.ts.map +1 -1
  104. package/libs/ui/inputs/src/lib/ui-inputs.module.d.ts +6 -7
  105. package/libs/ui/inputs/src/lib/ui-inputs.module.d.ts.map +1 -1
  106. package/libs/ui/inputs/src/lib/url-input/url-input.component.d.ts +2 -2
  107. package/libs/ui/inputs/src/lib/url-input/url-input.component.d.ts.map +1 -1
  108. package/libs/ui/layout/src/lib/interactive-table/interactive-table.component.d.ts +2 -1
  109. package/libs/ui/layout/src/lib/interactive-table/interactive-table.component.d.ts.map +1 -1
  110. package/libs/ui/search/src/lib/results-table/results-table.component.d.ts +3 -3
  111. package/libs/ui/search/src/lib/results-table/results-table.component.d.ts.map +1 -1
  112. package/libs/util/shared/src/lib/links/link-utils.d.ts +2 -1
  113. package/libs/util/shared/src/lib/links/link-utils.d.ts.map +1 -1
  114. package/package.json +1 -1
  115. package/src/libs/api/metadata-converter/src/lib/gn4/gn4.converter.ts +4 -3
  116. package/src/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts +8 -1
  117. package/src/libs/api/metadata-converter/src/lib/gn4/types/metadata.model.ts +1 -0
  118. package/src/libs/api/metadata-converter/src/lib/iso19139/utils/update-frequency.mapper.ts +9 -62
  119. package/src/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts +18 -0
  120. package/src/libs/api/repository/src/lib/gn4/gn4-repository.ts +53 -27
  121. package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +29 -7
  122. package/src/libs/common/domain/src/lib/repository/records-repository.interface.ts +5 -4
  123. package/src/libs/common/fixtures/src/lib/elasticsearch/full-response.fixtures.ts +2 -2
  124. package/src/libs/common/fixtures/src/lib/elasticsearch/search-responses.fixtures.ts +16 -16
  125. package/src/libs/common/fixtures/src/lib/records.fixtures.ts +163 -0
  126. package/src/libs/data-access/gn4/src/openapi/api/records.api.service.ts +24 -4
  127. package/src/libs/feature/editor/src/lib/+state/editor.actions.ts +10 -1
  128. package/src/libs/feature/editor/src/lib/+state/editor.effects.ts +57 -31
  129. package/src/libs/feature/editor/src/lib/+state/editor.facade.ts +15 -9
  130. package/src/libs/feature/editor/src/lib/+state/editor.reducer.ts +18 -12
  131. package/src/libs/feature/editor/src/lib/+state/editor.selectors.ts +13 -8
  132. package/src/libs/feature/editor/src/lib/components/constraint-card/constraint-card.component.html +1 -1
  133. package/src/libs/feature/editor/src/lib/components/generic-keywords/generic-keywords.component.html +1 -1
  134. package/src/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.html +62 -6
  135. package/src/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.ts +108 -4
  136. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.html +1 -1
  137. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.ts +31 -19
  138. 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
  139. 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
  140. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-resources/form-field-online-resources.component.html +12 -25
  141. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-resources/form-field-online-resources.component.ts +15 -10
  142. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.html +0 -9
  143. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.ts +3 -9
  144. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-spatial-extent/form-field-spatial-extent.component.html +6 -6
  145. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.ts +46 -74
  146. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html +3 -3
  147. package/src/libs/feature/editor/src/lib/components/record-form/record-form.component.html +3 -6
  148. package/src/libs/feature/editor/src/lib/fields.config.ts +10 -14
  149. package/src/libs/feature/editor/src/lib/services/editor.service.ts +18 -16
  150. package/src/libs/feature/search/src/lib/results-table/results-table-container.component.html +0 -1
  151. package/src/libs/feature/search/src/lib/results-table/results-table-container.component.ts +0 -3
  152. package/src/libs/ui/dataviz/src/lib/figure/figure.component.html +1 -0
  153. package/src/libs/ui/elements/src/index.ts +2 -1
  154. package/src/libs/ui/{inputs → elements}/src/lib/image-input/image-input.component.html +4 -19
  155. package/src/libs/ui/{inputs → elements}/src/lib/image-input/image-input.component.ts +13 -9
  156. package/src/libs/ui/elements/src/lib/ui-elements.module.ts +13 -10
  157. package/src/libs/ui/inputs/src/index.ts +4 -5
  158. package/src/libs/ui/inputs/src/lib/button/button.component.ts +2 -1
  159. package/src/libs/ui/inputs/src/lib/file-input/file-input.component.ts +1 -1
  160. package/src/libs/ui/inputs/src/lib/ui-inputs.module.ts +22 -25
  161. package/src/libs/ui/inputs/src/lib/url-input/url-input.component.html +5 -3
  162. package/src/libs/ui/inputs/src/lib/url-input/url-input.component.ts +1 -1
  163. package/src/libs/ui/layout/src/lib/interactive-table/interactive-table.component.html +12 -1
  164. package/src/libs/ui/layout/src/lib/interactive-table/interactive-table.component.ts +4 -6
  165. package/src/libs/ui/search/src/lib/results-table/results-table.component.html +23 -6
  166. package/src/libs/ui/search/src/lib/results-table/results-table.component.ts +6 -6
  167. package/src/libs/util/shared/src/lib/links/link-utils.ts +51 -1
  168. package/tailwind.base.config.js +2 -0
  169. package/translations/de.json +52 -17
  170. package/translations/en.json +32 -16
  171. package/translations/es.json +50 -15
  172. package/translations/fr.json +36 -20
  173. package/translations/it.json +265 -228
  174. package/translations/nl.json +50 -15
  175. package/translations/pt.json +50 -15
  176. package/translations/sk.json +50 -15
  177. package/esm2022/libs/ui/inputs/src/lib/image-input/image-input.component.mjs +0 -214
  178. package/libs/ui/inputs/src/lib/image-input/image-input.component.d.ts.map +0 -1
  179. package/src/libs/api/metadata-converter/src/lib/dcat-ap/utils/update-frequency.mapper.ts +0 -67
  180. /package/libs/ui/{inputs → elements}/src/lib/image-input/image-input.component.d.ts +0 -0
  181. /package/src/libs/ui/{inputs → elements}/src/lib/image-input/image-input.component.css +0 -0
@@ -1371,7 +1371,10 @@ export class RecordsApiService {
1371
1371
  hasAttachmentsOfSource?: boolean,
1372
1372
  observe?: 'body',
1373
1373
  reportProgress?: boolean,
1374
- options?: { httpHeaderAccept?: 'application/json' }
1374
+ options?: {
1375
+ httpHeaderAccept?: 'application/json'
1376
+ httpContentTypeSelected?: 'application/json;charset=UTF-8'
1377
+ }
1375
1378
  ): Observable<string>
1376
1379
  public create(
1377
1380
  sourceUuid: string,
@@ -1389,7 +1392,10 @@ export class RecordsApiService {
1389
1392
  hasAttachmentsOfSource?: boolean,
1390
1393
  observe?: 'response',
1391
1394
  reportProgress?: boolean,
1392
- options?: { httpHeaderAccept?: 'application/json' }
1395
+ options?: {
1396
+ httpHeaderAccept?: 'application/json'
1397
+ httpContentTypeSelected?: 'application/json;charset=UTF-8'
1398
+ }
1393
1399
  ): Observable<HttpResponse<string>>
1394
1400
  public create(
1395
1401
  sourceUuid: string,
@@ -1407,7 +1413,10 @@ export class RecordsApiService {
1407
1413
  hasAttachmentsOfSource?: boolean,
1408
1414
  observe?: 'events',
1409
1415
  reportProgress?: boolean,
1410
- options?: { httpHeaderAccept?: 'application/json' }
1416
+ options?: {
1417
+ httpHeaderAccept?: 'application/json'
1418
+ httpContentTypeSelected?: 'application/json;charset=UTF-8'
1419
+ }
1411
1420
  ): Observable<HttpEvent<string>>
1412
1421
  public create(
1413
1422
  sourceUuid: string,
@@ -1425,7 +1434,10 @@ export class RecordsApiService {
1425
1434
  hasAttachmentsOfSource?: boolean,
1426
1435
  observe: any = 'body',
1427
1436
  reportProgress: boolean = false,
1428
- options?: { httpHeaderAccept?: 'application/json' }
1437
+ options?: {
1438
+ httpHeaderAccept?: 'application/json'
1439
+ httpContentTypeSelected?: 'application/json;charset=UTF-8'
1440
+ }
1429
1441
  ): Observable<any> {
1430
1442
  if (sourceUuid === null || sourceUuid === undefined) {
1431
1443
  throw new Error(
@@ -1510,6 +1522,14 @@ export class RecordsApiService {
1510
1522
 
1511
1523
  let headers = this.defaultHeaders
1512
1524
 
1525
+ // to determine the Content-Type header
1526
+ const consumes: string[] = ['application/json;charset=UTF-8']
1527
+ const httpContentTypeSelected: string | undefined =
1528
+ this.configuration.selectHeaderContentType(consumes)
1529
+ if (httpContentTypeSelected !== undefined) {
1530
+ headers = headers.set('Content-Type', httpContentTypeSelected)
1531
+ }
1532
+
1513
1533
  let httpHeaderAcceptSelected: string | undefined =
1514
1534
  options && options.httpHeaderAccept
1515
1535
  if (httpHeaderAcceptSelected === undefined) {
@@ -7,7 +7,6 @@ export const openRecord = createAction(
7
7
  '[Editor] Open record',
8
8
  props<{
9
9
  record: CatalogRecord
10
- alreadySavedOnce: boolean
11
10
  recordSource?: string | null
12
11
  }>()
13
12
  )
@@ -51,3 +50,13 @@ export const hasRecordChangedSinceDraftSuccess = createAction(
51
50
  '[Editor] Has Record Changed Since Draft Success',
52
51
  props<{ changes: { user: string; date: Date } }>()
53
52
  )
53
+
54
+ export const isPublished = createAction(
55
+ '[Editor] Record Saved But Not Published',
56
+ props<{ isPublished: boolean }>()
57
+ )
58
+
59
+ export const canEditRecord = createAction(
60
+ '[Editor] User can edit record',
61
+ props<{ canEditRecord: boolean }>()
62
+ )
@@ -8,7 +8,6 @@ import { Store } from '@ngrx/store'
8
8
  import {
9
9
  selectEditorConfig,
10
10
  selectRecord,
11
- selectRecordAlreadySavedOnce,
12
11
  selectRecordSource,
13
12
  } from './editor.selectors'
14
13
  import { RecordsRepositoryInterface } from '../../../../../../libs/common/domain/src/lib/repository/records-repository.interface'
@@ -28,31 +27,27 @@ export class EditorEffects {
28
27
  withLatestFrom(
29
28
  this.store.select(selectRecord),
30
29
  this.store.select(selectRecordSource),
31
- this.store.select(selectEditorConfig),
32
- this.store.select(selectRecordAlreadySavedOnce)
30
+ this.store.select(selectEditorConfig)
33
31
  ),
34
- switchMap(([, record, recordSource, fieldsConfig, alreadySavedOnce]) =>
35
- this.editorService
36
- .saveRecord(record, recordSource, fieldsConfig, !alreadySavedOnce)
37
- .pipe(
38
- switchMap(([record, recordSource]) =>
39
- of(
40
- EditorActions.saveRecordSuccess(),
41
- EditorActions.openRecord({
42
- record,
43
- alreadySavedOnce: true,
44
- recordSource,
45
- })
46
- )
47
- ),
48
- catchError((error) =>
49
- of(
50
- EditorActions.saveRecordFailure({
51
- error,
52
- })
53
- )
32
+ switchMap(([, record, recordSource, fieldsConfig]) =>
33
+ this.editorService.saveRecord(record, recordSource, fieldsConfig).pipe(
34
+ switchMap(([record, recordSource]) =>
35
+ of(
36
+ EditorActions.saveRecordSuccess(),
37
+ EditorActions.openRecord({
38
+ record,
39
+ recordSource,
40
+ })
41
+ )
42
+ ),
43
+ catchError((error) =>
44
+ of(
45
+ EditorActions.saveRecordFailure({
46
+ error,
47
+ })
54
48
  )
55
49
  )
50
+ )
56
51
  )
57
52
  )
58
53
  )
@@ -63,12 +58,14 @@ export class EditorEffects {
63
58
  ofType(EditorActions.saveRecordSuccess),
64
59
  withLatestFrom(this.store.select(selectRecord)),
65
60
  switchMap(([_, record]) => {
66
- this.gn4PlateformService.cleanRecordAttachments(record).subscribe({
67
- next: (_) => undefined,
68
- error: (err) => {
69
- console.error(err)
70
- },
71
- })
61
+ if (record.uniqueIdentifier !== null) {
62
+ this.gn4PlateformService.cleanRecordAttachments(record).subscribe({
63
+ next: (_) => undefined,
64
+ error: (err) => {
65
+ console.error(err)
66
+ },
67
+ })
68
+ }
72
69
  return EMPTY
73
70
  }),
74
71
  catchError((error) => {
@@ -106,10 +103,9 @@ export class EditorEffects {
106
103
  ofType(EditorActions.undoRecordDraft),
107
104
  withLatestFrom(this.store.select(selectRecord)),
108
105
  switchMap(([, record]) => this.editorService.undoRecordDraft(record)),
109
- map(([record, recordSource, alreadySavedOnce]) =>
106
+ map(([record, recordSource]) =>
110
107
  EditorActions.openRecord({
111
108
  record,
112
- alreadySavedOnce,
113
109
  recordSource,
114
110
  })
115
111
  )
@@ -141,4 +137,34 @@ export class EditorEffects {
141
137
  )
142
138
  )
143
139
  )
140
+
141
+ checkIsRecordPublished$ = createEffect(() =>
142
+ this.actions$.pipe(
143
+ ofType(EditorActions.openRecord),
144
+ map(({ record }) => record.uniqueIdentifier),
145
+ switchMap((uniqueIdentifier) =>
146
+ this.recordsRepository.getRecordPublicationStatus(uniqueIdentifier)
147
+ ),
148
+ map((isPublished) =>
149
+ EditorActions.isPublished({
150
+ isPublished: isPublished,
151
+ })
152
+ )
153
+ )
154
+ )
155
+
156
+ checkCanEditRecord$ = createEffect(() =>
157
+ this.actions$.pipe(
158
+ ofType(EditorActions.openRecord),
159
+ map(({ record }) => record.uniqueIdentifier),
160
+ switchMap((uniqueIdentifier) =>
161
+ this.recordsRepository.canEditRecord(uniqueIdentifier)
162
+ ),
163
+ map((canEditRecord) =>
164
+ EditorActions.canEditRecord({
165
+ canEditRecord: canEditRecord,
166
+ })
167
+ )
168
+ )
169
+ )
144
170
  }
@@ -14,9 +14,6 @@ export class EditorFacade {
14
14
 
15
15
  record$ = this.store.pipe(select(EditorSelectors.selectRecord))
16
16
  recordSource$ = this.store.pipe(select(EditorSelectors.selectRecordSource))
17
- alreadySavedOnce$ = this.store.pipe(
18
- select(EditorSelectors.selectRecordAlreadySavedOnce)
19
- )
20
17
  saving$ = this.store.pipe(select(EditorSelectors.selectRecordSaving))
21
18
  saveError$ = this.store.pipe(
22
19
  select(EditorSelectors.selectRecordSaveError),
@@ -35,14 +32,15 @@ export class EditorFacade {
35
32
  hasRecordChanged$ = this.store.pipe(
36
33
  select(EditorSelectors.selectHasRecordChanged)
37
34
  )
35
+ isPublished$ = this.store.pipe(select(EditorSelectors.selectIsPublished))
36
+ canEditRecord$ = this.store.pipe(select(EditorSelectors.selectCanEditRecord))
38
37
 
39
- openRecord(
40
- record: CatalogRecord,
41
- recordSource: string,
42
- alreadySavedOnce: boolean
43
- ) {
38
+ openRecord(record: CatalogRecord, recordSource: string) {
44
39
  this.store.dispatch(
45
- EditorActions.openRecord({ record, recordSource, alreadySavedOnce })
40
+ EditorActions.openRecord({
41
+ record,
42
+ recordSource,
43
+ })
46
44
  )
47
45
  this.setCurrentPage(0)
48
46
  }
@@ -70,4 +68,12 @@ export class EditorFacade {
70
68
  checkHasRecordChanged(record: CatalogRecord) {
71
69
  this.store.dispatch(EditorActions.hasRecordChangedSinceDraft({ record }))
72
70
  }
71
+
72
+ isPublished(isPublished: boolean) {
73
+ this.store.dispatch(EditorActions.isPublished({ isPublished }))
74
+ }
75
+
76
+ canEditRecord(canEditRecord: boolean) {
77
+ this.store.dispatch(EditorActions.canEditRecord({ canEditRecord }))
78
+ }
73
79
  }
@@ -18,13 +18,14 @@ export const EDITOR_FEATURE_KEY = 'editor'
18
18
  export interface EditorState {
19
19
  record: CatalogRecord | null
20
20
  recordSource: string | null
21
- alreadySavedOnce: boolean
22
21
  saving: boolean
23
22
  saveError: SaveRecordError | null
24
23
  changedSinceSave: boolean
25
24
  editorConfig: EditorConfig
26
25
  currentPage: number
27
26
  hasRecordChanged: { user: string; date: Date }
27
+ isPublished: boolean
28
+ canEditRecord: boolean
28
29
  }
29
30
 
30
31
  export interface EditorPartialState {
@@ -34,27 +35,24 @@ export interface EditorPartialState {
34
35
  export const initialEditorState: EditorState = {
35
36
  record: null,
36
37
  recordSource: null,
37
- alreadySavedOnce: false,
38
38
  saving: false,
39
39
  saveError: null,
40
40
  changedSinceSave: false,
41
41
  editorConfig: DEFAULT_CONFIGURATION,
42
42
  currentPage: 0,
43
43
  hasRecordChanged: null,
44
+ isPublished: true,
45
+ canEditRecord: true,
44
46
  }
45
47
 
46
48
  const reducer = createReducer(
47
49
  initialEditorState,
48
- on(
49
- EditorActions.openRecord,
50
- (state, { record, recordSource, alreadySavedOnce }) => ({
51
- ...state,
52
- changedSinceSave: false,
53
- recordSource: recordSource ?? null,
54
- alreadySavedOnce,
55
- record,
56
- })
57
- ),
50
+ on(EditorActions.openRecord, (state, { record, recordSource }) => ({
51
+ ...state,
52
+ changedSinceSave: false,
53
+ recordSource: recordSource ?? null,
54
+ record,
55
+ })),
58
56
  on(EditorActions.saveRecord, (state) => ({
59
57
  ...state,
60
58
  saving: true,
@@ -110,6 +108,14 @@ const reducer = createReducer(
110
108
  on(EditorActions.hasRecordChangedSinceDraftSuccess, (state, { changes }) => ({
111
109
  ...state,
112
110
  hasRecordChanged: changes,
111
+ })),
112
+ on(EditorActions.isPublished, (state, { isPublished }) => ({
113
+ ...state,
114
+ isPublished: isPublished,
115
+ })),
116
+ on(EditorActions.canEditRecord, (state, { canEditRecord }) => ({
117
+ ...state,
118
+ canEditRecord: canEditRecord,
113
119
  }))
114
120
  )
115
121
 
@@ -30,11 +30,6 @@ export const selectRecordChangedSinceSave = createSelector(
30
30
  (state: EditorState) => state.changedSinceSave
31
31
  )
32
32
 
33
- export const selectRecordAlreadySavedOnce = createSelector(
34
- selectEditorState,
35
- (state: EditorState) => state.alreadySavedOnce
36
- )
37
-
38
33
  export const selectEditorConfig = createSelector(
39
34
  selectEditorState,
40
35
  (state: EditorState) => state.editorConfig
@@ -48,11 +43,11 @@ export const selectCurrentPage = createSelector(
48
43
  export const selectRecordSections = createSelector(
49
44
  selectEditorState,
50
45
  (state: EditorState) => {
51
- const currentPage = state.editorConfig.pages[state.currentPage]
52
- if (!currentPage) {
46
+ const currentPageConfig = state.editorConfig.pages[state.currentPage]
47
+ if (!currentPageConfig) {
53
48
  return [] as EditorSectionWithValues[]
54
49
  }
55
- return currentPage.sections.map((section) => ({
50
+ return currentPageConfig.sections.map((section) => ({
56
51
  ...section,
57
52
  fieldsWithValues: section.fields.map((fieldConfig) => ({
58
53
  config: fieldConfig,
@@ -66,3 +61,13 @@ export const selectHasRecordChanged = createSelector(
66
61
  selectEditorState,
67
62
  (state: EditorState) => state.hasRecordChanged
68
63
  )
64
+
65
+ export const selectIsPublished = createSelector(
66
+ selectEditorState,
67
+ (state: EditorState) => state.isPublished
68
+ )
69
+
70
+ export const selectCanEditRecord = createSelector(
71
+ selectEditorState,
72
+ (state: EditorState) => state.canEditRecord
73
+ )
@@ -22,7 +22,7 @@
22
22
  class="mt-3.5"
23
23
  [value]="constraint_.url?.toString()"
24
24
  (valueChange)="handleURLChange($event)"
25
- [showUploadButton]="false"
25
+ [showValidateButton]="false"
26
26
  >
27
27
  </gn-ui-url-input>
28
28
  </div>
@@ -1,4 +1,4 @@
1
- <div class="flex flex-col gap-3">
1
+ <div class="flex flex-col gap-4">
2
2
  <gn-ui-autocomplete
3
3
  [placeholder]="placeholder"
4
4
  [displayWithFn]="displayWithFn"
@@ -11,12 +11,13 @@
11
11
  help
12
12
  </span>
13
13
  </div>
14
- <div class="flex flex-row items-center gap-[16px] h-[48px]">
14
+ <div class="flex flex-row items-center gap-4 h-[48px]">
15
15
  <mat-radio-group
16
16
  aria-labelledby="example-radio-group-label"
17
17
  class="flex flex-row gap-[8px]"
18
18
  [(ngModel)]="service.accessServiceProtocol"
19
19
  [disabled]="disabled"
20
+ (change)="resetLayersSuggestion()"
20
21
  >
21
22
  <mat-radio-button
22
23
  *ngFor="let protocolOption of protocolOptions"
@@ -26,8 +27,63 @@
26
27
  </mat-radio-button>
27
28
  </mat-radio-group>
28
29
  </div>
29
- <gn-ui-text-input
30
- [(value)]="service.identifierInService"
31
- data-cy="identifier-in-service"
32
- [disabled]="disabled"
33
- ></gn-ui-text-input>
30
+
31
+ <div class="flex flex-col gap-4">
32
+ <gn-ui-url-input
33
+ class="w-full"
34
+ (uploadClick)="handleUploadClick($event)"
35
+ (valueChange)="handleUrlValueChange($event)"
36
+ [disabled]="disabled"
37
+ [value]="url"
38
+ [showValidateButton]="activeLayerSuggestion"
39
+ >
40
+ <ng-content *ngIf="activeLayerSuggestion">
41
+ <ng-icon name="iconoirCloudUpload"></ng-icon>
42
+ </ng-content>
43
+ </gn-ui-url-input>
44
+
45
+ <p class="text-sm text-red-500 pl-4" *ngIf="errorMessage" translate>
46
+ editor.record.form.field.onlineResource.edit.identifier.error
47
+ </p>
48
+
49
+ <gn-ui-text-input
50
+ class="grow border-b border-gray-300 pb-4"
51
+ [(value)]="service.identifierInService"
52
+ [placeholder]="getIdentifierPlaceholder() | translate"
53
+ data-cy="identifier-in-service"
54
+ [disabled]="disabled"
55
+ *ngIf="
56
+ !activeLayerSuggestion ||
57
+ (url && errorMessage) ||
58
+ (modifyMode && layers === undefined)
59
+ "
60
+ ></gn-ui-text-input>
61
+ <gn-ui-dropdown-selector
62
+ class="border-b border-gray-300 pb-4"
63
+ [showTitle]="false"
64
+ [title]="
65
+ 'editor.record.form.field.onlineResource.edit.identifier.select.label'
66
+ | translate
67
+ "
68
+ [choices]="layers || []"
69
+ *ngIf="activeLayerSuggestion && layers !== undefined"
70
+ [selected]="service.identifierInService"
71
+ (selectValue)="handleSelectValue($event)"
72
+ >
73
+ </gn-ui-dropdown-selector>
74
+ <gn-ui-button
75
+ (buttonClick)="submitIdentifier(service.identifierInService)"
76
+ [disabled]="disabled || !service.identifierInService"
77
+ type="primary"
78
+ *ngIf="
79
+ !modifyMode &&
80
+ ((activeLayerSuggestion && layers) ||
81
+ !activeLayerSuggestion ||
82
+ (url && errorMessage))
83
+ "
84
+ >
85
+ <span class="text-white font-bold" translate>
86
+ editor.record.form.field.onlineResource.edit.identifier.submit</span
87
+ >
88
+ </gn-ui-button>
89
+ </div>
@@ -1,9 +1,13 @@
1
1
  import { CommonModule } from '@angular/common'
2
2
  import {
3
3
  ChangeDetectionStrategy,
4
+ ChangeDetectorRef,
4
5
  Component,
6
+ EventEmitter,
5
7
  Input,
6
8
  OnChanges,
9
+ OnInit,
10
+ Output,
7
11
  } from '@angular/core'
8
12
  import { FormsModule } from '@angular/forms'
9
13
  import { MatRadioModule } from '@angular/material/radio'
@@ -13,8 +17,21 @@ import {
13
17
  DatasetServiceDistribution,
14
18
  ServiceProtocol,
15
19
  } from '../../../../../../../libs/common/domain/src/lib/model/record'
16
- import { TextInputComponent } from '../../../../../../../libs/ui/inputs/src'
20
+ import {
21
+ ButtonComponent,
22
+ DropdownChoice,
23
+ DropdownSelectorComponent,
24
+ TextInputComponent,
25
+ UrlInputComponent,
26
+ } from '../../../../../../../libs/ui/inputs/src'
17
27
  import { TranslateModule } from '@ngx-translate/core'
28
+ import {
29
+ NgIconComponent,
30
+ provideIcons,
31
+ provideNgIconsConfig,
32
+ } from '@ng-icons/core'
33
+ import { iconoirCloudUpload } from '@ng-icons/iconoir'
34
+ import { getLayers } from '../../../../../../../libs/util/shared/src'
18
35
 
19
36
  @Component({
20
37
  selector: 'gn-ui-online-service-resource-input',
@@ -23,20 +40,39 @@ import { TranslateModule } from '@ngx-translate/core'
23
40
  changeDetection: ChangeDetectionStrategy.OnPush,
24
41
  standalone: true,
25
42
  imports: [
43
+ DropdownSelectorComponent,
44
+ ButtonComponent,
26
45
  CommonModule,
46
+ FormsModule,
27
47
  MatTooltipModule,
28
48
  MatRadioModule,
29
- FormsModule,
49
+ NgIconComponent,
30
50
  TextInputComponent,
31
51
  TranslateModule,
52
+ UrlInputComponent,
53
+ ],
54
+ providers: [
55
+ provideIcons({ iconoirCloudUpload }),
56
+ provideNgIconsConfig({
57
+ size: '1.5em',
58
+ }),
32
59
  ],
33
60
  })
34
- export class OnlineServiceResourceInputComponent implements OnChanges {
35
- @Input() service: Omit<DatasetServiceDistribution, 'url'>
61
+ export class OnlineServiceResourceInputComponent implements OnChanges, OnInit {
62
+ @Input() service: DatasetServiceDistribution
36
63
  @Input() protocolHint?: string
37
64
  @Input() disabled? = false
65
+ @Input() modifyMode? = false
66
+ @Output() urlChange: EventEmitter<string> = new EventEmitter()
67
+ @Output() identifierSubmit: EventEmitter<{
68
+ url: string
69
+ identifier: string
70
+ }> = new EventEmitter()
38
71
 
72
+ errorMessage = false
39
73
  selectedProtocol: ServiceProtocol
74
+ url: string
75
+ layers: DropdownChoice[] | undefined = undefined
40
76
 
41
77
  protocolOptions: {
42
78
  label: string
@@ -72,10 +108,78 @@ export class OnlineServiceResourceInputComponent implements OnChanges {
72
108
  },
73
109
  ]
74
110
 
111
+ constructor(private cdr: ChangeDetectorRef) {}
112
+
113
+ get activeLayerSuggestion() {
114
+ return !['wps', 'GPFDL', 'esriRest', 'other'].includes(
115
+ this.service.accessServiceProtocol
116
+ )
117
+ }
118
+
75
119
  ngOnChanges() {
76
120
  this.selectedProtocol =
77
121
  this.protocolOptions.find(
78
122
  (option) => option.value === this.service.accessServiceProtocol
79
123
  )?.value ?? 'other'
80
124
  }
125
+
126
+ ngOnInit() {
127
+ if (this.service.url) {
128
+ this.url = this.service.url.toString()
129
+ }
130
+ }
131
+
132
+ handleUrlValueChange(url: string) {
133
+ this.url = url
134
+ this.service.url = new URL(url)
135
+ this.resetLayersSuggestion()
136
+ this.urlChange.emit(this.url)
137
+ }
138
+
139
+ async handleUploadClick(url: string) {
140
+ this.url = url
141
+
142
+ try {
143
+ const layers = await getLayers(url, this.service.accessServiceProtocol)
144
+ this.layers = layers.map((l) => {
145
+ return {
146
+ label: l.title ? `${l.title} ${l.name ? `(${l.name})` : ''}` : l.name,
147
+ value: l.name || l.title,
148
+ }
149
+ })
150
+
151
+ if (this.layers.length === 0) {
152
+ throw new Error('No layers found')
153
+ }
154
+ } catch (e) {
155
+ this.errorMessage = true
156
+ this.layers = undefined
157
+ }
158
+
159
+ this.cdr.detectChanges()
160
+ }
161
+
162
+ handleSelectValue(val: string) {
163
+ this.service.identifierInService = val
164
+ }
165
+
166
+ resetLayersSuggestion() {
167
+ this.errorMessage = false
168
+ this.layers = undefined
169
+ this.service.identifierInService = null
170
+ }
171
+
172
+ submitIdentifier(identifier: string) {
173
+ if (!identifier) return
174
+ this.identifierSubmit.emit({ url: this.url, identifier })
175
+ this.service.identifierInService = null
176
+ }
177
+
178
+ getIdentifierPlaceholder(): string {
179
+ const baseKey =
180
+ 'editor.record.form.field.onlineResource.edit.identifier.placeholder'
181
+ return this.service.accessServiceProtocol === 'wps'
182
+ ? `${baseKey}.wps`
183
+ : baseKey
184
+ }
81
185
  }
@@ -2,7 +2,7 @@
2
2
  <gn-ui-dropdown-selector
3
3
  [title]="label"
4
4
  [showTitle]="false"
5
- [choices]="licenceOptions"
5
+ [choices]="choices"
6
6
  [selected]="selectedLicence"
7
7
  (selectValue)="handleLicenceSelection($event)"
8
8
  [extraBtnClass]="'input-as-button gn-ui-text-input'"