geonetwork-ui 2.3.0-dev.a26c0b88 → 2.3.0-dev.aef43725

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 (130) hide show
  1. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/read-parts.mjs +2 -2
  2. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/write-parts.mjs +2 -2
  3. package/esm2022/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.mjs +9 -7
  4. package/esm2022/libs/feature/dataviz/src/lib/chart-view/chart-view.component.mjs +1 -1
  5. package/esm2022/libs/feature/dataviz/src/lib/service/data.service.mjs +14 -2
  6. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.mjs +1 -1
  7. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.mjs +104 -0
  8. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.mjs +8 -3
  9. package/esm2022/libs/feature/editor/src/lib/components/wizard-field/wizard-field.component.mjs +1 -1
  10. package/esm2022/libs/feature/editor/src/lib/fields.config.mjs +8 -1
  11. package/esm2022/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.mjs +1 -1
  12. package/esm2022/libs/feature/map/src/lib/map-context/map-context.model.mjs +1 -1
  13. package/esm2022/libs/feature/map/src/lib/map-context/map-context.service.mjs +30 -10
  14. package/esm2022/libs/feature/map/src/lib/utils/map-utils.service.mjs +7 -3
  15. package/esm2022/libs/feature/record/src/lib/data-view/data-view.component.mjs +1 -1
  16. package/esm2022/libs/feature/record/src/lib/map-view/map-view.component.mjs +11 -7
  17. package/esm2022/libs/feature/record/src/lib/state/mdview.facade.mjs +34 -5
  18. package/esm2022/libs/feature/record/src/lib/state/mdview.reducer.mjs +1 -3
  19. package/esm2022/libs/feature/search/src/index.mjs +2 -1
  20. package/esm2022/libs/feature/search/src/lib/results-layout/results-layout.component.mjs +1 -1
  21. package/esm2022/libs/feature/search/src/lib/results-list/results-list.container.component.mjs +4 -4
  22. package/esm2022/libs/feature/search/src/lib/sort-by/sort-by.component.mjs +1 -1
  23. package/esm2022/libs/ui/catalog/src/lib/language-switcher/language-switcher.component.mjs +1 -1
  24. package/esm2022/libs/ui/catalog/src/lib/organisations-filter/organisations-filter.component.mjs +1 -1
  25. package/esm2022/libs/ui/elements/src/index.mjs +2 -2
  26. package/esm2022/libs/ui/elements/src/lib/error/error.component.mjs +30 -0
  27. package/esm2022/libs/ui/elements/src/lib/record-api-form/record-api-form.component.mjs +69 -69
  28. package/esm2022/libs/ui/elements/src/lib/ui-elements.module.mjs +6 -6
  29. package/esm2022/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.mjs +3 -5
  30. package/esm2022/libs/ui/inputs/src/lib/check-toggle/check-toggle.component.mjs +4 -3
  31. package/esm2022/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.mjs +5 -3
  32. package/esm2022/libs/ui/inputs/src/lib/ui-inputs.module.mjs +6 -5
  33. package/esm2022/libs/util/app-config/src/lib/app-config.mjs +3 -1
  34. package/esm2022/libs/util/app-config/src/lib/fixtures.mjs +2 -1
  35. package/esm2022/libs/util/app-config/src/lib/model.mjs +1 -1
  36. package/esm2022/translations/de.json +3 -0
  37. package/esm2022/translations/en.json +3 -0
  38. package/esm2022/translations/es.json +3 -0
  39. package/esm2022/translations/fr.json +3 -0
  40. package/esm2022/translations/it.json +3 -0
  41. package/esm2022/translations/nl.json +3 -0
  42. package/esm2022/translations/pt.json +3 -0
  43. package/fesm2022/geonetwork-ui.mjs +445 -245
  44. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  45. package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts.map +1 -1
  46. package/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.d.ts.map +1 -1
  47. package/libs/feature/dataviz/src/lib/service/data.service.d.ts +2 -1
  48. package/libs/feature/dataviz/src/lib/service/data.service.d.ts.map +1 -1
  49. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.d.ts +21 -0
  50. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.d.ts.map +1 -0
  51. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts +1 -0
  52. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts.map +1 -1
  53. package/libs/feature/editor/src/lib/fields.config.d.ts.map +1 -1
  54. package/libs/feature/map/src/lib/map-context/map-context.model.d.ts +6 -0
  55. package/libs/feature/map/src/lib/map-context/map-context.model.d.ts.map +1 -1
  56. package/libs/feature/map/src/lib/map-context/map-context.service.d.ts +1 -1
  57. package/libs/feature/map/src/lib/map-context/map-context.service.d.ts.map +1 -1
  58. package/libs/feature/map/src/lib/utils/map-utils.service.d.ts.map +1 -1
  59. package/libs/feature/record/src/lib/map-view/map-view.component.d.ts +2 -2
  60. package/libs/feature/record/src/lib/map-view/map-view.component.d.ts.map +1 -1
  61. package/libs/feature/record/src/lib/state/mdview.facade.d.ts +5 -2
  62. package/libs/feature/record/src/lib/state/mdview.facade.d.ts.map +1 -1
  63. package/libs/feature/record/src/lib/state/mdview.reducer.d.ts.map +1 -1
  64. package/libs/feature/search/src/index.d.ts +1 -0
  65. package/libs/feature/search/src/index.d.ts.map +1 -1
  66. package/libs/ui/elements/src/index.d.ts +1 -1
  67. package/libs/ui/elements/src/index.d.ts.map +1 -1
  68. package/libs/ui/elements/src/lib/error/error.component.d.ts +16 -0
  69. package/libs/ui/elements/src/lib/error/error.component.d.ts.map +1 -0
  70. package/libs/ui/elements/src/lib/record-api-form/record-api-form.component.d.ts +14 -3
  71. package/libs/ui/elements/src/lib/record-api-form/record-api-form.component.d.ts.map +1 -1
  72. package/libs/ui/elements/src/lib/ui-elements.module.d.ts +2 -2
  73. package/libs/ui/elements/src/lib/ui-elements.module.d.ts.map +1 -1
  74. package/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.d.ts +1 -2
  75. package/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.d.ts.map +1 -1
  76. package/libs/ui/inputs/src/lib/check-toggle/check-toggle.component.d.ts +1 -1
  77. package/libs/ui/inputs/src/lib/check-toggle/check-toggle.component.d.ts.map +1 -1
  78. package/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.d.ts +2 -1
  79. package/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.d.ts.map +1 -1
  80. package/libs/ui/inputs/src/lib/ui-inputs.module.d.ts +27 -27
  81. package/libs/util/app-config/src/lib/app-config.d.ts.map +1 -1
  82. package/libs/util/app-config/src/lib/fixtures.d.ts.map +1 -1
  83. package/libs/util/app-config/src/lib/model.d.ts +1 -0
  84. package/libs/util/app-config/src/lib/model.d.ts.map +1 -1
  85. package/package.json +2 -2
  86. package/src/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts +1 -1
  87. package/src/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts +1 -4
  88. package/src/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.ts +16 -10
  89. package/src/libs/common/fixtures/src/lib/records.fixtures.ts +8 -0
  90. package/src/libs/feature/dataviz/src/lib/service/data.service.ts +15 -1
  91. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.css +0 -0
  92. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.html +14 -0
  93. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.ts +143 -0
  94. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html +5 -0
  95. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts +5 -0
  96. package/src/libs/feature/editor/src/lib/fields.config.ts +7 -0
  97. package/src/libs/feature/map/src/lib/map-context/map-context.model.ts +6 -0
  98. package/src/libs/feature/map/src/lib/map-context/map-context.service.ts +31 -9
  99. package/src/libs/feature/map/src/lib/utils/map-utils.service.ts +6 -2
  100. package/src/libs/feature/record/src/lib/map-view/map-view.component.ts +10 -8
  101. package/src/libs/feature/record/src/lib/state/mdview.facade.ts +40 -3
  102. package/src/libs/feature/record/src/lib/state/mdview.reducer.ts +0 -2
  103. package/src/libs/feature/search/src/index.ts +1 -0
  104. package/src/libs/feature/search/src/lib/results-list/results-list.container.component.html +4 -4
  105. package/src/libs/ui/elements/src/index.ts +1 -1
  106. package/src/libs/ui/elements/src/lib/{search-results-error/search-results-error.component.html → error/error.component.html} +18 -3
  107. package/src/libs/ui/elements/src/lib/{search-results-error/search-results-error.component.ts → error/error.component.ts} +5 -4
  108. package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.ts +95 -79
  109. package/src/libs/ui/elements/src/lib/ui-elements.module.ts +3 -4
  110. package/src/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.html +1 -1
  111. package/src/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.ts +0 -1
  112. package/src/libs/ui/inputs/src/lib/check-toggle/check-toggle.component.ts +3 -0
  113. package/src/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.html +1 -0
  114. package/src/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.ts +1 -0
  115. package/src/libs/ui/inputs/src/lib/ui-inputs.module.ts +1 -1
  116. package/src/libs/util/app-config/src/lib/app-config.ts +2 -0
  117. package/src/libs/util/app-config/src/lib/fixtures.ts +1 -0
  118. package/src/libs/util/app-config/src/lib/model.ts +1 -0
  119. package/translations/de.json +3 -0
  120. package/translations/en.json +3 -0
  121. package/translations/es.json +3 -0
  122. package/translations/fr.json +3 -0
  123. package/translations/it.json +3 -0
  124. package/translations/nl.json +3 -0
  125. package/translations/pt.json +3 -0
  126. package/translations/sk.json +3 -0
  127. package/esm2022/libs/ui/elements/src/lib/search-results-error/search-results-error.component.mjs +0 -29
  128. package/libs/ui/elements/src/lib/search-results-error/search-results-error.component.d.ts +0 -15
  129. package/libs/ui/elements/src/lib/search-results-error/search-results-error.component.d.ts.map +0 -1
  130. /package/src/libs/ui/elements/src/lib/{search-results-error/search-results-error.component.css → error/error.component.css} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../../../src/libs/util/app-config/src/lib/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAElC,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,0BAA0B,CAAC,EAAE,MAAM,CAAA;IACnC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS,CAAA;IACvC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7C,4BAA4B,CAAC,EAAE,MAAM,CAAA;IACrC,4BAA4B,CAAC,EAAE,OAAO,CAAA;IACtC,0BAA0B,EAAE,OAAO,CAAA;IACnC,UAAU,EAAE,WAAW,EAAE,CAAA;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;IACvB,UAAU,EAAE,MAAM,CAAA;IAClB,gBAAgB,EAAE,MAAM,CAAA;IACxB,uBAAuB,EAAE,MAAM,CAAA;IAC/B,iBAAiB,EAAE,MAAM,CAAA;IACzB,qBAAqB,EAAE,MAAM,CAAA;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,CAAA;CAC3C;AAED,MAAM,WAAW,YAAY;IAC3B,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,aAAa,CAAC,EAAE,YAAY,EAAE,CAAA;IAC9B,gBAAgB,CAAC,EAAE,EAAE,CAAA;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,MAAM,kBAAkB,GAAG;IAAE,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAA;AACrE,MAAM,MAAM,8BAA8B,GAAG;IAC3C,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAAA;CACnC,CAAA;AAED,MAAM,WAAW,YAAY;IAC3B,eAAe,CAAC,EAAE,QAAQ,CAAA;CAC3B"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../../../src/libs/util/app-config/src/lib/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAElC,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,0BAA0B,CAAC,EAAE,MAAM,CAAA;IACnC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS,CAAA;IACvC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,eAAe,EAAE,OAAO,CAAA;IACxB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7C,4BAA4B,CAAC,EAAE,MAAM,CAAA;IACrC,4BAA4B,CAAC,EAAE,OAAO,CAAA;IACtC,0BAA0B,EAAE,OAAO,CAAA;IACnC,UAAU,EAAE,WAAW,EAAE,CAAA;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;IACvB,UAAU,EAAE,MAAM,CAAA;IAClB,gBAAgB,EAAE,MAAM,CAAA;IACxB,uBAAuB,EAAE,MAAM,CAAA;IAC/B,iBAAiB,EAAE,MAAM,CAAA;IACzB,qBAAqB,EAAE,MAAM,CAAA;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,CAAA;CAC3C;AAED,MAAM,WAAW,YAAY;IAC3B,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,aAAa,CAAC,EAAE,YAAY,EAAE,CAAA;IAC9B,gBAAgB,CAAC,EAAE,EAAE,CAAA;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,MAAM,kBAAkB,GAAG;IAAE,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAA;AACrE,MAAM,MAAM,8BAA8B,GAAG;IAC3C,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAAA;CACnC,CAAA;AAED,MAAM,WAAW,YAAY;IAC3B,eAAe,CAAC,EAAE,QAAQ,CAAA;CAC3B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "geonetwork-ui",
3
- "version": "2.3.0-dev.a26c0b88",
3
+ "version": "2.3.0-dev.aef43725",
4
4
  "engines": {
5
5
  "node": ">=14.17.0"
6
6
  },
@@ -47,7 +47,7 @@
47
47
  },
48
48
  "dependencies": {
49
49
  "@biesbjerg/ngx-translate-extract-marker": "^1.0.0",
50
- "@camptocamp/ogc-client": "^1.1.0-RC.3",
50
+ "@camptocamp/ogc-client": "1.1.1-dev.ad6d9ab",
51
51
  "@geospatial-sdk/geocoding": "^0.0.5-alpha.2",
52
52
  "@ltd/j-toml": "~1.35.2",
53
53
  "@messageformat/core": "^3.0.1",
@@ -434,7 +434,7 @@ export function getUpdateFrequencyFromCustomPeriod(
434
434
  } else if (days <= 7) {
435
435
  return {
436
436
  per: 'week',
437
- updatedTimes: Math.round(7 / days),
437
+ updatedTimes: Math.round(7 / days - 0.0001), // this is to make sure that 'every 2 days' = '3 times per week'
438
438
  }
439
439
  } else if (days) {
440
440
  return {
@@ -24,10 +24,8 @@ import {
24
24
  findChildOrCreate,
25
25
  findChildrenElement,
26
26
  findNestedChildOrCreate,
27
- findNestedElement,
28
27
  findNestedElements,
29
28
  readAttribute,
30
- readText,
31
29
  removeAllChildren,
32
30
  removeChildren,
33
31
  removeChildrenByName,
@@ -36,7 +34,6 @@ import {
36
34
  } from '../xml-utils'
37
35
  import {
38
36
  ChainableFunction,
39
- combine,
40
37
  fallback,
41
38
  filterArray,
42
39
  getAtIndex,
@@ -220,7 +217,7 @@ export function getISODuration(updateFrequency: UpdateFrequencyCustom): string {
220
217
  else duration.hours = Math.round(24 / updateFrequency.updatedTimes)
221
218
  break
222
219
  case 'week':
223
- duration.days = Math.round(7 / updateFrequency.updatedTimes)
220
+ duration.days = Math.round(7 / updateFrequency.updatedTimes - 0.0001) // this is to make sure that '2 times per week' = 'every 3 days'
224
221
  break
225
222
  case 'month':
226
223
  if (updateFrequency.updatedTimes <= 1) duration.months = 1
@@ -162,19 +162,25 @@ export class Gn4PlatformService implements PlatformServiceInterface {
162
162
  }
163
163
 
164
164
  getUserFeedbacks(uuid: string): Observable<UserFeedback[]> {
165
- return this.userfeedbackApiService
166
- .getUserComments(uuid)
167
- .pipe(
168
- map((userFeedbacks) =>
169
- userFeedbacks.map(this.mapper.userFeedbacksFromApi)
170
- )
171
- )
165
+ return this.userfeedbackApiService.getUserComments(uuid).pipe(
166
+ map((userFeedbacks) =>
167
+ userFeedbacks.map(this.mapper.userFeedbacksFromApi)
168
+ ),
169
+ catchError((error) => {
170
+ console.error('Error fetching user feedbacks:', error)
171
+ return of(undefined)
172
+ })
173
+ )
172
174
  }
173
175
 
174
176
  postUserFeedbacks(userFeedback: UserFeedback): Observable<void> {
175
177
  const mappedUserFeedBack = this.mapper.userFeedbacksToApi(userFeedback)
176
- return this.userfeedbackApiService
177
- .newUserFeedback(mappedUserFeedBack)
178
- .pipe(map(() => undefined))
178
+ return this.userfeedbackApiService.newUserFeedback(mappedUserFeedBack).pipe(
179
+ map(() => undefined),
180
+ catchError((error) => {
181
+ console.error('Error posting user feedback:', error)
182
+ return of(undefined)
183
+ })
184
+ )
179
185
  }
180
186
  }
@@ -117,6 +117,14 @@ Cette section contient des *caractères internationaux* (ainsi que des "caractè
117
117
  description: 'This WFS service offers direct download capability',
118
118
  identifierInService: 'my:featuretype',
119
119
  },
120
+ {
121
+ type: 'service',
122
+ url: new URL('https://my-org.net/ogc'),
123
+ accessServiceProtocol: 'ogcFeatures',
124
+ name: 'my:featuretype',
125
+ description: 'This OGC service offers direct download capability',
126
+ identifierInService: 'my:featuretype',
127
+ },
120
128
  ],
121
129
  lineage: `This record was edited manually to test the conversion processes
122
130
 
@@ -3,6 +3,7 @@ import { marker } from '@biesbjerg/ngx-translate-extract-marker'
3
3
  import {
4
4
  OgcApiCollectionInfo,
5
5
  OgcApiEndpoint,
6
+ OgcApiRecord,
6
7
  WfsEndpoint,
7
8
  WfsVersion,
8
9
  } from '@camptocamp/ogc-client'
@@ -173,10 +174,23 @@ export class DataService {
173
174
  }
174
175
 
175
176
  async getDownloadUrlsFromOgcApi(url: string): Promise<OgcApiCollectionInfo> {
177
+ const endpoint = new OgcApiEndpoint(this.proxy.getProxiedUrl(url))
178
+ return await endpoint.allCollections
179
+ .then((collections) => {
180
+ return endpoint.getCollectionInfo(collections[0].name)
181
+ })
182
+ .catch((error) => {
183
+ throw new Error(`ogc.unreachable.unknown`)
184
+ })
185
+ }
186
+
187
+ async getItemsFromOgcApi(url: string): Promise<OgcApiRecord> {
176
188
  const endpoint = new OgcApiEndpoint(this.proxy.getProxiedUrl(url))
177
189
  return await endpoint.featureCollections
178
190
  .then((collections) => {
179
- return endpoint.getCollectionInfo(collections[0])
191
+ return collections.length
192
+ ? endpoint.getCollectionItem(collections[0], '1')
193
+ : null
180
194
  })
181
195
  .catch((error) => {
182
196
  throw new Error(`ogc.unreachable.unknown`)
@@ -0,0 +1,14 @@
1
+ <gn-ui-check-toggle
2
+ [label]="'editor.record.form.updateFrequency.planned' | translate"
3
+ [value]="planned"
4
+ (toggled)="onPlannedToggled()"
5
+ ></gn-ui-check-toggle>
6
+ <gn-ui-dropdown-selector
7
+ title="updateFrequency"
8
+ [showTitle]="false"
9
+ [choices]="choices"
10
+ [selected]="selectedFrequency"
11
+ (selectValue)="onSelectFrequencyValue($event)"
12
+ [disabled]="!planned"
13
+ >
14
+ </gn-ui-dropdown-selector>
@@ -0,0 +1,143 @@
1
+ import {
2
+ ChangeDetectionStrategy,
3
+ Component,
4
+ Input,
5
+ OnInit,
6
+ } from '@angular/core'
7
+ import { FormControl } from '@angular/forms'
8
+ import { marker } from '@biesbjerg/ngx-translate-extract-marker'
9
+ import {
10
+ CheckToggleComponent,
11
+ DropdownSelectorComponent,
12
+ } from '../../../../../../../../../libs/ui/inputs/src'
13
+ import { TranslateModule, TranslateService } from '@ngx-translate/core'
14
+
15
+ @Component({
16
+ selector: 'gn-ui-form-field-update-frequency',
17
+ templateUrl: './form-field-update-frequency.component.html',
18
+ styleUrls: ['./form-field-update-frequency.component.css'],
19
+ changeDetection: ChangeDetectionStrategy.OnPush,
20
+ standalone: true,
21
+ imports: [CheckToggleComponent, DropdownSelectorComponent, TranslateModule],
22
+ })
23
+ export class FormFieldUpdateFrequencyComponent implements OnInit {
24
+ @Input() control: FormControl
25
+
26
+ get planned() {
27
+ return this.control.value !== 'notPlanned'
28
+ }
29
+
30
+ constructor(private translateService: TranslateService) {}
31
+
32
+ ngOnInit() {
33
+ const updatedTimes = this.control.value?.updatedTimes
34
+ const per = this.control.value?.per
35
+ if (updatedTimes && updatedTimes !== 1 && updatedTimes !== 2) {
36
+ this.choices = [
37
+ {
38
+ value: `${per}.${updatedTimes}`,
39
+ label: this.translateService.instant(
40
+ `domain.record.updateFrequency.${per}`,
41
+ {
42
+ count: updatedTimes,
43
+ }
44
+ ),
45
+ },
46
+ ...this.choices,
47
+ ]
48
+ }
49
+ }
50
+
51
+ onPlannedToggled() {
52
+ if (this.planned) {
53
+ this.control.setValue('notPlanned')
54
+ } else {
55
+ this.control.setValue({ updatedTimes: 1, per: 'day' })
56
+ }
57
+ }
58
+
59
+ get selectedFrequency() {
60
+ const { updatedTimes, per } = this.control.value
61
+ return `${per}.${updatedTimes}`
62
+ }
63
+
64
+ onSelectFrequencyValue(value: unknown) {
65
+ const split = (value as string).split('.')
66
+ this.control.setValue({ updatedTimes: Number(split[1]), per: split[0] })
67
+ }
68
+
69
+ choices = [
70
+ {
71
+ value: 'day.1',
72
+ label: this.translateService.instant(
73
+ 'domain.record.updateFrequency.day',
74
+ {
75
+ count: 1,
76
+ }
77
+ ),
78
+ },
79
+ {
80
+ value: 'day.2',
81
+ label: this.translateService.instant(
82
+ 'domain.record.updateFrequency.day',
83
+ {
84
+ count: 2,
85
+ }
86
+ ),
87
+ },
88
+ {
89
+ value: 'week.1',
90
+ label: this.translateService.instant(
91
+ 'domain.record.updateFrequency.week',
92
+ {
93
+ count: 1,
94
+ }
95
+ ),
96
+ },
97
+ {
98
+ value: 'week.2',
99
+ label: this.translateService.instant(
100
+ 'domain.record.updateFrequency.week',
101
+ {
102
+ count: 2,
103
+ }
104
+ ),
105
+ },
106
+ {
107
+ value: 'month.1',
108
+ label: this.translateService.instant(
109
+ 'domain.record.updateFrequency.month',
110
+ {
111
+ count: 1,
112
+ }
113
+ ),
114
+ },
115
+ {
116
+ value: 'month.2',
117
+ label: this.translateService.instant(
118
+ 'domain.record.updateFrequency.month',
119
+ {
120
+ count: 2,
121
+ }
122
+ ),
123
+ },
124
+ {
125
+ value: 'year.1',
126
+ label: this.translateService.instant(
127
+ 'domain.record.updateFrequency.year',
128
+ {
129
+ count: 1,
130
+ }
131
+ ),
132
+ },
133
+ {
134
+ value: 'year.2',
135
+ label: this.translateService.instant(
136
+ 'domain.record.updateFrequency.year',
137
+ {
138
+ count: 2,
139
+ }
140
+ ),
141
+ },
142
+ ]
143
+ }
@@ -56,6 +56,11 @@
56
56
  [control]="formControl"
57
57
  ></gn-ui-form-field-resource-updated>
58
58
  </ng-container>
59
+ <ng-container *ngIf="isUpdateFrequency">
60
+ <gn-ui-form-field-update-frequency
61
+ [control]="formControl"
62
+ ></gn-ui-form-field-update-frequency>
63
+ </ng-container>
59
64
  <ng-container *ngIf="isSimpleField">
60
65
  <gn-ui-form-field-simple
61
66
  [type]="simpleType"
@@ -24,6 +24,7 @@ import { FormFieldSimpleComponent } from './form-field-simple/form-field-simple.
24
24
  import { FormFieldSpatialExtentComponent } from './form-field-spatial-extent/form-field-spatial-extent.component'
25
25
  import { FormFieldTemporalExtentComponent } from './form-field-temporal-extent/form-field-temporal-extent.component'
26
26
  import { FormFieldConfig } from './form-field.model'
27
+ import { FormFieldUpdateFrequencyComponent } from './form-field-update-frequency/form-field-update-frequency.component'
27
28
 
28
29
  @Component({
29
30
  selector: 'gn-ui-form-field',
@@ -40,6 +41,7 @@ import { FormFieldConfig } from './form-field.model'
40
41
  FormFieldWrapperComponent,
41
42
  FormFieldLicenseComponent,
42
43
  FormFieldResourceUpdatedComponent,
44
+ FormFieldUpdateFrequencyComponent,
43
45
  FormFieldSimpleComponent,
44
46
  FormFieldRichComponent,
45
47
  FormFieldObjectComponent,
@@ -130,6 +132,9 @@ export class FormFieldComponent {
130
132
  get isResourceUpdated() {
131
133
  return this.model === 'resourceUpdated'
132
134
  }
135
+ get isUpdateFrequency() {
136
+ return this.model === 'updateFrequency'
137
+ }
133
138
 
134
139
  get withoutWrapper() {
135
140
  return this.model === 'title' || this.model === 'abstract'
@@ -47,4 +47,11 @@ export const DEFAULT_FIELDS: EditorFieldsConfig = [
47
47
  type: 'date',
48
48
  },
49
49
  },
50
+ {
51
+ model: 'updateFrequency',
52
+ formFieldConfig: {
53
+ labelKey: marker('editor.record.form.updateFrequency'),
54
+ type: 'text',
55
+ },
56
+ },
50
57
  ]
@@ -20,18 +20,21 @@ export interface MapContextLayerWmsModel {
20
20
  type: 'wms'
21
21
  url: string
22
22
  name: string
23
+ attributions?: string
23
24
  }
24
25
 
25
26
  export interface MapContextLayerWmtsModel {
26
27
  type: 'wmts'
27
28
  url: string
28
29
  name: string
30
+ attributions?: string
29
31
  }
30
32
 
31
33
  interface MapContextLayerWfsModel {
32
34
  type: 'wfs'
33
35
  url: string
34
36
  name: string
37
+ attributions?: string
35
38
  }
36
39
 
37
40
  export interface MapContextLayerOgcapiModel {
@@ -39,11 +42,13 @@ export interface MapContextLayerOgcapiModel {
39
42
  url: string
40
43
  name: string
41
44
  layerType: 'feature' | 'vectorTiles' | 'mapTiles' | 'record'
45
+ attributions?: string
42
46
  }
43
47
 
44
48
  interface LayerXyzModel {
45
49
  type: 'xyz'
46
50
  name?: string
51
+ attributions?: string
47
52
  }
48
53
  interface LayerXyzModelWithUrl extends LayerXyzModel {
49
54
  url: string
@@ -59,6 +64,7 @@ export type MapContextLayerXyzModel =
59
64
 
60
65
  interface LayerGeojson {
61
66
  type: 'geojson'
67
+ attributions?: string
62
68
  }
63
69
  interface LayerGeojsonWithUrl extends LayerGeojson {
64
70
  url: string
@@ -29,6 +29,8 @@ import OGCVectorTile from 'ol/source/OGCVectorTile.js'
29
29
  import { MVT } from 'ol/format'
30
30
  import VectorTileLayer from 'ol/layer/VectorTile'
31
31
  import OGCMapTile from 'ol/source/OGCMapTile.js'
32
+ import ImageLayer from 'ol/layer/Image'
33
+ import ImageWMS from 'ol/source/ImageWMS'
32
34
 
33
35
  export const DEFAULT_BASELAYER_CONTEXT: MapContextLayerXyzModel = {
34
36
  type: MapContextLayerTypeEnum.XYZ,
@@ -37,6 +39,7 @@ export const DEFAULT_BASELAYER_CONTEXT: MapContextLayerXyzModel = {
37
39
  `https://b.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png`,
38
40
  `https://c.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png`,
39
41
  ],
42
+ attributions: `<span>© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, © <a href="https://carto.com/">Carto</a></span>`,
40
43
  }
41
44
 
42
45
  export const DEFAULT_VIEW: MapContextViewModel = {
@@ -73,11 +76,13 @@ export class MapContextService {
73
76
  }
74
77
  map.setView(this.createView(mapContext.view, map))
75
78
  map.getLayers().clear()
76
- mapContext.layers.forEach((layer) => map.addLayer(this.createLayer(layer)))
79
+ mapContext.layers.forEach((layer) =>
80
+ map.addLayer(this.createLayer(layer, mapConfig))
81
+ )
77
82
  return map
78
83
  }
79
84
 
80
- createLayer(layerModel: MapContextLayerModel): Layer {
85
+ createLayer(layerModel: MapContextLayerModel, mapConfig?: MapConfig): Layer {
81
86
  const { type } = layerModel
82
87
  const style = this.styleService.styles.default
83
88
  switch (type) {
@@ -87,12 +92,14 @@ export class MapContextService {
87
92
  source: new OGCVectorTile({
88
93
  url: layerModel.url,
89
94
  format: new MVT(),
95
+ attributions: layerModel.attributions,
90
96
  }),
91
97
  })
92
98
  } else if (layerModel.layerType === 'mapTiles') {
93
99
  return new TileLayer({
94
100
  source: new OGCMapTile({
95
101
  url: layerModel.url,
102
+ attributions: layerModel.attributions,
96
103
  }),
97
104
  })
98
105
  } else {
@@ -100,6 +107,7 @@ export class MapContextService {
100
107
  source: new VectorSource({
101
108
  format: new GeoJSON(),
102
109
  url: layerModel.url,
110
+ attributions: layerModel.attributions,
103
111
  }),
104
112
  style,
105
113
  })
@@ -109,16 +117,28 @@ export class MapContextService {
109
117
  source: new XYZ({
110
118
  url: 'url' in layerModel ? layerModel.url : undefined,
111
119
  urls: 'urls' in layerModel ? layerModel.urls : undefined,
120
+ attributions: layerModel.attributions,
112
121
  }),
113
122
  })
114
123
  case MapContextLayerTypeEnum.WMS:
115
- return new TileLayer({
116
- source: new TileWMS({
117
- url: layerModel.url,
118
- params: { LAYERS: layerModel.name },
119
- gutter: 20,
120
- }),
121
- })
124
+ if (mapConfig?.DO_NOT_TILE_WMS) {
125
+ return new ImageLayer({
126
+ source: new ImageWMS({
127
+ url: layerModel.url,
128
+ params: { LAYERS: layerModel.name },
129
+ attributions: layerModel.attributions,
130
+ }),
131
+ })
132
+ } else {
133
+ return new TileLayer({
134
+ source: new TileWMS({
135
+ url: layerModel.url,
136
+ params: { LAYERS: layerModel.name, TILED: true },
137
+ attributions: layerModel.attributions,
138
+ }),
139
+ })
140
+ }
141
+
122
142
  case MapContextLayerTypeEnum.WMTS: {
123
143
  // TODO: isolate this in utils service
124
144
  const olLayer = new TileLayer({})
@@ -141,6 +161,7 @@ export class MapContextService {
141
161
  tileGrid,
142
162
  projection: matrixSet.crs,
143
163
  dimensions,
164
+ attributions: layerModel.attributions,
144
165
  })
145
166
  )
146
167
  })
@@ -166,6 +187,7 @@ export class MapContextService {
166
187
  })
167
188
  },
168
189
  strategy: bboxStrategy,
190
+ attributions: layerModel.attributions,
169
191
  })
170
192
  )
171
193
  })
@@ -26,6 +26,7 @@ import {
26
26
  MapContextLayerWmsModel,
27
27
  } from '../map-context/map-context.model'
28
28
  import Collection from 'ol/Collection'
29
+ import { defaults as defaultControls } from 'ol/control.js'
29
30
  import MapBrowserEvent from 'ol/MapBrowserEvent'
30
31
  import { CatalogRecord } from '../../../../../../libs/common/domain/src/lib/model/record'
31
32
  import { ProxyService } from '../../../../../../libs/util/shared/src'
@@ -47,7 +48,10 @@ export class MapUtilsService {
47
48
 
48
49
  createEmptyMap(): Map {
49
50
  return new Map({
50
- controls: [],
51
+ controls: defaultControls({
52
+ attribution: true,
53
+ attributionOptions: { collapsible: false },
54
+ }),
51
55
  pixelRatio: 1,
52
56
  })
53
57
  }
@@ -213,7 +217,7 @@ export class MapUtilsService {
213
217
  }
214
218
 
215
219
  getRecordExtent(record: Partial<CatalogRecord>): Extent {
216
- if (!('spatialExtents' in record)) {
220
+ if (!('spatialExtents' in record) || record.spatialExtents.length === 0) {
217
221
  return null
218
222
  }
219
223
  // transform an array of geojson geometries into a bbox
@@ -15,7 +15,7 @@ import {
15
15
  MapUtilsService,
16
16
  } from '../../../../../../libs/feature/map/src'
17
17
  import { getOptionalMapConfig, MapConfig } from '../../../../../../libs/util/app-config/src'
18
- import { getLinkLabel, ProxyService } from '../../../../../../libs/util/shared/src'
18
+ import { getLinkLabel } from '../../../../../../libs/util/shared/src'
19
19
  import Feature from 'ol/Feature'
20
20
  import { Geometry } from 'ol/geom'
21
21
  import { StyleLike } from 'ol/style/Style'
@@ -23,10 +23,8 @@ import {
23
23
  BehaviorSubject,
24
24
  combineLatest,
25
25
  from,
26
- lastValueFrom,
27
26
  Observable,
28
27
  of,
29
- startWith,
30
28
  Subscription,
31
29
  throwError,
32
30
  withLatestFrom,
@@ -57,9 +55,11 @@ export class MapViewComponent implements OnInit, OnDestroy {
57
55
 
58
56
  compatibleMapLinks$ = combineLatest([
59
57
  this.mdViewFacade.mapApiLinks$,
60
- this.mdViewFacade.geoDataLinks$,
58
+ this.mdViewFacade.geoDataLinksWithGeometry$,
61
59
  ]).pipe(
62
- map(([mapApiLinks, geoDataLinks]) => [...mapApiLinks, ...geoDataLinks])
60
+ map(([mapApiLinks, geoDataLinksWithGeometry]) => {
61
+ return [...mapApiLinks, ...geoDataLinksWithGeometry]
62
+ })
63
63
  )
64
64
 
65
65
  dropdownChoices$ = this.compatibleMapLinks$.pipe(
@@ -104,8 +104,8 @@ export class MapViewComponent implements OnInit, OnDestroy {
104
104
  mapContext$ = this.currentLayers$.pipe(
105
105
  switchMap((layers) =>
106
106
  from(this.mapUtils.getLayerExtent(layers[0])).pipe(
107
- catchError((error) => {
108
- console.warn(error) // FIXME: report this to the user somehow
107
+ catchError(() => {
108
+ this.error = 'The layer has no extent'
109
109
  return of(undefined)
110
110
  }),
111
111
  map(
@@ -117,7 +117,9 @@ export class MapViewComponent implements OnInit, OnDestroy {
117
117
  },
118
118
  } as MapContextModel)
119
119
  ),
120
- tap(() => this.resetSelection())
120
+ tap((res) => {
121
+ this.resetSelection()
122
+ })
121
123
  )
122
124
  ),
123
125
  withLatestFrom(this.mdViewFacade.metadata$),
@@ -1,6 +1,6 @@
1
1
  import { Injectable } from '@angular/core'
2
2
  import { select, Store } from '@ngrx/store'
3
- import { filter, map } from 'rxjs/operators'
3
+ import { defaultIfEmpty, filter, map, mergeMap, scan } from 'rxjs/operators'
4
4
  import * as MdViewActions from './mdview.actions'
5
5
  import * as MdViewSelectors from './mdview.selectors'
6
6
  import { LinkClassifierService, LinkUsage } from '../../../../../../libs/util/shared/src'
@@ -10,6 +10,9 @@ import {
10
10
  UserFeedback,
11
11
  } from '../../../../../../libs/common/domain/src/lib/model/record'
12
12
  import { AvatarServiceInterface } from '../../../../../../libs/api/repository/src'
13
+ import { OgcApiRecord } from '@camptocamp/ogc-client'
14
+ import { from, of } from 'rxjs'
15
+ import { DataService } from '../../../../../../libs/feature/dataviz/src'
13
16
 
14
17
  @Injectable()
15
18
  /**
@@ -21,8 +24,9 @@ import { AvatarServiceInterface } from '../../../../../../libs/api/repository/sr
21
24
  export class MdViewFacade {
22
25
  constructor(
23
26
  private store: Store,
24
- private linkClassifier: LinkClassifierService,
25
- private avatarService: AvatarServiceInterface
27
+ public linkClassifier: LinkClassifierService,
28
+ private avatarService: AvatarServiceInterface,
29
+ public dataService: DataService
26
30
  ) {}
27
31
 
28
32
  isPresent$ = this.store.pipe(
@@ -90,6 +94,39 @@ export class MdViewFacade {
90
94
  )
91
95
  )
92
96
 
97
+ geoDataLinksWithGeometry$ = this.allLinks$.pipe(
98
+ mergeMap((links) => {
99
+ return from(links)
100
+ }),
101
+ mergeMap((link) => {
102
+ if (this.linkClassifier.hasUsage(link, LinkUsage.GEODATA)) {
103
+ if (
104
+ link.type === 'service' &&
105
+ link.accessServiceProtocol === 'ogcFeatures'
106
+ ) {
107
+ return from(this.dataService.getItemsFromOgcApi(link.url.href)).pipe(
108
+ map((collectionRecords: OgcApiRecord) => {
109
+ return collectionRecords && collectionRecords.geometry
110
+ ? link
111
+ : null
112
+ }),
113
+ defaultIfEmpty(null)
114
+ )
115
+ } else {
116
+ return of(link)
117
+ }
118
+ } else {
119
+ return of(null)
120
+ }
121
+ }),
122
+ scan((acc, val) => {
123
+ if (val !== null && !acc.includes(val)) {
124
+ acc.push(val)
125
+ }
126
+ return acc
127
+ }, [])
128
+ )
129
+
93
130
  landingPageLinks$ = this.metadata$.pipe(
94
131
  map((record) => ('landingPage' in record ? [record.landingPage] : []))
95
132
  )