geonetwork-ui 2.3.0-dev.c3722986 → 2.3.0-dev.e07c5606

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 (296) hide show
  1. package/esm2022/index.mjs +2 -1
  2. package/esm2022/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.mjs +6 -2
  3. package/esm2022/libs/api/repository/src/lib/gn4/auth/avatar.service.interface.mjs +1 -1
  4. package/esm2022/libs/api/repository/src/lib/gn4/auth/gravatar.service.mjs +12 -1
  5. package/esm2022/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.mjs +36 -3
  6. package/esm2022/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.mjs +19 -7
  7. package/esm2022/libs/common/domain/src/lib/model/record/index.mjs +2 -1
  8. package/esm2022/libs/common/domain/src/lib/model/record/user-feedbacks.model.mjs +2 -0
  9. package/esm2022/libs/common/domain/src/lib/model/user/index.mjs +2 -0
  10. package/esm2022/libs/common/domain/src/lib/platform.service.interface.mjs +1 -1
  11. package/esm2022/libs/feature/editor/src/index.mjs +2 -2
  12. package/esm2022/libs/feature/editor/src/lib/+state/editor.facade.mjs +6 -2
  13. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-array/form-field-array.component.mjs +11 -0
  14. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-file/form-field-file.component.mjs +28 -0
  15. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.mjs +64 -0
  16. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-object/form-field-object.component.mjs +11 -0
  17. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.mjs +45 -0
  18. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-simple/form-field-simple.component.mjs +50 -0
  19. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-spatial-extent/form-field-spatial-extent.component.mjs +11 -0
  20. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-temporal-extent/form-field-temporal-extent.component.mjs +11 -0
  21. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.mjs +116 -0
  22. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field.model.mjs +2 -0
  23. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/index.mjs +10 -0
  24. package/esm2022/libs/feature/editor/src/lib/components/record-form/record-form.component.mjs +29 -0
  25. package/esm2022/libs/feature/editor/src/lib/components/wizard-field/wizard-field.component.mjs +1 -1
  26. package/esm2022/libs/feature/editor/src/lib/feature-editor.module.mjs +10 -10
  27. package/esm2022/libs/feature/editor/src/lib/fields.config.mjs +9 -1
  28. package/esm2022/libs/feature/editor/src/lib/models/fields.model.mjs +1 -1
  29. package/esm2022/libs/feature/map/src/lib/add-layer-from-file/add-layer-from-file.component.mjs +3 -3
  30. package/esm2022/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.mjs +1 -1
  31. package/esm2022/libs/feature/map/src/lib/add-layer-from-wfs/add-layer-from-wfs.component.mjs +1 -1
  32. package/esm2022/libs/feature/map/src/lib/add-layer-from-wms/add-layer-from-wms.component.mjs +1 -1
  33. package/esm2022/libs/feature/notifications/src/index.mjs +4 -0
  34. package/esm2022/libs/feature/notifications/src/lib/feature-notifications.module.mjs +18 -0
  35. package/esm2022/libs/feature/notifications/src/lib/notification.model.mjs +2 -0
  36. package/esm2022/libs/feature/notifications/src/lib/notifications-container/notifications-container.component.mjs +49 -0
  37. package/esm2022/libs/feature/notifications/src/lib/notifications.service.mjs +29 -0
  38. package/esm2022/libs/feature/record/src/lib/feature-record.module.mjs +4 -4
  39. package/esm2022/libs/feature/record/src/lib/state/mdview.actions.mjs +22 -4
  40. package/esm2022/libs/feature/record/src/lib/state/mdview.effects.mjs +37 -10
  41. package/esm2022/libs/feature/record/src/lib/state/mdview.facade.mjs +22 -7
  42. package/esm2022/libs/feature/record/src/lib/state/mdview.reducer.mjs +52 -17
  43. package/esm2022/libs/feature/record/src/lib/state/mdview.selectors.mjs +18 -3
  44. package/esm2022/libs/feature/router/src/lib/default/state/router.effects.mjs +2 -2
  45. package/esm2022/libs/feature/search/src/lib/results-table/results-table.component.mjs +3 -3
  46. package/esm2022/libs/ui/catalog/src/lib/organisation-preview/organisation-preview.component.mjs +3 -3
  47. package/esm2022/libs/ui/elements/src/index.mjs +15 -15
  48. package/esm2022/libs/ui/elements/src/lib/image-overlay-preview/image-overlay-preview.component.mjs +3 -3
  49. package/esm2022/libs/ui/elements/src/lib/markdown-editor/markdown-editor.component.mjs +45 -0
  50. package/esm2022/libs/ui/elements/src/lib/notification/notification.component.mjs +34 -0
  51. package/esm2022/libs/ui/elements/src/lib/record-api-form/record-api-form.component.mjs +3 -3
  52. package/esm2022/libs/ui/elements/src/lib/ui-elements.module.mjs +10 -2
  53. package/esm2022/libs/ui/elements/src/lib/user-feedback-item/time-since.pipe.mjs +59 -0
  54. package/esm2022/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.mjs +62 -0
  55. package/esm2022/libs/ui/inputs/src/index.mjs +1 -2
  56. package/esm2022/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.mjs +17 -8
  57. package/esm2022/libs/ui/inputs/src/lib/text-area/text-area.component.mjs +27 -4
  58. package/esm2022/libs/ui/inputs/src/lib/text-input/text-input.component.mjs +19 -3
  59. package/esm2022/libs/ui/inputs/src/lib/ui-inputs.module.mjs +7 -25
  60. package/esm2022/libs/ui/layout/src/index.mjs +6 -5
  61. package/esm2022/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.mjs +18 -0
  62. package/esm2022/translations/de.json +33 -0
  63. package/esm2022/translations/en.json +33 -0
  64. package/esm2022/translations/es.json +33 -0
  65. package/esm2022/translations/fr.json +33 -0
  66. package/esm2022/translations/it.json +33 -0
  67. package/esm2022/translations/nl.json +33 -0
  68. package/esm2022/translations/pt.json +33 -0
  69. package/fesm2022/geonetwork-ui.mjs +1835 -1015
  70. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  71. package/index.d.ts +1 -0
  72. package/index.d.ts.map +1 -1
  73. package/index.ts +1 -0
  74. package/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.d.ts.map +1 -1
  75. package/libs/api/repository/src/lib/gn4/auth/avatar.service.interface.d.ts +1 -0
  76. package/libs/api/repository/src/lib/gn4/auth/avatar.service.interface.d.ts.map +1 -1
  77. package/libs/api/repository/src/lib/gn4/auth/gravatar.service.d.ts +1 -0
  78. package/libs/api/repository/src/lib/gn4/auth/gravatar.service.d.ts.map +1 -1
  79. package/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.d.ts +6 -2
  80. package/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.d.ts.map +1 -1
  81. package/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.d.ts +9 -6
  82. package/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.d.ts.map +1 -1
  83. package/libs/common/domain/src/lib/model/record/index.d.ts +1 -0
  84. package/libs/common/domain/src/lib/model/record/index.d.ts.map +1 -1
  85. package/libs/common/domain/src/lib/model/record/user-feedbacks.model.d.ts +15 -0
  86. package/libs/common/domain/src/lib/model/record/user-feedbacks.model.d.ts.map +1 -0
  87. package/libs/common/domain/src/lib/model/user/index.d.ts +2 -0
  88. package/libs/common/domain/src/lib/model/user/index.d.ts.map +1 -0
  89. package/libs/common/domain/src/lib/platform.service.interface.d.ts +3 -0
  90. package/libs/common/domain/src/lib/platform.service.interface.d.ts.map +1 -1
  91. package/libs/feature/editor/src/index.d.ts +1 -1
  92. package/libs/feature/editor/src/index.d.ts.map +1 -1
  93. package/libs/feature/editor/src/lib/+state/editor.facade.d.ts +8 -5
  94. package/libs/feature/editor/src/lib/+state/editor.facade.d.ts.map +1 -1
  95. package/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field-array/form-field-array.component.d.ts +1 -1
  96. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-array/form-field-array.component.d.ts.map +1 -0
  97. package/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field-file/form-field-file.component.d.ts +1 -1
  98. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-file/form-field-file.component.d.ts.map +1 -0
  99. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.d.ts +39 -0
  100. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.d.ts.map +1 -0
  101. package/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field-object/form-field-object.component.d.ts +1 -1
  102. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-object/form-field-object.component.d.ts.map +1 -0
  103. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.d.ts +16 -0
  104. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.d.ts.map +1 -0
  105. package/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field-simple/form-field-simple.component.d.ts +2 -2
  106. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-simple/form-field-simple.component.d.ts.map +1 -0
  107. package/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field-spatial-extent/form-field-spatial-extent.component.d.ts +1 -1
  108. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-spatial-extent/form-field-spatial-extent.component.d.ts.map +1 -0
  109. package/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field-temporal-extent/form-field-temporal-extent.component.d.ts +1 -1
  110. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-temporal-extent/form-field-temporal-extent.component.d.ts.map +1 -0
  111. package/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field.component.d.ts +11 -4
  112. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts.map +1 -0
  113. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.model.d.ts.map +1 -0
  114. package/libs/feature/editor/src/lib/components/record-form/form-field/index.d.ts.map +1 -0
  115. package/libs/feature/editor/src/lib/{record-form → components/record-form}/record-form.component.d.ts +3 -3
  116. package/libs/feature/editor/src/lib/components/record-form/record-form.component.d.ts.map +1 -0
  117. package/libs/feature/editor/src/lib/feature-editor.module.d.ts +1 -1
  118. package/libs/feature/editor/src/lib/feature-editor.module.d.ts.map +1 -1
  119. package/libs/feature/editor/src/lib/fields.config.d.ts.map +1 -1
  120. package/libs/feature/editor/src/lib/models/fields.model.d.ts +1 -1
  121. package/libs/feature/notifications/src/index.d.ts +4 -0
  122. package/libs/feature/notifications/src/index.d.ts.map +1 -0
  123. package/libs/feature/notifications/src/lib/feature-notifications.module.d.ts +7 -0
  124. package/libs/feature/notifications/src/lib/feature-notifications.module.d.ts.map +1 -0
  125. package/libs/feature/notifications/src/lib/notification.model.d.ts +7 -0
  126. package/libs/feature/notifications/src/lib/notification.model.d.ts.map +1 -0
  127. package/libs/feature/notifications/src/lib/notifications-container/notifications-container.component.d.ts +12 -0
  128. package/libs/feature/notifications/src/lib/notifications-container/notifications-container.component.d.ts.map +1 -0
  129. package/libs/feature/notifications/src/lib/notifications.service.d.ts +15 -0
  130. package/libs/feature/notifications/src/lib/notifications.service.d.ts.map +1 -0
  131. package/libs/feature/record/src/lib/feature-record.module.d.ts.map +1 -1
  132. package/libs/feature/record/src/lib/state/mdview.actions.d.ts +40 -6
  133. package/libs/feature/record/src/lib/state/mdview.actions.d.ts.map +1 -1
  134. package/libs/feature/record/src/lib/state/mdview.effects.d.ts +24 -4
  135. package/libs/feature/record/src/lib/state/mdview.effects.d.ts.map +1 -1
  136. package/libs/feature/record/src/lib/state/mdview.facade.d.ts +14 -4
  137. package/libs/feature/record/src/lib/state/mdview.facade.d.ts.map +1 -1
  138. package/libs/feature/record/src/lib/state/mdview.reducer.d.ts +8 -5
  139. package/libs/feature/record/src/lib/state/mdview.reducer.d.ts.map +1 -1
  140. package/libs/feature/record/src/lib/state/mdview.selectors.d.ts +12 -9
  141. package/libs/feature/record/src/lib/state/mdview.selectors.d.ts.map +1 -1
  142. package/libs/ui/elements/src/index.d.ts +14 -14
  143. package/libs/ui/elements/src/index.d.ts.map +1 -1
  144. package/libs/ui/elements/src/lib/markdown-editor/markdown-editor.component.d.ts +13 -0
  145. package/libs/ui/elements/src/lib/markdown-editor/markdown-editor.component.d.ts.map +1 -0
  146. package/libs/ui/elements/src/lib/notification/notification.component.d.ts +13 -0
  147. package/libs/ui/elements/src/lib/notification/notification.component.d.ts.map +1 -0
  148. package/libs/ui/elements/src/lib/ui-elements.module.d.ts +16 -14
  149. package/libs/ui/elements/src/lib/ui-elements.module.d.ts.map +1 -1
  150. package/libs/ui/elements/src/lib/user-feedback-item/time-since.pipe.d.ts +11 -0
  151. package/libs/ui/elements/src/lib/user-feedback-item/time-since.pipe.d.ts.map +1 -0
  152. package/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.d.ts +22 -0
  153. package/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.d.ts.map +1 -0
  154. package/libs/ui/inputs/src/index.d.ts +0 -1
  155. package/libs/ui/inputs/src/index.d.ts.map +1 -1
  156. package/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.d.ts +1 -1
  157. package/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.d.ts.map +1 -1
  158. package/libs/ui/inputs/src/lib/text-area/text-area.component.d.ts +7 -1
  159. package/libs/ui/inputs/src/lib/text-area/text-area.component.d.ts.map +1 -1
  160. package/libs/ui/inputs/src/lib/text-input/text-input.component.d.ts +4 -1
  161. package/libs/ui/inputs/src/lib/text-input/text-input.component.d.ts.map +1 -1
  162. package/libs/ui/inputs/src/lib/ui-inputs.module.d.ts +35 -43
  163. package/libs/ui/inputs/src/lib/ui-inputs.module.d.ts.map +1 -1
  164. package/libs/ui/layout/src/index.d.ts +5 -4
  165. package/libs/ui/layout/src/index.d.ts.map +1 -1
  166. package/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.d.ts +8 -0
  167. package/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.d.ts.map +1 -0
  168. package/package.json +1 -1
  169. package/src/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts +7 -1
  170. package/src/libs/api/repository/src/lib/gn4/auth/avatar.service.interface.ts +1 -0
  171. package/src/libs/api/repository/src/lib/gn4/auth/gravatar.service.ts +12 -1
  172. package/src/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.ts +51 -1
  173. package/src/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.ts +34 -7
  174. package/src/libs/common/domain/src/lib/model/record/index.ts +1 -0
  175. package/src/libs/common/domain/src/lib/model/record/user-feedbacks.model.ts +15 -0
  176. package/src/libs/common/domain/src/lib/platform.service.interface.ts +3 -0
  177. package/src/libs/common/fixtures/src/index.ts +8 -6
  178. package/src/libs/common/fixtures/src/lib/records.fixtures.ts +1 -1
  179. package/src/libs/common/fixtures/src/lib/user-feedbacks.fixtures.ts +83 -0
  180. package/src/libs/feature/editor/src/index.ts +1 -1
  181. package/src/libs/feature/editor/src/lib/+state/editor.facade.ts +8 -1
  182. package/src/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field-array/form-field-array.component.ts +1 -0
  183. package/src/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field-file/form-field-file.component.ts +4 -1
  184. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.html +8 -0
  185. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.ts +64 -0
  186. package/src/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field-object/form-field-object.component.ts +1 -0
  187. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.html +20 -0
  188. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.ts +44 -0
  189. package/src/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field-simple/form-field-simple.component.ts +4 -1
  190. package/src/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field-spatial-extent/form-field-spatial-extent.component.ts +1 -0
  191. package/src/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field-temporal-extent/form-field-temporal-extent.component.ts +1 -0
  192. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html +87 -0
  193. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts +132 -0
  194. package/src/libs/feature/editor/src/lib/components/record-form/record-form.component.css +0 -0
  195. package/src/libs/feature/editor/src/lib/{record-form → components/record-form}/record-form.component.html +1 -0
  196. package/src/libs/feature/editor/src/lib/{record-form → components/record-form}/record-form.component.ts +4 -4
  197. package/src/libs/feature/editor/src/lib/feature-editor.module.ts +9 -9
  198. package/src/libs/feature/editor/src/lib/fields.config.ts +8 -0
  199. package/src/libs/feature/editor/src/lib/models/fields.model.ts +1 -1
  200. package/src/libs/feature/map/src/lib/add-layer-from-file/add-layer-from-file.component.html +1 -1
  201. package/src/libs/feature/notifications/src/index.ts +3 -0
  202. package/src/libs/feature/notifications/src/lib/feature-notifications.module.ts +10 -0
  203. package/src/libs/feature/notifications/src/lib/notification.model.ts +6 -0
  204. package/src/libs/feature/notifications/src/lib/notifications-container/notifications-container.component.css +0 -0
  205. package/src/libs/feature/notifications/src/lib/notifications-container/notifications-container.component.html +17 -0
  206. package/src/libs/feature/notifications/src/lib/notifications-container/notifications-container.component.ts +44 -0
  207. package/src/libs/feature/notifications/src/lib/notifications.service.ts +27 -0
  208. package/src/libs/feature/record/src/lib/feature-record.module.ts +5 -2
  209. package/src/libs/feature/record/src/lib/state/mdview.actions.ts +51 -6
  210. package/src/libs/feature/record/src/lib/state/mdview.effects.ts +82 -7
  211. package/src/libs/feature/record/src/lib/state/mdview.facade.ts +49 -8
  212. package/src/libs/feature/record/src/lib/state/mdview.reducer.ts +81 -24
  213. package/src/libs/feature/record/src/lib/state/mdview.selectors.ts +40 -10
  214. package/src/libs/feature/router/src/lib/default/state/router.effects.ts +2 -2
  215. package/src/libs/feature/search/src/lib/results-table/results-table.component.html +3 -3
  216. package/src/libs/ui/catalog/src/lib/organisation-preview/organisation-preview.component.html +5 -5
  217. package/src/libs/ui/elements/src/index.ts +14 -14
  218. package/src/libs/ui/elements/src/lib/image-overlay-preview/image-overlay-preview.component.html +1 -1
  219. package/src/libs/ui/elements/src/lib/markdown-editor/markdown-editor.component.css +0 -5
  220. package/src/libs/ui/elements/src/lib/markdown-editor/markdown-editor.component.html +0 -21
  221. package/src/libs/ui/elements/src/lib/markdown-editor/markdown-editor.component.ts +1 -14
  222. package/src/libs/ui/elements/src/lib/notification/notification.component.css +0 -0
  223. package/src/libs/ui/elements/src/lib/notification/notification.component.html +52 -0
  224. package/src/libs/ui/elements/src/lib/notification/notification.component.ts +31 -0
  225. package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.html +1 -1
  226. package/src/libs/ui/elements/src/lib/ui-elements.module.ts +5 -0
  227. package/src/libs/ui/elements/src/lib/user-feedback-item/time-since.pipe.ts +54 -0
  228. package/src/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.css +0 -0
  229. package/src/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.html +75 -0
  230. package/src/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.ts +63 -0
  231. package/src/libs/ui/inputs/src/index.ts +0 -1
  232. package/src/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.ts +13 -0
  233. package/src/libs/ui/inputs/src/lib/text-area/text-area.component.html +2 -1
  234. package/src/libs/ui/inputs/src/lib/text-area/text-area.component.ts +29 -0
  235. package/src/libs/ui/inputs/src/lib/text-input/text-input.component.html +1 -1
  236. package/src/libs/ui/inputs/src/lib/text-input/text-input.component.ts +16 -1
  237. package/src/libs/ui/inputs/src/lib/ui-inputs.module.ts +1 -20
  238. package/src/libs/ui/layout/src/index.ts +5 -4
  239. package/src/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.css +0 -0
  240. package/src/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.html +18 -0
  241. package/src/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.ts +16 -0
  242. package/tailwind.base.css +36 -0
  243. package/translations/de.json +33 -0
  244. package/translations/en.json +33 -0
  245. package/translations/es.json +33 -0
  246. package/translations/fr.json +33 -0
  247. package/translations/it.json +33 -0
  248. package/translations/nl.json +33 -0
  249. package/translations/pt.json +33 -0
  250. package/translations/sk.json +33 -0
  251. package/esm2022/libs/feature/editor/src/lib/record-form/record-form.component.mjs +0 -30
  252. package/esm2022/libs/ui/inputs/src/lib/form-field/form-field-array/form-field-array.component.mjs +0 -11
  253. package/esm2022/libs/ui/inputs/src/lib/form-field/form-field-file/form-field-file.component.mjs +0 -27
  254. package/esm2022/libs/ui/inputs/src/lib/form-field/form-field-object/form-field-object.component.mjs +0 -11
  255. package/esm2022/libs/ui/inputs/src/lib/form-field/form-field-rich/form-field-rich.component.mjs +0 -27
  256. package/esm2022/libs/ui/inputs/src/lib/form-field/form-field-simple/form-field-simple.component.mjs +0 -49
  257. package/esm2022/libs/ui/inputs/src/lib/form-field/form-field-spatial-extent/form-field-spatial-extent.component.mjs +0 -11
  258. package/esm2022/libs/ui/inputs/src/lib/form-field/form-field-temporal-extent/form-field-temporal-extent.component.mjs +0 -11
  259. package/esm2022/libs/ui/inputs/src/lib/form-field/form-field.component.mjs +0 -76
  260. package/esm2022/libs/ui/inputs/src/lib/form-field/form-field.model.mjs +0 -2
  261. package/esm2022/libs/ui/inputs/src/lib/form-field/index.mjs +0 -10
  262. package/libs/feature/editor/src/lib/record-form/record-form.component.d.ts.map +0 -1
  263. package/libs/ui/inputs/src/lib/form-field/form-field-array/form-field-array.component.d.ts.map +0 -1
  264. package/libs/ui/inputs/src/lib/form-field/form-field-file/form-field-file.component.d.ts.map +0 -1
  265. package/libs/ui/inputs/src/lib/form-field/form-field-object/form-field-object.component.d.ts.map +0 -1
  266. package/libs/ui/inputs/src/lib/form-field/form-field-rich/form-field-rich.component.d.ts +0 -11
  267. package/libs/ui/inputs/src/lib/form-field/form-field-rich/form-field-rich.component.d.ts.map +0 -1
  268. package/libs/ui/inputs/src/lib/form-field/form-field-simple/form-field-simple.component.d.ts.map +0 -1
  269. package/libs/ui/inputs/src/lib/form-field/form-field-spatial-extent/form-field-spatial-extent.component.d.ts.map +0 -1
  270. package/libs/ui/inputs/src/lib/form-field/form-field-temporal-extent/form-field-temporal-extent.component.d.ts.map +0 -1
  271. package/libs/ui/inputs/src/lib/form-field/form-field.component.d.ts.map +0 -1
  272. package/libs/ui/inputs/src/lib/form-field/form-field.model.d.ts.map +0 -1
  273. package/libs/ui/inputs/src/lib/form-field/index.d.ts.map +0 -1
  274. package/src/libs/ui/inputs/src/lib/form-field/form-field-rich/form-field-rich.component.html +0 -11
  275. package/src/libs/ui/inputs/src/lib/form-field/form-field-rich/form-field-rich.component.ts +0 -15
  276. package/src/libs/ui/inputs/src/lib/form-field/form-field.component.html +0 -68
  277. package/src/libs/ui/inputs/src/lib/form-field/form-field.component.ts +0 -80
  278. /package/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field.model.d.ts +0 -0
  279. /package/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/index.d.ts +0 -0
  280. /package/src/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field-array/form-field-array.component.css +0 -0
  281. /package/src/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field-array/form-field-array.component.html +0 -0
  282. /package/src/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field-file/form-field-file.component.css +0 -0
  283. /package/src/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field-file/form-field-file.component.html +0 -0
  284. /package/src/libs/feature/editor/src/lib/{record-form/record-form.component.css → components/record-form/form-field/form-field-license/form-field-license.component.css} +0 -0
  285. /package/src/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field-object/form-field-object.component.css +0 -0
  286. /package/src/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field-object/form-field-object.component.html +0 -0
  287. /package/src/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field-rich/form-field-rich.component.css +0 -0
  288. /package/src/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field-simple/form-field-simple.component.css +0 -0
  289. /package/src/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field-simple/form-field-simple.component.html +0 -0
  290. /package/src/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field-spatial-extent/form-field-spatial-extent.component.css +0 -0
  291. /package/src/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field-spatial-extent/form-field-spatial-extent.component.html +0 -0
  292. /package/src/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field-temporal-extent/form-field-temporal-extent.component.css +0 -0
  293. /package/src/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field-temporal-extent/form-field-temporal-extent.component.html +0 -0
  294. /package/src/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field.component.css +0 -0
  295. /package/src/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field.model.ts +0 -0
  296. /package/src/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/index.ts +0 -0
@@ -1,7 +1,7 @@
1
1
  import { parseXml, XmlDocument, XmlElement, XmlText } from '@rgrove/parse-xml';
2
2
  import format from 'date-fns/format';
3
3
  import * as i0 from '@angular/core';
4
- import { InjectionToken, Injectable, Optional, Inject, NgModule, SkipSelf, Component, ChangeDetectionStrategy, Input, ViewChild, Directive, HostListener, EventEmitter, Output, ElementRef, ViewChildren, ViewContainerRef, TemplateRef, Host, ContentChild, HostBinding, ContentChildren, inject } from '@angular/core';
4
+ import { InjectionToken, Injectable, Optional, Inject, NgModule, SkipSelf, Component, ChangeDetectionStrategy, Input, ViewChild, Directive, HostListener, EventEmitter, Output, ElementRef, ViewChildren, ViewContainerRef, HostBinding, ContentChild, ContentChildren, TemplateRef, Host, Pipe, inject } from '@angular/core';
5
5
  import * as i1 from '@angular/common/http';
6
6
  import { HttpHeaders, HttpParams, HttpClient, HttpClientModule, HTTP_INTERCEPTORS, HttpClientXsrfModule } from '@angular/common/http';
7
7
  import * as i1$1 from '@ngx-translate/core';
@@ -12,7 +12,7 @@ import { map as map$1, shareReplay, filter, tap as tap$1, startWith, withLatestF
12
12
  import { marker } from '@biesbjerg/ngx-translate-extract-marker';
13
13
  import * as i1$3 from '@angular/common';
14
14
  import { CommonModule, NgOptimizedImage, NgForOf } from '@angular/common';
15
- import { of, map as map$2, lastValueFrom, switchMap, combineLatest, takeLast, forkJoin, Subject, merge, throwError, BehaviorSubject, firstValueFrom, fromEvent, timer, Subscription, ReplaySubject, distinctUntilChanged as distinctUntilChanged$1, debounceTime as debounceTime$1, animationFrameScheduler, from, tap as tap$2, Observable, buffer, combineLatestWith, catchError as catchError$1, takeUntil, EMPTY, withLatestFrom as withLatestFrom$1, startWith as startWith$1, pairwise as pairwise$1 } from 'rxjs';
15
+ import { of, map as map$2, lastValueFrom, switchMap, combineLatest, takeLast, forkJoin, firstValueFrom, Subject, merge, throwError, BehaviorSubject, fromEvent, timer, Subscription, ReplaySubject, distinctUntilChanged as distinctUntilChanged$1, debounceTime as debounceTime$1, animationFrameScheduler, from, tap as tap$2, Observable, buffer, combineLatestWith, catchError as catchError$1, takeUntil, exhaustMap, mergeMap as mergeMap$1, EMPTY, withLatestFrom as withLatestFrom$1, filter as filter$1, startWith as startWith$1, pairwise as pairwise$1 } from 'rxjs';
16
16
  import { valid, coerce, satisfies, ltr } from 'semver';
17
17
  import * as i1$2 from '@ngrx/store';
18
18
  import { createAction, props, createReducer, on, createFeatureSelector, createSelector, select, StoreModule, Store } from '@ngrx/store';
@@ -70,15 +70,18 @@ import { MatInputModule } from '@angular/material/input';
70
70
  import * as i1$7 from '@angular/router';
71
71
  import { RouterModule, RouterLink, RouteReuseStrategy } from '@angular/router';
72
72
  import Duration from 'duration-relativetimeformat';
73
+ import * as basicLightbox from 'basiclightbox';
73
74
  import { marked } from 'marked';
74
75
  import EmblaCarousel from 'embla-carousel';
75
- import * as basicLightbox from 'basiclightbox';
76
+ import { formatDistance } from 'date-fns';
77
+ import { enUS, sk, pt as pt$1, nl as nl$1, it as it$1, es as es$1, de as de$1, fr as fr$1 } from 'date-fns/locale';
76
78
  import * as i1$8 from '@ngrx/effects';
77
79
  import { createEffect, ofType, EffectsModule, Actions } from '@ngrx/effects';
78
80
  import tippy from 'tippy.js';
79
81
  import { valid as valid$1 } from 'geojson-validation';
80
82
  import { Polygon } from 'ol/geom';
81
83
  import { queryDataGouvFr, queryGeonames, queryGeoadmin } from '@geospatial-sdk/geocoding';
84
+ import { trigger, transition, animate, keyframes, style } from '@angular/animations';
82
85
  import { Chart, BarController, BarElement, CategoryScale, LinearScale, LineController, LineElement, PointElement, PieController, ArcElement, ScatterController, Tooltip, Colors, Legend } from 'chart.js';
83
86
  import * as i4$1 from '@angular/cdk/scrolling';
84
87
  import { ScrollingModule } from '@angular/cdk/scrolling';
@@ -17270,6 +17273,7 @@ var next$6 = "weiter";
17270
17273
  var previous$6 = "zurück";
17271
17274
  var records$6 = "Datensätze";
17272
17275
  var de = {
17276
+ "button.login": "",
17273
17277
  "catalog.figures.datasets": "{count, plural, =0{Datensätze} one{Datensatz} other{Datensätze}}",
17274
17278
  "catalog.figures.organisations": "{count, plural, =0{Organisationen} one{Organisation} other{Organisationen}}",
17275
17279
  "chart.aggregation.average": "Durchschnitt",
@@ -17415,7 +17419,25 @@ var de = {
17415
17419
  "downloads.format.unknown": "unbekannt",
17416
17420
  "downloads.wfs.featuretype.not.found": "Der Layer wurde nicht gefunden",
17417
17421
  dropFile: dropFile$6,
17422
+ "editor.record.form.license": "Lizenz",
17423
+ "editor.record.form.license.cc-by": "",
17424
+ "editor.record.form.license.cc-by-sa": "",
17425
+ "editor.record.form.license.cc-zero": "",
17426
+ "editor.record.form.license.etalab": "",
17427
+ "editor.record.form.license.etalab-v2": "",
17428
+ "editor.record.form.license.odbl": "",
17429
+ "editor.record.form.license.odc-by": "",
17430
+ "editor.record.form.license.pddl": "",
17431
+ "editor.record.form.license.unknown": "Unbekannt oder nicht vorhanden",
17432
+ "editor.record.loadError.body": "",
17433
+ "editor.record.loadError.closeMessage": "",
17434
+ "editor.record.loadError.title": "",
17418
17435
  "editor.record.publish": "",
17436
+ "editor.record.publishError.body": "",
17437
+ "editor.record.publishError.closeMessage": "",
17438
+ "editor.record.publishError.title": "",
17439
+ "editor.record.publishSuccess.body": "",
17440
+ "editor.record.publishSuccess.title": "",
17419
17441
  "editor.record.upToDate": "",
17420
17442
  "externalviewer.dataset.unnamed": "Datensatz aus dem Datahub",
17421
17443
  "facets.block.title.OrgForResource": "Organisation",
@@ -17541,6 +17563,14 @@ var de = {
17541
17563
  "record.metadata.quality.updateFrequency.failed": "Aktualisierungsfrequenz nicht angegeben",
17542
17564
  "record.metadata.quality.updateFrequency.success": "Aktualisierungsfrequenz angegeben",
17543
17565
  "record.metadata.related": "Ähnliche Datensätze",
17566
+ "record.metadata.userFeedbacks": "",
17567
+ "record.metadata.userFeedbacks.anonymousUser": "",
17568
+ "record.metadata.userFeedbacks.sortSelector.label": "",
17569
+ "record.metadata.userFeedbacks.sortSelector.choices.newestFirst": "",
17570
+ "record.metadata.userFeedbacks.sortSelector.choices.oldestFirst": "",
17571
+ "record.metadata.userFeedbacks.newComment.placeholder": "",
17572
+ "record.metadata.userFeedbacks.newAnswer.placeholder": "",
17573
+ "record.metadata.userFeedbacks.newAnswer.buttonTitle": "",
17544
17574
  "record.metadata.sheet": "Weitere Informationen verfügbar unter:",
17545
17575
  "record.metadata.status": "Status",
17546
17576
  "record.metadata.technical": "Technische Informationen",
@@ -17614,6 +17644,12 @@ var de = {
17614
17644
  "table.loading.data": "Daten werden geladen...",
17615
17645
  "table.object.count": "Objekte in diesem Datensatz",
17616
17646
  "table.select.data": "Datenquelle",
17647
+ "timeSincePipe.lessThanAMinute": "",
17648
+ "timeSincePipe.minutesAgo": "",
17649
+ "timeSincePipe.hoursAgo": "",
17650
+ "timeSincePipe.daysAgo": "",
17651
+ "timeSincePipe.monthsAgo": "",
17652
+ "timeSincePipe.yearsAgo": "",
17617
17653
  "tooltip.html.copy": "HTML kopieren",
17618
17654
  "tooltip.id.copy": "Eindeutige Kennung kopieren",
17619
17655
  "tooltip.url.copy": "URL kopieren",
@@ -17632,6 +17668,7 @@ var next$5 = "next";
17632
17668
  var previous$5 = "previous";
17633
17669
  var records$5 = "records";
17634
17670
  var en = {
17671
+ "button.login": "Log in",
17635
17672
  "catalog.figures.datasets": "{count, plural, =0{datasets} one{dataset} other{datasets}}",
17636
17673
  "catalog.figures.organisations": "{count, plural, =0{organisations} one{organisation} other{organisations}}",
17637
17674
  "chart.aggregation.average": "average",
@@ -17777,7 +17814,25 @@ var en = {
17777
17814
  "downloads.format.unknown": "unknown",
17778
17815
  "downloads.wfs.featuretype.not.found": "The layer was not found",
17779
17816
  dropFile: dropFile$5,
17817
+ "editor.record.form.license": "License",
17818
+ "editor.record.form.license.cc-by": "Creative Commons CC-BY",
17819
+ "editor.record.form.license.cc-by-sa": "Creative Commons CC-BY-SA",
17820
+ "editor.record.form.license.cc-zero": "Creative Commons CC-0",
17821
+ "editor.record.form.license.etalab": "Open Licence (Etalab)",
17822
+ "editor.record.form.license.etalab-v2": "Open Licence v2.0 (Etalab)",
17823
+ "editor.record.form.license.odbl": "Open Data Commons ODbL",
17824
+ "editor.record.form.license.odc-by": "Open Data Commons ODC-By",
17825
+ "editor.record.form.license.pddl": "Open Data Commons PDDL",
17826
+ "editor.record.form.license.unknown": "Unknown or absent",
17827
+ "editor.record.loadError.body": "The record could not be loaded:",
17828
+ "editor.record.loadError.closeMessage": "Understood",
17829
+ "editor.record.loadError.title": "Error loading record",
17780
17830
  "editor.record.publish": "Publish this record",
17831
+ "editor.record.publishError.body": "The record could not be published:",
17832
+ "editor.record.publishError.closeMessage": "Understood",
17833
+ "editor.record.publishError.title": "Error publishing record",
17834
+ "editor.record.publishSuccess.body": "The record was successfully published!",
17835
+ "editor.record.publishSuccess.title": "Publish success",
17781
17836
  "editor.record.upToDate": "This record is up to date",
17782
17837
  "externalviewer.dataset.unnamed": "Datahub layer",
17783
17838
  "facets.block.title.OrgForResource": "Organisation",
@@ -17903,6 +17958,14 @@ var en = {
17903
17958
  "record.metadata.quality.updateFrequency.failed": "Update frequency is not specified",
17904
17959
  "record.metadata.quality.updateFrequency.success": "Update frequency is specified",
17905
17960
  "record.metadata.related": "Related records",
17961
+ "record.metadata.userFeedbacks": "Questions / Answers",
17962
+ "record.metadata.userFeedbacks.anonymousUser": "In order to leave a comment, please log in.",
17963
+ "record.metadata.userFeedbacks.sortSelector.label": "Sort by ...",
17964
+ "record.metadata.userFeedbacks.sortSelector.choices.newestFirst": "Newest comments first",
17965
+ "record.metadata.userFeedbacks.sortSelector.choices.oldestFirst": "Oldest comments first",
17966
+ "record.metadata.userFeedbacks.newComment.placeholder": "Write your comment here...",
17967
+ "record.metadata.userFeedbacks.newAnswer.placeholder": "Answer...",
17968
+ "record.metadata.userFeedbacks.newAnswer.buttonTitle": "Publish",
17906
17969
  "record.metadata.sheet": "Original metadata",
17907
17970
  "record.metadata.status": "Status",
17908
17971
  "record.metadata.technical": "Technical information",
@@ -17976,6 +18039,12 @@ var en = {
17976
18039
  "table.loading.data": "Loading data...",
17977
18040
  "table.object.count": "objects in this dataset",
17978
18041
  "table.select.data": "Data source",
18042
+ "timeSincePipe.lessThanAMinute": "Less than a minute ago",
18043
+ "timeSincePipe.minutesAgo": "{value} minute{s} ago",
18044
+ "timeSincePipe.hoursAgo": "{value} hour{s} ago",
18045
+ "timeSincePipe.daysAgo": "{value} day{s} ago",
18046
+ "timeSincePipe.monthsAgo": "{value} month{s} ago",
18047
+ "timeSincePipe.yearsAgo": "{value} year{s} ago",
17979
18048
  "tooltip.html.copy": "Copy HTML",
17980
18049
  "tooltip.id.copy": "Copy unique identifier",
17981
18050
  "tooltip.url.copy": "Copy URL",
@@ -17994,6 +18063,7 @@ var next$4 = "";
17994
18063
  var previous$4 = "";
17995
18064
  var records$4 = "";
17996
18065
  var es = {
18066
+ "button.login": "",
17997
18067
  "catalog.figures.datasets": "conjuntos de datos",
17998
18068
  "catalog.figures.organisations": "organizaciones",
17999
18069
  "chart.aggregation.average": "promedio",
@@ -18139,7 +18209,25 @@ var es = {
18139
18209
  "downloads.format.unknown": "",
18140
18210
  "downloads.wfs.featuretype.not.found": "",
18141
18211
  dropFile: dropFile$4,
18212
+ "editor.record.form.license": "",
18213
+ "editor.record.form.license.cc-by": "",
18214
+ "editor.record.form.license.cc-by-sa": "",
18215
+ "editor.record.form.license.cc-zero": "",
18216
+ "editor.record.form.license.etalab": "",
18217
+ "editor.record.form.license.etalab-v2": "",
18218
+ "editor.record.form.license.odbl": "",
18219
+ "editor.record.form.license.odc-by": "",
18220
+ "editor.record.form.license.pddl": "",
18221
+ "editor.record.form.license.unknown": "",
18222
+ "editor.record.loadError.body": "",
18223
+ "editor.record.loadError.closeMessage": "",
18224
+ "editor.record.loadError.title": "",
18142
18225
  "editor.record.publish": "",
18226
+ "editor.record.publishError.body": "",
18227
+ "editor.record.publishError.closeMessage": "",
18228
+ "editor.record.publishError.title": "",
18229
+ "editor.record.publishSuccess.body": "",
18230
+ "editor.record.publishSuccess.title": "",
18143
18231
  "editor.record.upToDate": "",
18144
18232
  "externalviewer.dataset.unnamed": "",
18145
18233
  "facets.block.title.OrgForResource": "",
@@ -18265,6 +18353,14 @@ var es = {
18265
18353
  "record.metadata.quality.updateFrequency.failed": "",
18266
18354
  "record.metadata.quality.updateFrequency.success": "",
18267
18355
  "record.metadata.related": "",
18356
+ "record.metadata.userFeedbacks": "",
18357
+ "record.metadata.userFeedbacks.anonymousUser": "",
18358
+ "record.metadata.userFeedbacks.sortSelector.label": "",
18359
+ "record.metadata.userFeedbacks.sortSelector.choices.newestFirst": "",
18360
+ "record.metadata.userFeedbacks.sortSelector.choices.oldestFirst": "",
18361
+ "record.metadata.userFeedbacks.newComment.placeholder": "",
18362
+ "record.metadata.userFeedbacks.newAnswer.placeholder": "",
18363
+ "record.metadata.userFeedbacks.newAnswer.buttonTitle": "",
18268
18364
  "record.metadata.sheet": "",
18269
18365
  "record.metadata.status": "",
18270
18366
  "record.metadata.technical": "",
@@ -18338,6 +18434,12 @@ var es = {
18338
18434
  "table.loading.data": "",
18339
18435
  "table.object.count": "",
18340
18436
  "table.select.data": "",
18437
+ "timeSincePipe.lessThanAMinute": "",
18438
+ "timeSincePipe.minutesAgo": "",
18439
+ "timeSincePipe.hoursAgo": "",
18440
+ "timeSincePipe.daysAgo": "",
18441
+ "timeSincePipe.monthsAgo": "",
18442
+ "timeSincePipe.yearsAgo": "",
18341
18443
  "tooltip.html.copy": "",
18342
18444
  "tooltip.id.copy": "",
18343
18445
  "tooltip.url.copy": "",
@@ -18356,6 +18458,7 @@ var next$3 = "suivant";
18356
18458
  var previous$3 = "précédent";
18357
18459
  var records$3 = "enregistrements";
18358
18460
  var fr = {
18461
+ "button.login": "Se connecter",
18359
18462
  "catalog.figures.datasets": "{count, plural, =0{données} one{donnée} other{données}}",
18360
18463
  "catalog.figures.organisations": "{count, plural, =0{organisations} one{organisation} other{organisations}}",
18361
18464
  "chart.aggregation.average": "moyenne",
@@ -18501,7 +18604,25 @@ var fr = {
18501
18604
  "downloads.format.unknown": "inconnu",
18502
18605
  "downloads.wfs.featuretype.not.found": "La couche n'a pas été retrouvée",
18503
18606
  dropFile: dropFile$3,
18607
+ "editor.record.form.license": "Licence",
18608
+ "editor.record.form.license.cc-by": "",
18609
+ "editor.record.form.license.cc-by-sa": "",
18610
+ "editor.record.form.license.cc-zero": "",
18611
+ "editor.record.form.license.etalab": "Licence Ouverte (Etalab)",
18612
+ "editor.record.form.license.etalab-v2": "Licence Ouverte v2.0 (Etalab)",
18613
+ "editor.record.form.license.odbl": "",
18614
+ "editor.record.form.license.odc-by": "",
18615
+ "editor.record.form.license.pddl": "",
18616
+ "editor.record.form.license.unknown": "Non-reconnue ou absente",
18617
+ "editor.record.loadError.body": "",
18618
+ "editor.record.loadError.closeMessage": "",
18619
+ "editor.record.loadError.title": "",
18504
18620
  "editor.record.publish": "",
18621
+ "editor.record.publishError.body": "",
18622
+ "editor.record.publishError.closeMessage": "",
18623
+ "editor.record.publishError.title": "",
18624
+ "editor.record.publishSuccess.body": "",
18625
+ "editor.record.publishSuccess.title": "",
18505
18626
  "editor.record.upToDate": "",
18506
18627
  "externalviewer.dataset.unnamed": "Couche du datahub",
18507
18628
  "facets.block.title.OrgForResource": "Organisation",
@@ -18627,6 +18748,14 @@ var fr = {
18627
18748
  "record.metadata.quality.updateFrequency.failed": "Fréquence de mise à jour n'est pas renseignée",
18628
18749
  "record.metadata.quality.updateFrequency.success": "Fréquence de mise à jour est renseignée",
18629
18750
  "record.metadata.related": "Voir aussi",
18751
+ "record.metadata.userFeedbacks": "Questions / Réponses",
18752
+ "record.metadata.userFeedbacks.anonymousUser": "Pour rédiger un commentaire, veuillez vous identifier.",
18753
+ "record.metadata.userFeedbacks.sortSelector.label": "Trier par ...",
18754
+ "record.metadata.userFeedbacks.sortSelector.choices.newestFirst": "Les plus récents en premier",
18755
+ "record.metadata.userFeedbacks.sortSelector.choices.oldestFirst": "Les plus anciens en premier",
18756
+ "record.metadata.userFeedbacks.newComment.placeholder": "Rédiger votre commentaire ici...",
18757
+ "record.metadata.userFeedbacks.newAnswer.placeholder": "Répondre...",
18758
+ "record.metadata.userFeedbacks.newAnswer.buttonTitle": "Publier",
18630
18759
  "record.metadata.sheet": "Fiche de métadonnées d'origine",
18631
18760
  "record.metadata.status": "Statut",
18632
18761
  "record.metadata.technical": "Informations techniques",
@@ -18700,6 +18829,12 @@ var fr = {
18700
18829
  "table.loading.data": "Chargement des données...",
18701
18830
  "table.object.count": "enregistrements dans ces données",
18702
18831
  "table.select.data": "Source de données",
18832
+ "timeSincePipe.lessThanAMinute": "Il y a moins d'une minute",
18833
+ "timeSincePipe.minutesAgo": "Il y a {value} minute{s}",
18834
+ "timeSincePipe.hoursAgo": "Il y a {value} heure{s}",
18835
+ "timeSincePipe.daysAgo": "Il y a {value} jour{s}",
18836
+ "timeSincePipe.monthsAgo": "Il y a {value} mois",
18837
+ "timeSincePipe.yearsAgo": "Il y a {value} an{s}",
18703
18838
  "tooltip.html.copy": "Copier le HTML",
18704
18839
  "tooltip.id.copy": "Copier l'identifiant unique",
18705
18840
  "tooltip.url.copy": "Copier l'URL",
@@ -18718,6 +18853,7 @@ var next$2 = "successivo";
18718
18853
  var previous$2 = "precedente";
18719
18854
  var records$2 = "record";
18720
18855
  var it = {
18856
+ "button.login": "",
18721
18857
  "catalog.figures.datasets": "{count, plural, =0{datasets} one{dataset} other{datasets}}",
18722
18858
  "catalog.figures.organisations": "{count, plural, =0{organizzazioni} one{organizzazione} other{organizzazioni}}",
18723
18859
  "chart.aggregation.average": "media",
@@ -18863,7 +18999,25 @@ var it = {
18863
18999
  "downloads.format.unknown": "sconosciuto",
18864
19000
  "downloads.wfs.featuretype.not.found": "Il layer non è stato trovato",
18865
19001
  dropFile: dropFile$2,
19002
+ "editor.record.form.license": "Licenza",
19003
+ "editor.record.form.license.cc-by": "",
19004
+ "editor.record.form.license.cc-by-sa": "",
19005
+ "editor.record.form.license.cc-zero": "",
19006
+ "editor.record.form.license.etalab": "Licenza aperta (Etalab)",
19007
+ "editor.record.form.license.etalab-v2": "Licenza aperta v2.0 (Etalab)",
19008
+ "editor.record.form.license.odbl": "",
19009
+ "editor.record.form.license.odc-by": "",
19010
+ "editor.record.form.license.pddl": "",
19011
+ "editor.record.form.license.unknown": "Non riconosciuta o assente",
19012
+ "editor.record.loadError.body": "",
19013
+ "editor.record.loadError.closeMessage": "",
19014
+ "editor.record.loadError.title": "",
18866
19015
  "editor.record.publish": "",
19016
+ "editor.record.publishError.body": "",
19017
+ "editor.record.publishError.closeMessage": "",
19018
+ "editor.record.publishError.title": "",
19019
+ "editor.record.publishSuccess.body": "",
19020
+ "editor.record.publishSuccess.title": "",
18867
19021
  "editor.record.upToDate": "",
18868
19022
  "externalviewer.dataset.unnamed": "Layer del datahub",
18869
19023
  "facets.block.title.OrgForResource": "Organizzazione",
@@ -18989,6 +19143,14 @@ var it = {
18989
19143
  "record.metadata.quality.updateFrequency.failed": "La frequenza di aggiornamento non è specificata",
18990
19144
  "record.metadata.quality.updateFrequency.success": "La frequenza di aggiornamento è specificata",
18991
19145
  "record.metadata.related": "Vedi anche",
19146
+ "record.metadata.userFeedbacks": "",
19147
+ "record.metadata.userFeedbacks.anonymousUser": "",
19148
+ "record.metadata.userFeedbacks.sortSelector.label": "",
19149
+ "record.metadata.userFeedbacks.sortSelector.choices.newestFirst": "",
19150
+ "record.metadata.userFeedbacks.sortSelector.choices.oldestFirst": "",
19151
+ "record.metadata.userFeedbacks.newComment.placeholder": "",
19152
+ "record.metadata.userFeedbacks.newAnswer.placeholder": "",
19153
+ "record.metadata.userFeedbacks.newAnswer.buttonTitle": "",
18992
19154
  "record.metadata.sheet": "Origine del metadata",
18993
19155
  "record.metadata.status": "Stato",
18994
19156
  "record.metadata.technical": "Informazioni tecniche",
@@ -19062,6 +19224,12 @@ var it = {
19062
19224
  "table.loading.data": "Caricamento dei dati...",
19063
19225
  "table.object.count": "record in questi dati",
19064
19226
  "table.select.data": "Sorgente dati",
19227
+ "timeSincePipe.lessThanAMinute": "",
19228
+ "timeSincePipe.minutesAgo": "",
19229
+ "timeSincePipe.hoursAgo": "",
19230
+ "timeSincePipe.daysAgo": "",
19231
+ "timeSincePipe.monthsAgo": "",
19232
+ "timeSincePipe.yearsAgo": "",
19065
19233
  "tooltip.html.copy": "Copiare il HTML",
19066
19234
  "tooltip.id.copy": "Copiare l'identificatore unico",
19067
19235
  "tooltip.url.copy": "Copiare l'URL",
@@ -19080,6 +19248,7 @@ var next$1 = "";
19080
19248
  var previous$1 = "";
19081
19249
  var records$1 = "";
19082
19250
  var nl = {
19251
+ "button.login": "",
19083
19252
  "catalog.figures.datasets": "datasets",
19084
19253
  "catalog.figures.organisations": "organisaties",
19085
19254
  "chart.aggregation.average": "gemiddelde",
@@ -19225,7 +19394,25 @@ var nl = {
19225
19394
  "downloads.format.unknown": "",
19226
19395
  "downloads.wfs.featuretype.not.found": "",
19227
19396
  dropFile: dropFile$1,
19397
+ "editor.record.form.license": "",
19398
+ "editor.record.form.license.cc-by": "",
19399
+ "editor.record.form.license.cc-by-sa": "",
19400
+ "editor.record.form.license.cc-zero": "",
19401
+ "editor.record.form.license.etalab": "",
19402
+ "editor.record.form.license.etalab-v2": "",
19403
+ "editor.record.form.license.odbl": "",
19404
+ "editor.record.form.license.odc-by": "",
19405
+ "editor.record.form.license.pddl": "",
19406
+ "editor.record.form.license.unknown": "",
19407
+ "editor.record.loadError.body": "",
19408
+ "editor.record.loadError.closeMessage": "",
19409
+ "editor.record.loadError.title": "",
19228
19410
  "editor.record.publish": "",
19411
+ "editor.record.publishError.body": "",
19412
+ "editor.record.publishError.closeMessage": "",
19413
+ "editor.record.publishError.title": "",
19414
+ "editor.record.publishSuccess.body": "",
19415
+ "editor.record.publishSuccess.title": "",
19229
19416
  "editor.record.upToDate": "",
19230
19417
  "externalviewer.dataset.unnamed": "",
19231
19418
  "facets.block.title.OrgForResource": "",
@@ -19351,6 +19538,14 @@ var nl = {
19351
19538
  "record.metadata.quality.updateFrequency.failed": "",
19352
19539
  "record.metadata.quality.updateFrequency.success": "",
19353
19540
  "record.metadata.related": "",
19541
+ "record.metadata.userFeedbacks": "",
19542
+ "record.metadata.userFeedbacks.anonymousUser": "",
19543
+ "record.metadata.userFeedbacks.sortSelector.label": "",
19544
+ "record.metadata.userFeedbacks.sortSelector.choices.newestFirst": "",
19545
+ "record.metadata.userFeedbacks.sortSelector.choices.oldestFirst": "",
19546
+ "record.metadata.userFeedbacks.newComment.placeholder": "",
19547
+ "record.metadata.userFeedbacks.newAnswer.placeholder": "",
19548
+ "record.metadata.userFeedbacks.newAnswer.buttonTitle": "",
19354
19549
  "record.metadata.sheet": "",
19355
19550
  "record.metadata.status": "",
19356
19551
  "record.metadata.technical": "",
@@ -19424,6 +19619,12 @@ var nl = {
19424
19619
  "table.loading.data": "",
19425
19620
  "table.object.count": "",
19426
19621
  "table.select.data": "",
19622
+ "timeSincePipe.lessThanAMinute": "",
19623
+ "timeSincePipe.minutesAgo": "",
19624
+ "timeSincePipe.hoursAgo": "",
19625
+ "timeSincePipe.daysAgo": "",
19626
+ "timeSincePipe.monthsAgo": "",
19627
+ "timeSincePipe.yearsAgo": "",
19427
19628
  "tooltip.html.copy": "",
19428
19629
  "tooltip.id.copy": "",
19429
19630
  "tooltip.url.copy": "",
@@ -19442,6 +19643,7 @@ var next = "";
19442
19643
  var previous = "";
19443
19644
  var records = "";
19444
19645
  var pt = {
19646
+ "button.login": "",
19445
19647
  "catalog.figures.datasets": "conjuntos de dados",
19446
19648
  "catalog.figures.organisations": "organizações",
19447
19649
  "chart.aggregation.average": "média",
@@ -19587,7 +19789,25 @@ var pt = {
19587
19789
  "downloads.format.unknown": "",
19588
19790
  "downloads.wfs.featuretype.not.found": "",
19589
19791
  dropFile: dropFile,
19792
+ "editor.record.form.license": "",
19793
+ "editor.record.form.license.cc-by": "",
19794
+ "editor.record.form.license.cc-by-sa": "",
19795
+ "editor.record.form.license.cc-zero": "",
19796
+ "editor.record.form.license.etalab": "",
19797
+ "editor.record.form.license.etalab-v2": "",
19798
+ "editor.record.form.license.odbl": "",
19799
+ "editor.record.form.license.odc-by": "",
19800
+ "editor.record.form.license.pddl": "",
19801
+ "editor.record.form.license.unknown": "",
19802
+ "editor.record.loadError.body": "",
19803
+ "editor.record.loadError.closeMessage": "",
19804
+ "editor.record.loadError.title": "",
19590
19805
  "editor.record.publish": "",
19806
+ "editor.record.publishError.body": "",
19807
+ "editor.record.publishError.closeMessage": "",
19808
+ "editor.record.publishError.title": "",
19809
+ "editor.record.publishSuccess.body": "",
19810
+ "editor.record.publishSuccess.title": "",
19591
19811
  "editor.record.upToDate": "",
19592
19812
  "externalviewer.dataset.unnamed": "",
19593
19813
  "facets.block.title.OrgForResource": "",
@@ -19713,6 +19933,14 @@ var pt = {
19713
19933
  "record.metadata.quality.updateFrequency.failed": "",
19714
19934
  "record.metadata.quality.updateFrequency.success": "",
19715
19935
  "record.metadata.related": "",
19936
+ "record.metadata.userFeedbacks": "",
19937
+ "record.metadata.userFeedbacks.anonymousUser": "",
19938
+ "record.metadata.userFeedbacks.sortSelector.label": "",
19939
+ "record.metadata.userFeedbacks.sortSelector.choices.newestFirst": "",
19940
+ "record.metadata.userFeedbacks.sortSelector.choices.oldestFirst": "",
19941
+ "record.metadata.userFeedbacks.newComment.placeholder": "",
19942
+ "record.metadata.userFeedbacks.newAnswer.placeholder": "",
19943
+ "record.metadata.userFeedbacks.newAnswer.buttonTitle": "",
19716
19944
  "record.metadata.sheet": "",
19717
19945
  "record.metadata.status": "",
19718
19946
  "record.metadata.technical": "",
@@ -19786,6 +20014,12 @@ var pt = {
19786
20014
  "table.loading.data": "",
19787
20015
  "table.object.count": "",
19788
20016
  "table.select.data": "",
20017
+ "timeSincePipe.lessThanAMinute": "",
20018
+ "timeSincePipe.minutesAgo": "",
20019
+ "timeSincePipe.hoursAgo": "",
20020
+ "timeSincePipe.daysAgo": "",
20021
+ "timeSincePipe.monthsAgo": "",
20022
+ "timeSincePipe.yearsAgo": "",
19789
20023
  "tooltip.html.copy": "",
19790
20024
  "tooltip.id.copy": "",
19791
20025
  "tooltip.url.copy": "",
@@ -19880,7 +20114,11 @@ class Gn4FieldMapper {
19880
20114
  }),
19881
20115
  creationDateForResource: (output, source) => ({
19882
20116
  ...output,
19883
- datasetCreated: toDate(getFirstValue(selectField(source, 'creationDateForResource'))),
20117
+ resourceCreated: toDate(getFirstValue(selectField(source, 'creationDateForResource'))),
20118
+ }),
20119
+ revisionDateForResource: (output, source) => ({
20120
+ ...output,
20121
+ resourceUpdated: toDate(getFirstValue(selectField(source, 'revisionDateForResource'))),
19884
20122
  }),
19885
20123
  createDate: (output, source) => ({
19886
20124
  ...output,
@@ -21105,6 +21343,16 @@ class GravatarService {
21105
21343
  getProfileIcon(hash) {
21106
21344
  return this.identicon$.pipe(map$1((identicon) => identicon || this.GRAVATAR_IDENTICON), map$1((identicon) => `${this.GRAVATAR_URL}${hash}?d=${identicon}`));
21107
21345
  }
21346
+ async getProfileIconUrl(userId) {
21347
+ let iconUrl = '';
21348
+ try {
21349
+ iconUrl = await firstValueFrom(this.getProfileIcon(userId));
21350
+ }
21351
+ catch (error) {
21352
+ return '';
21353
+ }
21354
+ return iconUrl;
21355
+ }
21108
21356
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: GravatarService, deps: [{ token: Gn4SettingsService }], target: i0.ɵɵFactoryTarget.Injectable }); }
21109
21357
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: GravatarService, providedIn: 'root' }); }
21110
21358
  }
@@ -21256,6 +21504,39 @@ class Gn4PlatformMapper {
21256
21504
  };
21257
21505
  });
21258
21506
  }
21507
+ userFeedbacksFromApi(userFeedback) {
21508
+ return {
21509
+ uuid: userFeedback.uuid,
21510
+ metadataUUID: userFeedback.metadataUUID,
21511
+ comment: userFeedback.comment,
21512
+ authorUserId: userFeedback.authorUserId.toString(),
21513
+ authorName: userFeedback.authorName,
21514
+ authorEmail: userFeedback.authorEmail,
21515
+ published: userFeedback.published,
21516
+ parentUuid: userFeedback.parentUuid ?? undefined,
21517
+ date: new Date(userFeedback.date),
21518
+ };
21519
+ }
21520
+ userFeedbacksToApi(userFeedback) {
21521
+ return {
21522
+ uuid: userFeedback.uuid,
21523
+ metadataUUID: userFeedback.metadataUUID,
21524
+ comment: userFeedback.comment,
21525
+ authorUserId: Number.parseInt(userFeedback.authorUserId),
21526
+ authorName: userFeedback.authorName,
21527
+ authorEmail: userFeedback.authorEmail,
21528
+ published: userFeedback.published,
21529
+ parentUuid: userFeedback.parentUuid,
21530
+ date: userFeedback.date.getTime().toString(),
21531
+ };
21532
+ }
21533
+ async createUserFeedbackViewModel(baseUserFeedback) {
21534
+ const userAvatarUrl = await this.avatarService.getProfileIconUrl(baseUserFeedback.authorUserId?.toString());
21535
+ return {
21536
+ ...baseUserFeedback,
21537
+ avatarUrl: userAvatarUrl,
21538
+ };
21539
+ }
21259
21540
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: Gn4PlatformMapper, deps: [{ token: AvatarServiceInterface }], target: i0.ɵɵFactoryTarget.Injectable }); }
21260
21541
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: Gn4PlatformMapper }); }
21261
21542
  }
@@ -21265,7 +21546,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
21265
21546
 
21266
21547
  const minApiVersion = '4.2.2';
21267
21548
  class Gn4PlatformService {
21268
- constructor(siteApiService, meApi, usersApi, mapper, toolsApiService, registriesApiService, langService) {
21549
+ constructor(siteApiService, meApi, usersApi, mapper, toolsApiService, registriesApiService, langService, userfeedbackApiService) {
21269
21550
  this.siteApiService = siteApiService;
21270
21551
  this.meApi = meApi;
21271
21552
  this.usersApi = usersApi;
@@ -21273,6 +21554,7 @@ class Gn4PlatformService {
21273
21554
  this.toolsApiService = toolsApiService;
21274
21555
  this.registriesApiService = registriesApiService;
21275
21556
  this.langService = langService;
21557
+ this.userfeedbackApiService = userfeedbackApiService;
21276
21558
  this.type = 'GeoNetwork';
21277
21559
  this.keyTranslations$ = this.toolsApiService
21278
21560
  .getTranslationsPackage1('gnui')
@@ -21292,7 +21574,7 @@ class Gn4PlatformService {
21292
21574
  */
21293
21575
  this.thesauri = {};
21294
21576
  this.me$ = this.meApi.getMe().pipe(switchMap((apiUser) => this.mapper.userFromMeApi(apiUser)), shareReplay({ bufferSize: 1, refCount: true }));
21295
- this.isAnonymous$ = this.me$.pipe(map$1((user) => !user || !('id' in user)));
21577
+ this.isUserAnonymous$ = this.me$.pipe(map$1((user) => !user || !('id' in user)));
21296
21578
  this.users$ = this.usersApi.getUsers().pipe(map$1((users) => users.map((user) => this.mapper.userFromApi(user))), shareReplay());
21297
21579
  }
21298
21580
  getType() {
@@ -21305,7 +21587,7 @@ class Gn4PlatformService {
21305
21587
  return this.me$;
21306
21588
  }
21307
21589
  isAnonymous() {
21308
- return this.isAnonymous$;
21590
+ return this.isUserAnonymous$;
21309
21591
  }
21310
21592
  getOrganizations() {
21311
21593
  return undefined;
@@ -21341,12 +21623,23 @@ class Gn4PlatformService {
21341
21623
  .pipe(map$1((thesaurus) => this.mapper.thesaurusFromApi(thesaurus, this.langService.iso3)), shareReplay(1));
21342
21624
  return this.thesauri[uri];
21343
21625
  }
21344
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: Gn4PlatformService, deps: [{ token: SiteApiService }, { token: MeApiService }, { token: UsersApiService }, { token: Gn4PlatformMapper }, { token: ToolsApiService }, { token: RegistriesApiService }, { token: LangService }], target: i0.ɵɵFactoryTarget.Injectable }); }
21626
+ getUserFeedbacks(uuid) {
21627
+ return this.userfeedbackApiService
21628
+ .getUserComments(uuid)
21629
+ .pipe(map$1((userFeedbacks) => userFeedbacks.map(this.mapper.userFeedbacksFromApi)));
21630
+ }
21631
+ postUserFeedbacks(userFeedback) {
21632
+ const mappedUserFeedBack = this.mapper.userFeedbacksToApi(userFeedback);
21633
+ return this.userfeedbackApiService
21634
+ .newUserFeedback(mappedUserFeedBack)
21635
+ .pipe(map$1(() => undefined));
21636
+ }
21637
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: Gn4PlatformService, deps: [{ token: SiteApiService }, { token: MeApiService }, { token: UsersApiService }, { token: Gn4PlatformMapper }, { token: ToolsApiService }, { token: RegistriesApiService }, { token: LangService }, { token: UserfeedbackApiService }], target: i0.ɵɵFactoryTarget.Injectable }); }
21345
21638
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: Gn4PlatformService }); }
21346
21639
  }
21347
21640
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: Gn4PlatformService, decorators: [{
21348
21641
  type: Injectable
21349
- }], ctorParameters: function () { return [{ type: SiteApiService }, { type: MeApiService }, { type: UsersApiService }, { type: Gn4PlatformMapper }, { type: ToolsApiService }, { type: RegistriesApiService }, { type: LangService }]; } });
21642
+ }], ctorParameters: function () { return [{ type: SiteApiService }, { type: MeApiService }, { type: UsersApiService }, { type: Gn4PlatformMapper }, { type: ToolsApiService }, { type: RegistriesApiService }, { type: LangService }, { type: UserfeedbackApiService }]; } });
21350
21643
 
21351
21644
  function provideGn4() {
21352
21645
  return [
@@ -23934,11 +24227,17 @@ class DropdownSelectorComponent {
23934
24227
  }
23935
24228
  }
23936
24229
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: DropdownSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
23937
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: DropdownSelectorComponent, selector: "gn-ui-dropdown-selector", inputs: { title: "title", showTitle: "showTitle", ariaName: "ariaName", choices: "choices", selected: "selected", maxRows: "maxRows", extraBtnClass: "extraBtnClass", minWidth: "minWidth" }, outputs: { selectValue: "selectValue" }, viewQueries: [{ propertyName: "overlayOrigin", first: true, predicate: ["overlayOrigin"], descendants: true }, { propertyName: "overlay", first: true, predicate: CdkConnectedOverlay, descendants: true }, { propertyName: "choiceInputs", predicate: ["choiceInputs"], descendants: true, read: ElementRef }], ngImport: i0, template: "<div class=\"flex flex-col sm:flex-row sm:items-center relative w-full\">\n <span\n *ngIf=\"showTitle\"\n class=\"tracking-wide text-sm mb-2 sm:mb-0 sm:mr-2 whitespace-nowrap\"\n [attr.for]=\"id\"\n >\n {{ title }}\n </span>\n <gn-ui-button\n type=\"outline\"\n class=\"grow min-w-0\"\n extraClass=\"bg-background !p-[8px] !pl-[16px] flex flex-row w-full {{\n extraBtnClass\n }}\"\n [title]=\"title\"\n [attr.aria-owns]=\"id\"\n (buttonClick)=\"openOverlay()\"\n cdkOverlayOrigin\n #overlayOrigin=\"cdkOverlayOrigin\"\n (keydown)=\"handleTriggerKeydown($event)\"\n >\n <div class=\"grow font-medium truncate py-1 mr-2 text-left\">\n {{ getChoiceLabel() | translate }}\n </div>\n <mat-icon class=\"material-symbols-outlined shrink-0 opacity-40\">\n <ng-container *ngIf=\"overlayOpen\">expand_less</ng-container>\n <ng-container *ngIf=\"!overlayOpen\">expand_more</ng-container>\n </mat-icon>\n </gn-ui-button>\n</div>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayHasBackdrop\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n [cdkConnectedOverlayOrigin]=\"overlayOrigin\"\n [cdkConnectedOverlayOpen]=\"overlayOpen\"\n [cdkConnectedOverlayPositions]=\"overlayPositions\"\n [cdkConnectedOverlayFlexibleDimensions]=\"true\"\n (overlayOutsideClick)=\"closeOverlay()\"\n (detach)=\"closeOverlay()\"\n>\n <div\n class=\"bg-white border border-gray-300 rounded shadow-lg py-2 w-full overflow-x-hidden overflow-y-auto overlay-container\"\n [style.max-height]=\"overlayMaxHeight\"\n [style.min-width]=\"overlayWidth\"\n role=\"listbox\"\n tabindex=\"-1\"\n [attr.id]=\"id\"\n [attr.aria-multiselectable]=\"true\"\n [attr.aria-label]=\"title\"\n (keydown)=\"handleOverlayKeydown($event)\"\n >\n <button\n #choiceInputs\n type=\"button\"\n *ngFor=\"let choice of choices\"\n [title]=\"choice.label | translate\"\n class=\"flex px-5 py-1 w-full text-start cursor-pointer transition-colors\"\n [ngClass]=\"\n isSelected(choice)\n ? 'text-white bg-primary hover:text-white hover:bg-primary-darker focus:text-white focus:bg-primary-darker'\n : 'text-gray-900 hover:text-primary-darkest hover:bg-gray-50 focus:text-primary-darkest focus:bg-gray-50'\n \"\n (click)=\"onSelectValue(choice)\"\n (keydown)=\"selectIfEnter($event, choice)\"\n [attr.data-cy-value]=\"choice.value.toString()\"\n [attr.data-cy-active]=\"isSelected(choice) ? 'true' : undefined\"\n >\n <span class=\"text-[14px]\">\n {{ choice.label | translate }}\n </span>\n </button>\n </div>\n</ng-template>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1$4.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i1$4.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
24230
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: DropdownSelectorComponent, isStandalone: true, selector: "gn-ui-dropdown-selector", inputs: { title: "title", showTitle: "showTitle", ariaName: "ariaName", choices: "choices", selected: "selected", maxRows: "maxRows", extraBtnClass: "extraBtnClass", minWidth: "minWidth" }, outputs: { selectValue: "selectValue" }, viewQueries: [{ propertyName: "overlayOrigin", first: true, predicate: ["overlayOrigin"], descendants: true }, { propertyName: "overlay", first: true, predicate: CdkConnectedOverlay, descendants: true }, { propertyName: "choiceInputs", predicate: ["choiceInputs"], descendants: true, read: ElementRef }], ngImport: i0, template: "<div class=\"flex flex-col sm:flex-row sm:items-center relative w-full\">\n <span\n *ngIf=\"showTitle\"\n class=\"tracking-wide text-sm mb-2 sm:mb-0 sm:mr-2 whitespace-nowrap\"\n [attr.for]=\"id\"\n >\n {{ title }}\n </span>\n <gn-ui-button\n type=\"outline\"\n class=\"grow min-w-0\"\n extraClass=\"bg-background !p-[8px] !pl-[16px] flex flex-row w-full {{\n extraBtnClass\n }}\"\n [title]=\"title\"\n [attr.aria-owns]=\"id\"\n (buttonClick)=\"openOverlay()\"\n cdkOverlayOrigin\n #overlayOrigin=\"cdkOverlayOrigin\"\n (keydown)=\"handleTriggerKeydown($event)\"\n >\n <div class=\"grow font-medium truncate py-1 mr-2 text-left\">\n {{ getChoiceLabel() | translate }}\n </div>\n <mat-icon class=\"material-symbols-outlined shrink-0 opacity-40\">\n <ng-container *ngIf=\"overlayOpen\">expand_less</ng-container>\n <ng-container *ngIf=\"!overlayOpen\">expand_more</ng-container>\n </mat-icon>\n </gn-ui-button>\n</div>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayHasBackdrop\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n [cdkConnectedOverlayOrigin]=\"overlayOrigin\"\n [cdkConnectedOverlayOpen]=\"overlayOpen\"\n [cdkConnectedOverlayPositions]=\"overlayPositions\"\n [cdkConnectedOverlayFlexibleDimensions]=\"true\"\n (overlayOutsideClick)=\"closeOverlay()\"\n (detach)=\"closeOverlay()\"\n>\n <div\n class=\"bg-white border border-gray-300 rounded shadow-lg py-2 w-full overflow-x-hidden overflow-y-auto overlay-container\"\n [style.max-height]=\"overlayMaxHeight\"\n [style.min-width]=\"overlayWidth\"\n role=\"listbox\"\n tabindex=\"-1\"\n [attr.id]=\"id\"\n [attr.aria-multiselectable]=\"true\"\n [attr.aria-label]=\"title\"\n (keydown)=\"handleOverlayKeydown($event)\"\n >\n <button\n #choiceInputs\n type=\"button\"\n *ngFor=\"let choice of choices\"\n [title]=\"choice.label | translate\"\n class=\"flex px-5 py-1 w-full text-start cursor-pointer transition-colors\"\n [ngClass]=\"\n isSelected(choice)\n ? 'text-white bg-primary hover:text-white hover:bg-primary-darker focus:text-white focus:bg-primary-darker'\n : 'text-gray-900 hover:text-primary-darkest hover:bg-gray-50 focus:text-primary-darkest focus:bg-gray-50'\n \"\n (click)=\"onSelectValue(choice)\"\n (keydown)=\"selectIfEnter($event, choice)\"\n [attr.data-cy-value]=\"choice.value.toString()\"\n [attr.data-cy-active]=\"isSelected(choice) ? 'true' : undefined\"\n >\n <span class=\"text-[14px]\">\n {{ choice.label | translate }}\n </span>\n </button>\n </div>\n</ng-template>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1$4.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i1$4.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
23938
24231
  }
23939
24232
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: DropdownSelectorComponent, decorators: [{
23940
24233
  type: Component,
23941
- args: [{ selector: 'gn-ui-dropdown-selector', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col sm:flex-row sm:items-center relative w-full\">\n <span\n *ngIf=\"showTitle\"\n class=\"tracking-wide text-sm mb-2 sm:mb-0 sm:mr-2 whitespace-nowrap\"\n [attr.for]=\"id\"\n >\n {{ title }}\n </span>\n <gn-ui-button\n type=\"outline\"\n class=\"grow min-w-0\"\n extraClass=\"bg-background !p-[8px] !pl-[16px] flex flex-row w-full {{\n extraBtnClass\n }}\"\n [title]=\"title\"\n [attr.aria-owns]=\"id\"\n (buttonClick)=\"openOverlay()\"\n cdkOverlayOrigin\n #overlayOrigin=\"cdkOverlayOrigin\"\n (keydown)=\"handleTriggerKeydown($event)\"\n >\n <div class=\"grow font-medium truncate py-1 mr-2 text-left\">\n {{ getChoiceLabel() | translate }}\n </div>\n <mat-icon class=\"material-symbols-outlined shrink-0 opacity-40\">\n <ng-container *ngIf=\"overlayOpen\">expand_less</ng-container>\n <ng-container *ngIf=\"!overlayOpen\">expand_more</ng-container>\n </mat-icon>\n </gn-ui-button>\n</div>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayHasBackdrop\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n [cdkConnectedOverlayOrigin]=\"overlayOrigin\"\n [cdkConnectedOverlayOpen]=\"overlayOpen\"\n [cdkConnectedOverlayPositions]=\"overlayPositions\"\n [cdkConnectedOverlayFlexibleDimensions]=\"true\"\n (overlayOutsideClick)=\"closeOverlay()\"\n (detach)=\"closeOverlay()\"\n>\n <div\n class=\"bg-white border border-gray-300 rounded shadow-lg py-2 w-full overflow-x-hidden overflow-y-auto overlay-container\"\n [style.max-height]=\"overlayMaxHeight\"\n [style.min-width]=\"overlayWidth\"\n role=\"listbox\"\n tabindex=\"-1\"\n [attr.id]=\"id\"\n [attr.aria-multiselectable]=\"true\"\n [attr.aria-label]=\"title\"\n (keydown)=\"handleOverlayKeydown($event)\"\n >\n <button\n #choiceInputs\n type=\"button\"\n *ngFor=\"let choice of choices\"\n [title]=\"choice.label | translate\"\n class=\"flex px-5 py-1 w-full text-start cursor-pointer transition-colors\"\n [ngClass]=\"\n isSelected(choice)\n ? 'text-white bg-primary hover:text-white hover:bg-primary-darker focus:text-white focus:bg-primary-darker'\n : 'text-gray-900 hover:text-primary-darkest hover:bg-gray-50 focus:text-primary-darkest focus:bg-gray-50'\n \"\n (click)=\"onSelectValue(choice)\"\n (keydown)=\"selectIfEnter($event, choice)\"\n [attr.data-cy-value]=\"choice.value.toString()\"\n [attr.data-cy-active]=\"isSelected(choice) ? 'true' : undefined\"\n >\n <span class=\"text-[14px]\">\n {{ choice.label | translate }}\n </span>\n </button>\n </div>\n</ng-template>\n" }]
24234
+ args: [{ selector: 'gn-ui-dropdown-selector', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
24235
+ CommonModule,
24236
+ ButtonComponent,
24237
+ OverlayModule,
24238
+ MatIconModule,
24239
+ TranslateModule,
24240
+ ], template: "<div class=\"flex flex-col sm:flex-row sm:items-center relative w-full\">\n <span\n *ngIf=\"showTitle\"\n class=\"tracking-wide text-sm mb-2 sm:mb-0 sm:mr-2 whitespace-nowrap\"\n [attr.for]=\"id\"\n >\n {{ title }}\n </span>\n <gn-ui-button\n type=\"outline\"\n class=\"grow min-w-0\"\n extraClass=\"bg-background !p-[8px] !pl-[16px] flex flex-row w-full {{\n extraBtnClass\n }}\"\n [title]=\"title\"\n [attr.aria-owns]=\"id\"\n (buttonClick)=\"openOverlay()\"\n cdkOverlayOrigin\n #overlayOrigin=\"cdkOverlayOrigin\"\n (keydown)=\"handleTriggerKeydown($event)\"\n >\n <div class=\"grow font-medium truncate py-1 mr-2 text-left\">\n {{ getChoiceLabel() | translate }}\n </div>\n <mat-icon class=\"material-symbols-outlined shrink-0 opacity-40\">\n <ng-container *ngIf=\"overlayOpen\">expand_less</ng-container>\n <ng-container *ngIf=\"!overlayOpen\">expand_more</ng-container>\n </mat-icon>\n </gn-ui-button>\n</div>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayHasBackdrop\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n [cdkConnectedOverlayOrigin]=\"overlayOrigin\"\n [cdkConnectedOverlayOpen]=\"overlayOpen\"\n [cdkConnectedOverlayPositions]=\"overlayPositions\"\n [cdkConnectedOverlayFlexibleDimensions]=\"true\"\n (overlayOutsideClick)=\"closeOverlay()\"\n (detach)=\"closeOverlay()\"\n>\n <div\n class=\"bg-white border border-gray-300 rounded shadow-lg py-2 w-full overflow-x-hidden overflow-y-auto overlay-container\"\n [style.max-height]=\"overlayMaxHeight\"\n [style.min-width]=\"overlayWidth\"\n role=\"listbox\"\n tabindex=\"-1\"\n [attr.id]=\"id\"\n [attr.aria-multiselectable]=\"true\"\n [attr.aria-label]=\"title\"\n (keydown)=\"handleOverlayKeydown($event)\"\n >\n <button\n #choiceInputs\n type=\"button\"\n *ngFor=\"let choice of choices\"\n [title]=\"choice.label | translate\"\n class=\"flex px-5 py-1 w-full text-start cursor-pointer transition-colors\"\n [ngClass]=\"\n isSelected(choice)\n ? 'text-white bg-primary hover:text-white hover:bg-primary-darker focus:text-white focus:bg-primary-darker'\n : 'text-gray-900 hover:text-primary-darkest hover:bg-gray-50 focus:text-primary-darkest focus:bg-gray-50'\n \"\n (click)=\"onSelectValue(choice)\"\n (keydown)=\"selectIfEnter($event, choice)\"\n [attr.data-cy-value]=\"choice.value.toString()\"\n [attr.data-cy-active]=\"isSelected(choice) ? 'true' : undefined\"\n >\n <span class=\"text-[14px]\">\n {{ choice.label | translate }}\n </span>\n </button>\n </div>\n</ng-template>\n" }]
23942
24241
  }], propDecorators: { title: [{
23943
24242
  type: Input
23944
24243
  }], showTitle: [{
@@ -24152,11 +24451,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
24152
24451
 
24153
24452
  class TextInputComponent {
24154
24453
  constructor() {
24454
+ this.baseClass = [
24455
+ 'appearance-none',
24456
+ 'border border-gray-300',
24457
+ 'rounded w-full',
24458
+ 'p-2',
24459
+ 'text-gray-700',
24460
+ 'leading-tight',
24461
+ 'focus:outline-none',
24462
+ 'focus:border-primary',
24463
+ ].join(' ');
24155
24464
  this.value = '';
24465
+ this.extraClass = '';
24156
24466
  this.required = false;
24157
24467
  this.rawChange = new Subject();
24158
24468
  this.valueChange = this.rawChange.pipe(distinctUntilChanged());
24159
24469
  }
24470
+ get classList() {
24471
+ return `${this.baseClass} ${this.extraClass}`;
24472
+ }
24160
24473
  ngAfterViewInit() {
24161
24474
  this.checkRequired(this.input.nativeElement.value);
24162
24475
  }
@@ -24169,13 +24482,15 @@ class TextInputComponent {
24169
24482
  this.rawChange.next(value);
24170
24483
  }
24171
24484
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: TextInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
24172
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: TextInputComponent, selector: "gn-ui-text-input", inputs: { value: "value", hint: "hint", required: "required" }, outputs: { valueChange: "valueChange" }, viewQueries: [{ propertyName: "input", first: true, predicate: ["input"], descendants: true }], ngImport: i0, template: "<input\n #input\n class=\"appearance-none border border-gray-300 rounded w-full p-2 text-gray-700 leading-tight focus:outline-none focus:border-primary\"\n type=\"text\"\n [value]=\"value\"\n (change)=\"handleChange($event)\"\n (input)=\"handleChange($event)\"\n [placeholder]=\"hint\"\n [attr.aria-label]=\"hint\"\n [attr.required]=\"required || null\"\n/>\n", styles: [".invalid{border-color:var(--color-secondary)}\n"] }); }
24485
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: TextInputComponent, selector: "gn-ui-text-input", inputs: { value: "value", extraClass: "extraClass", hint: "hint", required: "required" }, outputs: { valueChange: "valueChange" }, viewQueries: [{ propertyName: "input", first: true, predicate: ["input"], descendants: true }], ngImport: i0, template: "<input\n #input\n [class]=\"classList\"\n type=\"text\"\n [value]=\"value\"\n (change)=\"handleChange($event)\"\n (input)=\"handleChange($event)\"\n [placeholder]=\"hint\"\n [attr.aria-label]=\"hint\"\n [attr.required]=\"required || null\"\n/>\n", styles: [".invalid{border-color:var(--color-secondary)}\n"] }); }
24173
24486
  }
24174
24487
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: TextInputComponent, decorators: [{
24175
24488
  type: Component,
24176
- args: [{ selector: 'gn-ui-text-input', template: "<input\n #input\n class=\"appearance-none border border-gray-300 rounded w-full p-2 text-gray-700 leading-tight focus:outline-none focus:border-primary\"\n type=\"text\"\n [value]=\"value\"\n (change)=\"handleChange($event)\"\n (input)=\"handleChange($event)\"\n [placeholder]=\"hint\"\n [attr.aria-label]=\"hint\"\n [attr.required]=\"required || null\"\n/>\n", styles: [".invalid{border-color:var(--color-secondary)}\n"] }]
24489
+ args: [{ selector: 'gn-ui-text-input', template: "<input\n #input\n [class]=\"classList\"\n type=\"text\"\n [value]=\"value\"\n (change)=\"handleChange($event)\"\n (input)=\"handleChange($event)\"\n [placeholder]=\"hint\"\n [attr.aria-label]=\"hint\"\n [attr.required]=\"required || null\"\n/>\n", styles: [".invalid{border-color:var(--color-secondary)}\n"] }]
24177
24490
  }], propDecorators: { value: [{
24178
24491
  type: Input
24492
+ }], extraClass: [{
24493
+ type: Input
24179
24494
  }], hint: [{
24180
24495
  type: Input
24181
24496
  }], required: [{
@@ -24256,9 +24571,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
24256
24571
  class TextAreaComponent {
24257
24572
  constructor() {
24258
24573
  this.value = '';
24574
+ this.disabled = false;
24575
+ this.extraClass = '';
24259
24576
  this.required = false;
24260
24577
  this.rawChange = new Subject();
24261
24578
  this.valueChange = this.rawChange.pipe(distinctUntilChanged());
24579
+ this.baseClasses = [
24580
+ 'w-full',
24581
+ 'pt-2',
24582
+ 'pl-2',
24583
+ 'resize-none',
24584
+ 'border',
24585
+ 'border-gray-800',
24586
+ 'rounded italic',
24587
+ 'leading-tight',
24588
+ 'focus:outline-none',
24589
+ 'focus:bg-background',
24590
+ 'focus:border-primary',
24591
+ ].join(' ');
24592
+ this.disabledClasses = ['cursor-not-allowed'].join(' ');
24593
+ }
24594
+ get classList() {
24595
+ return `${this.baseClasses} ${this.extraClass} ${this.disabled ? this.disabledClasses : ''}`;
24262
24596
  }
24263
24597
  ngAfterViewInit() {
24264
24598
  this.checkRequired(this.input.nativeElement.value);
@@ -24272,12 +24606,16 @@ class TextAreaComponent {
24272
24606
  this.rawChange.next(value);
24273
24607
  }
24274
24608
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: TextAreaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
24275
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: TextAreaComponent, isStandalone: true, selector: "gn-ui-text-area", inputs: { value: "value", placeholder: "placeholder", required: "required" }, outputs: { valueChange: "valueChange" }, viewQueries: [{ propertyName: "input", first: true, predicate: ["input"], descendants: true }], ngImport: i0, template: "<div class=\"h-full flex\">\n <textarea\n #input\n name=\"textArea\"\n [placeholder]=\"placeholder\"\n [value]=\"value\"\n (change)=\"handleChange($event)\"\n (input)=\"handleChange($event)\"\n class=\"w-full pt-2 pl-2 resize-none border border-gray-800 rounded italic leading-tight focus:outline-none focus:bg-background focus:border-primary\"\n [attr.required]=\"required || null\"\n ></textarea>\n</div>\n", styles: [".invalid{border-color:var(--color-secondary)}\n"] }); }
24609
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: TextAreaComponent, isStandalone: true, selector: "gn-ui-text-area", inputs: { value: "value", disabled: "disabled", extraClass: "extraClass", placeholder: "placeholder", required: "required" }, outputs: { valueChange: "valueChange" }, viewQueries: [{ propertyName: "input", first: true, predicate: ["input"], descendants: true }], ngImport: i0, template: "<div class=\"h-full flex\">\n <textarea\n #input\n name=\"textArea\"\n [disabled]=\"disabled\"\n [placeholder]=\"placeholder\"\n [value]=\"value\"\n (change)=\"handleChange($event)\"\n (input)=\"handleChange($event)\"\n [class]=\"classList\"\n [attr.required]=\"required || null\"\n ></textarea>\n</div>\n", styles: [".invalid{border-color:var(--color-secondary)}\n"] }); }
24276
24610
  }
24277
24611
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: TextAreaComponent, decorators: [{
24278
24612
  type: Component,
24279
- args: [{ selector: 'gn-ui-text-area', standalone: true, template: "<div class=\"h-full flex\">\n <textarea\n #input\n name=\"textArea\"\n [placeholder]=\"placeholder\"\n [value]=\"value\"\n (change)=\"handleChange($event)\"\n (input)=\"handleChange($event)\"\n class=\"w-full pt-2 pl-2 resize-none border border-gray-800 rounded italic leading-tight focus:outline-none focus:bg-background focus:border-primary\"\n [attr.required]=\"required || null\"\n ></textarea>\n</div>\n", styles: [".invalid{border-color:var(--color-secondary)}\n"] }]
24280
- }], propDecorators: { value: [{
24613
+ args: [{ selector: 'gn-ui-text-area', standalone: true, template: "<div class=\"h-full flex\">\n <textarea\n #input\n name=\"textArea\"\n [disabled]=\"disabled\"\n [placeholder]=\"placeholder\"\n [value]=\"value\"\n (change)=\"handleChange($event)\"\n (input)=\"handleChange($event)\"\n [class]=\"classList\"\n [attr.required]=\"required || null\"\n ></textarea>\n</div>\n", styles: [".invalid{border-color:var(--color-secondary)}\n"] }]
24614
+ }], ctorParameters: function () { return []; }, propDecorators: { value: [{
24615
+ type: Input
24616
+ }], disabled: [{
24617
+ type: Input
24618
+ }], extraClass: [{
24281
24619
  type: Input
24282
24620
  }], placeholder: [{
24283
24621
  type: Input
@@ -24804,192 +25142,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
24804
25142
  }]
24805
25143
  }] });
24806
25144
 
24807
- class FormFieldSimpleComponent {
24808
- constructor() {
24809
- this.readonly = false;
24810
- this.invalid = false;
24811
- this.placeholder = '';
24812
- }
24813
- get inputType() {
24814
- switch (this.type) {
24815
- case 'url':
24816
- case 'text':
24817
- return 'text';
24818
- case 'date':
24819
- return 'datetime-local';
24820
- case 'number':
24821
- return 'number';
24822
- case 'toggle':
24823
- return 'checkbox';
24824
- default:
24825
- return '';
24826
- }
24827
- }
24828
- get isSelect() {
24829
- return this.type === 'list';
24830
- }
24831
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldSimpleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
24832
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: FormFieldSimpleComponent, selector: "gn-ui-form-field-simple", inputs: { type: "type", control: "control", readonly: "readonly", invalid: "invalid", placeholder: "placeholder", options: "options" }, ngImport: i0, template: "<input\n *ngIf=\"!isSelect\"\n [type]=\"inputType\"\n [readonly]=\"readonly\"\n [formControl]=\"control\"\n [placeholder]=\"placeholder\"\n class=\"border rounded-md p-3 w-full bg-white transition-colors\"\n [ngClass]=\"{\n 'border-pink-500': invalid,\n 'border-gray-200': !invalid,\n 'text-gray-600': readonly\n }\"\n/>\n<select\n *ngIf=\"isSelect\"\n [formControl]=\"control\"\n class=\"border rounded-md p-3 w-full bg-white transition-colors\"\n [ngClass]=\"{\n 'border-pink-500': invalid,\n 'border-gray-200': !invalid,\n 'text-gray-600': readonly\n }\"\n>\n <option *ngFor=\"let option of options\" [ngValue]=\"option.value\">\n {{ option.label }}\n </option>\n</select>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
24833
- }
24834
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldSimpleComponent, decorators: [{
24835
- type: Component,
24836
- args: [{ selector: 'gn-ui-form-field-simple', changeDetection: ChangeDetectionStrategy.OnPush, template: "<input\n *ngIf=\"!isSelect\"\n [type]=\"inputType\"\n [readonly]=\"readonly\"\n [formControl]=\"control\"\n [placeholder]=\"placeholder\"\n class=\"border rounded-md p-3 w-full bg-white transition-colors\"\n [ngClass]=\"{\n 'border-pink-500': invalid,\n 'border-gray-200': !invalid,\n 'text-gray-600': readonly\n }\"\n/>\n<select\n *ngIf=\"isSelect\"\n [formControl]=\"control\"\n class=\"border rounded-md p-3 w-full bg-white transition-colors\"\n [ngClass]=\"{\n 'border-pink-500': invalid,\n 'border-gray-200': !invalid,\n 'text-gray-600': readonly\n }\"\n>\n <option *ngFor=\"let option of options\" [ngValue]=\"option.value\">\n {{ option.label }}\n </option>\n</select>\n" }]
24837
- }], propDecorators: { type: [{
24838
- type: Input
24839
- }], control: [{
24840
- type: Input
24841
- }], readonly: [{
24842
- type: Input
24843
- }], invalid: [{
24844
- type: Input
24845
- }], placeholder: [{
24846
- type: Input
24847
- }], options: [{
24848
- type: Input
24849
- }] } });
24850
-
24851
- class FormFieldFileComponent {
24852
- constructor() {
24853
- this.readonly = false;
24854
- this.invalid = false;
24855
- this.placeholder = '';
24856
- }
24857
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldFileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
24858
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: FormFieldFileComponent, selector: "gn-ui-form-field-file", inputs: { control: "control", readonly: "readonly", invalid: "invalid", placeholder: "placeholder" }, ngImport: i0, template: "<input\n type=\"file\"\n [readonly]=\"readonly\"\n [formControl]=\"control\"\n [placeholder]=\"placeholder\"\n class=\"border rounded-md p-3 w-full bg-white transition-colors\"\n [ngClass]=\"{\n 'border-pink-500': invalid,\n 'border-gray-200': !invalid,\n 'text-gray-600': readonly\n }\"\n/>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
24859
- }
24860
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldFileComponent, decorators: [{
24861
- type: Component,
24862
- args: [{ selector: 'gn-ui-form-field-file', changeDetection: ChangeDetectionStrategy.OnPush, template: "<input\n type=\"file\"\n [readonly]=\"readonly\"\n [formControl]=\"control\"\n [placeholder]=\"placeholder\"\n class=\"border rounded-md p-3 w-full bg-white transition-colors\"\n [ngClass]=\"{\n 'border-pink-500': invalid,\n 'border-gray-200': !invalid,\n 'text-gray-600': readonly\n }\"\n/>\n" }]
24863
- }], propDecorators: { control: [{
24864
- type: Input
24865
- }], readonly: [{
24866
- type: Input
24867
- }], invalid: [{
24868
- type: Input
24869
- }], placeholder: [{
24870
- type: Input
24871
- }] } });
24872
-
24873
- class FormFieldRichComponent {
24874
- constructor() {
24875
- this.readonly = false;
24876
- this.invalid = false;
24877
- this.placeholder = '';
24878
- }
24879
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldRichComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
24880
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: FormFieldRichComponent, selector: "gn-ui-form-field-rich", inputs: { control: "control", readonly: "readonly", invalid: "invalid", placeholder: "placeholder" }, ngImport: i0, template: "<textarea\n [readonly]=\"readonly\"\n [formControl]=\"control\"\n [placeholder]=\"placeholder\"\n class=\"border rounded-md p-3 w-full bg-white h-full resize-none transition-colors\"\n [ngClass]=\"{\n 'border-pink-500': invalid,\n 'border-gray-200': !invalid,\n 'text-gray-600': readonly\n }\"\n></textarea>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
24881
- }
24882
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldRichComponent, decorators: [{
24883
- type: Component,
24884
- args: [{ selector: 'gn-ui-form-field-rich', changeDetection: ChangeDetectionStrategy.OnPush, template: "<textarea\n [readonly]=\"readonly\"\n [formControl]=\"control\"\n [placeholder]=\"placeholder\"\n class=\"border rounded-md p-3 w-full bg-white h-full resize-none transition-colors\"\n [ngClass]=\"{\n 'border-pink-500': invalid,\n 'border-gray-200': !invalid,\n 'text-gray-600': readonly\n }\"\n></textarea>\n" }]
24885
- }], propDecorators: { control: [{
24886
- type: Input
24887
- }], readonly: [{
24888
- type: Input
24889
- }], invalid: [{
24890
- type: Input
24891
- }], placeholder: [{
24892
- type: Input
24893
- }] } });
24894
-
24895
- class FormFieldObjectComponent {
24896
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldObjectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
24897
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: FormFieldObjectComponent, selector: "gn-ui-form-field-object", ngImport: i0, template: "<p>form-field-object works!</p>\n", styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
24898
- }
24899
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldObjectComponent, decorators: [{
24900
- type: Component,
24901
- args: [{ selector: 'gn-ui-form-field-object', changeDetection: ChangeDetectionStrategy.OnPush, template: "<p>form-field-object works!</p>\n" }]
24902
- }] });
24903
-
24904
- class FormFieldArrayComponent {
24905
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldArrayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
24906
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: FormFieldArrayComponent, selector: "gn-ui-form-field-array", ngImport: i0, template: "<p>form-field-array works!</p>\n", styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
24907
- }
24908
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldArrayComponent, decorators: [{
24909
- type: Component,
24910
- args: [{ selector: 'gn-ui-form-field-array', changeDetection: ChangeDetectionStrategy.OnPush, template: "<p>form-field-array works!</p>\n" }]
24911
- }] });
24912
-
24913
- class FormFieldSpatialExtentComponent {
24914
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldSpatialExtentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
24915
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: FormFieldSpatialExtentComponent, selector: "gn-ui-form-field-spatial-extent", ngImport: i0, template: "<p>form-field-spatial-extent works!</p>\n", styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
24916
- }
24917
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldSpatialExtentComponent, decorators: [{
24918
- type: Component,
24919
- args: [{ selector: 'gn-ui-form-field-spatial-extent', changeDetection: ChangeDetectionStrategy.OnPush, template: "<p>form-field-spatial-extent works!</p>\n" }]
24920
- }] });
24921
-
24922
- class FormFieldTemporalExtentComponent {
24923
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldTemporalExtentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
24924
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: FormFieldTemporalExtentComponent, selector: "gn-ui-form-field-temporal-extent", ngImport: i0, template: "<p>form-field-temporal-extent works!</p>\n", styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
24925
- }
24926
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldTemporalExtentComponent, decorators: [{
24927
- type: Component,
24928
- args: [{ selector: 'gn-ui-form-field-temporal-extent', changeDetection: ChangeDetectionStrategy.OnPush, template: "<p>form-field-temporal-extent works!</p>\n" }]
24929
- }] });
24930
-
24931
- class FormFieldComponent {
24932
- set value(v) {
24933
- this.formControl.setValue(v, {
24934
- emitEvent: false,
24935
- });
24936
- }
24937
- constructor() {
24938
- this.formControl = new FormControl();
24939
- this.valueChange = this.formControl.valueChanges;
24940
- }
24941
- get simpleType() {
24942
- return this.config.type;
24943
- }
24944
- get isSimpleField() {
24945
- return (this.config.type === 'text' ||
24946
- this.config.type === 'number' ||
24947
- this.config.type === 'date' ||
24948
- this.config.type === 'list' ||
24949
- this.config.type === 'url' ||
24950
- this.config.type === 'toggle');
24951
- }
24952
- get isRichField() {
24953
- return this.config.type === 'rich';
24954
- }
24955
- get isFileField() {
24956
- return this.config.type === 'file';
24957
- }
24958
- get isSpatialExtentField() {
24959
- return this.config.type === 'spatial_extent';
24960
- }
24961
- get isTemporalExtentField() {
24962
- return this.config.type === 'temporal_extent';
24963
- }
24964
- get isArrayField() {
24965
- return this.config.type === 'array';
24966
- }
24967
- get isObjectField() {
24968
- return this.config.type === 'object';
24969
- }
24970
- get isFieldOk() {
24971
- return !this.config.locked && !this.config.invalid;
24972
- }
24973
- get isFieldLocked() {
24974
- return this.config.locked;
24975
- }
24976
- get isFieldInvalid() {
24977
- return !this.config.locked && this.config.invalid;
24978
- }
24979
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
24980
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: FormFieldComponent, selector: "gn-ui-form-field", inputs: { config: "config", value: "value" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div class=\"flex flex-col h-full\">\n <div class=\"mb-2 flex flex-row\">\n <label class=\"grow\">\n <span class=\"font-medium field-label\">{{\n config.labelKey | translate\n }}</span>\n <span *ngIf=\"config.hintKey\" class=\"text-gray-900 text-sm\">\n - {{ config.hintKey | translate }}\n </span>\n </label>\n <mat-icon\n *ngIf=\"isFieldOk\"\n class=\"material-symbols-outlined text-[#c6d950] icon-ok\"\n >check_circle</mat-icon\n >\n <mat-icon\n *ngIf=\"isFieldLocked\"\n class=\"material-symbols-outlined text-blue-400 icon-locked\"\n >lock</mat-icon\n >\n <mat-icon\n *ngIf=\"isFieldInvalid\"\n class=\"material-symbols-outlined text-pink-500 icon-invalid\"\n >cancel</mat-icon\n >\n </div>\n <ng-container *ngIf=\"isSimpleField\">\n <gn-ui-form-field-simple\n [type]=\"simpleType\"\n [control]=\"formControl\"\n [readonly]=\"isFieldLocked\"\n [invalid]=\"isFieldInvalid\"\n ></gn-ui-form-field-simple>\n </ng-container>\n <ng-container *ngIf=\"isFileField\">\n <gn-ui-form-field-file\n [control]=\"formControl\"\n [readonly]=\"isFieldLocked\"\n [invalid]=\"isFieldInvalid\"\n ></gn-ui-form-field-file>\n </ng-container>\n <ng-container *ngIf=\"isRichField\">\n <gn-ui-form-field-rich\n class=\"grow\"\n [control]=\"formControl\"\n [readonly]=\"isFieldLocked\"\n [invalid]=\"isFieldInvalid\"\n ></gn-ui-form-field-rich>\n </ng-container>\n <ng-container *ngIf=\"isArrayField\">\n <gn-ui-form-field-array></gn-ui-form-field-array>\n </ng-container>\n <ng-container *ngIf=\"isObjectField\">\n <gn-ui-form-field-object></gn-ui-form-field-object>\n </ng-container>\n <ng-container *ngIf=\"isSpatialExtentField\">\n <gn-ui-form-field-spatial-extent></gn-ui-form-field-spatial-extent>\n </ng-container>\n <ng-container *ngIf=\"isTemporalExtentField\">\n <gn-ui-form-field-temporal-extent></gn-ui-form-field-temporal-extent>\n </ng-container>\n <div\n *ngIf=\"isFieldInvalid && config.invalidHintKey\"\n class=\"mt-2 text-pink-500 text-sm field-invalid-hint\"\n >\n {{ config.invalidHintKey | translate }}\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: FormFieldSimpleComponent, selector: "gn-ui-form-field-simple", inputs: ["type", "control", "readonly", "invalid", "placeholder", "options"] }, { kind: "component", type: FormFieldArrayComponent, selector: "gn-ui-form-field-array" }, { kind: "component", type: FormFieldObjectComponent, selector: "gn-ui-form-field-object" }, { kind: "component", type: FormFieldRichComponent, selector: "gn-ui-form-field-rich", inputs: ["control", "readonly", "invalid", "placeholder"] }, { kind: "component", type: FormFieldFileComponent, selector: "gn-ui-form-field-file", inputs: ["control", "readonly", "invalid", "placeholder"] }, { kind: "component", type: FormFieldSpatialExtentComponent, selector: "gn-ui-form-field-spatial-extent" }, { kind: "component", type: FormFieldTemporalExtentComponent, selector: "gn-ui-form-field-temporal-extent" }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
24981
- }
24982
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldComponent, decorators: [{
24983
- type: Component,
24984
- args: [{ selector: 'gn-ui-form-field', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col h-full\">\n <div class=\"mb-2 flex flex-row\">\n <label class=\"grow\">\n <span class=\"font-medium field-label\">{{\n config.labelKey | translate\n }}</span>\n <span *ngIf=\"config.hintKey\" class=\"text-gray-900 text-sm\">\n - {{ config.hintKey | translate }}\n </span>\n </label>\n <mat-icon\n *ngIf=\"isFieldOk\"\n class=\"material-symbols-outlined text-[#c6d950] icon-ok\"\n >check_circle</mat-icon\n >\n <mat-icon\n *ngIf=\"isFieldLocked\"\n class=\"material-symbols-outlined text-blue-400 icon-locked\"\n >lock</mat-icon\n >\n <mat-icon\n *ngIf=\"isFieldInvalid\"\n class=\"material-symbols-outlined text-pink-500 icon-invalid\"\n >cancel</mat-icon\n >\n </div>\n <ng-container *ngIf=\"isSimpleField\">\n <gn-ui-form-field-simple\n [type]=\"simpleType\"\n [control]=\"formControl\"\n [readonly]=\"isFieldLocked\"\n [invalid]=\"isFieldInvalid\"\n ></gn-ui-form-field-simple>\n </ng-container>\n <ng-container *ngIf=\"isFileField\">\n <gn-ui-form-field-file\n [control]=\"formControl\"\n [readonly]=\"isFieldLocked\"\n [invalid]=\"isFieldInvalid\"\n ></gn-ui-form-field-file>\n </ng-container>\n <ng-container *ngIf=\"isRichField\">\n <gn-ui-form-field-rich\n class=\"grow\"\n [control]=\"formControl\"\n [readonly]=\"isFieldLocked\"\n [invalid]=\"isFieldInvalid\"\n ></gn-ui-form-field-rich>\n </ng-container>\n <ng-container *ngIf=\"isArrayField\">\n <gn-ui-form-field-array></gn-ui-form-field-array>\n </ng-container>\n <ng-container *ngIf=\"isObjectField\">\n <gn-ui-form-field-object></gn-ui-form-field-object>\n </ng-container>\n <ng-container *ngIf=\"isSpatialExtentField\">\n <gn-ui-form-field-spatial-extent></gn-ui-form-field-spatial-extent>\n </ng-container>\n <ng-container *ngIf=\"isTemporalExtentField\">\n <gn-ui-form-field-temporal-extent></gn-ui-form-field-temporal-extent>\n </ng-container>\n <div\n *ngIf=\"isFieldInvalid && config.invalidHintKey\"\n class=\"mt-2 text-pink-500 text-sm field-invalid-hint\"\n >\n {{ config.invalidHintKey | translate }}\n </div>\n</div>\n" }]
24985
- }], ctorParameters: function () { return []; }, propDecorators: { config: [{
24986
- type: Input
24987
- }], value: [{
24988
- type: Input
24989
- }], valueChange: [{
24990
- type: Output
24991
- }] } });
24992
-
24993
25145
  class CopyTextButtonComponent {
24994
25146
  constructor() {
24995
25147
  this.displayText = true;
@@ -25359,8 +25511,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
25359
25511
 
25360
25512
  class UiInputsModule {
25361
25513
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UiInputsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
25362
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.1.7", ngImport: i0, type: UiInputsModule, declarations: [DropdownSelectorComponent,
25363
- AutocompleteComponent,
25514
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.1.7", ngImport: i0, type: UiInputsModule, declarations: [AutocompleteComponent,
25364
25515
  TextInputComponent,
25365
25516
  DragAndDropFileInputComponent,
25366
25517
  ChipsInputComponent,
@@ -25368,14 +25519,6 @@ class UiInputsModule {
25368
25519
  StarToggleComponent,
25369
25520
  DropdownMultiselectComponent,
25370
25521
  ViewportIntersectorComponent,
25371
- FormFieldComponent,
25372
- FormFieldSimpleComponent,
25373
- FormFieldArrayComponent,
25374
- FormFieldObjectComponent,
25375
- FormFieldRichComponent,
25376
- FormFieldFileComponent,
25377
- FormFieldSpatialExtentComponent,
25378
- FormFieldTemporalExtentComponent,
25379
25522
  CheckToggleComponent,
25380
25523
  CopyTextButtonComponent,
25381
25524
  CheckboxComponent,
@@ -25398,7 +25541,8 @@ class UiInputsModule {
25398
25541
  EditableLabelDirective,
25399
25542
  TextAreaComponent,
25400
25543
  ButtonComponent,
25401
- ImageInputComponent], exports: [DropdownSelectorComponent,
25544
+ ImageInputComponent,
25545
+ DropdownSelectorComponent], exports: [DropdownSelectorComponent,
25402
25546
  AutocompleteComponent,
25403
25547
  ButtonComponent,
25404
25548
  TextInputComponent,
@@ -25409,7 +25553,6 @@ class UiInputsModule {
25409
25553
  StarToggleComponent,
25410
25554
  DropdownMultiselectComponent,
25411
25555
  ViewportIntersectorComponent,
25412
- FormFieldComponent,
25413
25556
  CheckToggleComponent,
25414
25557
  CopyTextButtonComponent,
25415
25558
  CheckboxComponent,
@@ -25434,13 +25577,13 @@ class UiInputsModule {
25434
25577
  MatInputModule,
25435
25578
  MatDatepickerModule,
25436
25579
  MatNativeDateModule,
25437
- ImageInputComponent] }); }
25580
+ ImageInputComponent,
25581
+ DropdownSelectorComponent] }); }
25438
25582
  }
25439
25583
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UiInputsModule, decorators: [{
25440
25584
  type: NgModule,
25441
25585
  args: [{
25442
25586
  declarations: [
25443
- DropdownSelectorComponent,
25444
25587
  AutocompleteComponent,
25445
25588
  TextInputComponent,
25446
25589
  DragAndDropFileInputComponent,
@@ -25449,14 +25592,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
25449
25592
  StarToggleComponent,
25450
25593
  DropdownMultiselectComponent,
25451
25594
  ViewportIntersectorComponent,
25452
- FormFieldComponent,
25453
- FormFieldSimpleComponent,
25454
- FormFieldArrayComponent,
25455
- FormFieldObjectComponent,
25456
- FormFieldRichComponent,
25457
- FormFieldFileComponent,
25458
- FormFieldSpatialExtentComponent,
25459
- FormFieldTemporalExtentComponent,
25460
25595
  CheckToggleComponent,
25461
25596
  CopyTextButtonComponent,
25462
25597
  CheckboxComponent,
@@ -25485,6 +25620,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
25485
25620
  TextAreaComponent,
25486
25621
  ButtonComponent,
25487
25622
  ImageInputComponent,
25623
+ DropdownSelectorComponent,
25488
25624
  ],
25489
25625
  exports: [
25490
25626
  DropdownSelectorComponent,
@@ -25498,7 +25634,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
25498
25634
  StarToggleComponent,
25499
25635
  DropdownMultiselectComponent,
25500
25636
  ViewportIntersectorComponent,
25501
- FormFieldComponent,
25502
25637
  CheckToggleComponent,
25503
25638
  CopyTextButtonComponent,
25504
25639
  CheckboxComponent,
@@ -25559,7 +25694,7 @@ class AddLayerFromOgcApiComponent {
25559
25694
  this.layerAdded.emit({ ...layerToAdd, title: layer });
25560
25695
  }
25561
25696
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: AddLayerFromOgcApiComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
25562
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: AddLayerFromOgcApiComponent, isStandalone: true, selector: "gn-ui-add-layer-from-ogc-api", inputs: { ogcUrl: "ogcUrl" }, outputs: { layerAdded: "layerAdded" }, ngImport: i0, template: "<div class=\"flex items-center mb-5\">\n <gn-ui-text-input\n [(value)]=\"ogcUrl\"\n (valueChange)=\"urlChange.next($event)\"\n [hint]=\"'map.ogc.urlInput.hint' | translate\"\n class=\"w-96\"\n >\n </gn-ui-text-input>\n</div>\n\n<div *ngIf=\"errorMessage\" class=\"text-red-500 mt-2\">\n {{ errorMessage }}\n</div>\n\n<div *ngIf=\"loading\">\n <p class=\"loading-message\" translate>map.loading.service</p>\n</div>\n\n<div *ngIf=\"!loading && layers.length > 0\">\n <h2 class=\"font-bold\" translate>map.layers.available</h2>\n <ng-container *ngFor=\"let layer of layers\">\n <div class=\"flex items-center justify-between my-2 layer-item-tree\">\n <p class=\"max-w-xs overflow-hidden overflow-ellipsis whitespace-nowrap\">\n {{ layer }}\n </p>\n <gn-ui-button\n class=\"layer-add-btn\"\n type=\"primary\"\n (buttonClick)=\"addLayer(layer)\"\n extraClass=\"text-sm !px-2 !py-1\"\n translate\n ><span translate> map.layer.add </span></gn-ui-button\n >\n </div>\n </ng-container>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "ngmodule", type: UiInputsModule }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: TextInputComponent, selector: "gn-ui-text-input", inputs: ["value", "hint", "required"], outputs: ["valueChange"] }] }); }
25697
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: AddLayerFromOgcApiComponent, isStandalone: true, selector: "gn-ui-add-layer-from-ogc-api", inputs: { ogcUrl: "ogcUrl" }, outputs: { layerAdded: "layerAdded" }, ngImport: i0, template: "<div class=\"flex items-center mb-5\">\n <gn-ui-text-input\n [(value)]=\"ogcUrl\"\n (valueChange)=\"urlChange.next($event)\"\n [hint]=\"'map.ogc.urlInput.hint' | translate\"\n class=\"w-96\"\n >\n </gn-ui-text-input>\n</div>\n\n<div *ngIf=\"errorMessage\" class=\"text-red-500 mt-2\">\n {{ errorMessage }}\n</div>\n\n<div *ngIf=\"loading\">\n <p class=\"loading-message\" translate>map.loading.service</p>\n</div>\n\n<div *ngIf=\"!loading && layers.length > 0\">\n <h2 class=\"font-bold\" translate>map.layers.available</h2>\n <ng-container *ngFor=\"let layer of layers\">\n <div class=\"flex items-center justify-between my-2 layer-item-tree\">\n <p class=\"max-w-xs overflow-hidden overflow-ellipsis whitespace-nowrap\">\n {{ layer }}\n </p>\n <gn-ui-button\n class=\"layer-add-btn\"\n type=\"primary\"\n (buttonClick)=\"addLayer(layer)\"\n extraClass=\"text-sm !px-2 !py-1\"\n translate\n ><span translate> map.layer.add </span></gn-ui-button\n >\n </div>\n </ng-container>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "ngmodule", type: UiInputsModule }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: TextInputComponent, selector: "gn-ui-text-input", inputs: ["value", "extraClass", "hint", "required"], outputs: ["valueChange"] }] }); }
25563
25698
  }
25564
25699
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: AddLayerFromOgcApiComponent, decorators: [{
25565
25700
  type: Component,
@@ -26298,44 +26433,52 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
26298
26433
  type: Output
26299
26434
  }] } });
26300
26435
 
26301
- class ExpandablePanelComponent {
26436
+ class ApiCardComponent {
26302
26437
  constructor() {
26303
- this.collapsed = true;
26304
- this.maxHeight = this.setMaxHeight();
26438
+ this.currentlyActive = false;
26439
+ this.openRecordApiForm = new EventEmitter();
26305
26440
  }
26306
- toggle() {
26307
- this.collapsed = !this.collapsed;
26308
- this.maxHeight = this.setMaxHeight();
26441
+ ngOnInit() {
26442
+ this.displayApiFormButton =
26443
+ this.link.accessServiceProtocol === 'ogcFeatures' ? true : false;
26309
26444
  }
26310
- setMaxHeight() {
26311
- return `${this.collapsed ? '0' : this.contentDiv.nativeElement.scrollHeight}px`;
26445
+ ngOnChanges(changes) {
26446
+ this.currentlyActive =
26447
+ changes.currentLink.currentValue === this.link ? true : false;
26312
26448
  }
26313
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ExpandablePanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26314
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: ExpandablePanelComponent, selector: "gn-ui-expandable-panel", inputs: { title: "title", collapsed: "collapsed" }, viewQueries: [{ propertyName: "contentDiv", first: true, predicate: ["contentDiv"], descendants: true }], ngImport: i0, template: "<div\n class=\"group flex align-middle title border-b border-gray-100 cursor-pointer pt-2.5\"\n (click)=\"toggle()\"\n>\n <div class=\"grow font-medium text-black text-sm\">\n {{ title }}\n </div>\n <div\n class=\"w-8 opacity-25 text-primary group-hover:opacity-100 transition-opacity\"\n >\n <mat-icon class=\"material-symbols-outlined\" *ngIf=\"collapsed\">add</mat-icon>\n <mat-icon class=\"material-symbols-outlined\" *ngIf=\"!collapsed\"\n >remove</mat-icon\n >\n </div>\n</div>\n<div\n class=\"content overflow-hidden transition-[max-height] duration-300\"\n [ngClass]=\"collapsed ? 'ease-out' : 'ease-in'\"\n [style.maxHeight]=\"maxHeight\"\n #contentDiv\n>\n <ng-content></ng-content>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26449
+ openRecordApiFormPanel() {
26450
+ if (this.displayApiFormButton) {
26451
+ this.currentlyActive = !this.currentlyActive;
26452
+ this.openRecordApiForm.emit(this.currentlyActive ? this.link : undefined);
26453
+ }
26454
+ }
26455
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ApiCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26456
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: ApiCardComponent, selector: "gn-ui-api-card", inputs: { link: "link", currentLink: "currentLink" }, outputs: { openRecordApiForm: "openRecordApiForm" }, usesOnChanges: true, ngImport: i0, template: "<div\n class=\"group flex flex-col justify-between h-40 pt-5 pb-6 px-7 rounded filter overflow-hidden\"\n [ngClass]=\"{ 'cursor-pointer': displayApiFormButton }\"\n (click)=\"openRecordApiFormPanel()\"\n>\n <div\n class=\"font-title font-medium text-21 text-black text-ellipsis overflow-hidden break-words pb-5 h-[4.5rem]\"\n >\n {{ link.name || link.description }}\n </div>\n <div class=\"\">\n <div class=\"flex flex-row justify-between\">\n <span\n class=\"bg-primary-opacity-50 uppercase inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded text-primary-lightest group-hover:bg-primary transition-colors\"\n [ngClass]=\"{\n '!bg-primary': currentlyActive\n }\"\n >{{ link.accessServiceProtocol }}</span\n >\n <gn-ui-copy-text-button\n *ngIf=\"!displayApiFormButton\"\n [text]=\"link.url.toString()\"\n [tooltipText]=\"'tooltip.url.copy' | translate\"\n [displayText]=\"false\"\n ></gn-ui-copy-text-button>\n <button\n *ngIf=\"displayApiFormButton\"\n type=\"button\"\n [ngClass]=\"{\n 'py-2 px-4 rounded-r-md bg-gray-400 hover:bg-gray-600 focus:bg-gray-800 text-white':\n displayText\n }\"\n mat-raised-button\n [matTooltip]=\"\n !currentlyActive\n ? ('record.metadata.api.form.openForm' | translate)\n : ('record.metadata.api.form.closeForm' | translate)\n \"\n matTooltipPosition=\"above\"\n >\n <mat-icon\n class=\"material-symbols-outlined pointer-events-none align-middle card-icon\"\n [ngClass]=\"{\n 'text-secondary opacity-100': currentlyActive\n }\"\n >more_horiz</mat-icon\n >\n </button>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: CopyTextButtonComponent, selector: "gn-ui-copy-text-button", inputs: ["text", "tooltipText", "displayText", "rows"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26315
26457
  }
26316
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ExpandablePanelComponent, decorators: [{
26458
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ApiCardComponent, decorators: [{
26317
26459
  type: Component,
26318
- args: [{ selector: 'gn-ui-expandable-panel', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"group flex align-middle title border-b border-gray-100 cursor-pointer pt-2.5\"\n (click)=\"toggle()\"\n>\n <div class=\"grow font-medium text-black text-sm\">\n {{ title }}\n </div>\n <div\n class=\"w-8 opacity-25 text-primary group-hover:opacity-100 transition-opacity\"\n >\n <mat-icon class=\"material-symbols-outlined\" *ngIf=\"collapsed\">add</mat-icon>\n <mat-icon class=\"material-symbols-outlined\" *ngIf=\"!collapsed\"\n >remove</mat-icon\n >\n </div>\n</div>\n<div\n class=\"content overflow-hidden transition-[max-height] duration-300\"\n [ngClass]=\"collapsed ? 'ease-out' : 'ease-in'\"\n [style.maxHeight]=\"maxHeight\"\n #contentDiv\n>\n <ng-content></ng-content>\n</div>\n" }]
26319
- }], propDecorators: { title: [{
26460
+ args: [{ selector: 'gn-ui-api-card', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"group flex flex-col justify-between h-40 pt-5 pb-6 px-7 rounded filter overflow-hidden\"\n [ngClass]=\"{ 'cursor-pointer': displayApiFormButton }\"\n (click)=\"openRecordApiFormPanel()\"\n>\n <div\n class=\"font-title font-medium text-21 text-black text-ellipsis overflow-hidden break-words pb-5 h-[4.5rem]\"\n >\n {{ link.name || link.description }}\n </div>\n <div class=\"\">\n <div class=\"flex flex-row justify-between\">\n <span\n class=\"bg-primary-opacity-50 uppercase inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded text-primary-lightest group-hover:bg-primary transition-colors\"\n [ngClass]=\"{\n '!bg-primary': currentlyActive\n }\"\n >{{ link.accessServiceProtocol }}</span\n >\n <gn-ui-copy-text-button\n *ngIf=\"!displayApiFormButton\"\n [text]=\"link.url.toString()\"\n [tooltipText]=\"'tooltip.url.copy' | translate\"\n [displayText]=\"false\"\n ></gn-ui-copy-text-button>\n <button\n *ngIf=\"displayApiFormButton\"\n type=\"button\"\n [ngClass]=\"{\n 'py-2 px-4 rounded-r-md bg-gray-400 hover:bg-gray-600 focus:bg-gray-800 text-white':\n displayText\n }\"\n mat-raised-button\n [matTooltip]=\"\n !currentlyActive\n ? ('record.metadata.api.form.openForm' | translate)\n : ('record.metadata.api.form.closeForm' | translate)\n \"\n matTooltipPosition=\"above\"\n >\n <mat-icon\n class=\"material-symbols-outlined pointer-events-none align-middle card-icon\"\n [ngClass]=\"{\n 'text-secondary opacity-100': currentlyActive\n }\"\n >more_horiz</mat-icon\n >\n </button>\n </div>\n </div>\n</div>\n" }]
26461
+ }], propDecorators: { link: [{
26320
26462
  type: Input
26321
- }], collapsed: [{
26463
+ }], currentLink: [{
26322
26464
  type: Input
26323
- }], contentDiv: [{
26324
- type: ViewChild,
26325
- args: ['contentDiv']
26465
+ }], openRecordApiForm: [{
26466
+ type: Output
26326
26467
  }] } });
26327
26468
 
26328
- class MarkdownParserComponent {
26329
- get parsedMarkdown() {
26330
- return marked.parse(this.textContent);
26469
+ class AvatarComponent {
26470
+ hideImage() {
26471
+ this.avatarUrl = this.avatarPlaceholder;
26331
26472
  }
26332
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MarkdownParserComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26333
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: MarkdownParserComponent, isStandalone: true, selector: "gn-ui-markdown-parser", inputs: { textContent: "textContent" }, ngImport: i0, template: "<div class=\"markdown-body\" [innerHTML]=\"parsedMarkdown\"></div>\n", styles: [":host ::ng-deep .markdown-body{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;margin:0px 0px 1.5rem;line-height:1.5;word-wrap:break-word}:host ::ng-deep .markdown-body strong{@apply font-bold;color:var(--color-secondary-darker)}:host ::ng-deep .markdown-body h1,:host ::ng-deep .markdown-body h2,:host ::ng-deep .markdown-body h3,:host ::ng-deep .markdown-body h4,:host ::ng-deep .markdown-body h5,:host ::ng-deep .markdown-body h6{margin-top:24px;margin-bottom:16px;line-height:1.25;@apply text-title font-title font-bold;}:host ::ng-deep .markdown-body h1{margin:.67em 0;padding-bottom:.3em;font-size:2em;color:var(--color-primary)}:host ::ng-deep .markdown-body h2{padding-bottom:.3em;font-size:1.5em;color:var(--color-secondary)}:host ::ng-deep .markdown-body h3{font-size:1.25em;color:var(--color-secondary)}:host ::ng-deep .markdown-body h4{font-size:1em;color:var(--color-secondary)}:host ::ng-deep .markdown-body h5{font-size:.875em;color:var(--color-secondary)}:host ::ng-deep .markdown-body h6{font-size:.85em;color:var(--color-secondary-lighter)}:host ::ng-deep .markdown-body p{margin-top:0;margin-bottom:10px}:host ::ng-deep .markdown-body p>a{margin-top:0;margin-bottom:10px;color:var(--color-primary)!important;text-decoration:none}:host ::ng-deep .markdown-body p>a:hover{color:var(--color-primary-darker)!important;@apply underline;}:host ::ng-deep .markdown-body blockquote{margin:0;padding:0 1em;color:var(--color-secondary-lighter);border-left:.25em solid var(--color-primary-lighter)}:host ::ng-deep .markdown-body pre{margin-top:0;margin-bottom:0;font-size:12px;background-color:var(--color-gray-100);word-wrap:normal}:host ::ng-deep .markdown-body pre{padding:16px;overflow:auto;font-size:85%;line-height:1.45;color:var(--color-secondary);border-radius:6px}:host ::ng-deep .markdown-body code{padding:.2em .4em;margin:0;font-size:85%;white-space:break-spaces;border-radius:6px}:host ::ng-deep .markdown-body pre code{display:inline;max-width:auto;padding:0;margin:0;overflow:visible;line-height:inherit;word-wrap:normal;border:0}:host ::ng-deep .markdown-body hr{box-sizing:content-box;overflow:hidden;background:transparent;border-bottom:1px solid var(--color-secondary);height:.15em;padding:0;margin:24px 0;background-color:var(--color-secondary);border:0}:host ::ng-deep .markdown-body hr:before{display:table;content:\"\"}:host ::ng-deep .markdown-body hr:after{display:table;clear:both;content:\"\"}:host ::ng-deep .markdown-body ul,:host ::ng-deep .markdown-body ol{margin-top:0;margin-bottom:0;padding-left:2em;list-style:revert}:host ::ng-deep .markdown-body ol ol,:host ::ng-deep .markdown-body ul ol{list-style-type:lower-roman}:host ::ng-deep .markdown-body ul ul ol,:host ::ng-deep .markdown-body ul ol ol,:host ::ng-deep .markdown-body ol ul ol,:host ::ng-deep .markdown-body ol ol ol{list-style-type:lower-alpha}:host ::ng-deep .markdown-body ol[type=\"a s\"]{list-style-type:lower-alpha}:host ::ng-deep .markdown-body ol[type=\"A s\"]{list-style-type:upper-alpha}:host ::ng-deep .markdown-body ol[type=\"i s\"]{list-style-type:lower-roman}:host ::ng-deep .markdown-body ol[type=\"I s\"]{list-style-type:upper-roman}:host ::ng-deep .markdown-body ol[type=\"1\"]{list-style:unset;list-style-type:decimal}:host ::ng-deep .markdown-body div>ol:not([type]){list-style:unset;list-style-type:decimal}:host ::ng-deep .markdown-body table{border-spacing:0;border-collapse:collapse;display:block;width:max-content;max-width:100%;overflow:auto;padding-bottom:15px}:host ::ng-deep .markdown-body td,:host ::ng-deep .markdown-body th{padding:0}:host ::ng-deep .markdown-body th{color:var(--color-secondary)}:host ::ng-deep .markdown-body table th,:host ::ng-deep .markdown-body table td{padding:6px 13px;border:1px solid var(--color-gray-500)}:host ::ng-deep .markdown-body table td>:last-child{margin-bottom:0}:host ::ng-deep .markdown-body table tr{background-color:#fff;border-top:1px solid var(--color-secondary-lighter)}:host ::ng-deep .markdown-body table tr:nth-child(2n){background-color:var(--color-gray-100)}:host ::ng-deep .markdown-body table img{background-color:transparent}:host ::ng-deep .markdown-body img{border-style:none;max-width:100%;box-sizing:content-box;background-color:transparent}:host ::ng-deep .markdown-body img[align=right]{padding-left:20px}:host ::ng-deep .markdown-body img[align=left]{padding-right:20px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26473
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: AvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26474
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: AvatarComponent, selector: "gn-ui-avatar", inputs: { avatarUrl: "avatarUrl", avatarPlaceholder: "avatarPlaceholder" }, ngImport: i0, template: "<img\n *ngIf=\"avatarUrl\"\n class=\"rounded-full object-cover\"\n [src]=\"avatarUrl\"\n (error)=\"hideImage()\"\n/>\n<div\n *ngIf=\"!avatarUrl\"\n class=\"w-full h-full rounded-full bg-gradient-to-tr from-primary to-slate-200\"\n></div>\n", dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26334
26475
  }
26335
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MarkdownParserComponent, decorators: [{
26476
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: AvatarComponent, decorators: [{
26336
26477
  type: Component,
26337
- args: [{ selector: 'gn-ui-markdown-parser', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<div class=\"markdown-body\" [innerHTML]=\"parsedMarkdown\"></div>\n", styles: [":host ::ng-deep .markdown-body{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;margin:0px 0px 1.5rem;line-height:1.5;word-wrap:break-word}:host ::ng-deep .markdown-body strong{@apply font-bold;color:var(--color-secondary-darker)}:host ::ng-deep .markdown-body h1,:host ::ng-deep .markdown-body h2,:host ::ng-deep .markdown-body h3,:host ::ng-deep .markdown-body h4,:host ::ng-deep .markdown-body h5,:host ::ng-deep .markdown-body h6{margin-top:24px;margin-bottom:16px;line-height:1.25;@apply text-title font-title font-bold;}:host ::ng-deep .markdown-body h1{margin:.67em 0;padding-bottom:.3em;font-size:2em;color:var(--color-primary)}:host ::ng-deep .markdown-body h2{padding-bottom:.3em;font-size:1.5em;color:var(--color-secondary)}:host ::ng-deep .markdown-body h3{font-size:1.25em;color:var(--color-secondary)}:host ::ng-deep .markdown-body h4{font-size:1em;color:var(--color-secondary)}:host ::ng-deep .markdown-body h5{font-size:.875em;color:var(--color-secondary)}:host ::ng-deep .markdown-body h6{font-size:.85em;color:var(--color-secondary-lighter)}:host ::ng-deep .markdown-body p{margin-top:0;margin-bottom:10px}:host ::ng-deep .markdown-body p>a{margin-top:0;margin-bottom:10px;color:var(--color-primary)!important;text-decoration:none}:host ::ng-deep .markdown-body p>a:hover{color:var(--color-primary-darker)!important;@apply underline;}:host ::ng-deep .markdown-body blockquote{margin:0;padding:0 1em;color:var(--color-secondary-lighter);border-left:.25em solid var(--color-primary-lighter)}:host ::ng-deep .markdown-body pre{margin-top:0;margin-bottom:0;font-size:12px;background-color:var(--color-gray-100);word-wrap:normal}:host ::ng-deep .markdown-body pre{padding:16px;overflow:auto;font-size:85%;line-height:1.45;color:var(--color-secondary);border-radius:6px}:host ::ng-deep .markdown-body code{padding:.2em .4em;margin:0;font-size:85%;white-space:break-spaces;border-radius:6px}:host ::ng-deep .markdown-body pre code{display:inline;max-width:auto;padding:0;margin:0;overflow:visible;line-height:inherit;word-wrap:normal;border:0}:host ::ng-deep .markdown-body hr{box-sizing:content-box;overflow:hidden;background:transparent;border-bottom:1px solid var(--color-secondary);height:.15em;padding:0;margin:24px 0;background-color:var(--color-secondary);border:0}:host ::ng-deep .markdown-body hr:before{display:table;content:\"\"}:host ::ng-deep .markdown-body hr:after{display:table;clear:both;content:\"\"}:host ::ng-deep .markdown-body ul,:host ::ng-deep .markdown-body ol{margin-top:0;margin-bottom:0;padding-left:2em;list-style:revert}:host ::ng-deep .markdown-body ol ol,:host ::ng-deep .markdown-body ul ol{list-style-type:lower-roman}:host ::ng-deep .markdown-body ul ul ol,:host ::ng-deep .markdown-body ul ol ol,:host ::ng-deep .markdown-body ol ul ol,:host ::ng-deep .markdown-body ol ol ol{list-style-type:lower-alpha}:host ::ng-deep .markdown-body ol[type=\"a s\"]{list-style-type:lower-alpha}:host ::ng-deep .markdown-body ol[type=\"A s\"]{list-style-type:upper-alpha}:host ::ng-deep .markdown-body ol[type=\"i s\"]{list-style-type:lower-roman}:host ::ng-deep .markdown-body ol[type=\"I s\"]{list-style-type:upper-roman}:host ::ng-deep .markdown-body ol[type=\"1\"]{list-style:unset;list-style-type:decimal}:host ::ng-deep .markdown-body div>ol:not([type]){list-style:unset;list-style-type:decimal}:host ::ng-deep .markdown-body table{border-spacing:0;border-collapse:collapse;display:block;width:max-content;max-width:100%;overflow:auto;padding-bottom:15px}:host ::ng-deep .markdown-body td,:host ::ng-deep .markdown-body th{padding:0}:host ::ng-deep .markdown-body th{color:var(--color-secondary)}:host ::ng-deep .markdown-body table th,:host ::ng-deep .markdown-body table td{padding:6px 13px;border:1px solid var(--color-gray-500)}:host ::ng-deep .markdown-body table td>:last-child{margin-bottom:0}:host ::ng-deep .markdown-body table tr{background-color:#fff;border-top:1px solid var(--color-secondary-lighter)}:host ::ng-deep .markdown-body table tr:nth-child(2n){background-color:var(--color-gray-100)}:host ::ng-deep .markdown-body table img{background-color:transparent}:host ::ng-deep .markdown-body img{border-style:none;max-width:100%;box-sizing:content-box;background-color:transparent}:host ::ng-deep .markdown-body img[align=right]{padding-left:20px}:host ::ng-deep .markdown-body img[align=left]{padding-right:20px}\n"] }]
26338
- }], propDecorators: { textContent: [{
26478
+ args: [{ selector: 'gn-ui-avatar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<img\n *ngIf=\"avatarUrl\"\n class=\"rounded-full object-cover\"\n [src]=\"avatarUrl\"\n (error)=\"hideImage()\"\n/>\n<div\n *ngIf=\"!avatarUrl\"\n class=\"w-full h-full rounded-full bg-gradient-to-tr from-primary to-slate-200\"\n></div>\n" }]
26479
+ }], propDecorators: { avatarUrl: [{
26480
+ type: Input
26481
+ }], avatarPlaceholder: [{
26339
26482
  type: Input
26340
26483
  }] } });
26341
26484
 
@@ -26355,80 +26498,183 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
26355
26498
  type: Input
26356
26499
  }] } });
26357
26500
 
26358
- /* eslint-disable @angular-eslint/directive-selector */
26359
- class GnUiLinkifyDirective {
26360
- constructor(el, renderer) {
26361
- this.el = el;
26362
- this.renderer = renderer;
26501
+ class DownloadItemComponent {
26502
+ constructor() {
26503
+ this.exportUrl = new EventEmitter();
26363
26504
  }
26364
- ngOnInit() {
26365
- setTimeout(() => {
26366
- this.processLinks(this.el.nativeElement);
26367
- }, 0);
26505
+ openUrl() {
26506
+ this.exportUrl.emit(this.link.url.toString());
26368
26507
  }
26369
- processLinks(container) {
26370
- const nodes = Array.from(container.childNodes);
26371
- nodes.forEach((node) => {
26372
- if (node instanceof Text) {
26373
- const textNode = node;
26374
- const linkified = this.linkifyNode(textNode.nodeValue);
26375
- if (linkified) {
26376
- this.createLinkElements(container, linkified, node);
26377
- }
26378
- }
26379
- else if (node instanceof HTMLAnchorElement) {
26380
- const url = node.href;
26381
- const displayValue = node.innerHTML;
26382
- const linkified = this.linkifyNode(displayValue, url);
26383
- if (linkified) {
26384
- this.createLinkElements(container, linkified, node);
26385
- }
26386
- }
26387
- else {
26388
- this.processLinks(node);
26389
- }
26390
- });
26508
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: DownloadItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26509
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: DownloadItemComponent, selector: "gn-ui-download-item", inputs: { link: "link", color: "color", format: "format", isFromWfs: "isFromWfs" }, outputs: { exportUrl: "exportUrl" }, ngImport: i0, template: "<a\n href=\"{{ link.url }}\"\n target=\"_blank\"\n class=\"group flex justify-between card-shadow px-6 py-5 cursor-pointer\"\n rel=\"noopener\"\n>\n <div class=\"grow-1 w-full overflow-hidden\">\n <div\n class=\"text-21 text-black truncate font-title w-11/12\"\n [title]=\"link.description || link.name\"\n >\n {{ link.description || link.name }}\n </div>\n <div class=\"pt-1\">\n <span\n class=\"inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded transition-opacity opacity-70 group-hover:opacity-100\"\n [style.background-color]=\"color\"\n data-cy=\"download-format\"\n >{{ format || ('downloads.format.unknown' | translate) }}</span\n >\n <span\n class=\"pl-2 inline-flex items-center text-gray-800 text-sm\"\n *ngIf=\"isFromWfs\"\n translate=\"\"\n >datahub.search.filter.generatedByWfs</span\n >\n </div>\n </div>\n <div class=\"shrink-1 w-14 flex flex-col justify-center items-center\">\n <mat-icon class=\"!w-8 !h-8 card-icon text-3xl material-symbols-outlined\">\n cloud_download\n </mat-icon>\n </div>\n</a>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26510
+ }
26511
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: DownloadItemComponent, decorators: [{
26512
+ type: Component,
26513
+ args: [{ selector: 'gn-ui-download-item', changeDetection: ChangeDetectionStrategy.OnPush, template: "<a\n href=\"{{ link.url }}\"\n target=\"_blank\"\n class=\"group flex justify-between card-shadow px-6 py-5 cursor-pointer\"\n rel=\"noopener\"\n>\n <div class=\"grow-1 w-full overflow-hidden\">\n <div\n class=\"text-21 text-black truncate font-title w-11/12\"\n [title]=\"link.description || link.name\"\n >\n {{ link.description || link.name }}\n </div>\n <div class=\"pt-1\">\n <span\n class=\"inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded transition-opacity opacity-70 group-hover:opacity-100\"\n [style.background-color]=\"color\"\n data-cy=\"download-format\"\n >{{ format || ('downloads.format.unknown' | translate) }}</span\n >\n <span\n class=\"pl-2 inline-flex items-center text-gray-800 text-sm\"\n *ngIf=\"isFromWfs\"\n translate=\"\"\n >datahub.search.filter.generatedByWfs</span\n >\n </div>\n </div>\n <div class=\"shrink-1 w-14 flex flex-col justify-center items-center\">\n <mat-icon class=\"!w-8 !h-8 card-icon text-3xl material-symbols-outlined\">\n cloud_download\n </mat-icon>\n </div>\n</a>\n" }]
26514
+ }], propDecorators: { link: [{
26515
+ type: Input
26516
+ }], color: [{
26517
+ type: Input
26518
+ }], format: [{
26519
+ type: Input
26520
+ }], isFromWfs: [{
26521
+ type: Input
26522
+ }], exportUrl: [{
26523
+ type: Output
26524
+ }] } });
26525
+
26526
+ marker('datahub.search.filter.all');
26527
+ marker('datahub.search.filter.others');
26528
+ const FILTER_FORMATS = ['all', 'csv', 'excel', 'json', 'shp', 'others'];
26529
+ class DownloadsListComponent {
26530
+ constructor(translateService) {
26531
+ this.translateService = translateService;
26532
+ this.activeFilterFormats = ['all'];
26391
26533
  }
26392
- linkifyNode(displayValue, url) {
26393
- if (url) {
26394
- displayValue = this.createLink(displayValue, url);
26534
+ get filteredLinks() {
26535
+ return this.links.filter((link) => this.activeFilterFormats.some((format) => this.isLinkOfFormat(link, format)));
26536
+ }
26537
+ get visibleFormats() {
26538
+ return FILTER_FORMATS.filter((format) => this.links.some((link) => this.isLinkOfFormat(link, format)));
26539
+ }
26540
+ toggleFilterFormat(format) {
26541
+ if (format === 'all') {
26542
+ this.activeFilterFormats = ['all'];
26543
+ return;
26544
+ }
26545
+ if (this.isFilterActive(format)) {
26546
+ this.activeFilterFormats = this.activeFilterFormats.filter((f) => format !== f);
26395
26547
  }
26396
26548
  else {
26397
- const urlRegex = /\bhttps?:\/\/(?:\([^\s()]+\)|[^\s()]+)+/g;
26398
- const matches = displayValue.match(urlRegex);
26399
- if (matches && matches.length > 0) {
26400
- matches.forEach((match) => {
26401
- url = match;
26402
- displayValue = displayValue.replace(match, (match) => {
26403
- return this.createLink(match, url);
26404
- });
26405
- });
26406
- }
26549
+ this.activeFilterFormats = [
26550
+ ...this.activeFilterFormats.filter((f) => f !== 'all'),
26551
+ format,
26552
+ ];
26553
+ }
26554
+ if (this.activeFilterFormats.length === 0) {
26555
+ this.activeFilterFormats = ['all'];
26407
26556
  }
26408
- return displayValue;
26409
26557
  }
26410
- createLinkElements(container, htmlContent, node) {
26411
- const div = this.renderer.createElement('div');
26412
- div.innerHTML = htmlContent;
26413
- const fragment = document.createDocumentFragment();
26414
- Array.from(div.childNodes).forEach((childNode) => {
26415
- fragment.appendChild(childNode);
26416
- });
26417
- container.insertBefore(fragment, node);
26418
- container.removeChild(node);
26558
+ isFilterActive(filter) {
26559
+ return this.activeFilterFormats.includes(filter);
26419
26560
  }
26420
- createLink(displayValue, url) {
26421
- return `<a href="${url}" target="_blank" class="text-primary cursor-pointer hover:underline">${displayValue} <mat-icon class="material-symbols-outlined !w-[12px] !h-[14px] !text-[14px] opacity-75">open_in_new</mat-icon></a>`;
26561
+ getFilterFormatTitle(format) {
26562
+ if (format === 'all' || format === 'others') {
26563
+ return this.translateService.instant(`datahub.search.filter.${format}`);
26564
+ }
26565
+ return format;
26422
26566
  }
26423
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: GnUiLinkifyDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive }); }
26424
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.1.7", type: GnUiLinkifyDirective, selector: "[gnUiLinkify]", ngImport: i0 }); }
26567
+ isLinkOfFormat(link, format) {
26568
+ if (format === 'all') {
26569
+ return true;
26570
+ }
26571
+ if (getFileFormat(link) === null) {
26572
+ return format === 'others';
26573
+ }
26574
+ if (format === 'others') {
26575
+ const knownFormats = FILTER_FORMATS.filter((format) => format !== 'all' && format !== 'others');
26576
+ return knownFormats.every((knownFormat) => !getFileFormat(link).includes(knownFormat));
26577
+ }
26578
+ return getFileFormat(link).includes(format);
26579
+ }
26580
+ getLinkFormat(link) {
26581
+ return getFileFormat(link);
26582
+ }
26583
+ getLinkColor(link) {
26584
+ return getBadgeColor(getFileFormat(link));
26585
+ }
26586
+ isFromWfs(link) {
26587
+ return link.type === 'service' && link.accessServiceProtocol === 'wfs';
26588
+ }
26589
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: DownloadsListComponent, deps: [{ token: i1$1.TranslateService }], target: i0.ɵɵFactoryTarget.Component }); }
26590
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: DownloadsListComponent, selector: "gn-ui-downloads-list", inputs: { links: "links" }, ngImport: i0, template: "<div\n class=\"flex flex-wrap justify-between mt-8 mb-6 sm:mt-12 sm:mb-2\"\n *ngIf=\"links && links.length > 0\"\n>\n <p\n class=\"font-title text-[28px] text-title font-medium mr-4 pb-4 text-center sm:text-left\"\n translate\n >\n record.metadata.download\n </p>\n <div\n class=\"flex flex-wrap justify-start sm:justify-end sm:pb-4\"\n data-cy=\"download-format-filters\"\n >\n <gn-ui-button\n class=\"m-1 format-filter\"\n [extraClass]=\"\n '!px-[12px] !py-[8px] !text-[15px]' +\n (isFilterActive(format) ? ' opacity-100' : ' opacity-50')\n \"\n (buttonClick)=\"toggleFilterFormat(format)\"\n [attr.data-format]=\"format\"\n *ngFor=\"let format of visibleFormats\"\n >\n {{ getFilterFormatTitle(format) }}\n </gn-ui-button>\n </div>\n</div>\n<div class=\"mb-2 sm:mb-3\" *ngFor=\"let link of filteredLinks\">\n <gn-ui-download-item\n [link]=\"link\"\n [color]=\"getLinkColor(link)\"\n [format]=\"getLinkFormat(link)\"\n [isFromWfs]=\"isFromWfs(link)\"\n ></gn-ui-download-item>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: DownloadItemComponent, selector: "gn-ui-download-item", inputs: ["link", "color", "format", "isFromWfs"], outputs: ["exportUrl"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26425
26591
  }
26426
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: GnUiLinkifyDirective, decorators: [{
26427
- type: Directive,
26428
- args: [{
26429
- selector: '[gnUiLinkify]',
26430
- }]
26431
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }]; } });
26592
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: DownloadsListComponent, decorators: [{
26593
+ type: Component,
26594
+ args: [{ selector: 'gn-ui-downloads-list', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"flex flex-wrap justify-between mt-8 mb-6 sm:mt-12 sm:mb-2\"\n *ngIf=\"links && links.length > 0\"\n>\n <p\n class=\"font-title text-[28px] text-title font-medium mr-4 pb-4 text-center sm:text-left\"\n translate\n >\n record.metadata.download\n </p>\n <div\n class=\"flex flex-wrap justify-start sm:justify-end sm:pb-4\"\n data-cy=\"download-format-filters\"\n >\n <gn-ui-button\n class=\"m-1 format-filter\"\n [extraClass]=\"\n '!px-[12px] !py-[8px] !text-[15px]' +\n (isFilterActive(format) ? ' opacity-100' : ' opacity-50')\n \"\n (buttonClick)=\"toggleFilterFormat(format)\"\n [attr.data-format]=\"format\"\n *ngFor=\"let format of visibleFormats\"\n >\n {{ getFilterFormatTitle(format) }}\n </gn-ui-button>\n </div>\n</div>\n<div class=\"mb-2 sm:mb-3\" *ngFor=\"let link of filteredLinks\">\n <gn-ui-download-item\n [link]=\"link\"\n [color]=\"getLinkColor(link)\"\n [format]=\"getLinkFormat(link)\"\n [isFromWfs]=\"isFromWfs(link)\"\n ></gn-ui-download-item>\n</div>\n" }]
26595
+ }], ctorParameters: function () { return [{ type: i1$1.TranslateService }]; }, propDecorators: { links: [{
26596
+ type: Input
26597
+ }] } });
26598
+
26599
+ class ImageOverlayPreviewComponent {
26600
+ constructor() {
26601
+ this.isPlaceholderShown = new EventEmitter();
26602
+ }
26603
+ openLightbox(src) {
26604
+ basicLightbox.create(`<img src="${src}"/>`).show();
26605
+ }
26606
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ImageOverlayPreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26607
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: ImageOverlayPreviewComponent, selector: "gn-ui-image-overlay-preview", inputs: { imageUrl: "imageUrl" }, outputs: { isPlaceholderShown: "isPlaceholderShown" }, ngImport: i0, template: "<gn-ui-content-ghost\n [showContent]=\"imageUrl !== undefined\"\n ghostClass=\"h-48 mb-3\"\n>\n <div\n *ngIf=\"imageUrl\"\n [showContent]=\"imageUrl !== undefined\"\n data-cy=\"record-thumbnail\"\n class=\"shrink-0 bg-gray-100 rounded-lg overflow-hidden w-full border border-gray-300 group-hover:shadow-xl group-hover:border-0 h-48 mb-3\"\n >\n <gn-ui-thumbnail\n class=\"relative h-full w-full\"\n [thumbnailUrl]=\"imageUrl\"\n fit=\"cover\"\n (placeholderShown)=\"isPlaceholderShown.emit($event)\"\n ></gn-ui-thumbnail>\n <div class=\"relative\">\n <gn-ui-button\n class=\"absolute bottom-0 right-0 z-10 mr-2 mb-2\"\n [type]=\"'outline'\"\n [extraClass]=\"'!py-2 !px-0'\"\n (buttonClick)=\"openLightbox(imageUrl)\"\n >\n <mat-icon class=\"material-symbols-outlined font-extralight\"\n >zoom_out_map</mat-icon\n >\n </gn-ui-button>\n </div>\n </div>\n</gn-ui-content-ghost>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: ThumbnailComponent, selector: "gn-ui-thumbnail", inputs: ["thumbnailUrl", "fit"], outputs: ["placeholderShown"] }, { kind: "component", type: ContentGhostComponent, selector: "gn-ui-content-ghost", inputs: ["showContent", "ghostClass"] }] }); }
26608
+ }
26609
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ImageOverlayPreviewComponent, decorators: [{
26610
+ type: Component,
26611
+ args: [{ selector: 'gn-ui-image-overlay-preview', template: "<gn-ui-content-ghost\n [showContent]=\"imageUrl !== undefined\"\n ghostClass=\"h-48 mb-3\"\n>\n <div\n *ngIf=\"imageUrl\"\n [showContent]=\"imageUrl !== undefined\"\n data-cy=\"record-thumbnail\"\n class=\"shrink-0 bg-gray-100 rounded-lg overflow-hidden w-full border border-gray-300 group-hover:shadow-xl group-hover:border-0 h-48 mb-3\"\n >\n <gn-ui-thumbnail\n class=\"relative h-full w-full\"\n [thumbnailUrl]=\"imageUrl\"\n fit=\"cover\"\n (placeholderShown)=\"isPlaceholderShown.emit($event)\"\n ></gn-ui-thumbnail>\n <div class=\"relative\">\n <gn-ui-button\n class=\"absolute bottom-0 right-0 z-10 mr-2 mb-2\"\n [type]=\"'outline'\"\n [extraClass]=\"'!py-2 !px-0'\"\n (buttonClick)=\"openLightbox(imageUrl)\"\n >\n <mat-icon class=\"material-symbols-outlined font-extralight\"\n >zoom_out_map</mat-icon\n >\n </gn-ui-button>\n </div>\n </div>\n</gn-ui-content-ghost>\n" }]
26612
+ }], propDecorators: { imageUrl: [{
26613
+ type: Input
26614
+ }], isPlaceholderShown: [{
26615
+ type: Output
26616
+ }] } });
26617
+
26618
+ class LinkCardComponent {
26619
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: LinkCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26620
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: LinkCardComponent, selector: "gn-ui-link-card", inputs: { link: "link" }, ngImport: i0, template: "<a\n [href]=\"link.url\"\n target=\"_blank\"\n class=\"flex flex-col justify-between group h-40 grow py-5 px-5 bg-white rounded border-gray-300 filter card-shadow overflow-hidden lg:w-80\"\n>\n <div class=\"max-h-24 overflow-hidden text-ellipsis\">\n <p\n class=\"font-title font-medium text-21 text-black break-words mb-1 line-clamp-2\"\n >\n {{ link.name }}\n </p>\n <p class=\"font-medium text-sm break-words\">\n {{ link.description }}\n </p>\n <p\n *ngIf=\"!link.name && !link.description\"\n class=\"font-medium text-sm break-words truncate\"\n >\n {{ link.url }}\n </p>\n </div>\n <div>\n <mat-icon class=\"material-symbols-outlined card-icon\">open_in_new</mat-icon>\n </div>\n</a>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26621
+ }
26622
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: LinkCardComponent, decorators: [{
26623
+ type: Component,
26624
+ args: [{ selector: 'gn-ui-link-card', changeDetection: ChangeDetectionStrategy.OnPush, template: "<a\n [href]=\"link.url\"\n target=\"_blank\"\n class=\"flex flex-col justify-between group h-40 grow py-5 px-5 bg-white rounded border-gray-300 filter card-shadow overflow-hidden lg:w-80\"\n>\n <div class=\"max-h-24 overflow-hidden text-ellipsis\">\n <p\n class=\"font-title font-medium text-21 text-black break-words mb-1 line-clamp-2\"\n >\n {{ link.name }}\n </p>\n <p class=\"font-medium text-sm break-words\">\n {{ link.description }}\n </p>\n <p\n *ngIf=\"!link.name && !link.description\"\n class=\"font-medium text-sm break-words truncate\"\n >\n {{ link.url }}\n </p>\n </div>\n <div>\n <mat-icon class=\"material-symbols-outlined card-icon\">open_in_new</mat-icon>\n </div>\n</a>\n" }]
26625
+ }], propDecorators: { link: [{
26626
+ type: Input
26627
+ }] } });
26628
+
26629
+ class MarkdownParserComponent {
26630
+ get parsedMarkdown() {
26631
+ return marked.parse(this.textContent);
26632
+ }
26633
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MarkdownParserComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26634
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: MarkdownParserComponent, isStandalone: true, selector: "gn-ui-markdown-parser", inputs: { textContent: "textContent" }, ngImport: i0, template: "<div class=\"markdown-body\" [innerHTML]=\"parsedMarkdown\"></div>\n", styles: [":host ::ng-deep .markdown-body{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;margin:0px 0px 1.5rem;line-height:1.5;word-wrap:break-word}:host ::ng-deep .markdown-body strong{@apply font-bold;color:var(--color-secondary-darker)}:host ::ng-deep .markdown-body h1,:host ::ng-deep .markdown-body h2,:host ::ng-deep .markdown-body h3,:host ::ng-deep .markdown-body h4,:host ::ng-deep .markdown-body h5,:host ::ng-deep .markdown-body h6{margin-top:24px;margin-bottom:16px;line-height:1.25;@apply text-title font-title font-bold;}:host ::ng-deep .markdown-body h1{margin:.67em 0;padding-bottom:.3em;font-size:2em;color:var(--color-primary)}:host ::ng-deep .markdown-body h2{padding-bottom:.3em;font-size:1.5em;color:var(--color-secondary)}:host ::ng-deep .markdown-body h3{font-size:1.25em;color:var(--color-secondary)}:host ::ng-deep .markdown-body h4{font-size:1em;color:var(--color-secondary)}:host ::ng-deep .markdown-body h5{font-size:.875em;color:var(--color-secondary)}:host ::ng-deep .markdown-body h6{font-size:.85em;color:var(--color-secondary-lighter)}:host ::ng-deep .markdown-body p{margin-top:0;margin-bottom:10px}:host ::ng-deep .markdown-body p>a{margin-top:0;margin-bottom:10px;color:var(--color-primary)!important;text-decoration:none}:host ::ng-deep .markdown-body p>a:hover{color:var(--color-primary-darker)!important;@apply underline;}:host ::ng-deep .markdown-body blockquote{margin:0;padding:0 1em;color:var(--color-secondary-lighter);border-left:.25em solid var(--color-primary-lighter)}:host ::ng-deep .markdown-body pre{margin-top:0;margin-bottom:0;font-size:12px;background-color:var(--color-gray-100);word-wrap:normal}:host ::ng-deep .markdown-body pre{padding:16px;overflow:auto;font-size:85%;line-height:1.45;color:var(--color-secondary);border-radius:6px}:host ::ng-deep .markdown-body code{padding:.2em .4em;margin:0;font-size:85%;white-space:break-spaces;border-radius:6px}:host ::ng-deep .markdown-body pre code{display:inline;max-width:auto;padding:0;margin:0;overflow:visible;line-height:inherit;word-wrap:normal;border:0}:host ::ng-deep .markdown-body hr{box-sizing:content-box;overflow:hidden;background:transparent;border-bottom:1px solid var(--color-secondary);height:.15em;padding:0;margin:24px 0;background-color:var(--color-secondary);border:0}:host ::ng-deep .markdown-body hr:before{display:table;content:\"\"}:host ::ng-deep .markdown-body hr:after{display:table;clear:both;content:\"\"}:host ::ng-deep .markdown-body ul,:host ::ng-deep .markdown-body ol{margin-top:0;margin-bottom:0;padding-left:2em;list-style:revert}:host ::ng-deep .markdown-body ol ol,:host ::ng-deep .markdown-body ul ol{list-style-type:lower-roman}:host ::ng-deep .markdown-body ul ul ol,:host ::ng-deep .markdown-body ul ol ol,:host ::ng-deep .markdown-body ol ul ol,:host ::ng-deep .markdown-body ol ol ol{list-style-type:lower-alpha}:host ::ng-deep .markdown-body ol[type=\"a s\"]{list-style-type:lower-alpha}:host ::ng-deep .markdown-body ol[type=\"A s\"]{list-style-type:upper-alpha}:host ::ng-deep .markdown-body ol[type=\"i s\"]{list-style-type:lower-roman}:host ::ng-deep .markdown-body ol[type=\"I s\"]{list-style-type:upper-roman}:host ::ng-deep .markdown-body ol[type=\"1\"]{list-style:unset;list-style-type:decimal}:host ::ng-deep .markdown-body div>ol:not([type]){list-style:unset;list-style-type:decimal}:host ::ng-deep .markdown-body table{border-spacing:0;border-collapse:collapse;display:block;width:max-content;max-width:100%;overflow:auto;padding-bottom:15px}:host ::ng-deep .markdown-body td,:host ::ng-deep .markdown-body th{padding:0}:host ::ng-deep .markdown-body th{color:var(--color-secondary)}:host ::ng-deep .markdown-body table th,:host ::ng-deep .markdown-body table td{padding:6px 13px;border:1px solid var(--color-gray-500)}:host ::ng-deep .markdown-body table td>:last-child{margin-bottom:0}:host ::ng-deep .markdown-body table tr{background-color:#fff;border-top:1px solid var(--color-secondary-lighter)}:host ::ng-deep .markdown-body table tr:nth-child(2n){background-color:var(--color-gray-100)}:host ::ng-deep .markdown-body table img{background-color:transparent}:host ::ng-deep .markdown-body img{border-style:none;max-width:100%;box-sizing:content-box;background-color:transparent}:host ::ng-deep .markdown-body img[align=right]{padding-left:20px}:host ::ng-deep .markdown-body img[align=left]{padding-right:20px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26635
+ }
26636
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MarkdownParserComponent, decorators: [{
26637
+ type: Component,
26638
+ args: [{ selector: 'gn-ui-markdown-parser', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<div class=\"markdown-body\" [innerHTML]=\"parsedMarkdown\"></div>\n", styles: [":host ::ng-deep .markdown-body{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;margin:0px 0px 1.5rem;line-height:1.5;word-wrap:break-word}:host ::ng-deep .markdown-body strong{@apply font-bold;color:var(--color-secondary-darker)}:host ::ng-deep .markdown-body h1,:host ::ng-deep .markdown-body h2,:host ::ng-deep .markdown-body h3,:host ::ng-deep .markdown-body h4,:host ::ng-deep .markdown-body h5,:host ::ng-deep .markdown-body h6{margin-top:24px;margin-bottom:16px;line-height:1.25;@apply text-title font-title font-bold;}:host ::ng-deep .markdown-body h1{margin:.67em 0;padding-bottom:.3em;font-size:2em;color:var(--color-primary)}:host ::ng-deep .markdown-body h2{padding-bottom:.3em;font-size:1.5em;color:var(--color-secondary)}:host ::ng-deep .markdown-body h3{font-size:1.25em;color:var(--color-secondary)}:host ::ng-deep .markdown-body h4{font-size:1em;color:var(--color-secondary)}:host ::ng-deep .markdown-body h5{font-size:.875em;color:var(--color-secondary)}:host ::ng-deep .markdown-body h6{font-size:.85em;color:var(--color-secondary-lighter)}:host ::ng-deep .markdown-body p{margin-top:0;margin-bottom:10px}:host ::ng-deep .markdown-body p>a{margin-top:0;margin-bottom:10px;color:var(--color-primary)!important;text-decoration:none}:host ::ng-deep .markdown-body p>a:hover{color:var(--color-primary-darker)!important;@apply underline;}:host ::ng-deep .markdown-body blockquote{margin:0;padding:0 1em;color:var(--color-secondary-lighter);border-left:.25em solid var(--color-primary-lighter)}:host ::ng-deep .markdown-body pre{margin-top:0;margin-bottom:0;font-size:12px;background-color:var(--color-gray-100);word-wrap:normal}:host ::ng-deep .markdown-body pre{padding:16px;overflow:auto;font-size:85%;line-height:1.45;color:var(--color-secondary);border-radius:6px}:host ::ng-deep .markdown-body code{padding:.2em .4em;margin:0;font-size:85%;white-space:break-spaces;border-radius:6px}:host ::ng-deep .markdown-body pre code{display:inline;max-width:auto;padding:0;margin:0;overflow:visible;line-height:inherit;word-wrap:normal;border:0}:host ::ng-deep .markdown-body hr{box-sizing:content-box;overflow:hidden;background:transparent;border-bottom:1px solid var(--color-secondary);height:.15em;padding:0;margin:24px 0;background-color:var(--color-secondary);border:0}:host ::ng-deep .markdown-body hr:before{display:table;content:\"\"}:host ::ng-deep .markdown-body hr:after{display:table;clear:both;content:\"\"}:host ::ng-deep .markdown-body ul,:host ::ng-deep .markdown-body ol{margin-top:0;margin-bottom:0;padding-left:2em;list-style:revert}:host ::ng-deep .markdown-body ol ol,:host ::ng-deep .markdown-body ul ol{list-style-type:lower-roman}:host ::ng-deep .markdown-body ul ul ol,:host ::ng-deep .markdown-body ul ol ol,:host ::ng-deep .markdown-body ol ul ol,:host ::ng-deep .markdown-body ol ol ol{list-style-type:lower-alpha}:host ::ng-deep .markdown-body ol[type=\"a s\"]{list-style-type:lower-alpha}:host ::ng-deep .markdown-body ol[type=\"A s\"]{list-style-type:upper-alpha}:host ::ng-deep .markdown-body ol[type=\"i s\"]{list-style-type:lower-roman}:host ::ng-deep .markdown-body ol[type=\"I s\"]{list-style-type:upper-roman}:host ::ng-deep .markdown-body ol[type=\"1\"]{list-style:unset;list-style-type:decimal}:host ::ng-deep .markdown-body div>ol:not([type]){list-style:unset;list-style-type:decimal}:host ::ng-deep .markdown-body table{border-spacing:0;border-collapse:collapse;display:block;width:max-content;max-width:100%;overflow:auto;padding-bottom:15px}:host ::ng-deep .markdown-body td,:host ::ng-deep .markdown-body th{padding:0}:host ::ng-deep .markdown-body th{color:var(--color-secondary)}:host ::ng-deep .markdown-body table th,:host ::ng-deep .markdown-body table td{padding:6px 13px;border:1px solid var(--color-gray-500)}:host ::ng-deep .markdown-body table td>:last-child{margin-bottom:0}:host ::ng-deep .markdown-body table tr{background-color:#fff;border-top:1px solid var(--color-secondary-lighter)}:host ::ng-deep .markdown-body table tr:nth-child(2n){background-color:var(--color-gray-100)}:host ::ng-deep .markdown-body table img{background-color:transparent}:host ::ng-deep .markdown-body img{border-style:none;max-width:100%;box-sizing:content-box;background-color:transparent}:host ::ng-deep .markdown-body img[align=right]{padding-left:20px}:host ::ng-deep .markdown-body img[align=left]{padding-right:20px}\n"] }]
26639
+ }], propDecorators: { textContent: [{
26640
+ type: Input
26641
+ }] } });
26642
+
26643
+ class MarkdownEditorComponent {
26644
+ constructor() {
26645
+ this.preview = false;
26646
+ this.textContentChanged = new EventEmitter();
26647
+ }
26648
+ textContentChangedHandler(textContent) {
26649
+ this.textContent = textContent;
26650
+ this.textContentChanged.emit(this.textContent);
26651
+ }
26652
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MarkdownEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26653
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: MarkdownEditorComponent, isStandalone: true, selector: "gn-ui-markdown-editor", inputs: { preview: "preview", helperText: "helperText", placeholder: "placeholder", textContent: "textContent" }, outputs: { textContentChanged: "textContentChanged" }, ngImport: i0, template: "<div class=\"h-full flex flex-col\">\n <p class=\"flex-none mb-2 font-medium text-sm text-gray-900\">\n {{ helperText }}\n </p>\n <div class=\"flex-1\" [hidden]=\"preview\">\n <gn-ui-text-area\n [placeholder]=\"placeholder\"\n [value]=\"textContent\"\n (valueChange)=\"textContentChangedHandler($event)\"\n ></gn-ui-text-area>\n </div>\n <div\n class=\"flex-1 border border-gray-800 rounded overflow-y-scroll\"\n [hidden]=\"!preview\"\n >\n <gn-ui-markdown-parser [textContent]=\"textContent\"></gn-ui-markdown-parser>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "component", type: TextAreaComponent, selector: "gn-ui-text-area", inputs: ["value", "disabled", "extraClass", "placeholder", "required"], outputs: ["valueChange"] }, { kind: "component", type: MarkdownParserComponent, selector: "gn-ui-markdown-parser", inputs: ["textContent"] }, { kind: "ngmodule", type: TranslateModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26654
+ }
26655
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MarkdownEditorComponent, decorators: [{
26656
+ type: Component,
26657
+ args: [{ selector: 'gn-ui-markdown-editor', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
26658
+ CommonModule,
26659
+ FormsModule,
26660
+ MatIconModule,
26661
+ MatTooltipModule,
26662
+ ButtonComponent,
26663
+ TextAreaComponent,
26664
+ MarkdownParserComponent,
26665
+ TranslateModule,
26666
+ ], template: "<div class=\"h-full flex flex-col\">\n <p class=\"flex-none mb-2 font-medium text-sm text-gray-900\">\n {{ helperText }}\n </p>\n <div class=\"flex-1\" [hidden]=\"preview\">\n <gn-ui-text-area\n [placeholder]=\"placeholder\"\n [value]=\"textContent\"\n (valueChange)=\"textContentChangedHandler($event)\"\n ></gn-ui-text-area>\n </div>\n <div\n class=\"flex-1 border border-gray-800 rounded overflow-y-scroll\"\n [hidden]=\"!preview\"\n >\n <gn-ui-markdown-parser [textContent]=\"textContent\"></gn-ui-markdown-parser>\n </div>\n</div>\n" }]
26667
+ }], propDecorators: { preview: [{
26668
+ type: Input
26669
+ }], helperText: [{
26670
+ type: Input
26671
+ }], placeholder: [{
26672
+ type: Input
26673
+ }], textContent: [{
26674
+ type: Input
26675
+ }], textContentChanged: [{
26676
+ type: Output
26677
+ }] } });
26432
26678
 
26433
26679
  class MaxLinesComponent {
26434
26680
  constructor(cdr) {
@@ -26495,6 +26741,155 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
26495
26741
  args: ['container']
26496
26742
  }] } });
26497
26743
 
26744
+ class MetadataCatalogComponent {
26745
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MetadataCatalogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26746
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: MetadataCatalogComponent, selector: "gn-ui-metadata-catalog", inputs: { sourceLabel: "sourceLabel" }, ngImport: i0, template: "<div>\n <p class=\"text-gray-700 text-xs mb-3 uppercase\" translate>\n record.metadata.catalog\n </p>\n <p class=\"text-primary font-title text-21 mb-1\">\n {{ sourceLabel }}\n </p>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26747
+ }
26748
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MetadataCatalogComponent, decorators: [{
26749
+ type: Component,
26750
+ args: [{ selector: 'gn-ui-metadata-catalog', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div>\n <p class=\"text-gray-700 text-xs mb-3 uppercase\" translate>\n record.metadata.catalog\n </p>\n <p class=\"text-primary font-title text-21 mb-1\">\n {{ sourceLabel }}\n </p>\n</div>\n" }]
26751
+ }], propDecorators: { sourceLabel: [{
26752
+ type: Input
26753
+ }] } });
26754
+
26755
+ class MetadataContactComponent {
26756
+ constructor() {
26757
+ this.organizationClick = new EventEmitter();
26758
+ this.contactClick = new EventEmitter();
26759
+ }
26760
+ get shownOrganization() {
26761
+ return this.metadata.ownerOrganization;
26762
+ }
26763
+ get contacts() {
26764
+ return ((this.metadata.kind === 'dataset'
26765
+ ? this.metadata.contactsForResource
26766
+ : this.metadata.contacts) || []);
26767
+ }
26768
+ get address() {
26769
+ const addressParts = this.contacts[0].address
26770
+ .split(',')
26771
+ .map((part) => part.trim());
26772
+ return addressParts;
26773
+ }
26774
+ onOrganizationClick() {
26775
+ this.organizationClick.emit(this.shownOrganization);
26776
+ }
26777
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MetadataContactComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26778
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: MetadataContactComponent, selector: "gn-ui-metadata-contact", inputs: { metadata: "metadata" }, outputs: { organizationClick: "organizationClick", contactClick: "contactClick" }, ngImport: i0, template: "<div class=\"py-5 px-5 rounded bg-gray-100 text-black mb-6\">\n <div class=\"grid gap-3 overflow-hidden\">\n <div>\n <p class=\"text-sm font-medium\" translate>record.metadata.contact</p>\n </div>\n <div\n *ngIf=\"shownOrganization?.logoUrl?.href\"\n class=\"flex items-center justify-center border-solid border border-gray-300 rounded-md bg-white h-32 overflow-hidden\"\n >\n <gn-ui-thumbnail\n class=\"relative h-full w-full\"\n [thumbnailUrl]=\"shownOrganization.logoUrl.href\"\n fit=\"contain\"\n ></gn-ui-thumbnail>\n </div>\n <div class=\"grid gap-1\">\n <div class=\"flex\">\n <div\n class=\"text-primary font-title text-21 mr-2 cursor-pointer hover:underline\"\n (click)=\"onOrganizationClick()\"\n data-cy=\"organization-name\"\n >\n {{ shownOrganization?.name }}\n </div>\n </div>\n <div *ngIf=\"shownOrganization?.website\">\n <a\n [href]=\"shownOrganization.website\"\n target=\"_blank\"\n class=\"contact-website text-primary text-sm cursor-pointer hover:underline transition-all\"\n >{{ shownOrganization.website }}\n <mat-icon\n class=\"material-symbols-outlined !w-[12px] !h-[12px] !text-[12px] opacity-75 shrink-0\"\n >open_in_new</mat-icon\n >\n </a>\n </div>\n </div>\n <div class=\"grid gap-5 py-3 overflow-hidden\">\n <div *ngIf=\"contacts[0]?.phone\">\n <div class=\"flex\">\n <mat-icon\n class=\"material-symbols-outlined !w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n >call_outline</mat-icon\n >\n <div class=\"flex flex-col ml-2\">\n <p class=\"text-sm\">{{ contacts[0].phone }}</p>\n </div>\n </div>\n </div>\n <div *ngIf=\"contacts[0]?.email\">\n <div class=\"flex\">\n <mat-icon\n class=\"material-symbols-outlined !w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n >\n mail_outline</mat-icon\n >\n <a\n *ngIf=\"contacts.length\"\n [href]=\"'mailto:' + contacts[0].email\"\n class=\"text-sm hover:underline ml-2\"\n target=\"_blank\"\n data-cy=\"contact-email\"\n >{{ contacts[0].email }}</a\n >\n </div>\n </div>\n <div *ngIf=\"contacts[0]?.firstName || contacts[0]?.lastName\">\n <div class=\"flex\">\n <mat-icon\n class=\"material-symbols-outlined !w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n >person_outline</mat-icon\n >\n <div class=\"flex flex-col ml-2\">\n <p class=\"text-sm\">\n {{ contacts[0]?.firstName || '' }}\n {{ contacts[0]?.lastName || '' }}\n </p>\n </div>\n </div>\n </div>\n <div *ngIf=\"contacts[0]?.address\">\n <div class=\"flex\">\n <mat-icon\n class=\"material-symbols-outlined !w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n >\n location_on</mat-icon\n >\n <div class=\"flex flex-col ml-2\">\n <p *ngFor=\"let addressPart of address\" class=\"text-sm\">\n {{ addressPart }}\n </p>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: ThumbnailComponent, selector: "gn-ui-thumbnail", inputs: ["thumbnailUrl", "fit"], outputs: ["placeholderShown"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26779
+ }
26780
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MetadataContactComponent, decorators: [{
26781
+ type: Component,
26782
+ args: [{ selector: 'gn-ui-metadata-contact', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"py-5 px-5 rounded bg-gray-100 text-black mb-6\">\n <div class=\"grid gap-3 overflow-hidden\">\n <div>\n <p class=\"text-sm font-medium\" translate>record.metadata.contact</p>\n </div>\n <div\n *ngIf=\"shownOrganization?.logoUrl?.href\"\n class=\"flex items-center justify-center border-solid border border-gray-300 rounded-md bg-white h-32 overflow-hidden\"\n >\n <gn-ui-thumbnail\n class=\"relative h-full w-full\"\n [thumbnailUrl]=\"shownOrganization.logoUrl.href\"\n fit=\"contain\"\n ></gn-ui-thumbnail>\n </div>\n <div class=\"grid gap-1\">\n <div class=\"flex\">\n <div\n class=\"text-primary font-title text-21 mr-2 cursor-pointer hover:underline\"\n (click)=\"onOrganizationClick()\"\n data-cy=\"organization-name\"\n >\n {{ shownOrganization?.name }}\n </div>\n </div>\n <div *ngIf=\"shownOrganization?.website\">\n <a\n [href]=\"shownOrganization.website\"\n target=\"_blank\"\n class=\"contact-website text-primary text-sm cursor-pointer hover:underline transition-all\"\n >{{ shownOrganization.website }}\n <mat-icon\n class=\"material-symbols-outlined !w-[12px] !h-[12px] !text-[12px] opacity-75 shrink-0\"\n >open_in_new</mat-icon\n >\n </a>\n </div>\n </div>\n <div class=\"grid gap-5 py-3 overflow-hidden\">\n <div *ngIf=\"contacts[0]?.phone\">\n <div class=\"flex\">\n <mat-icon\n class=\"material-symbols-outlined !w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n >call_outline</mat-icon\n >\n <div class=\"flex flex-col ml-2\">\n <p class=\"text-sm\">{{ contacts[0].phone }}</p>\n </div>\n </div>\n </div>\n <div *ngIf=\"contacts[0]?.email\">\n <div class=\"flex\">\n <mat-icon\n class=\"material-symbols-outlined !w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n >\n mail_outline</mat-icon\n >\n <a\n *ngIf=\"contacts.length\"\n [href]=\"'mailto:' + contacts[0].email\"\n class=\"text-sm hover:underline ml-2\"\n target=\"_blank\"\n data-cy=\"contact-email\"\n >{{ contacts[0].email }}</a\n >\n </div>\n </div>\n <div *ngIf=\"contacts[0]?.firstName || contacts[0]?.lastName\">\n <div class=\"flex\">\n <mat-icon\n class=\"material-symbols-outlined !w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n >person_outline</mat-icon\n >\n <div class=\"flex flex-col ml-2\">\n <p class=\"text-sm\">\n {{ contacts[0]?.firstName || '' }}\n {{ contacts[0]?.lastName || '' }}\n </p>\n </div>\n </div>\n </div>\n <div *ngIf=\"contacts[0]?.address\">\n <div class=\"flex\">\n <mat-icon\n class=\"material-symbols-outlined !w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n >\n location_on</mat-icon\n >\n <div class=\"flex flex-col ml-2\">\n <p *ngFor=\"let addressPart of address\" class=\"text-sm\">\n {{ addressPart }}\n </p>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n" }]
26783
+ }], propDecorators: { metadata: [{
26784
+ type: Input
26785
+ }], organizationClick: [{
26786
+ type: Output
26787
+ }], contactClick: [{
26788
+ type: Output
26789
+ }] } });
26790
+
26791
+ class ExpandablePanelComponent {
26792
+ constructor() {
26793
+ this.collapsed = true;
26794
+ this.maxHeight = this.setMaxHeight();
26795
+ }
26796
+ toggle() {
26797
+ this.collapsed = !this.collapsed;
26798
+ this.maxHeight = this.setMaxHeight();
26799
+ }
26800
+ setMaxHeight() {
26801
+ return `${this.collapsed ? '0' : this.contentDiv.nativeElement.scrollHeight}px`;
26802
+ }
26803
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ExpandablePanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26804
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: ExpandablePanelComponent, selector: "gn-ui-expandable-panel", inputs: { title: "title", collapsed: "collapsed" }, viewQueries: [{ propertyName: "contentDiv", first: true, predicate: ["contentDiv"], descendants: true }], ngImport: i0, template: "<div\n class=\"group flex align-middle title border-b border-gray-100 cursor-pointer pt-2.5\"\n (click)=\"toggle()\"\n>\n <div class=\"grow font-medium text-black text-sm\">\n {{ title }}\n </div>\n <div\n class=\"w-8 opacity-25 text-primary group-hover:opacity-100 transition-opacity\"\n >\n <mat-icon class=\"material-symbols-outlined\" *ngIf=\"collapsed\">add</mat-icon>\n <mat-icon class=\"material-symbols-outlined\" *ngIf=\"!collapsed\"\n >remove</mat-icon\n >\n </div>\n</div>\n<div\n class=\"content overflow-hidden transition-[max-height] duration-300\"\n [ngClass]=\"collapsed ? 'ease-out' : 'ease-in'\"\n [style.maxHeight]=\"maxHeight\"\n #contentDiv\n>\n <ng-content></ng-content>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26805
+ }
26806
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ExpandablePanelComponent, decorators: [{
26807
+ type: Component,
26808
+ args: [{ selector: 'gn-ui-expandable-panel', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"group flex align-middle title border-b border-gray-100 cursor-pointer pt-2.5\"\n (click)=\"toggle()\"\n>\n <div class=\"grow font-medium text-black text-sm\">\n {{ title }}\n </div>\n <div\n class=\"w-8 opacity-25 text-primary group-hover:opacity-100 transition-opacity\"\n >\n <mat-icon class=\"material-symbols-outlined\" *ngIf=\"collapsed\">add</mat-icon>\n <mat-icon class=\"material-symbols-outlined\" *ngIf=\"!collapsed\"\n >remove</mat-icon\n >\n </div>\n</div>\n<div\n class=\"content overflow-hidden transition-[max-height] duration-300\"\n [ngClass]=\"collapsed ? 'ease-out' : 'ease-in'\"\n [style.maxHeight]=\"maxHeight\"\n #contentDiv\n>\n <ng-content></ng-content>\n</div>\n" }]
26809
+ }], propDecorators: { title: [{
26810
+ type: Input
26811
+ }], collapsed: [{
26812
+ type: Input
26813
+ }], contentDiv: [{
26814
+ type: ViewChild,
26815
+ args: ['contentDiv']
26816
+ }] } });
26817
+
26818
+ /* eslint-disable @angular-eslint/directive-selector */
26819
+ class GnUiLinkifyDirective {
26820
+ constructor(el, renderer) {
26821
+ this.el = el;
26822
+ this.renderer = renderer;
26823
+ }
26824
+ ngOnInit() {
26825
+ setTimeout(() => {
26826
+ this.processLinks(this.el.nativeElement);
26827
+ }, 0);
26828
+ }
26829
+ processLinks(container) {
26830
+ const nodes = Array.from(container.childNodes);
26831
+ nodes.forEach((node) => {
26832
+ if (node instanceof Text) {
26833
+ const textNode = node;
26834
+ const linkified = this.linkifyNode(textNode.nodeValue);
26835
+ if (linkified) {
26836
+ this.createLinkElements(container, linkified, node);
26837
+ }
26838
+ }
26839
+ else if (node instanceof HTMLAnchorElement) {
26840
+ const url = node.href;
26841
+ const displayValue = node.innerHTML;
26842
+ const linkified = this.linkifyNode(displayValue, url);
26843
+ if (linkified) {
26844
+ this.createLinkElements(container, linkified, node);
26845
+ }
26846
+ }
26847
+ else {
26848
+ this.processLinks(node);
26849
+ }
26850
+ });
26851
+ }
26852
+ linkifyNode(displayValue, url) {
26853
+ if (url) {
26854
+ displayValue = this.createLink(displayValue, url);
26855
+ }
26856
+ else {
26857
+ const urlRegex = /\bhttps?:\/\/(?:\([^\s()]+\)|[^\s()]+)+/g;
26858
+ const matches = displayValue.match(urlRegex);
26859
+ if (matches && matches.length > 0) {
26860
+ matches.forEach((match) => {
26861
+ url = match;
26862
+ displayValue = displayValue.replace(match, (match) => {
26863
+ return this.createLink(match, url);
26864
+ });
26865
+ });
26866
+ }
26867
+ }
26868
+ return displayValue;
26869
+ }
26870
+ createLinkElements(container, htmlContent, node) {
26871
+ const div = this.renderer.createElement('div');
26872
+ div.innerHTML = htmlContent;
26873
+ const fragment = document.createDocumentFragment();
26874
+ Array.from(div.childNodes).forEach((childNode) => {
26875
+ fragment.appendChild(childNode);
26876
+ });
26877
+ container.insertBefore(fragment, node);
26878
+ container.removeChild(node);
26879
+ }
26880
+ createLink(displayValue, url) {
26881
+ return `<a href="${url}" target="_blank" class="text-primary cursor-pointer hover:underline">${displayValue} <mat-icon class="material-symbols-outlined !w-[12px] !h-[14px] !text-[14px] opacity-75">open_in_new</mat-icon></a>`;
26882
+ }
26883
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: GnUiLinkifyDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive }); }
26884
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.1.7", type: GnUiLinkifyDirective, selector: "[gnUiLinkify]", ngImport: i0 }); }
26885
+ }
26886
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: GnUiLinkifyDirective, decorators: [{
26887
+ type: Directive,
26888
+ args: [{
26889
+ selector: '[gnUiLinkify]',
26890
+ }]
26891
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }]; } });
26892
+
26498
26893
  class MetadataInfoComponent {
26499
26894
  constructor() {
26500
26895
  this.keyword = new EventEmitter();
@@ -26572,210 +26967,210 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
26572
26967
  type: Output
26573
26968
  }] } });
26574
26969
 
26575
- class DownloadItemComponent {
26970
+ class PaginationButtonsComponent {
26576
26971
  constructor() {
26577
- this.exportUrl = new EventEmitter();
26578
- }
26579
- openUrl() {
26580
- this.exportUrl.emit(this.link.url.toString());
26581
- }
26582
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: DownloadItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26583
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: DownloadItemComponent, selector: "gn-ui-download-item", inputs: { link: "link", color: "color", format: "format", isFromWfs: "isFromWfs" }, outputs: { exportUrl: "exportUrl" }, ngImport: i0, template: "<a\n href=\"{{ link.url }}\"\n target=\"_blank\"\n class=\"group flex justify-between card-shadow px-6 py-5 cursor-pointer\"\n rel=\"noopener\"\n>\n <div class=\"grow-1 w-full overflow-hidden\">\n <div\n class=\"text-21 text-black truncate font-title w-11/12\"\n [title]=\"link.description || link.name\"\n >\n {{ link.description || link.name }}\n </div>\n <div class=\"pt-1\">\n <span\n class=\"inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded transition-opacity opacity-70 group-hover:opacity-100\"\n [style.background-color]=\"color\"\n data-cy=\"download-format\"\n >{{ format || ('downloads.format.unknown' | translate) }}</span\n >\n <span\n class=\"pl-2 inline-flex items-center text-gray-800 text-sm\"\n *ngIf=\"isFromWfs\"\n translate=\"\"\n >datahub.search.filter.generatedByWfs</span\n >\n </div>\n </div>\n <div class=\"shrink-1 w-14 flex flex-col justify-center items-center\">\n <mat-icon class=\"!w-8 !h-8 card-icon text-3xl material-symbols-outlined\">\n cloud_download\n </mat-icon>\n </div>\n</a>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26584
- }
26585
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: DownloadItemComponent, decorators: [{
26586
- type: Component,
26587
- args: [{ selector: 'gn-ui-download-item', changeDetection: ChangeDetectionStrategy.OnPush, template: "<a\n href=\"{{ link.url }}\"\n target=\"_blank\"\n class=\"group flex justify-between card-shadow px-6 py-5 cursor-pointer\"\n rel=\"noopener\"\n>\n <div class=\"grow-1 w-full overflow-hidden\">\n <div\n class=\"text-21 text-black truncate font-title w-11/12\"\n [title]=\"link.description || link.name\"\n >\n {{ link.description || link.name }}\n </div>\n <div class=\"pt-1\">\n <span\n class=\"inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded transition-opacity opacity-70 group-hover:opacity-100\"\n [style.background-color]=\"color\"\n data-cy=\"download-format\"\n >{{ format || ('downloads.format.unknown' | translate) }}</span\n >\n <span\n class=\"pl-2 inline-flex items-center text-gray-800 text-sm\"\n *ngIf=\"isFromWfs\"\n translate=\"\"\n >datahub.search.filter.generatedByWfs</span\n >\n </div>\n </div>\n <div class=\"shrink-1 w-14 flex flex-col justify-center items-center\">\n <mat-icon class=\"!w-8 !h-8 card-icon text-3xl material-symbols-outlined\">\n cloud_download\n </mat-icon>\n </div>\n</a>\n" }]
26588
- }], propDecorators: { link: [{
26589
- type: Input
26590
- }], color: [{
26591
- type: Input
26592
- }], format: [{
26593
- type: Input
26594
- }], isFromWfs: [{
26595
- type: Input
26596
- }], exportUrl: [{
26597
- type: Output
26598
- }] } });
26599
-
26600
- marker('datahub.search.filter.all');
26601
- marker('datahub.search.filter.others');
26602
- const FILTER_FORMATS = ['all', 'csv', 'excel', 'json', 'shp', 'others'];
26603
- class DownloadsListComponent {
26604
- constructor(translateService) {
26605
- this.translateService = translateService;
26606
- this.activeFilterFormats = ['all'];
26607
- }
26608
- get filteredLinks() {
26609
- return this.links.filter((link) => this.activeFilterFormats.some((format) => this.isLinkOfFormat(link, format)));
26972
+ this.visiblePages = [];
26973
+ this.newCurrentPageEvent = new EventEmitter();
26610
26974
  }
26611
- get visibleFormats() {
26612
- return FILTER_FORMATS.filter((format) => this.links.some((link) => this.isLinkOfFormat(link, format)));
26975
+ ngOnChanges() {
26976
+ this.calculateVisiblePages();
26613
26977
  }
26614
- toggleFilterFormat(format) {
26615
- if (format === 'all') {
26616
- this.activeFilterFormats = ['all'];
26617
- return;
26618
- }
26619
- if (this.isFilterActive(format)) {
26620
- this.activeFilterFormats = this.activeFilterFormats.filter((f) => format !== f);
26621
- }
26622
- else {
26623
- this.activeFilterFormats = [
26624
- ...this.activeFilterFormats.filter((f) => f !== 'all'),
26625
- format,
26626
- ];
26978
+ calculateVisiblePages() {
26979
+ const maxVisiblePages = 5;
26980
+ const halfVisible = Math.floor(maxVisiblePages / 2);
26981
+ const startPage = Math.max(this.currentPage - halfVisible, 1);
26982
+ const endPage = Math.min(this.currentPage + halfVisible, this.totalPages);
26983
+ const visiblePages = [];
26984
+ if (startPage > 1) {
26985
+ visiblePages.push(1);
26986
+ if (startPage > 2) {
26987
+ visiblePages.push('...');
26988
+ }
26627
26989
  }
26628
- if (this.activeFilterFormats.length === 0) {
26629
- this.activeFilterFormats = ['all'];
26990
+ for (let page = startPage; page <= endPage; page++) {
26991
+ visiblePages.push(page);
26630
26992
  }
26631
- }
26632
- isFilterActive(filter) {
26633
- return this.activeFilterFormats.includes(filter);
26634
- }
26635
- getFilterFormatTitle(format) {
26636
- if (format === 'all' || format === 'others') {
26637
- return this.translateService.instant(`datahub.search.filter.${format}`);
26993
+ if (endPage < this.totalPages) {
26994
+ if (endPage < this.totalPages - 1) {
26995
+ visiblePages.push('...');
26996
+ }
26997
+ visiblePages.push(this.totalPages);
26638
26998
  }
26639
- return format;
26999
+ this.visiblePages = visiblePages;
26640
27000
  }
26641
- isLinkOfFormat(link, format) {
26642
- if (format === 'all') {
26643
- return true;
26644
- }
26645
- if (getFileFormat(link) === null) {
26646
- return format === 'others';
26647
- }
26648
- if (format === 'others') {
26649
- const knownFormats = FILTER_FORMATS.filter((format) => format !== 'all' && format !== 'others');
26650
- return knownFormats.every((knownFormat) => !getFileFormat(link).includes(knownFormat));
26651
- }
26652
- return getFileFormat(link).includes(format);
27001
+ changePage(page) {
27002
+ this.setPage(page);
26653
27003
  }
26654
- getLinkFormat(link) {
26655
- return getFileFormat(link);
27004
+ nextPage() {
27005
+ this.setPage(this.currentPage + 1);
26656
27006
  }
26657
- getLinkColor(link) {
26658
- return getBadgeColor(getFileFormat(link));
27007
+ previousPage() {
27008
+ this.setPage(this.currentPage - 1);
26659
27009
  }
26660
- isFromWfs(link) {
26661
- return link.type === 'service' && link.accessServiceProtocol === 'wfs';
27010
+ setPage(newPage) {
27011
+ if (!Number.isInteger(newPage))
27012
+ return;
27013
+ this.currentPage = newPage;
27014
+ this.calculateVisiblePages();
27015
+ this.newCurrentPageEvent.emit(this.currentPage);
26662
27016
  }
26663
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: DownloadsListComponent, deps: [{ token: i1$1.TranslateService }], target: i0.ɵɵFactoryTarget.Component }); }
26664
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: DownloadsListComponent, selector: "gn-ui-downloads-list", inputs: { links: "links" }, ngImport: i0, template: "<div\n class=\"flex flex-wrap justify-between mt-8 mb-6 sm:mt-12 sm:mb-2\"\n *ngIf=\"links && links.length > 0\"\n>\n <p\n class=\"font-title text-[28px] text-title font-medium mr-4 pb-4 text-center sm:text-left\"\n translate\n >\n record.metadata.download\n </p>\n <div\n class=\"flex flex-wrap justify-start sm:justify-end sm:pb-4\"\n data-cy=\"download-format-filters\"\n >\n <gn-ui-button\n class=\"m-1 format-filter\"\n [extraClass]=\"\n '!px-[12px] !py-[8px] !text-[15px]' +\n (isFilterActive(format) ? ' opacity-100' : ' opacity-50')\n \"\n (buttonClick)=\"toggleFilterFormat(format)\"\n [attr.data-format]=\"format\"\n *ngFor=\"let format of visibleFormats\"\n >\n {{ getFilterFormatTitle(format) }}\n </gn-ui-button>\n </div>\n</div>\n<div class=\"mb-2 sm:mb-3\" *ngFor=\"let link of filteredLinks\">\n <gn-ui-download-item\n [link]=\"link\"\n [color]=\"getLinkColor(link)\"\n [format]=\"getLinkFormat(link)\"\n [isFromWfs]=\"isFromWfs(link)\"\n ></gn-ui-download-item>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: DownloadItemComponent, selector: "gn-ui-download-item", inputs: ["link", "color", "format", "isFromWfs"], outputs: ["exportUrl"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
27017
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: PaginationButtonsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27018
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: PaginationButtonsComponent, selector: "gn-ui-pagination-buttons", inputs: { currentPage: "currentPage", totalPages: "totalPages" }, outputs: { newCurrentPageEvent: "newCurrentPageEvent" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"relative\">\n <div class=\"flex flex-row gap-[5px] items-center\">\n <gn-ui-button\n type=\"light\"\n [disabled]=\"currentPage === 1\"\n (buttonClick)=\"previousPage()\"\n extraClass=\"!px-[3px]\"\n >\n <mat-icon class=\"material-symbols-outlined\">chevron_left</mat-icon>\n </gn-ui-button>\n <ng-container *ngFor=\"let page of visiblePages\">\n <ng-container *ngIf=\"page === '...'\">\n <span class=\"mx-[5px]\">{{ page }}</span>\n </ng-container>\n <ng-container *ngIf=\"page !== '...'\">\n <gn-ui-button\n [type]=\"page === currentPage ? 'primary' : 'light'\"\n [disabled]=\"page === currentPage\"\n (buttonClick)=\"changePage(page)\"\n >{{ page }}</gn-ui-button\n >\n </ng-container>\n </ng-container>\n <gn-ui-button\n type=\"light\"\n [disabled]=\"currentPage === totalPages\"\n (buttonClick)=\"nextPage()\"\n extraClass=\"!px-[3px]\"\n >\n <mat-icon class=\"material-symbols-outlined\">chevron_right</mat-icon>\n </gn-ui-button>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }] }); }
26665
27019
  }
26666
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: DownloadsListComponent, decorators: [{
27020
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: PaginationButtonsComponent, decorators: [{
26667
27021
  type: Component,
26668
- args: [{ selector: 'gn-ui-downloads-list', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"flex flex-wrap justify-between mt-8 mb-6 sm:mt-12 sm:mb-2\"\n *ngIf=\"links && links.length > 0\"\n>\n <p\n class=\"font-title text-[28px] text-title font-medium mr-4 pb-4 text-center sm:text-left\"\n translate\n >\n record.metadata.download\n </p>\n <div\n class=\"flex flex-wrap justify-start sm:justify-end sm:pb-4\"\n data-cy=\"download-format-filters\"\n >\n <gn-ui-button\n class=\"m-1 format-filter\"\n [extraClass]=\"\n '!px-[12px] !py-[8px] !text-[15px]' +\n (isFilterActive(format) ? ' opacity-100' : ' opacity-50')\n \"\n (buttonClick)=\"toggleFilterFormat(format)\"\n [attr.data-format]=\"format\"\n *ngFor=\"let format of visibleFormats\"\n >\n {{ getFilterFormatTitle(format) }}\n </gn-ui-button>\n </div>\n</div>\n<div class=\"mb-2 sm:mb-3\" *ngFor=\"let link of filteredLinks\">\n <gn-ui-download-item\n [link]=\"link\"\n [color]=\"getLinkColor(link)\"\n [format]=\"getLinkFormat(link)\"\n [isFromWfs]=\"isFromWfs(link)\"\n ></gn-ui-download-item>\n</div>\n" }]
26669
- }], ctorParameters: function () { return [{ type: i1$1.TranslateService }]; }, propDecorators: { links: [{
27022
+ args: [{ selector: 'gn-ui-pagination-buttons', template: "<div class=\"relative\">\n <div class=\"flex flex-row gap-[5px] items-center\">\n <gn-ui-button\n type=\"light\"\n [disabled]=\"currentPage === 1\"\n (buttonClick)=\"previousPage()\"\n extraClass=\"!px-[3px]\"\n >\n <mat-icon class=\"material-symbols-outlined\">chevron_left</mat-icon>\n </gn-ui-button>\n <ng-container *ngFor=\"let page of visiblePages\">\n <ng-container *ngIf=\"page === '...'\">\n <span class=\"mx-[5px]\">{{ page }}</span>\n </ng-container>\n <ng-container *ngIf=\"page !== '...'\">\n <gn-ui-button\n [type]=\"page === currentPage ? 'primary' : 'light'\"\n [disabled]=\"page === currentPage\"\n (buttonClick)=\"changePage(page)\"\n >{{ page }}</gn-ui-button\n >\n </ng-container>\n </ng-container>\n <gn-ui-button\n type=\"light\"\n [disabled]=\"currentPage === totalPages\"\n (buttonClick)=\"nextPage()\"\n extraClass=\"!px-[3px]\"\n >\n <mat-icon class=\"material-symbols-outlined\">chevron_right</mat-icon>\n </gn-ui-button>\n </div>\n</div>\n" }]
27023
+ }], propDecorators: { currentPage: [{
27024
+ type: Input
27025
+ }], totalPages: [{
26670
27026
  type: Input
27027
+ }], newCurrentPageEvent: [{
27028
+ type: Output
26671
27029
  }] } });
26672
27030
 
26673
- class ApiCardComponent {
27031
+ class PaginationComponent {
26674
27032
  constructor() {
26675
- this.currentlyActive = false;
26676
- this.openRecordApiForm = new EventEmitter();
27033
+ this.currentPage = 1;
27034
+ this.nPages = 1;
27035
+ this.hideButton = false;
27036
+ this.newCurrentPageEvent = new EventEmitter();
26677
27037
  }
26678
- ngOnInit() {
26679
- this.displayApiFormButton =
26680
- this.link.accessServiceProtocol === 'ogcFeatures' ? true : false;
27038
+ applyPageBounds() {
27039
+ // make sure this works with NaN inputs as well by adding `|| 1`
27040
+ this.nPages = Math.max(1, this.nPages || 1);
27041
+ this.currentPage = Math.max(1, Math.min(this.nPages, this.currentPage || 1));
26681
27042
  }
26682
27043
  ngOnChanges(changes) {
26683
- this.currentlyActive =
26684
- changes.currentLink.currentValue === this.link ? true : false;
26685
- }
26686
- openRecordApiFormPanel() {
26687
- if (this.displayApiFormButton) {
26688
- this.currentlyActive = !this.currentlyActive;
26689
- this.openRecordApiForm.emit(this.currentlyActive ? this.link : undefined);
27044
+ // make sure the inputs are valid
27045
+ if ('currentPage' in changes || 'nPages' in changes) {
27046
+ this.applyPageBounds();
26690
27047
  }
26691
27048
  }
26692
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ApiCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26693
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: ApiCardComponent, selector: "gn-ui-api-card", inputs: { link: "link", currentLink: "currentLink" }, outputs: { openRecordApiForm: "openRecordApiForm" }, usesOnChanges: true, ngImport: i0, template: "<div\n class=\"group flex flex-col justify-between h-40 pt-5 pb-6 px-7 rounded filter overflow-hidden\"\n [ngClass]=\"{ 'cursor-pointer': displayApiFormButton }\"\n (click)=\"openRecordApiFormPanel()\"\n>\n <div\n class=\"font-title font-medium text-21 text-black text-ellipsis overflow-hidden break-words pb-5 h-[4.5rem]\"\n >\n {{ link.name || link.description }}\n </div>\n <div class=\"\">\n <div class=\"flex flex-row justify-between\">\n <span\n class=\"bg-primary-opacity-50 uppercase inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded text-primary-lightest group-hover:bg-primary transition-colors\"\n [ngClass]=\"{\n '!bg-primary': currentlyActive\n }\"\n >{{ link.accessServiceProtocol }}</span\n >\n <gn-ui-copy-text-button\n *ngIf=\"!displayApiFormButton\"\n [text]=\"link.url.toString()\"\n [tooltipText]=\"'tooltip.url.copy' | translate\"\n [displayText]=\"false\"\n ></gn-ui-copy-text-button>\n <button\n *ngIf=\"displayApiFormButton\"\n type=\"button\"\n [ngClass]=\"{\n 'py-2 px-4 rounded-r-md bg-gray-400 hover:bg-gray-600 focus:bg-gray-800 text-white':\n displayText\n }\"\n mat-raised-button\n [matTooltip]=\"\n !currentlyActive\n ? ('record.metadata.api.form.openForm' | translate)\n : ('record.metadata.api.form.closeForm' | translate)\n \"\n matTooltipPosition=\"above\"\n >\n <mat-icon\n class=\"material-symbols-outlined pointer-events-none align-middle card-icon\"\n [ngClass]=\"{\n 'text-secondary opacity-100': currentlyActive\n }\"\n >more_horiz</mat-icon\n >\n </button>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: CopyTextButtonComponent, selector: "gn-ui-copy-text-button", inputs: ["text", "tooltipText", "displayText", "rows"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
27049
+ setPage(newPage) {
27050
+ if (!Number.isInteger(newPage))
27051
+ return;
27052
+ this.currentPage = newPage;
27053
+ this.applyPageBounds();
27054
+ this.newCurrentPageEvent.emit(this.currentPage);
27055
+ }
27056
+ nextPage() {
27057
+ this.setPage(this.currentPage + 1);
27058
+ }
27059
+ previousPage() {
27060
+ this.setPage(this.currentPage - 1);
27061
+ }
27062
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: PaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27063
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: PaginationComponent, selector: "gn-ui-pagination", inputs: { currentPage: "currentPage", nPages: "nPages", hideButton: "hideButton" }, outputs: { newCurrentPageEvent: "newCurrentPageEvent" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"relative\">\n <div class=\"sm:absolute sm:inset-0\" *ngIf=\"!hideButton\">\n <gn-ui-button\n (buttonClick)=\"nextPage()\"\n type=\"secondary\"\n [disabled]=\"currentPage === nPages\"\n extraClass=\"lg:m-auto !p-[22px]\"\n >\n <span class=\"uppercase font-medium tracking-widest\" translate\n >pagination.nextPage</span\n >\n </gn-ui-button>\n </div>\n <div\n class=\"relative pointer-events-none flex flex-row justify-start sm:justify-end\"\n >\n <div class=\"pointer-events-auto flex flex-row items-center py-[13px]\">\n <span class=\"mr-3 capitalize text-sm text-gray-900\" translate\n >pagination.page</span\n >\n <input\n type=\"number\"\n [ngModel]=\"currentPage\"\n [min]=\"1\"\n [max]=\"nPages\"\n (ngModelChange)=\"setPage($event)\"\n class=\"border border-gray-300 rounded w-[54px] h-[34px] pl-[12px] mr-3 text-center\"\n />\n <span class=\"mr-3 text-sm text-gray-900\"\n ><span translate>pagination.pageOf</span> {{ nPages }}</span\n >\n <gn-ui-button\n (buttonClick)=\"previousPage()\"\n id=\"navigate_previous\"\n class=\"mr-2\"\n [disabled]=\"currentPage === 1\"\n [type]=\"'light'\"\n extraClass=\"!px-[3px]\"\n data-cy=\"prev-page\"\n >\n <mat-icon class=\"material-symbols-outlined\">navigate_before</mat-icon>\n </gn-ui-button>\n <gn-ui-button\n (buttonClick)=\"nextPage()\"\n id=\"navigate_next\"\n [disabled]=\"currentPage === nPages\"\n [type]=\"'light'\"\n extraClass=\"!px-[3px]\"\n data-cy=\"next-page\"\n >\n <mat-icon class=\"material-symbols-outlined\">navigate_next</mat-icon>\n </gn-ui-button>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i2$1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26694
27064
  }
26695
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ApiCardComponent, decorators: [{
27065
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: PaginationComponent, decorators: [{
26696
27066
  type: Component,
26697
- args: [{ selector: 'gn-ui-api-card', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"group flex flex-col justify-between h-40 pt-5 pb-6 px-7 rounded filter overflow-hidden\"\n [ngClass]=\"{ 'cursor-pointer': displayApiFormButton }\"\n (click)=\"openRecordApiFormPanel()\"\n>\n <div\n class=\"font-title font-medium text-21 text-black text-ellipsis overflow-hidden break-words pb-5 h-[4.5rem]\"\n >\n {{ link.name || link.description }}\n </div>\n <div class=\"\">\n <div class=\"flex flex-row justify-between\">\n <span\n class=\"bg-primary-opacity-50 uppercase inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded text-primary-lightest group-hover:bg-primary transition-colors\"\n [ngClass]=\"{\n '!bg-primary': currentlyActive\n }\"\n >{{ link.accessServiceProtocol }}</span\n >\n <gn-ui-copy-text-button\n *ngIf=\"!displayApiFormButton\"\n [text]=\"link.url.toString()\"\n [tooltipText]=\"'tooltip.url.copy' | translate\"\n [displayText]=\"false\"\n ></gn-ui-copy-text-button>\n <button\n *ngIf=\"displayApiFormButton\"\n type=\"button\"\n [ngClass]=\"{\n 'py-2 px-4 rounded-r-md bg-gray-400 hover:bg-gray-600 focus:bg-gray-800 text-white':\n displayText\n }\"\n mat-raised-button\n [matTooltip]=\"\n !currentlyActive\n ? ('record.metadata.api.form.openForm' | translate)\n : ('record.metadata.api.form.closeForm' | translate)\n \"\n matTooltipPosition=\"above\"\n >\n <mat-icon\n class=\"material-symbols-outlined pointer-events-none align-middle card-icon\"\n [ngClass]=\"{\n 'text-secondary opacity-100': currentlyActive\n }\"\n >more_horiz</mat-icon\n >\n </button>\n </div>\n </div>\n</div>\n" }]
26698
- }], propDecorators: { link: [{
27067
+ args: [{ selector: 'gn-ui-pagination', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"relative\">\n <div class=\"sm:absolute sm:inset-0\" *ngIf=\"!hideButton\">\n <gn-ui-button\n (buttonClick)=\"nextPage()\"\n type=\"secondary\"\n [disabled]=\"currentPage === nPages\"\n extraClass=\"lg:m-auto !p-[22px]\"\n >\n <span class=\"uppercase font-medium tracking-widest\" translate\n >pagination.nextPage</span\n >\n </gn-ui-button>\n </div>\n <div\n class=\"relative pointer-events-none flex flex-row justify-start sm:justify-end\"\n >\n <div class=\"pointer-events-auto flex flex-row items-center py-[13px]\">\n <span class=\"mr-3 capitalize text-sm text-gray-900\" translate\n >pagination.page</span\n >\n <input\n type=\"number\"\n [ngModel]=\"currentPage\"\n [min]=\"1\"\n [max]=\"nPages\"\n (ngModelChange)=\"setPage($event)\"\n class=\"border border-gray-300 rounded w-[54px] h-[34px] pl-[12px] mr-3 text-center\"\n />\n <span class=\"mr-3 text-sm text-gray-900\"\n ><span translate>pagination.pageOf</span> {{ nPages }}</span\n >\n <gn-ui-button\n (buttonClick)=\"previousPage()\"\n id=\"navigate_previous\"\n class=\"mr-2\"\n [disabled]=\"currentPage === 1\"\n [type]=\"'light'\"\n extraClass=\"!px-[3px]\"\n data-cy=\"prev-page\"\n >\n <mat-icon class=\"material-symbols-outlined\">navigate_before</mat-icon>\n </gn-ui-button>\n <gn-ui-button\n (buttonClick)=\"nextPage()\"\n id=\"navigate_next\"\n [disabled]=\"currentPage === nPages\"\n [type]=\"'light'\"\n extraClass=\"!px-[3px]\"\n data-cy=\"next-page\"\n >\n <mat-icon class=\"material-symbols-outlined\">navigate_next</mat-icon>\n </gn-ui-button>\n </div>\n </div>\n</div>\n" }]
27068
+ }], propDecorators: { currentPage: [{
26699
27069
  type: Input
26700
- }], currentLink: [{
27070
+ }], nPages: [{
26701
27071
  type: Input
26702
- }], openRecordApiForm: [{
27072
+ }], hideButton: [{
27073
+ type: Input
27074
+ }], newCurrentPageEvent: [{
26703
27075
  type: Output
26704
27076
  }] } });
26705
27077
 
26706
- /**
26707
- * This component will make a block that will stay sticky on the top of the page,
26708
- * but will also shrink down to a minimum height when scrolling.
26709
- * The ratio between minimum and nominal height is stored in the shrinkRatio
26710
- * property, and can be used to change e.g. the opacity or size of child elements.
26711
- * This component renders at z-index: 50 by default.
26712
- * The first parent element with an overflow of `scroll` or `overflow` is considered
26713
- * for scroll events.
26714
- */
26715
- class StickyHeaderComponent {
26716
- constructor(changeDetector, hostEl, zone) {
26717
- this.changeDetector = changeDetector;
26718
- this.hostEl = hostEl;
26719
- this.zone = zone;
27078
+ const DEFAULT_PARAMS = {
27079
+ OFFSET: '',
27080
+ LIMIT: '-1',
27081
+ FORMAT: 'json',
27082
+ };
27083
+ class RecordApiFormComponent {
27084
+ constructor() {
27085
+ this.offset$ = new BehaviorSubject('');
27086
+ this.limit$ = new BehaviorSubject('');
27087
+ this.format$ = new BehaviorSubject('');
27088
+ this.formatsList = [
27089
+ { label: 'JSON', value: 'json' },
27090
+ { label: 'CSV', value: 'csv' },
27091
+ ];
27092
+ this.apiQueryUrl$ = combineLatest([this.offset$, this.limit$, this.format$]).pipe(map$2(([offset, limit, format]) => {
27093
+ let outputUrl;
27094
+ if (this.apiBaseUrl) {
27095
+ const url = new URL(this.apiBaseUrl);
27096
+ const params = { offset: offset, limit: limit, f: format };
27097
+ for (const [key, value] of Object.entries(params)) {
27098
+ if (value && value !== '0') {
27099
+ url.searchParams.set(key, value);
27100
+ }
27101
+ else {
27102
+ url.searchParams.delete(key);
27103
+ }
27104
+ }
27105
+ outputUrl = url.toString();
27106
+ }
27107
+ return outputUrl;
27108
+ }));
27109
+ this.noLimitChecked$ = this.limit$.pipe(map$2((limit) => limit === '-1' || limit === ''));
27110
+ this.displayLimit$ = this.limit$.pipe(map$2((limit) => (limit !== '-1' ? limit : '')));
26720
27111
  }
26721
- ngAfterViewInit() {
26722
- this.scrollSub = fromEvent(window, 'scroll', {
26723
- passive: true,
26724
- })
26725
- .pipe(throttleTime(0, animationFrameScheduler, {
26726
- leading: true,
26727
- trailing: true,
26728
- }))
26729
- .subscribe(this.updateSize.bind(this));
27112
+ set apiLink(value) {
27113
+ this.apiBaseUrl = value ? value.url.href : undefined;
27114
+ this.resetUrl();
26730
27115
  }
26731
- ngOnInit() {
26732
- this.placeholderEl = document.createElement('div');
26733
- this.placeholderEl.style.position = 'absolute';
26734
- this.placeholderEl.classList.add('sticky-header-placeholder');
26735
- this.hostEl.nativeElement.insertAdjacentElement('beforebegin', this.placeholderEl);
27116
+ setOffset(value) {
27117
+ this.offset$.next(value);
26736
27118
  }
26737
- ngAfterViewChecked() {
26738
- this.updateSize();
27119
+ setLimit(value) {
27120
+ const newLimit = value === '' ? '-1' : value;
27121
+ this.limit$.next(newLimit);
26739
27122
  }
26740
- ngOnDestroy() {
26741
- this.scrollSub.unsubscribe();
26742
- this.placeholderEl.remove();
27123
+ setFormat(value) {
27124
+ this.format$.next(String(value));
26743
27125
  }
26744
- updateSize() {
26745
- this.zone.runOutsideAngular(() => {
26746
- if (window.scrollY === this.parentScroll)
26747
- return;
26748
- this.parentScroll = window.scrollY;
26749
- const offsetTop = Math.max(0, this.parentScroll - this.placeholderEl.offsetTop);
26750
- const newHeightPx = Math.max(this.minHeightPx, this.fullHeightPx - offsetTop);
26751
- this.innerContainer.nativeElement.style.transform = `translate(0, ${newHeightPx - this.fullHeightPx}px)`;
26752
- this.expandRatio =
26753
- (newHeightPx - this.minHeightPx) /
26754
- (this.fullHeightPx - this.minHeightPx);
26755
- this.changeDetector.detectChanges();
26756
- });
27126
+ resetUrl() {
27127
+ this.offset$.next(DEFAULT_PARAMS.OFFSET);
27128
+ this.limit$.next(DEFAULT_PARAMS.LIMIT);
27129
+ this.format$.next(DEFAULT_PARAMS.FORMAT);
26757
27130
  }
26758
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: StickyHeaderComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef, host: true }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
26759
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: StickyHeaderComponent, selector: "gn-ui-sticky-header", inputs: { minHeightPx: "minHeightPx", fullHeightPx: "fullHeightPx" }, queries: [{ propertyName: "template", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "outerContainer", first: true, predicate: ["outerContainer"], descendants: true }, { propertyName: "innerContainer", first: true, predicate: ["innerContainer"], descendants: true }], ngImport: i0, template: "<div\n #outerContainer\n class=\"sticky pointer-events-none z-50 top-0\"\n [style.height]=\"fullHeightPx + 'px'\"\n>\n <div\n #innerContainer\n class=\"relative pointer-events-auto\"\n [style.height]=\"fullHeightPx + 'px'\"\n >\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: expandRatio }\"\n ></ng-container>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
27131
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: RecordApiFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27132
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: RecordApiFormComponent, selector: "gn-ui-record-api-form", inputs: { apiLink: "apiLink" }, ngImport: i0, template: "<div class=\"flex flex-col gap-8\">\n <div class=\"flex flex-col bg-white p-8 ng-star-inserted shadow-xl gap-8\">\n <div class=\"flex flex-row\">\n <div class=\"text-[16px] text-black truncate font-title w-11/12\" translate>\n record.metadata.api.form.create\n </div>\n <button\n (click)=\"resetUrl()\"\n class=\"bg-primary-opacity-50 inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded capitalize text-primary-lightest hover:bg-primary transition-colors\"\n >\n <p class=\"text-[13px] uppercase\" translate>\n record.metadata.api.form.reset\n </p>\n </button>\n </div>\n <div class=\"flex flex-row flex-wrap justify-between grow gap-5\">\n <div class=\"flex flex-col gap-3\">\n <p class=\"text-[14px]\" translate>record.metadata.api.form.limit</p>\n <div class=\"flex flex-row items-center gap-2\">\n <gn-ui-text-input\n class=\"mr-2 w-20\"\n (valueChange)=\"setLimit($event)\"\n [value]=\"displayLimit$ | async\"\n hint=\"\"\n >\n </gn-ui-text-input>\n <div class=\"flex items-center\">\n <input\n class=\"mr-2 cursor-pointer\"\n type=\"checkbox\"\n [checked]=\"noLimitChecked$ | async\"\n (change)=\"setLimit('-1')\"\n />\n <span class=\"text-sm\" translate\n >record.metadata.api.form.limit.all</span\n >\n </div>\n </div>\n </div>\n <div class=\"flex flex-col gap-3\">\n <p class=\"text-sm\" translate>record.metadata.api.form.offset</p>\n <gn-ui-text-input\n class=\"w-20\"\n [value]=\"offset$ | async\"\n (valueChange)=\"setOffset($event)\"\n hint=\"\"\n >\n </gn-ui-text-input>\n </div>\n <div class=\"flex flex-col gap-3\">\n <p class=\"text-sm\" translate>record.metadata.api.form.type</p>\n <gn-ui-dropdown-selector\n #dropdown\n [title]=\"''\"\n extraBtnClass=\"secondary min-w-full !w-40 !text-black\"\n [showTitle]=\"false\"\n class=\"text-black\"\n [choices]=\"formatsList\"\n (selectValue)=\"setFormat($event)\"\n [selected]=\"format$ | async\"\n ></gn-ui-dropdown-selector>\n </div>\n </div>\n </div>\n <div class=\"flex flex-col gap-3 mb-3\">\n <div class=\"text-sm text-black truncate font-title w-11/12\" translate>\n record.metadata.api.form.customUrl\n </div>\n <div class=\"bg-white rounded-lg\">\n <gn-ui-copy-text-button\n [text]=\"apiQueryUrl$ | async\"\n ></gn-ui-copy-text-button>\n </div>\n </div>\n</div>\n", styles: [":host ::ng-deep input{color:#000;opacity:1}:host ::ng-deep gn-ui-copy-text-button input[type=text]{color:#000;background-color:#fff}:host ::ng-deep gn-ui-copy-text-button button,host ::ng-deep gn-ui-copy-text-button button:hover{background-color:var(--color-secondary)!important}:host ::ng-deep gn-ui-copy-text-button button mat-icon{color:#fff!important;opacity:1!important}:host ::ng-deep gn-ui-copy-text-button button:hover mat-icon{color:#d3d3d3!important}\n"], dependencies: [{ kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: DropdownSelectorComponent, selector: "gn-ui-dropdown-selector", inputs: ["title", "showTitle", "ariaName", "choices", "selected", "maxRows", "extraBtnClass", "minWidth"], outputs: ["selectValue"] }, { kind: "component", type: TextInputComponent, selector: "gn-ui-text-input", inputs: ["value", "extraClass", "hint", "required"], outputs: ["valueChange"] }, { kind: "component", type: CopyTextButtonComponent, selector: "gn-ui-copy-text-button", inputs: ["text", "tooltipText", "displayText", "rows"] }, { kind: "pipe", type: i1$3.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26760
27133
  }
26761
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: StickyHeaderComponent, decorators: [{
27134
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: RecordApiFormComponent, decorators: [{
26762
27135
  type: Component,
26763
- args: [{ selector: 'gn-ui-sticky-header', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n #outerContainer\n class=\"sticky pointer-events-none z-50 top-0\"\n [style.height]=\"fullHeightPx + 'px'\"\n>\n <div\n #innerContainer\n class=\"relative pointer-events-auto\"\n [style.height]=\"fullHeightPx + 'px'\"\n >\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: expandRatio }\"\n ></ng-container>\n </div>\n</div>\n" }]
26764
- }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef, decorators: [{
26765
- type: Host
26766
- }] }, { type: i0.NgZone }]; }, propDecorators: { minHeightPx: [{
27136
+ args: [{ selector: 'gn-ui-record-api-form', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col gap-8\">\n <div class=\"flex flex-col bg-white p-8 ng-star-inserted shadow-xl gap-8\">\n <div class=\"flex flex-row\">\n <div class=\"text-[16px] text-black truncate font-title w-11/12\" translate>\n record.metadata.api.form.create\n </div>\n <button\n (click)=\"resetUrl()\"\n class=\"bg-primary-opacity-50 inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded capitalize text-primary-lightest hover:bg-primary transition-colors\"\n >\n <p class=\"text-[13px] uppercase\" translate>\n record.metadata.api.form.reset\n </p>\n </button>\n </div>\n <div class=\"flex flex-row flex-wrap justify-between grow gap-5\">\n <div class=\"flex flex-col gap-3\">\n <p class=\"text-[14px]\" translate>record.metadata.api.form.limit</p>\n <div class=\"flex flex-row items-center gap-2\">\n <gn-ui-text-input\n class=\"mr-2 w-20\"\n (valueChange)=\"setLimit($event)\"\n [value]=\"displayLimit$ | async\"\n hint=\"\"\n >\n </gn-ui-text-input>\n <div class=\"flex items-center\">\n <input\n class=\"mr-2 cursor-pointer\"\n type=\"checkbox\"\n [checked]=\"noLimitChecked$ | async\"\n (change)=\"setLimit('-1')\"\n />\n <span class=\"text-sm\" translate\n >record.metadata.api.form.limit.all</span\n >\n </div>\n </div>\n </div>\n <div class=\"flex flex-col gap-3\">\n <p class=\"text-sm\" translate>record.metadata.api.form.offset</p>\n <gn-ui-text-input\n class=\"w-20\"\n [value]=\"offset$ | async\"\n (valueChange)=\"setOffset($event)\"\n hint=\"\"\n >\n </gn-ui-text-input>\n </div>\n <div class=\"flex flex-col gap-3\">\n <p class=\"text-sm\" translate>record.metadata.api.form.type</p>\n <gn-ui-dropdown-selector\n #dropdown\n [title]=\"''\"\n extraBtnClass=\"secondary min-w-full !w-40 !text-black\"\n [showTitle]=\"false\"\n class=\"text-black\"\n [choices]=\"formatsList\"\n (selectValue)=\"setFormat($event)\"\n [selected]=\"format$ | async\"\n ></gn-ui-dropdown-selector>\n </div>\n </div>\n </div>\n <div class=\"flex flex-col gap-3 mb-3\">\n <div class=\"text-sm text-black truncate font-title w-11/12\" translate>\n record.metadata.api.form.customUrl\n </div>\n <div class=\"bg-white rounded-lg\">\n <gn-ui-copy-text-button\n [text]=\"apiQueryUrl$ | async\"\n ></gn-ui-copy-text-button>\n </div>\n </div>\n</div>\n", styles: [":host ::ng-deep input{color:#000;opacity:1}:host ::ng-deep gn-ui-copy-text-button input[type=text]{color:#000;background-color:#fff}:host ::ng-deep gn-ui-copy-text-button button,host ::ng-deep gn-ui-copy-text-button button:hover{background-color:var(--color-secondary)!important}:host ::ng-deep gn-ui-copy-text-button button mat-icon{color:#fff!important;opacity:1!important}:host ::ng-deep gn-ui-copy-text-button button:hover mat-icon{color:#d3d3d3!important}\n"] }]
27137
+ }], propDecorators: { apiLink: [{
26767
27138
  type: Input
26768
- }], fullHeightPx: [{
27139
+ }] } });
27140
+
27141
+ class RelatedRecordCardComponent {
27142
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: RelatedRecordCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27143
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: RelatedRecordCardComponent, selector: "gn-ui-related-record-card", inputs: { record: "record" }, ngImport: i0, template: "<a\n class=\"w-72 h-96 overflow-hidden rounded-lg bg-white cursor-pointer block hover:-translate-y-2 duration-[180ms]\"\n [routerLink]=\"['/dataset', record.uniqueIdentifier]\"\n target=\"_blank\"\n>\n <div class=\"h-52 bg-gray-100\">\n <gn-ui-thumbnail\n class=\"h-52 w-full object-cover\"\n [thumbnailUrl]=\"record.overviews?.[0]?.url.toString()\"\n ></gn-ui-thumbnail>\n </div>\n <div class=\"flex flex-col justify-between h-44 px-5 pt-4 pb-6\">\n <h4\n class=\"max-h-24 font-title text-21 text-black text-ellipsis overflow-hidden\"\n >\n {{ record.title }}\n </h4>\n <div>\n <button\n mat-raised-button\n [matTooltip]=\"'tooltip.url.open' | translate\"\n matTooltipPosition=\"above\"\n >\n <mat-icon class=\"material-symbols-outlined align-middle text-secondary\"\n >open_in_new</mat-icon\n >\n </button>\n </div>\n </div>\n</a>\n", styles: [""], dependencies: [{ kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "directive", type: i1$7.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: ThumbnailComponent, selector: "gn-ui-thumbnail", inputs: ["thumbnailUrl", "fit"], outputs: ["placeholderShown"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
27144
+ }
27145
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: RelatedRecordCardComponent, decorators: [{
27146
+ type: Component,
27147
+ args: [{ selector: 'gn-ui-related-record-card', changeDetection: ChangeDetectionStrategy.OnPush, template: "<a\n class=\"w-72 h-96 overflow-hidden rounded-lg bg-white cursor-pointer block hover:-translate-y-2 duration-[180ms]\"\n [routerLink]=\"['/dataset', record.uniqueIdentifier]\"\n target=\"_blank\"\n>\n <div class=\"h-52 bg-gray-100\">\n <gn-ui-thumbnail\n class=\"h-52 w-full object-cover\"\n [thumbnailUrl]=\"record.overviews?.[0]?.url.toString()\"\n ></gn-ui-thumbnail>\n </div>\n <div class=\"flex flex-col justify-between h-44 px-5 pt-4 pb-6\">\n <h4\n class=\"max-h-24 font-title text-21 text-black text-ellipsis overflow-hidden\"\n >\n {{ record.title }}\n </h4>\n <div>\n <button\n mat-raised-button\n [matTooltip]=\"'tooltip.url.open' | translate\"\n matTooltipPosition=\"above\"\n >\n <mat-icon class=\"material-symbols-outlined align-middle text-secondary\"\n >open_in_new</mat-icon\n >\n </button>\n </div>\n </div>\n</a>\n" }]
27148
+ }], propDecorators: { record: [{
27149
+ type: Input
27150
+ }] } });
27151
+
27152
+ var ErrorType;
27153
+ (function (ErrorType) {
27154
+ ErrorType[ErrorType["COULD_NOT_REACH_API"] = 0] = "COULD_NOT_REACH_API";
27155
+ ErrorType[ErrorType["RECEIVED_ERROR"] = 1] = "RECEIVED_ERROR";
27156
+ ErrorType[ErrorType["RECORD_NOT_FOUND"] = 2] = "RECORD_NOT_FOUND";
27157
+ })(ErrorType || (ErrorType = {}));
27158
+ class SearchResultsErrorComponent {
27159
+ constructor() {
27160
+ this.types = ErrorType;
27161
+ }
27162
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SearchResultsErrorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27163
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: SearchResultsErrorComponent, selector: "gn-ui-search-results-error", inputs: { type: "type", error: "error", recordId: "recordId" }, ngImport: i0, template: "<div\n class=\"p-[1.7em] bg-red-50 text-red-800 text-[1.5em] text-center rounded-lg\"\n>\n <div *ngIf=\"type === types.COULD_NOT_REACH_API\">\n <div class=\"relative opacity-40\">\n <mat-icon class=\"material-symbols-outlined face\">face</mat-icon>\n <mat-icon class=\"material-symbols-outlined question-mark1\"\n >question_mark</mat-icon\n >\n <mat-icon class=\"material-symbols-outlined question-mark2\"\n >question_mark</mat-icon\n >\n </div>\n <div translate>search.error.couldNotReachApi</div>\n </div>\n <div *ngIf=\"type === types.RECEIVED_ERROR\">\n <div class=\"relative opacity-40\">\n <mat-icon class=\"material-symbols-outlined face\">mood_bad</mat-icon>\n </div>\n <div translate>search.error.receivedError</div>\n <div *ngIf=\"error\">{{ error }}</div>\n </div>\n <div *ngIf=\"type === types.RECORD_NOT_FOUND\">\n <div class=\"relative opacity-40\">\n <mat-icon class=\"material-symbols-outlined computer\">computer</mat-icon>\n <mat-icon class=\"material-symbols-outlined computer-question-mark\"\n >question_mark</mat-icon\n >\n </div>\n <div translate [translateParams]=\"{ id: recordId }\">\n search.error.recordNotFound\n </div>\n <div *ngIf=\"error\">{{ error }}</div>\n </div>\n</div>\n", styles: ["mat-icon{width:auto;height:auto}mat-icon.face{font-size:3em}mat-icon.question-mark1{position:absolute;bottom:1.1em;left:calc(50% + .7em);font-size:1.7em}mat-icon.question-mark2{position:absolute;bottom:1.6em;left:calc(50% + 1.6em);font-size:1.4em}.computer{font-size:3em}.computer-question-mark{position:absolute;top:.6em;left:calc(50% - .5em);font-size:1.2em}\n"], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
27164
+ }
27165
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SearchResultsErrorComponent, decorators: [{
27166
+ type: Component,
27167
+ args: [{ selector: 'gn-ui-search-results-error', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"p-[1.7em] bg-red-50 text-red-800 text-[1.5em] text-center rounded-lg\"\n>\n <div *ngIf=\"type === types.COULD_NOT_REACH_API\">\n <div class=\"relative opacity-40\">\n <mat-icon class=\"material-symbols-outlined face\">face</mat-icon>\n <mat-icon class=\"material-symbols-outlined question-mark1\"\n >question_mark</mat-icon\n >\n <mat-icon class=\"material-symbols-outlined question-mark2\"\n >question_mark</mat-icon\n >\n </div>\n <div translate>search.error.couldNotReachApi</div>\n </div>\n <div *ngIf=\"type === types.RECEIVED_ERROR\">\n <div class=\"relative opacity-40\">\n <mat-icon class=\"material-symbols-outlined face\">mood_bad</mat-icon>\n </div>\n <div translate>search.error.receivedError</div>\n <div *ngIf=\"error\">{{ error }}</div>\n </div>\n <div *ngIf=\"type === types.RECORD_NOT_FOUND\">\n <div class=\"relative opacity-40\">\n <mat-icon class=\"material-symbols-outlined computer\">computer</mat-icon>\n <mat-icon class=\"material-symbols-outlined computer-question-mark\"\n >question_mark</mat-icon\n >\n </div>\n <div translate [translateParams]=\"{ id: recordId }\">\n search.error.recordNotFound\n </div>\n <div *ngIf=\"error\">{{ error }}</div>\n </div>\n</div>\n", styles: ["mat-icon{width:auto;height:auto}mat-icon.face{font-size:3em}mat-icon.question-mark1{position:absolute;bottom:1.1em;left:calc(50% + .7em);font-size:1.7em}mat-icon.question-mark2{position:absolute;bottom:1.6em;left:calc(50% + 1.6em);font-size:1.4em}.computer{font-size:3em}.computer-question-mark{position:absolute;top:.6em;left:calc(50% - .5em);font-size:1.2em}\n"] }]
27168
+ }], propDecorators: { type: [{
27169
+ type: Input
27170
+ }], error: [{
27171
+ type: Input
27172
+ }], recordId: [{
26769
27173
  type: Input
26770
- }], template: [{
26771
- type: ContentChild,
26772
- args: [TemplateRef]
26773
- }], outerContainer: [{
26774
- type: ViewChild,
26775
- args: ['outerContainer']
26776
- }], innerContainer: [{
26777
- type: ViewChild,
26778
- args: ['innerContainer']
26779
27174
  }] } });
26780
27175
 
26781
27176
  class AnchorLinkDirective {
@@ -26880,6 +27275,157 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
26880
27275
  args: ['carouselOverflowContainer']
26881
27276
  }] } });
26882
27277
 
27278
+ class FormFieldWrapperComponent {
27279
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27280
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: FormFieldWrapperComponent, isStandalone: true, selector: "gn-ui-form-field-wrapper", inputs: { label: "label", hint: "hint" }, ngImport: i0, template: "<div class=\"h-full flex flex-col\">\n <div class=\"flex-none w-full flex flex-row items-center\">\n <span class=\"flex-none font-bold\">{{ label }}</span>\n <div class=\"flex-1 flex justify-end items-center\">\n <ng-content select=\"[form-field-interaction]\"></ng-content>\n <span\n class=\"material-symbols-outlined m-2 gn-ui-icon-small\"\n [matTooltip]=\"hint\"\n matTooltipPosition=\"above\"\n >\n help\n </span>\n </div>\n </div>\n <div class=\"flex-1\">\n <ng-content></ng-content>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
27281
+ }
27282
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldWrapperComponent, decorators: [{
27283
+ type: Component,
27284
+ args: [{ selector: 'gn-ui-form-field-wrapper', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [MatIconModule, MatTooltipModule], template: "<div class=\"h-full flex flex-col\">\n <div class=\"flex-none w-full flex flex-row items-center\">\n <span class=\"flex-none font-bold\">{{ label }}</span>\n <div class=\"flex-1 flex justify-end items-center\">\n <ng-content select=\"[form-field-interaction]\"></ng-content>\n <span\n class=\"material-symbols-outlined m-2 gn-ui-icon-small\"\n [matTooltip]=\"hint\"\n matTooltipPosition=\"above\"\n >\n help\n </span>\n </div>\n </div>\n <div class=\"flex-1\">\n <ng-content></ng-content>\n </div>\n</div>\n" }]
27285
+ }], propDecorators: { label: [{
27286
+ type: Input
27287
+ }], hint: [{
27288
+ type: Input
27289
+ }] } });
27290
+
27291
+ class InteractiveTableColumnComponent {
27292
+ constructor() {
27293
+ this.grow = false;
27294
+ this.sortable = false;
27295
+ this.activeSort = null;
27296
+ this.sortChange = new EventEmitter();
27297
+ }
27298
+ handleSortChange() {
27299
+ this.activeSort = this.activeSort === 'asc' ? 'desc' : 'asc';
27300
+ this.sortChange.emit(this.activeSort);
27301
+ }
27302
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: InteractiveTableColumnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27303
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: InteractiveTableColumnComponent, isStandalone: true, selector: "gn-ui-interactive-table-column", inputs: { grow: "grow", sortable: "sortable", activeSort: "activeSort" }, outputs: { sortChange: "sortChange" }, queries: [{ propertyName: "header", first: true, predicate: ["header"], descendants: true }, { propertyName: "cell", first: true, predicate: ["cell"], descendants: true }], ngImport: i0, template: "<span>empty</span>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
27304
+ }
27305
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: InteractiveTableColumnComponent, decorators: [{
27306
+ type: Component,
27307
+ args: [{ selector: 'gn-ui-interactive-table-column', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<span>empty</span>\n" }]
27308
+ }], propDecorators: { header: [{
27309
+ type: ContentChild,
27310
+ args: ['header']
27311
+ }], cell: [{
27312
+ type: ContentChild,
27313
+ args: ['cell']
27314
+ }], grow: [{
27315
+ type: Input
27316
+ }], sortable: [{
27317
+ type: Input
27318
+ }], activeSort: [{
27319
+ type: Input
27320
+ }], sortChange: [{
27321
+ type: Output
27322
+ }] } });
27323
+
27324
+ class InteractiveTableComponent {
27325
+ constructor() {
27326
+ this.items = [];
27327
+ this.itemClick = new EventEmitter();
27328
+ }
27329
+ get gridStyle() {
27330
+ return {
27331
+ 'grid-template-columns': this.columns
27332
+ .map((column) => column.grow ? `minmax(0px,1fr)` : `minmax(0px,max-content)`)
27333
+ .join(' '),
27334
+ };
27335
+ }
27336
+ handleRowClick(item) {
27337
+ this.itemClick.emit(item);
27338
+ }
27339
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: InteractiveTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27340
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: InteractiveTableComponent, isStandalone: true, selector: "gn-ui-interactive-table", inputs: { items: "items" }, outputs: { itemClick: "itemClick" }, queries: [{ propertyName: "columns", predicate: InteractiveTableColumnComponent }], ngImport: i0, template: "<div class=\"grid w-full\" [ngStyle]=\"gridStyle\">\n <div class=\"contents\">\n <ng-container *ngFor=\"let column of columns\">\n <button\n *ngIf=\"column.sortable\"\n type=\"button\"\n class=\"table-header-cell\"\n (click)=\"column.sortable && column.handleSortChange()\"\n >\n <ng-container *ngTemplateOutlet=\"column.header\"></ng-container>\n <div class=\"sort-button flex flex-col\" *ngIf=\"column.sortable\">\n <mat-icon\n class=\"material-symbols-outlined text-gray-600\"\n [ngClass]=\"{ 'text-main': column.activeSort === 'asc' }\"\n >expand_less</mat-icon\n >\n <mat-icon\n class=\"material-symbols-outlined text-gray-600\"\n [ngClass]=\"{ 'text-main': column.activeSort === 'desc' }\"\n >expand_more</mat-icon\n >\n </div>\n </button>\n <div *ngIf=\"!column.sortable\" class=\"table-header-cell\">\n <ng-container *ngTemplateOutlet=\"column.header\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div\n class=\"contents text-gray-900 cursor-pointer group\"\n *ngFor=\"let item of items\"\n (click)=\"handleRowClick(item)\"\n >\n <div\n class=\"relative h-0\"\n [ngStyle]=\"{ 'grid-column': 'span ' + this.columns.length }\"\n >\n <!-- this element is only used in keyboard navigation -->\n <button\n type=\"button\"\n class=\"absolute inset-x-0 h-[50px] bg-transparent pointer-events-none\"\n ></button>\n </div>\n <ng-container *ngFor=\"let column of columns\">\n <div\n class=\"table-row-cell px-4 py-3 flex items-center bg-white transition-colors duration-75 truncate group-hover:text-main group-hover:bg-gray-50 border-b border-gray-200\"\n >\n <ng-container\n *ngTemplateOutlet=\"column.cell; context: { $implicit: item }\"\n ></ng-container>\n </div>\n </ng-container>\n </div>\n</div>\n", styles: [".sort-button mat-icon{padding:0;margin:0;height:8px;line-height:8px;font-size:18px}.table-header-cell{@apply text-gray-700 px-4 py-5 flex items-center truncate bg-white;}button.table-header-cell{@apply transition-colors duration-75 hover:text-main hover:bg-gray-50 focus:text-main focus:bg-gray-50;}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
27341
+ }
27342
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: InteractiveTableComponent, decorators: [{
27343
+ type: Component,
27344
+ args: [{ selector: 'gn-ui-interactive-table', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, InteractiveTableColumnComponent, MatIconModule], template: "<div class=\"grid w-full\" [ngStyle]=\"gridStyle\">\n <div class=\"contents\">\n <ng-container *ngFor=\"let column of columns\">\n <button\n *ngIf=\"column.sortable\"\n type=\"button\"\n class=\"table-header-cell\"\n (click)=\"column.sortable && column.handleSortChange()\"\n >\n <ng-container *ngTemplateOutlet=\"column.header\"></ng-container>\n <div class=\"sort-button flex flex-col\" *ngIf=\"column.sortable\">\n <mat-icon\n class=\"material-symbols-outlined text-gray-600\"\n [ngClass]=\"{ 'text-main': column.activeSort === 'asc' }\"\n >expand_less</mat-icon\n >\n <mat-icon\n class=\"material-symbols-outlined text-gray-600\"\n [ngClass]=\"{ 'text-main': column.activeSort === 'desc' }\"\n >expand_more</mat-icon\n >\n </div>\n </button>\n <div *ngIf=\"!column.sortable\" class=\"table-header-cell\">\n <ng-container *ngTemplateOutlet=\"column.header\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div\n class=\"contents text-gray-900 cursor-pointer group\"\n *ngFor=\"let item of items\"\n (click)=\"handleRowClick(item)\"\n >\n <div\n class=\"relative h-0\"\n [ngStyle]=\"{ 'grid-column': 'span ' + this.columns.length }\"\n >\n <!-- this element is only used in keyboard navigation -->\n <button\n type=\"button\"\n class=\"absolute inset-x-0 h-[50px] bg-transparent pointer-events-none\"\n ></button>\n </div>\n <ng-container *ngFor=\"let column of columns\">\n <div\n class=\"table-row-cell px-4 py-3 flex items-center bg-white transition-colors duration-75 truncate group-hover:text-main group-hover:bg-gray-50 border-b border-gray-200\"\n >\n <ng-container\n *ngTemplateOutlet=\"column.cell; context: { $implicit: item }\"\n ></ng-container>\n </div>\n </ng-container>\n </div>\n</div>\n", styles: [".sort-button mat-icon{padding:0;margin:0;height:8px;line-height:8px;font-size:18px}.table-header-cell{@apply text-gray-700 px-4 py-5 flex items-center truncate bg-white;}button.table-header-cell{@apply transition-colors duration-75 hover:text-main hover:bg-gray-50 focus:text-main focus:bg-gray-50;}\n"] }]
27345
+ }], propDecorators: { columns: [{
27346
+ type: ContentChildren,
27347
+ args: [InteractiveTableColumnComponent]
27348
+ }], items: [{
27349
+ type: Input
27350
+ }], itemClick: [{
27351
+ type: Output
27352
+ }] } });
27353
+
27354
+ /**
27355
+ * This component will make a block that will stay sticky on the top of the page,
27356
+ * but will also shrink down to a minimum height when scrolling.
27357
+ * The ratio between minimum and nominal height is stored in the shrinkRatio
27358
+ * property, and can be used to change e.g. the opacity or size of child elements.
27359
+ * This component renders at z-index: 50 by default.
27360
+ * The first parent element with an overflow of `scroll` or `overflow` is considered
27361
+ * for scroll events.
27362
+ */
27363
+ class StickyHeaderComponent {
27364
+ constructor(changeDetector, hostEl, zone) {
27365
+ this.changeDetector = changeDetector;
27366
+ this.hostEl = hostEl;
27367
+ this.zone = zone;
27368
+ }
27369
+ ngAfterViewInit() {
27370
+ this.scrollSub = fromEvent(window, 'scroll', {
27371
+ passive: true,
27372
+ })
27373
+ .pipe(throttleTime(0, animationFrameScheduler, {
27374
+ leading: true,
27375
+ trailing: true,
27376
+ }))
27377
+ .subscribe(this.updateSize.bind(this));
27378
+ }
27379
+ ngOnInit() {
27380
+ this.placeholderEl = document.createElement('div');
27381
+ this.placeholderEl.style.position = 'absolute';
27382
+ this.placeholderEl.classList.add('sticky-header-placeholder');
27383
+ this.hostEl.nativeElement.insertAdjacentElement('beforebegin', this.placeholderEl);
27384
+ }
27385
+ ngAfterViewChecked() {
27386
+ this.updateSize();
27387
+ }
27388
+ ngOnDestroy() {
27389
+ this.scrollSub.unsubscribe();
27390
+ this.placeholderEl.remove();
27391
+ }
27392
+ updateSize() {
27393
+ this.zone.runOutsideAngular(() => {
27394
+ if (window.scrollY === this.parentScroll)
27395
+ return;
27396
+ this.parentScroll = window.scrollY;
27397
+ const offsetTop = Math.max(0, this.parentScroll - this.placeholderEl.offsetTop);
27398
+ const newHeightPx = Math.max(this.minHeightPx, this.fullHeightPx - offsetTop);
27399
+ this.innerContainer.nativeElement.style.transform = `translate(0, ${newHeightPx - this.fullHeightPx}px)`;
27400
+ this.expandRatio =
27401
+ (newHeightPx - this.minHeightPx) /
27402
+ (this.fullHeightPx - this.minHeightPx);
27403
+ this.changeDetector.detectChanges();
27404
+ });
27405
+ }
27406
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: StickyHeaderComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef, host: true }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
27407
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: StickyHeaderComponent, selector: "gn-ui-sticky-header", inputs: { minHeightPx: "minHeightPx", fullHeightPx: "fullHeightPx" }, queries: [{ propertyName: "template", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "outerContainer", first: true, predicate: ["outerContainer"], descendants: true }, { propertyName: "innerContainer", first: true, predicate: ["innerContainer"], descendants: true }], ngImport: i0, template: "<div\n #outerContainer\n class=\"sticky pointer-events-none z-50 top-0\"\n [style.height]=\"fullHeightPx + 'px'\"\n>\n <div\n #innerContainer\n class=\"relative pointer-events-auto\"\n [style.height]=\"fullHeightPx + 'px'\"\n >\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: expandRatio }\"\n ></ng-container>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
27408
+ }
27409
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: StickyHeaderComponent, decorators: [{
27410
+ type: Component,
27411
+ args: [{ selector: 'gn-ui-sticky-header', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n #outerContainer\n class=\"sticky pointer-events-none z-50 top-0\"\n [style.height]=\"fullHeightPx + 'px'\"\n>\n <div\n #innerContainer\n class=\"relative pointer-events-auto\"\n [style.height]=\"fullHeightPx + 'px'\"\n >\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: expandRatio }\"\n ></ng-container>\n </div>\n</div>\n" }]
27412
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef, decorators: [{
27413
+ type: Host
27414
+ }] }, { type: i0.NgZone }]; }, propDecorators: { minHeightPx: [{
27415
+ type: Input
27416
+ }], fullHeightPx: [{
27417
+ type: Input
27418
+ }], template: [{
27419
+ type: ContentChild,
27420
+ args: [TemplateRef]
27421
+ }], outerContainer: [{
27422
+ type: ViewChild,
27423
+ args: ['outerContainer']
27424
+ }], innerContainer: [{
27425
+ type: ViewChild,
27426
+ args: ['innerContainer']
27427
+ }] } });
27428
+
26883
27429
  class UiLayoutModule {
26884
27430
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UiLayoutModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
26885
27431
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.1.7", ngImport: i0, type: UiLayoutModule, declarations: [ExpandablePanelComponent,
@@ -26914,225 +27460,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
26914
27460
  }]
26915
27461
  }] });
26916
27462
 
26917
- class InteractiveTableColumnComponent {
26918
- constructor() {
26919
- this.grow = false;
26920
- this.sortable = false;
26921
- this.activeSort = null;
26922
- this.sortChange = new EventEmitter();
26923
- }
26924
- handleSortChange() {
26925
- this.activeSort = this.activeSort === 'asc' ? 'desc' : 'asc';
26926
- this.sortChange.emit(this.activeSort);
26927
- }
26928
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: InteractiveTableColumnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26929
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: InteractiveTableColumnComponent, isStandalone: true, selector: "gn-ui-interactive-table-column", inputs: { grow: "grow", sortable: "sortable", activeSort: "activeSort" }, outputs: { sortChange: "sortChange" }, queries: [{ propertyName: "header", first: true, predicate: ["header"], descendants: true }, { propertyName: "cell", first: true, predicate: ["cell"], descendants: true }], ngImport: i0, template: "<span>empty</span>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26930
- }
26931
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: InteractiveTableColumnComponent, decorators: [{
26932
- type: Component,
26933
- args: [{ selector: 'gn-ui-interactive-table-column', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<span>empty</span>\n" }]
26934
- }], propDecorators: { header: [{
26935
- type: ContentChild,
26936
- args: ['header']
26937
- }], cell: [{
26938
- type: ContentChild,
26939
- args: ['cell']
26940
- }], grow: [{
26941
- type: Input
26942
- }], sortable: [{
26943
- type: Input
26944
- }], activeSort: [{
26945
- type: Input
26946
- }], sortChange: [{
26947
- type: Output
26948
- }] } });
26949
-
26950
- class InteractiveTableComponent {
26951
- constructor() {
26952
- this.items = [];
26953
- this.itemClick = new EventEmitter();
26954
- }
26955
- get gridStyle() {
26956
- return {
26957
- 'grid-template-columns': this.columns
26958
- .map((column) => column.grow ? `minmax(0px,1fr)` : `minmax(0px,max-content)`)
26959
- .join(' '),
26960
- };
26961
- }
26962
- handleRowClick(item) {
26963
- this.itemClick.emit(item);
26964
- }
26965
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: InteractiveTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26966
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: InteractiveTableComponent, isStandalone: true, selector: "gn-ui-interactive-table", inputs: { items: "items" }, outputs: { itemClick: "itemClick" }, queries: [{ propertyName: "columns", predicate: InteractiveTableColumnComponent }], ngImport: i0, template: "<div class=\"grid w-full\" [ngStyle]=\"gridStyle\">\n <div class=\"contents\">\n <ng-container *ngFor=\"let column of columns\">\n <button\n *ngIf=\"column.sortable\"\n type=\"button\"\n class=\"table-header-cell\"\n (click)=\"column.sortable && column.handleSortChange()\"\n >\n <ng-container *ngTemplateOutlet=\"column.header\"></ng-container>\n <div class=\"sort-button flex flex-col\" *ngIf=\"column.sortable\">\n <mat-icon\n class=\"material-symbols-outlined text-gray-600\"\n [ngClass]=\"{ 'text-main': column.activeSort === 'asc' }\"\n >expand_less</mat-icon\n >\n <mat-icon\n class=\"material-symbols-outlined text-gray-600\"\n [ngClass]=\"{ 'text-main': column.activeSort === 'desc' }\"\n >expand_more</mat-icon\n >\n </div>\n </button>\n <div *ngIf=\"!column.sortable\" class=\"table-header-cell\">\n <ng-container *ngTemplateOutlet=\"column.header\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div\n class=\"contents text-gray-900 cursor-pointer group\"\n *ngFor=\"let item of items\"\n (click)=\"handleRowClick(item)\"\n >\n <div\n class=\"relative h-0\"\n [ngStyle]=\"{ 'grid-column': 'span ' + this.columns.length }\"\n >\n <!-- this element is only used in keyboard navigation -->\n <button\n type=\"button\"\n class=\"absolute inset-x-0 h-[50px] bg-transparent pointer-events-none\"\n ></button>\n </div>\n <ng-container *ngFor=\"let column of columns\">\n <div\n class=\"table-row-cell px-4 py-3 flex items-center bg-white transition-colors duration-75 truncate group-hover:text-main group-hover:bg-gray-50 border-b border-gray-200\"\n >\n <ng-container\n *ngTemplateOutlet=\"column.cell; context: { $implicit: item }\"\n ></ng-container>\n </div>\n </ng-container>\n </div>\n</div>\n", styles: [".sort-button mat-icon{padding:0;margin:0;height:8px;line-height:8px;font-size:18px}.table-header-cell{@apply text-gray-700 px-4 py-5 flex items-center truncate bg-white;}button.table-header-cell{@apply transition-colors duration-75 hover:text-main hover:bg-gray-50 focus:text-main focus:bg-gray-50;}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26967
- }
26968
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: InteractiveTableComponent, decorators: [{
26969
- type: Component,
26970
- args: [{ selector: 'gn-ui-interactive-table', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, InteractiveTableColumnComponent, MatIconModule], template: "<div class=\"grid w-full\" [ngStyle]=\"gridStyle\">\n <div class=\"contents\">\n <ng-container *ngFor=\"let column of columns\">\n <button\n *ngIf=\"column.sortable\"\n type=\"button\"\n class=\"table-header-cell\"\n (click)=\"column.sortable && column.handleSortChange()\"\n >\n <ng-container *ngTemplateOutlet=\"column.header\"></ng-container>\n <div class=\"sort-button flex flex-col\" *ngIf=\"column.sortable\">\n <mat-icon\n class=\"material-symbols-outlined text-gray-600\"\n [ngClass]=\"{ 'text-main': column.activeSort === 'asc' }\"\n >expand_less</mat-icon\n >\n <mat-icon\n class=\"material-symbols-outlined text-gray-600\"\n [ngClass]=\"{ 'text-main': column.activeSort === 'desc' }\"\n >expand_more</mat-icon\n >\n </div>\n </button>\n <div *ngIf=\"!column.sortable\" class=\"table-header-cell\">\n <ng-container *ngTemplateOutlet=\"column.header\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div\n class=\"contents text-gray-900 cursor-pointer group\"\n *ngFor=\"let item of items\"\n (click)=\"handleRowClick(item)\"\n >\n <div\n class=\"relative h-0\"\n [ngStyle]=\"{ 'grid-column': 'span ' + this.columns.length }\"\n >\n <!-- this element is only used in keyboard navigation -->\n <button\n type=\"button\"\n class=\"absolute inset-x-0 h-[50px] bg-transparent pointer-events-none\"\n ></button>\n </div>\n <ng-container *ngFor=\"let column of columns\">\n <div\n class=\"table-row-cell px-4 py-3 flex items-center bg-white transition-colors duration-75 truncate group-hover:text-main group-hover:bg-gray-50 border-b border-gray-200\"\n >\n <ng-container\n *ngTemplateOutlet=\"column.cell; context: { $implicit: item }\"\n ></ng-container>\n </div>\n </ng-container>\n </div>\n</div>\n", styles: [".sort-button mat-icon{padding:0;margin:0;height:8px;line-height:8px;font-size:18px}.table-header-cell{@apply text-gray-700 px-4 py-5 flex items-center truncate bg-white;}button.table-header-cell{@apply transition-colors duration-75 hover:text-main hover:bg-gray-50 focus:text-main focus:bg-gray-50;}\n"] }]
26971
- }], propDecorators: { columns: [{
26972
- type: ContentChildren,
26973
- args: [InteractiveTableColumnComponent]
26974
- }], items: [{
26975
- type: Input
26976
- }], itemClick: [{
26977
- type: Output
26978
- }] } });
26979
-
26980
- class LinkCardComponent {
26981
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: LinkCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26982
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: LinkCardComponent, selector: "gn-ui-link-card", inputs: { link: "link" }, ngImport: i0, template: "<a\n [href]=\"link.url\"\n target=\"_blank\"\n class=\"flex flex-col justify-between group h-40 grow py-5 px-5 bg-white rounded border-gray-300 filter card-shadow overflow-hidden lg:w-80\"\n>\n <div class=\"max-h-24 overflow-hidden text-ellipsis\">\n <p\n class=\"font-title font-medium text-21 text-black break-words mb-1 line-clamp-2\"\n >\n {{ link.name }}\n </p>\n <p class=\"font-medium text-sm break-words\">\n {{ link.description }}\n </p>\n <p\n *ngIf=\"!link.name && !link.description\"\n class=\"font-medium text-sm break-words truncate\"\n >\n {{ link.url }}\n </p>\n </div>\n <div>\n <mat-icon class=\"material-symbols-outlined card-icon\">open_in_new</mat-icon>\n </div>\n</a>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26983
- }
26984
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: LinkCardComponent, decorators: [{
26985
- type: Component,
26986
- args: [{ selector: 'gn-ui-link-card', changeDetection: ChangeDetectionStrategy.OnPush, template: "<a\n [href]=\"link.url\"\n target=\"_blank\"\n class=\"flex flex-col justify-between group h-40 grow py-5 px-5 bg-white rounded border-gray-300 filter card-shadow overflow-hidden lg:w-80\"\n>\n <div class=\"max-h-24 overflow-hidden text-ellipsis\">\n <p\n class=\"font-title font-medium text-21 text-black break-words mb-1 line-clamp-2\"\n >\n {{ link.name }}\n </p>\n <p class=\"font-medium text-sm break-words\">\n {{ link.description }}\n </p>\n <p\n *ngIf=\"!link.name && !link.description\"\n class=\"font-medium text-sm break-words truncate\"\n >\n {{ link.url }}\n </p>\n </div>\n <div>\n <mat-icon class=\"material-symbols-outlined card-icon\">open_in_new</mat-icon>\n </div>\n</a>\n" }]
26987
- }], propDecorators: { link: [{
26988
- type: Input
26989
- }] } });
26990
-
26991
- class RelatedRecordCardComponent {
26992
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: RelatedRecordCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26993
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: RelatedRecordCardComponent, selector: "gn-ui-related-record-card", inputs: { record: "record" }, ngImport: i0, template: "<a\n class=\"w-72 h-96 overflow-hidden rounded-lg bg-white cursor-pointer block hover:-translate-y-2 duration-[180ms]\"\n [routerLink]=\"['/dataset', record.uniqueIdentifier]\"\n target=\"_blank\"\n>\n <div class=\"h-52 bg-gray-100\">\n <gn-ui-thumbnail\n class=\"h-52 w-full object-cover\"\n [thumbnailUrl]=\"record.overviews?.[0]?.url.toString()\"\n ></gn-ui-thumbnail>\n </div>\n <div class=\"flex flex-col justify-between h-44 px-5 pt-4 pb-6\">\n <h4\n class=\"max-h-24 font-title text-21 text-black text-ellipsis overflow-hidden\"\n >\n {{ record.title }}\n </h4>\n <div>\n <button\n mat-raised-button\n [matTooltip]=\"'tooltip.url.open' | translate\"\n matTooltipPosition=\"above\"\n >\n <mat-icon class=\"material-symbols-outlined align-middle text-secondary\"\n >open_in_new</mat-icon\n >\n </button>\n </div>\n </div>\n</a>\n", styles: [""], dependencies: [{ kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "directive", type: i1$7.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: ThumbnailComponent, selector: "gn-ui-thumbnail", inputs: ["thumbnailUrl", "fit"], outputs: ["placeholderShown"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26994
- }
26995
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: RelatedRecordCardComponent, decorators: [{
26996
- type: Component,
26997
- args: [{ selector: 'gn-ui-related-record-card', changeDetection: ChangeDetectionStrategy.OnPush, template: "<a\n class=\"w-72 h-96 overflow-hidden rounded-lg bg-white cursor-pointer block hover:-translate-y-2 duration-[180ms]\"\n [routerLink]=\"['/dataset', record.uniqueIdentifier]\"\n target=\"_blank\"\n>\n <div class=\"h-52 bg-gray-100\">\n <gn-ui-thumbnail\n class=\"h-52 w-full object-cover\"\n [thumbnailUrl]=\"record.overviews?.[0]?.url.toString()\"\n ></gn-ui-thumbnail>\n </div>\n <div class=\"flex flex-col justify-between h-44 px-5 pt-4 pb-6\">\n <h4\n class=\"max-h-24 font-title text-21 text-black text-ellipsis overflow-hidden\"\n >\n {{ record.title }}\n </h4>\n <div>\n <button\n mat-raised-button\n [matTooltip]=\"'tooltip.url.open' | translate\"\n matTooltipPosition=\"above\"\n >\n <mat-icon class=\"material-symbols-outlined align-middle text-secondary\"\n >open_in_new</mat-icon\n >\n </button>\n </div>\n </div>\n</a>\n" }]
26998
- }], propDecorators: { record: [{
26999
- type: Input
27000
- }] } });
27001
-
27002
- class MetadataContactComponent {
27003
- constructor() {
27004
- this.organizationClick = new EventEmitter();
27005
- this.contactClick = new EventEmitter();
27006
- }
27007
- get shownOrganization() {
27008
- return this.metadata.ownerOrganization;
27009
- }
27010
- get contacts() {
27011
- return ((this.metadata.kind === 'dataset'
27012
- ? this.metadata.contactsForResource
27013
- : this.metadata.contacts) || []);
27014
- }
27015
- get address() {
27016
- const addressParts = this.contacts[0].address
27017
- .split(',')
27018
- .map((part) => part.trim());
27019
- return addressParts;
27020
- }
27021
- onOrganizationClick() {
27022
- this.organizationClick.emit(this.shownOrganization);
27023
- }
27024
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MetadataContactComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27025
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: MetadataContactComponent, selector: "gn-ui-metadata-contact", inputs: { metadata: "metadata" }, outputs: { organizationClick: "organizationClick", contactClick: "contactClick" }, ngImport: i0, template: "<div class=\"py-5 px-5 rounded bg-gray-100 text-black mb-6\">\n <div class=\"grid gap-3 overflow-hidden\">\n <div>\n <p class=\"text-sm font-medium\" translate>record.metadata.contact</p>\n </div>\n <div\n *ngIf=\"shownOrganization?.logoUrl?.href\"\n class=\"flex items-center justify-center border-solid border border-gray-300 rounded-md bg-white h-32 overflow-hidden\"\n >\n <gn-ui-thumbnail\n class=\"relative h-full w-full\"\n [thumbnailUrl]=\"shownOrganization.logoUrl.href\"\n fit=\"contain\"\n ></gn-ui-thumbnail>\n </div>\n <div class=\"grid gap-1\">\n <div class=\"flex\">\n <div\n class=\"text-primary font-title text-21 mr-2 cursor-pointer hover:underline\"\n (click)=\"onOrganizationClick()\"\n data-cy=\"organization-name\"\n >\n {{ shownOrganization?.name }}\n </div>\n </div>\n <div *ngIf=\"shownOrganization?.website\">\n <a\n [href]=\"shownOrganization.website\"\n target=\"_blank\"\n class=\"contact-website text-primary text-sm cursor-pointer hover:underline transition-all\"\n >{{ shownOrganization.website }}\n <mat-icon\n class=\"material-symbols-outlined !w-[12px] !h-[12px] !text-[12px] opacity-75 shrink-0\"\n >open_in_new</mat-icon\n >\n </a>\n </div>\n </div>\n <div class=\"grid gap-5 py-3 overflow-hidden\">\n <div *ngIf=\"contacts[0]?.phone\">\n <div class=\"flex\">\n <mat-icon\n class=\"material-symbols-outlined !w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n >call_outline</mat-icon\n >\n <div class=\"flex flex-col ml-2\">\n <p class=\"text-sm\">{{ contacts[0].phone }}</p>\n </div>\n </div>\n </div>\n <div *ngIf=\"contacts[0]?.email\">\n <div class=\"flex\">\n <mat-icon\n class=\"material-symbols-outlined !w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n >\n mail_outline</mat-icon\n >\n <a\n *ngIf=\"contacts.length\"\n [href]=\"'mailto:' + contacts[0].email\"\n class=\"text-sm hover:underline ml-2\"\n target=\"_blank\"\n data-cy=\"contact-email\"\n >{{ contacts[0].email }}</a\n >\n </div>\n </div>\n <div *ngIf=\"contacts[0]?.firstName || contacts[0]?.lastName\">\n <div class=\"flex\">\n <mat-icon\n class=\"material-symbols-outlined !w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n >person_outline</mat-icon\n >\n <div class=\"flex flex-col ml-2\">\n <p class=\"text-sm\">\n {{ contacts[0]?.firstName || '' }}\n {{ contacts[0]?.lastName || '' }}\n </p>\n </div>\n </div>\n </div>\n <div *ngIf=\"contacts[0]?.address\">\n <div class=\"flex\">\n <mat-icon\n class=\"material-symbols-outlined !w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n >\n location_on</mat-icon\n >\n <div class=\"flex flex-col ml-2\">\n <p *ngFor=\"let addressPart of address\" class=\"text-sm\">\n {{ addressPart }}\n </p>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: ThumbnailComponent, selector: "gn-ui-thumbnail", inputs: ["thumbnailUrl", "fit"], outputs: ["placeholderShown"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
27026
- }
27027
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MetadataContactComponent, decorators: [{
27028
- type: Component,
27029
- args: [{ selector: 'gn-ui-metadata-contact', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"py-5 px-5 rounded bg-gray-100 text-black mb-6\">\n <div class=\"grid gap-3 overflow-hidden\">\n <div>\n <p class=\"text-sm font-medium\" translate>record.metadata.contact</p>\n </div>\n <div\n *ngIf=\"shownOrganization?.logoUrl?.href\"\n class=\"flex items-center justify-center border-solid border border-gray-300 rounded-md bg-white h-32 overflow-hidden\"\n >\n <gn-ui-thumbnail\n class=\"relative h-full w-full\"\n [thumbnailUrl]=\"shownOrganization.logoUrl.href\"\n fit=\"contain\"\n ></gn-ui-thumbnail>\n </div>\n <div class=\"grid gap-1\">\n <div class=\"flex\">\n <div\n class=\"text-primary font-title text-21 mr-2 cursor-pointer hover:underline\"\n (click)=\"onOrganizationClick()\"\n data-cy=\"organization-name\"\n >\n {{ shownOrganization?.name }}\n </div>\n </div>\n <div *ngIf=\"shownOrganization?.website\">\n <a\n [href]=\"shownOrganization.website\"\n target=\"_blank\"\n class=\"contact-website text-primary text-sm cursor-pointer hover:underline transition-all\"\n >{{ shownOrganization.website }}\n <mat-icon\n class=\"material-symbols-outlined !w-[12px] !h-[12px] !text-[12px] opacity-75 shrink-0\"\n >open_in_new</mat-icon\n >\n </a>\n </div>\n </div>\n <div class=\"grid gap-5 py-3 overflow-hidden\">\n <div *ngIf=\"contacts[0]?.phone\">\n <div class=\"flex\">\n <mat-icon\n class=\"material-symbols-outlined !w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n >call_outline</mat-icon\n >\n <div class=\"flex flex-col ml-2\">\n <p class=\"text-sm\">{{ contacts[0].phone }}</p>\n </div>\n </div>\n </div>\n <div *ngIf=\"contacts[0]?.email\">\n <div class=\"flex\">\n <mat-icon\n class=\"material-symbols-outlined !w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n >\n mail_outline</mat-icon\n >\n <a\n *ngIf=\"contacts.length\"\n [href]=\"'mailto:' + contacts[0].email\"\n class=\"text-sm hover:underline ml-2\"\n target=\"_blank\"\n data-cy=\"contact-email\"\n >{{ contacts[0].email }}</a\n >\n </div>\n </div>\n <div *ngIf=\"contacts[0]?.firstName || contacts[0]?.lastName\">\n <div class=\"flex\">\n <mat-icon\n class=\"material-symbols-outlined !w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n >person_outline</mat-icon\n >\n <div class=\"flex flex-col ml-2\">\n <p class=\"text-sm\">\n {{ contacts[0]?.firstName || '' }}\n {{ contacts[0]?.lastName || '' }}\n </p>\n </div>\n </div>\n </div>\n <div *ngIf=\"contacts[0]?.address\">\n <div class=\"flex\">\n <mat-icon\n class=\"material-symbols-outlined !w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n >\n location_on</mat-icon\n >\n <div class=\"flex flex-col ml-2\">\n <p *ngFor=\"let addressPart of address\" class=\"text-sm\">\n {{ addressPart }}\n </p>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n" }]
27030
- }], propDecorators: { metadata: [{
27031
- type: Input
27032
- }], organizationClick: [{
27033
- type: Output
27034
- }], contactClick: [{
27035
- type: Output
27036
- }] } });
27037
-
27038
- class MetadataCatalogComponent {
27039
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MetadataCatalogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27040
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: MetadataCatalogComponent, selector: "gn-ui-metadata-catalog", inputs: { sourceLabel: "sourceLabel" }, ngImport: i0, template: "<div>\n <p class=\"text-gray-700 text-xs mb-3 uppercase\" translate>\n record.metadata.catalog\n </p>\n <p class=\"text-primary font-title text-21 mb-1\">\n {{ sourceLabel }}\n </p>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
27041
- }
27042
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MetadataCatalogComponent, decorators: [{
27043
- type: Component,
27044
- args: [{ selector: 'gn-ui-metadata-catalog', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div>\n <p class=\"text-gray-700 text-xs mb-3 uppercase\" translate>\n record.metadata.catalog\n </p>\n <p class=\"text-primary font-title text-21 mb-1\">\n {{ sourceLabel }}\n </p>\n</div>\n" }]
27045
- }], propDecorators: { sourceLabel: [{
27046
- type: Input
27047
- }] } });
27048
-
27049
- var ErrorType;
27050
- (function (ErrorType) {
27051
- ErrorType[ErrorType["COULD_NOT_REACH_API"] = 0] = "COULD_NOT_REACH_API";
27052
- ErrorType[ErrorType["RECEIVED_ERROR"] = 1] = "RECEIVED_ERROR";
27053
- ErrorType[ErrorType["RECORD_NOT_FOUND"] = 2] = "RECORD_NOT_FOUND";
27054
- })(ErrorType || (ErrorType = {}));
27055
- class SearchResultsErrorComponent {
27056
- constructor() {
27057
- this.types = ErrorType;
27058
- }
27059
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SearchResultsErrorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27060
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: SearchResultsErrorComponent, selector: "gn-ui-search-results-error", inputs: { type: "type", error: "error", recordId: "recordId" }, ngImport: i0, template: "<div\n class=\"p-[1.7em] bg-red-50 text-red-800 text-[1.5em] text-center rounded-lg\"\n>\n <div *ngIf=\"type === types.COULD_NOT_REACH_API\">\n <div class=\"relative opacity-40\">\n <mat-icon class=\"material-symbols-outlined face\">face</mat-icon>\n <mat-icon class=\"material-symbols-outlined question-mark1\"\n >question_mark</mat-icon\n >\n <mat-icon class=\"material-symbols-outlined question-mark2\"\n >question_mark</mat-icon\n >\n </div>\n <div translate>search.error.couldNotReachApi</div>\n </div>\n <div *ngIf=\"type === types.RECEIVED_ERROR\">\n <div class=\"relative opacity-40\">\n <mat-icon class=\"material-symbols-outlined face\">mood_bad</mat-icon>\n </div>\n <div translate>search.error.receivedError</div>\n <div *ngIf=\"error\">{{ error }}</div>\n </div>\n <div *ngIf=\"type === types.RECORD_NOT_FOUND\">\n <div class=\"relative opacity-40\">\n <mat-icon class=\"material-symbols-outlined computer\">computer</mat-icon>\n <mat-icon class=\"material-symbols-outlined computer-question-mark\"\n >question_mark</mat-icon\n >\n </div>\n <div translate [translateParams]=\"{ id: recordId }\">\n search.error.recordNotFound\n </div>\n <div *ngIf=\"error\">{{ error }}</div>\n </div>\n</div>\n", styles: ["mat-icon{width:auto;height:auto}mat-icon.face{font-size:3em}mat-icon.question-mark1{position:absolute;bottom:1.1em;left:calc(50% + .7em);font-size:1.7em}mat-icon.question-mark2{position:absolute;bottom:1.6em;left:calc(50% + 1.6em);font-size:1.4em}.computer{font-size:3em}.computer-question-mark{position:absolute;top:.6em;left:calc(50% - .5em);font-size:1.2em}\n"], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
27061
- }
27062
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SearchResultsErrorComponent, decorators: [{
27063
- type: Component,
27064
- args: [{ selector: 'gn-ui-search-results-error', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"p-[1.7em] bg-red-50 text-red-800 text-[1.5em] text-center rounded-lg\"\n>\n <div *ngIf=\"type === types.COULD_NOT_REACH_API\">\n <div class=\"relative opacity-40\">\n <mat-icon class=\"material-symbols-outlined face\">face</mat-icon>\n <mat-icon class=\"material-symbols-outlined question-mark1\"\n >question_mark</mat-icon\n >\n <mat-icon class=\"material-symbols-outlined question-mark2\"\n >question_mark</mat-icon\n >\n </div>\n <div translate>search.error.couldNotReachApi</div>\n </div>\n <div *ngIf=\"type === types.RECEIVED_ERROR\">\n <div class=\"relative opacity-40\">\n <mat-icon class=\"material-symbols-outlined face\">mood_bad</mat-icon>\n </div>\n <div translate>search.error.receivedError</div>\n <div *ngIf=\"error\">{{ error }}</div>\n </div>\n <div *ngIf=\"type === types.RECORD_NOT_FOUND\">\n <div class=\"relative opacity-40\">\n <mat-icon class=\"material-symbols-outlined computer\">computer</mat-icon>\n <mat-icon class=\"material-symbols-outlined computer-question-mark\"\n >question_mark</mat-icon\n >\n </div>\n <div translate [translateParams]=\"{ id: recordId }\">\n search.error.recordNotFound\n </div>\n <div *ngIf=\"error\">{{ error }}</div>\n </div>\n</div>\n", styles: ["mat-icon{width:auto;height:auto}mat-icon.face{font-size:3em}mat-icon.question-mark1{position:absolute;bottom:1.1em;left:calc(50% + .7em);font-size:1.7em}mat-icon.question-mark2{position:absolute;bottom:1.6em;left:calc(50% + 1.6em);font-size:1.4em}.computer{font-size:3em}.computer-question-mark{position:absolute;top:.6em;left:calc(50% - .5em);font-size:1.2em}\n"] }]
27065
- }], propDecorators: { type: [{
27066
- type: Input
27067
- }], error: [{
27068
- type: Input
27069
- }], recordId: [{
27070
- type: Input
27071
- }] } });
27072
-
27073
- class PaginationComponent {
27074
- constructor() {
27075
- this.currentPage = 1;
27076
- this.nPages = 1;
27077
- this.hideButton = false;
27078
- this.newCurrentPageEvent = new EventEmitter();
27079
- }
27080
- applyPageBounds() {
27081
- // make sure this works with NaN inputs as well by adding `|| 1`
27082
- this.nPages = Math.max(1, this.nPages || 1);
27083
- this.currentPage = Math.max(1, Math.min(this.nPages, this.currentPage || 1));
27084
- }
27085
- ngOnChanges(changes) {
27086
- // make sure the inputs are valid
27087
- if ('currentPage' in changes || 'nPages' in changes) {
27088
- this.applyPageBounds();
27089
- }
27090
- }
27091
- setPage(newPage) {
27092
- if (!Number.isInteger(newPage))
27093
- return;
27094
- this.currentPage = newPage;
27095
- this.applyPageBounds();
27096
- this.newCurrentPageEvent.emit(this.currentPage);
27097
- }
27098
- nextPage() {
27099
- this.setPage(this.currentPage + 1);
27100
- }
27101
- previousPage() {
27102
- this.setPage(this.currentPage - 1);
27103
- }
27104
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: PaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27105
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: PaginationComponent, selector: "gn-ui-pagination", inputs: { currentPage: "currentPage", nPages: "nPages", hideButton: "hideButton" }, outputs: { newCurrentPageEvent: "newCurrentPageEvent" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"relative\">\n <div class=\"sm:absolute sm:inset-0\" *ngIf=\"!hideButton\">\n <gn-ui-button\n (buttonClick)=\"nextPage()\"\n type=\"secondary\"\n [disabled]=\"currentPage === nPages\"\n extraClass=\"lg:m-auto !p-[22px]\"\n >\n <span class=\"uppercase font-medium tracking-widest\" translate\n >pagination.nextPage</span\n >\n </gn-ui-button>\n </div>\n <div\n class=\"relative pointer-events-none flex flex-row justify-start sm:justify-end\"\n >\n <div class=\"pointer-events-auto flex flex-row items-center py-[13px]\">\n <span class=\"mr-3 capitalize text-sm text-gray-900\" translate\n >pagination.page</span\n >\n <input\n type=\"number\"\n [ngModel]=\"currentPage\"\n [min]=\"1\"\n [max]=\"nPages\"\n (ngModelChange)=\"setPage($event)\"\n class=\"border border-gray-300 rounded w-[54px] h-[34px] pl-[12px] mr-3 text-center\"\n />\n <span class=\"mr-3 text-sm text-gray-900\"\n ><span translate>pagination.pageOf</span> {{ nPages }}</span\n >\n <gn-ui-button\n (buttonClick)=\"previousPage()\"\n id=\"navigate_previous\"\n class=\"mr-2\"\n [disabled]=\"currentPage === 1\"\n [type]=\"'light'\"\n extraClass=\"!px-[3px]\"\n data-cy=\"prev-page\"\n >\n <mat-icon class=\"material-symbols-outlined\">navigate_before</mat-icon>\n </gn-ui-button>\n <gn-ui-button\n (buttonClick)=\"nextPage()\"\n id=\"navigate_next\"\n [disabled]=\"currentPage === nPages\"\n [type]=\"'light'\"\n extraClass=\"!px-[3px]\"\n data-cy=\"next-page\"\n >\n <mat-icon class=\"material-symbols-outlined\">navigate_next</mat-icon>\n </gn-ui-button>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i2$1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
27106
- }
27107
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: PaginationComponent, decorators: [{
27108
- type: Component,
27109
- args: [{ selector: 'gn-ui-pagination', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"relative\">\n <div class=\"sm:absolute sm:inset-0\" *ngIf=\"!hideButton\">\n <gn-ui-button\n (buttonClick)=\"nextPage()\"\n type=\"secondary\"\n [disabled]=\"currentPage === nPages\"\n extraClass=\"lg:m-auto !p-[22px]\"\n >\n <span class=\"uppercase font-medium tracking-widest\" translate\n >pagination.nextPage</span\n >\n </gn-ui-button>\n </div>\n <div\n class=\"relative pointer-events-none flex flex-row justify-start sm:justify-end\"\n >\n <div class=\"pointer-events-auto flex flex-row items-center py-[13px]\">\n <span class=\"mr-3 capitalize text-sm text-gray-900\" translate\n >pagination.page</span\n >\n <input\n type=\"number\"\n [ngModel]=\"currentPage\"\n [min]=\"1\"\n [max]=\"nPages\"\n (ngModelChange)=\"setPage($event)\"\n class=\"border border-gray-300 rounded w-[54px] h-[34px] pl-[12px] mr-3 text-center\"\n />\n <span class=\"mr-3 text-sm text-gray-900\"\n ><span translate>pagination.pageOf</span> {{ nPages }}</span\n >\n <gn-ui-button\n (buttonClick)=\"previousPage()\"\n id=\"navigate_previous\"\n class=\"mr-2\"\n [disabled]=\"currentPage === 1\"\n [type]=\"'light'\"\n extraClass=\"!px-[3px]\"\n data-cy=\"prev-page\"\n >\n <mat-icon class=\"material-symbols-outlined\">navigate_before</mat-icon>\n </gn-ui-button>\n <gn-ui-button\n (buttonClick)=\"nextPage()\"\n id=\"navigate_next\"\n [disabled]=\"currentPage === nPages\"\n [type]=\"'light'\"\n extraClass=\"!px-[3px]\"\n data-cy=\"next-page\"\n >\n <mat-icon class=\"material-symbols-outlined\">navigate_next</mat-icon>\n </gn-ui-button>\n </div>\n </div>\n</div>\n" }]
27110
- }], propDecorators: { currentPage: [{
27111
- type: Input
27112
- }], nPages: [{
27113
- type: Input
27114
- }], hideButton: [{
27115
- type: Input
27116
- }], newCurrentPageEvent: [{
27117
- type: Output
27118
- }] } });
27119
-
27120
- class AvatarComponent {
27121
- hideImage() {
27122
- this.avatarUrl = this.avatarPlaceholder;
27123
- }
27124
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: AvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27125
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: AvatarComponent, selector: "gn-ui-avatar", inputs: { avatarUrl: "avatarUrl", avatarPlaceholder: "avatarPlaceholder" }, ngImport: i0, template: "<img\n *ngIf=\"avatarUrl\"\n class=\"rounded-full object-cover\"\n [src]=\"avatarUrl\"\n (error)=\"hideImage()\"\n/>\n<div\n *ngIf=\"!avatarUrl\"\n class=\"w-full h-full rounded-full bg-gradient-to-tr from-primary to-slate-200\"\n></div>\n", dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
27126
- }
27127
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: AvatarComponent, decorators: [{
27128
- type: Component,
27129
- args: [{ selector: 'gn-ui-avatar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<img\n *ngIf=\"avatarUrl\"\n class=\"rounded-full object-cover\"\n [src]=\"avatarUrl\"\n (error)=\"hideImage()\"\n/>\n<div\n *ngIf=\"!avatarUrl\"\n class=\"w-full h-full rounded-full bg-gradient-to-tr from-primary to-slate-200\"\n></div>\n" }]
27130
- }], propDecorators: { avatarUrl: [{
27131
- type: Input
27132
- }], avatarPlaceholder: [{
27133
- type: Input
27134
- }] } });
27135
-
27136
27463
  class UserPreviewComponent {
27137
27464
  get userFullName() {
27138
27465
  return (this.user.name + ' ' + this.user.surname).trim();
@@ -27149,146 +27476,109 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
27149
27476
  type: Input
27150
27477
  }] } });
27151
27478
 
27152
- class PaginationButtonsComponent {
27153
- constructor() {
27154
- this.visiblePages = [];
27155
- this.newCurrentPageEvent = new EventEmitter();
27156
- }
27157
- ngOnChanges() {
27158
- this.calculateVisiblePages();
27479
+ class TimeSincePipe {
27480
+ constructor(translate) {
27481
+ this.translate = translate;
27159
27482
  }
27160
- calculateVisiblePages() {
27161
- const maxVisiblePages = 5;
27162
- const halfVisible = Math.floor(maxVisiblePages / 2);
27163
- const startPage = Math.max(this.currentPage - halfVisible, 1);
27164
- const endPage = Math.min(this.currentPage + halfVisible, this.totalPages);
27165
- const visiblePages = [];
27166
- if (startPage > 1) {
27167
- visiblePages.push(1);
27168
- if (startPage > 2) {
27169
- visiblePages.push('...');
27170
- }
27171
- }
27172
- for (let page = startPage; page <= endPage; page++) {
27173
- visiblePages.push(page);
27483
+ transform(value) {
27484
+ if (isNaN(value.getTime())) {
27485
+ throw new Error('Invalid Date');
27174
27486
  }
27175
- if (endPage < this.totalPages) {
27176
- if (endPage < this.totalPages - 1) {
27177
- visiblePages.push('...');
27178
- }
27179
- visiblePages.push(this.totalPages);
27487
+ const maintenant = new Date();
27488
+ let locale;
27489
+ switch (this.translate.currentLang) {
27490
+ case 'fr':
27491
+ locale = fr$1;
27492
+ break;
27493
+ case 'de':
27494
+ locale = de$1;
27495
+ break;
27496
+ case 'es':
27497
+ locale = es$1;
27498
+ break;
27499
+ case 'it':
27500
+ locale = it$1;
27501
+ break;
27502
+ case 'nl':
27503
+ locale = nl$1;
27504
+ break;
27505
+ case 'pt':
27506
+ locale = pt$1;
27507
+ break;
27508
+ case 'sk':
27509
+ locale = sk;
27510
+ break;
27511
+ case 'en':
27512
+ default:
27513
+ locale = enUS;
27514
+ break;
27180
27515
  }
27181
- this.visiblePages = visiblePages;
27182
- }
27183
- changePage(page) {
27184
- this.setPage(page);
27185
- }
27186
- nextPage() {
27187
- this.setPage(this.currentPage + 1);
27188
- }
27189
- previousPage() {
27190
- this.setPage(this.currentPage - 1);
27191
- }
27192
- setPage(newPage) {
27193
- if (!Number.isInteger(newPage))
27194
- return;
27195
- this.currentPage = newPage;
27196
- this.calculateVisiblePages();
27197
- this.newCurrentPageEvent.emit(this.currentPage);
27516
+ return formatDistance(value, maintenant, {
27517
+ addSuffix: true,
27518
+ locale: locale,
27519
+ });
27198
27520
  }
27199
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: PaginationButtonsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27200
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: PaginationButtonsComponent, selector: "gn-ui-pagination-buttons", inputs: { currentPage: "currentPage", totalPages: "totalPages" }, outputs: { newCurrentPageEvent: "newCurrentPageEvent" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"relative\">\n <div class=\"flex flex-row gap-[5px] items-center\">\n <gn-ui-button\n type=\"light\"\n [disabled]=\"currentPage === 1\"\n (buttonClick)=\"previousPage()\"\n extraClass=\"!px-[3px]\"\n >\n <mat-icon class=\"material-symbols-outlined\">chevron_left</mat-icon>\n </gn-ui-button>\n <ng-container *ngFor=\"let page of visiblePages\">\n <ng-container *ngIf=\"page === '...'\">\n <span class=\"mx-[5px]\">{{ page }}</span>\n </ng-container>\n <ng-container *ngIf=\"page !== '...'\">\n <gn-ui-button\n [type]=\"page === currentPage ? 'primary' : 'light'\"\n [disabled]=\"page === currentPage\"\n (buttonClick)=\"changePage(page)\"\n >{{ page }}</gn-ui-button\n >\n </ng-container>\n </ng-container>\n <gn-ui-button\n type=\"light\"\n [disabled]=\"currentPage === totalPages\"\n (buttonClick)=\"nextPage()\"\n extraClass=\"!px-[3px]\"\n >\n <mat-icon class=\"material-symbols-outlined\">chevron_right</mat-icon>\n </gn-ui-button>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }] }); }
27521
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: TimeSincePipe, deps: [{ token: i1$1.TranslateService }], target: i0.ɵɵFactoryTarget.Pipe }); }
27522
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "16.1.7", ngImport: i0, type: TimeSincePipe, isStandalone: true, name: "timeSince" }); }
27201
27523
  }
27202
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: PaginationButtonsComponent, decorators: [{
27203
- type: Component,
27204
- args: [{ selector: 'gn-ui-pagination-buttons', template: "<div class=\"relative\">\n <div class=\"flex flex-row gap-[5px] items-center\">\n <gn-ui-button\n type=\"light\"\n [disabled]=\"currentPage === 1\"\n (buttonClick)=\"previousPage()\"\n extraClass=\"!px-[3px]\"\n >\n <mat-icon class=\"material-symbols-outlined\">chevron_left</mat-icon>\n </gn-ui-button>\n <ng-container *ngFor=\"let page of visiblePages\">\n <ng-container *ngIf=\"page === '...'\">\n <span class=\"mx-[5px]\">{{ page }}</span>\n </ng-container>\n <ng-container *ngIf=\"page !== '...'\">\n <gn-ui-button\n [type]=\"page === currentPage ? 'primary' : 'light'\"\n [disabled]=\"page === currentPage\"\n (buttonClick)=\"changePage(page)\"\n >{{ page }}</gn-ui-button\n >\n </ng-container>\n </ng-container>\n <gn-ui-button\n type=\"light\"\n [disabled]=\"currentPage === totalPages\"\n (buttonClick)=\"nextPage()\"\n extraClass=\"!px-[3px]\"\n >\n <mat-icon class=\"material-symbols-outlined\">chevron_right</mat-icon>\n </gn-ui-button>\n </div>\n</div>\n" }]
27205
- }], propDecorators: { currentPage: [{
27206
- type: Input
27207
- }], totalPages: [{
27208
- type: Input
27209
- }], newCurrentPageEvent: [{
27210
- type: Output
27211
- }] } });
27524
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: TimeSincePipe, decorators: [{
27525
+ type: Pipe,
27526
+ args: [{
27527
+ name: 'timeSince',
27528
+ standalone: true,
27529
+ }]
27530
+ }], ctorParameters: function () { return [{ type: i1$1.TranslateService }]; } });
27212
27531
 
27213
- const DEFAULT_PARAMS = {
27214
- OFFSET: '',
27215
- LIMIT: '-1',
27216
- FORMAT: 'json',
27217
- };
27218
- class RecordApiFormComponent {
27532
+ class UserFeedbackItemComponent {
27219
27533
  constructor() {
27220
- this.offset$ = new BehaviorSubject('');
27221
- this.limit$ = new BehaviorSubject('');
27222
- this.format$ = new BehaviorSubject('');
27223
- this.formatsList = [
27224
- { label: 'JSON', value: 'json' },
27225
- { label: 'CSV', value: 'csv' },
27226
- ];
27227
- this.apiQueryUrl$ = combineLatest([this.offset$, this.limit$, this.format$]).pipe(map$2(([offset, limit, format]) => {
27228
- let outputUrl;
27229
- if (this.apiBaseUrl) {
27230
- const url = new URL(this.apiBaseUrl);
27231
- const params = { offset: offset, limit: limit, f: format };
27232
- for (const [key, value] of Object.entries(params)) {
27233
- if (value && value !== '0') {
27234
- url.searchParams.set(key, value);
27235
- }
27236
- else {
27237
- url.searchParams.delete(key);
27238
- }
27239
- }
27240
- outputUrl = url.toString();
27241
- }
27242
- return outputUrl;
27243
- }));
27244
- this.noLimitChecked$ = this.limit$.pipe(map$2((limit) => limit === '-1' || limit === ''));
27245
- this.displayLimit$ = this.limit$.pipe(map$2((limit) => (limit !== '-1' ? limit : '')));
27534
+ this.newUserFeedbackAnswer = new EventEmitter();
27535
+ this.isAnAnswer = false;
27536
+ this.newAnswer = '';
27537
+ this.isAnswerEmpty = true;
27246
27538
  }
27247
- set apiLink(value) {
27248
- this.apiBaseUrl = value ? value.url.href : undefined;
27249
- this.resetUrl();
27250
- }
27251
- setOffset(value) {
27252
- this.offset$.next(value);
27253
- }
27254
- setLimit(value) {
27255
- const newLimit = value === '' ? '-1' : value;
27256
- this.limit$.next(newLimit);
27539
+ ngOnInit() {
27540
+ this.isAnAnswer = !!this.userFeedbackParent.parentUuid;
27257
27541
  }
27258
- setFormat(value) {
27259
- this.format$.next(String(value));
27542
+ onNewAnswerValueChange() {
27543
+ this.isAnswerEmpty = this.newAnswer.length === 0;
27260
27544
  }
27261
- resetUrl() {
27262
- this.offset$.next(DEFAULT_PARAMS.OFFSET);
27263
- this.limit$.next(DEFAULT_PARAMS.LIMIT);
27264
- this.format$.next(DEFAULT_PARAMS.FORMAT);
27545
+ publishNewAnswer() {
27546
+ if (this.newAnswer.trim() === '')
27547
+ return;
27548
+ const newAnswer = {
27549
+ ...this.userFeedbackParent,
27550
+ uuid: undefined,
27551
+ published: true,
27552
+ comment: this.newAnswer,
27553
+ parentUuid: this.userFeedbackParent.uuid,
27554
+ authorUserId: this.activeUser?.id,
27555
+ authorEmail: this.activeUser?.email,
27556
+ date: new Date(),
27557
+ authorName: `${this.activeUser?.name} ${this.activeUser?.surname}`,
27558
+ };
27559
+ this.newUserFeedbackAnswer.emit(newAnswer);
27560
+ this.newAnswer = '';
27561
+ this.onNewAnswerValueChange();
27265
27562
  }
27266
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: RecordApiFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27267
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: RecordApiFormComponent, selector: "gn-ui-record-api-form", inputs: { apiLink: "apiLink" }, ngImport: i0, template: "<div class=\"flex flex-col gap-8\">\n <div class=\"flex flex-col bg-white p-8 ng-star-inserted shadow-xl gap-8\">\n <div class=\"flex flex-row\">\n <div class=\"text-[16px] text-black truncate font-title w-11/12\" translate>\n record.metadata.api.form.create\n </div>\n <button\n (click)=\"resetUrl()\"\n class=\"bg-primary-opacity-50 inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded capitalize text-primary-lightest hover:bg-primary transition-colors\"\n >\n <p class=\"text-[13px] uppercase\" translate>\n record.metadata.api.form.reset\n </p>\n </button>\n </div>\n <div class=\"flex flex-row flex-wrap justify-between flex-grow gap-5\">\n <div class=\"flex flex-col gap-3\">\n <p class=\"text-[14px]\" translate>record.metadata.api.form.limit</p>\n <div class=\"flex flex-row items-center gap-2\">\n <gn-ui-text-input\n class=\"mr-2 w-20\"\n (valueChange)=\"setLimit($event)\"\n [value]=\"displayLimit$ | async\"\n hint=\"\"\n >\n </gn-ui-text-input>\n <div class=\"flex items-center\">\n <input\n class=\"mr-2 cursor-pointer\"\n type=\"checkbox\"\n [checked]=\"noLimitChecked$ | async\"\n (change)=\"setLimit('-1')\"\n />\n <span class=\"text-sm\" translate\n >record.metadata.api.form.limit.all</span\n >\n </div>\n </div>\n </div>\n <div class=\"flex flex-col gap-3\">\n <p class=\"text-sm\" translate>record.metadata.api.form.offset</p>\n <gn-ui-text-input\n class=\"w-20\"\n [value]=\"offset$ | async\"\n (valueChange)=\"setOffset($event)\"\n hint=\"\"\n >\n </gn-ui-text-input>\n </div>\n <div class=\"flex flex-col gap-3\">\n <p class=\"text-sm\" translate>record.metadata.api.form.type</p>\n <gn-ui-dropdown-selector\n #dropdown\n [title]=\"''\"\n extraBtnClass=\"secondary min-w-full !w-40 !text-black\"\n [showTitle]=\"false\"\n class=\"text-black\"\n [choices]=\"formatsList\"\n (selectValue)=\"setFormat($event)\"\n [selected]=\"format$ | async\"\n ></gn-ui-dropdown-selector>\n </div>\n </div>\n </div>\n <div class=\"flex flex-col gap-3 mb-3\">\n <div class=\"text-sm text-black truncate font-title w-11/12\" translate>\n record.metadata.api.form.customUrl\n </div>\n <div class=\"bg-white rounded-lg\">\n <gn-ui-copy-text-button\n [text]=\"apiQueryUrl$ | async\"\n ></gn-ui-copy-text-button>\n </div>\n </div>\n</div>\n", styles: [":host ::ng-deep input{color:#000;opacity:1}:host ::ng-deep gn-ui-copy-text-button input[type=text]{color:#000;background-color:#fff}:host ::ng-deep gn-ui-copy-text-button button,host ::ng-deep gn-ui-copy-text-button button:hover{background-color:var(--color-secondary)!important}:host ::ng-deep gn-ui-copy-text-button button mat-icon{color:#fff!important;opacity:1!important}:host ::ng-deep gn-ui-copy-text-button button:hover mat-icon{color:#d3d3d3!important}\n"], dependencies: [{ kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: DropdownSelectorComponent, selector: "gn-ui-dropdown-selector", inputs: ["title", "showTitle", "ariaName", "choices", "selected", "maxRows", "extraBtnClass", "minWidth"], outputs: ["selectValue"] }, { kind: "component", type: TextInputComponent, selector: "gn-ui-text-input", inputs: ["value", "hint", "required"], outputs: ["valueChange"] }, { kind: "component", type: CopyTextButtonComponent, selector: "gn-ui-copy-text-button", inputs: ["text", "tooltipText", "displayText", "rows"] }, { kind: "pipe", type: i1$3.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
27563
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UserFeedbackItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27564
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: UserFeedbackItemComponent, selector: "gn-ui-user-feedback-item", inputs: { userFeedbackParent: "userFeedbackParent", userFeedBacksAnswers: "userFeedBacksAnswers", isActiveUserEditor: "isActiveUserEditor", activeUser: "activeUser", isLastComment: "isLastComment", isAddUserFeedbackLoading: "isAddUserFeedbackLoading" }, outputs: { newUserFeedbackAnswer: "newUserFeedbackAnswer" }, ngImport: i0, template: "<div\n *ngIf=\"userFeedbackParent.published\"\n class=\"flex flex-col bg-white rounded w-full\"\n [ngClass]=\"[isAnAnswer ? 'ps-4 ' : 'p-4']\"\n>\n <div class=\"flex flex-row\">\n <div class=\"avatar\">\n <img\n class=\"rounded-full\"\n [src]=\"userFeedbackParent.avatarUrl\"\n alt=\"avatar\"\n />\n </div>\n <div class=\"p-4 flex flex-col\">\n <span>{{ userFeedbackParent.authorName }}</span>\n <span> {{ userFeedbackParent.date | timeSince }}</span>\n </div>\n </div>\n <div data-cy=\"commentText\" class=\"mt-4 whitespace-pre-line\">\n {{ userFeedbackParent.comment }}\n </div>\n <div\n class=\"w-full\"\n *ngFor=\"let userFeedBacksAnswer of userFeedBacksAnswers; let last = last\"\n >\n <hr class=\"-mx-4 my-6\" />\n <gn-ui-user-feedback-item\n [userFeedbackParent]=\"userFeedBacksAnswer\"\n [isLastComment]=\"last\"\n ></gn-ui-user-feedback-item>\n </div>\n\n <div *ngIf=\"isActiveUserEditor\" class=\"mt-2 flex flex-col\">\n <hr class=\"-mx-4 my-4\" />\n <div\n id=\"new-comment-buttons\"\n class=\"flex flex-row gap-2 items-center justify-end\"\n >\n <gn-ui-text-area\n [disabled]=\"isAddUserFeedbackLoading\"\n [(value)]=\"newAnswer\"\n (valueChange)=\"onNewAnswerValueChange()\"\n (keyup.control.enter)=\"publishNewAnswer()\"\n [placeholder]=\"\n 'record.metadata.userFeedbacks.newAnswer.placeholder' | translate\n \"\n class=\"grow\"\n extraClass=\"bg-transparent border-0 placeholder-primary-darker text-primary-darker h-9\"\n ></gn-ui-text-area>\n <div *ngIf=\"!isAnswerEmpty\" class=\"flex flex-row justify-end\">\n <gn-ui-button\n [disabled]=\"isAddUserFeedbackLoading\"\n [type]=\"'outline'\"\n (buttonClick)=\"publishNewAnswer()\"\n [title]=\"\n 'record.metadata.userFeedbacks.newAnswer.buttonTitle' | translate\n \"\n extraClass=\"!p-[0.5em] text-primary-darker border-primary-darker h-9\"\n >\n <mat-icon\n class=\"material-symbols-outlined\"\n *ngIf=\"!isAddUserFeedbackLoading\"\n >\n send\n </mat-icon>\n <ng-container *ngIf=\"isAddUserFeedbackLoading\">\n <div class=\"flex justify-center w-full\">\n <gn-ui-spinning-loader></gn-ui-spinning-loader>\n </div>\n </ng-container>\n </gn-ui-button>\n </div>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: SpinningLoaderComponent, selector: "gn-ui-spinning-loader" }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: TextAreaComponent, selector: "gn-ui-text-area", inputs: ["value", "disabled", "extraClass", "placeholder", "required"], outputs: ["valueChange"] }, { kind: "component", type: UserFeedbackItemComponent, selector: "gn-ui-user-feedback-item", inputs: ["userFeedbackParent", "userFeedBacksAnswers", "isActiveUserEditor", "activeUser", "isLastComment", "isAddUserFeedbackLoading"], outputs: ["newUserFeedbackAnswer"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "pipe", type: TimeSincePipe, name: "timeSince" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
27268
27565
  }
27269
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: RecordApiFormComponent, decorators: [{
27566
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UserFeedbackItemComponent, decorators: [{
27270
27567
  type: Component,
27271
- args: [{ selector: 'gn-ui-record-api-form', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col gap-8\">\n <div class=\"flex flex-col bg-white p-8 ng-star-inserted shadow-xl gap-8\">\n <div class=\"flex flex-row\">\n <div class=\"text-[16px] text-black truncate font-title w-11/12\" translate>\n record.metadata.api.form.create\n </div>\n <button\n (click)=\"resetUrl()\"\n class=\"bg-primary-opacity-50 inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded capitalize text-primary-lightest hover:bg-primary transition-colors\"\n >\n <p class=\"text-[13px] uppercase\" translate>\n record.metadata.api.form.reset\n </p>\n </button>\n </div>\n <div class=\"flex flex-row flex-wrap justify-between flex-grow gap-5\">\n <div class=\"flex flex-col gap-3\">\n <p class=\"text-[14px]\" translate>record.metadata.api.form.limit</p>\n <div class=\"flex flex-row items-center gap-2\">\n <gn-ui-text-input\n class=\"mr-2 w-20\"\n (valueChange)=\"setLimit($event)\"\n [value]=\"displayLimit$ | async\"\n hint=\"\"\n >\n </gn-ui-text-input>\n <div class=\"flex items-center\">\n <input\n class=\"mr-2 cursor-pointer\"\n type=\"checkbox\"\n [checked]=\"noLimitChecked$ | async\"\n (change)=\"setLimit('-1')\"\n />\n <span class=\"text-sm\" translate\n >record.metadata.api.form.limit.all</span\n >\n </div>\n </div>\n </div>\n <div class=\"flex flex-col gap-3\">\n <p class=\"text-sm\" translate>record.metadata.api.form.offset</p>\n <gn-ui-text-input\n class=\"w-20\"\n [value]=\"offset$ | async\"\n (valueChange)=\"setOffset($event)\"\n hint=\"\"\n >\n </gn-ui-text-input>\n </div>\n <div class=\"flex flex-col gap-3\">\n <p class=\"text-sm\" translate>record.metadata.api.form.type</p>\n <gn-ui-dropdown-selector\n #dropdown\n [title]=\"''\"\n extraBtnClass=\"secondary min-w-full !w-40 !text-black\"\n [showTitle]=\"false\"\n class=\"text-black\"\n [choices]=\"formatsList\"\n (selectValue)=\"setFormat($event)\"\n [selected]=\"format$ | async\"\n ></gn-ui-dropdown-selector>\n </div>\n </div>\n </div>\n <div class=\"flex flex-col gap-3 mb-3\">\n <div class=\"text-sm text-black truncate font-title w-11/12\" translate>\n record.metadata.api.form.customUrl\n </div>\n <div class=\"bg-white rounded-lg\">\n <gn-ui-copy-text-button\n [text]=\"apiQueryUrl$ | async\"\n ></gn-ui-copy-text-button>\n </div>\n </div>\n</div>\n", styles: [":host ::ng-deep input{color:#000;opacity:1}:host ::ng-deep gn-ui-copy-text-button input[type=text]{color:#000;background-color:#fff}:host ::ng-deep gn-ui-copy-text-button button,host ::ng-deep gn-ui-copy-text-button button:hover{background-color:var(--color-secondary)!important}:host ::ng-deep gn-ui-copy-text-button button mat-icon{color:#fff!important;opacity:1!important}:host ::ng-deep gn-ui-copy-text-button button:hover mat-icon{color:#d3d3d3!important}\n"] }]
27272
- }], propDecorators: { apiLink: [{
27568
+ args: [{ selector: 'gn-ui-user-feedback-item', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n *ngIf=\"userFeedbackParent.published\"\n class=\"flex flex-col bg-white rounded w-full\"\n [ngClass]=\"[isAnAnswer ? 'ps-4 ' : 'p-4']\"\n>\n <div class=\"flex flex-row\">\n <div class=\"avatar\">\n <img\n class=\"rounded-full\"\n [src]=\"userFeedbackParent.avatarUrl\"\n alt=\"avatar\"\n />\n </div>\n <div class=\"p-4 flex flex-col\">\n <span>{{ userFeedbackParent.authorName }}</span>\n <span> {{ userFeedbackParent.date | timeSince }}</span>\n </div>\n </div>\n <div data-cy=\"commentText\" class=\"mt-4 whitespace-pre-line\">\n {{ userFeedbackParent.comment }}\n </div>\n <div\n class=\"w-full\"\n *ngFor=\"let userFeedBacksAnswer of userFeedBacksAnswers; let last = last\"\n >\n <hr class=\"-mx-4 my-6\" />\n <gn-ui-user-feedback-item\n [userFeedbackParent]=\"userFeedBacksAnswer\"\n [isLastComment]=\"last\"\n ></gn-ui-user-feedback-item>\n </div>\n\n <div *ngIf=\"isActiveUserEditor\" class=\"mt-2 flex flex-col\">\n <hr class=\"-mx-4 my-4\" />\n <div\n id=\"new-comment-buttons\"\n class=\"flex flex-row gap-2 items-center justify-end\"\n >\n <gn-ui-text-area\n [disabled]=\"isAddUserFeedbackLoading\"\n [(value)]=\"newAnswer\"\n (valueChange)=\"onNewAnswerValueChange()\"\n (keyup.control.enter)=\"publishNewAnswer()\"\n [placeholder]=\"\n 'record.metadata.userFeedbacks.newAnswer.placeholder' | translate\n \"\n class=\"grow\"\n extraClass=\"bg-transparent border-0 placeholder-primary-darker text-primary-darker h-9\"\n ></gn-ui-text-area>\n <div *ngIf=\"!isAnswerEmpty\" class=\"flex flex-row justify-end\">\n <gn-ui-button\n [disabled]=\"isAddUserFeedbackLoading\"\n [type]=\"'outline'\"\n (buttonClick)=\"publishNewAnswer()\"\n [title]=\"\n 'record.metadata.userFeedbacks.newAnswer.buttonTitle' | translate\n \"\n extraClass=\"!p-[0.5em] text-primary-darker border-primary-darker h-9\"\n >\n <mat-icon\n class=\"material-symbols-outlined\"\n *ngIf=\"!isAddUserFeedbackLoading\"\n >\n send\n </mat-icon>\n <ng-container *ngIf=\"isAddUserFeedbackLoading\">\n <div class=\"flex justify-center w-full\">\n <gn-ui-spinning-loader></gn-ui-spinning-loader>\n </div>\n </ng-container>\n </gn-ui-button>\n </div>\n </div>\n </div>\n</div>\n" }]
27569
+ }], propDecorators: { userFeedbackParent: [{
27273
27570
  type: Input
27274
- }] } });
27275
-
27276
- class ImageOverlayPreviewComponent {
27277
- constructor() {
27278
- this.isPlaceholderShown = new EventEmitter();
27279
- }
27280
- openLightbox(src) {
27281
- basicLightbox.create(`<img src="${src}"/>`).show();
27282
- }
27283
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ImageOverlayPreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27284
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: ImageOverlayPreviewComponent, selector: "gn-ui-image-overlay-preview", inputs: { imageUrl: "imageUrl" }, outputs: { isPlaceholderShown: "isPlaceholderShown" }, ngImport: i0, template: "<gn-ui-content-ghost\n [showContent]=\"imageUrl !== undefined\"\n ghostClass=\"h-48 mb-3\"\n>\n <div\n *ngIf=\"imageUrl\"\n [showContent]=\"imageUrl !== undefined\"\n data-cy=\"record-thumbnail\"\n class=\"flex-shrink-0 bg-gray-100 rounded-lg overflow-hidden w-full border border-gray-300 group-hover:shadow-xl group-hover:border-0 h-48 mb-3\"\n >\n <gn-ui-thumbnail\n class=\"relative h-full w-full\"\n [thumbnailUrl]=\"imageUrl\"\n fit=\"cover\"\n (placeholderShown)=\"isPlaceholderShown.emit($event)\"\n ></gn-ui-thumbnail>\n <div class=\"relative\">\n <gn-ui-button\n class=\"absolute bottom-0 right-0 z-10 mr-2 mb-2\"\n [type]=\"'outline'\"\n [extraClass]=\"'!py-2 !px-0'\"\n (buttonClick)=\"openLightbox(imageUrl)\"\n >\n <mat-icon class=\"material-symbols-outlined font-extralight\"\n >zoom_out_map</mat-icon\n >\n </gn-ui-button>\n </div>\n </div>\n</gn-ui-content-ghost>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: ThumbnailComponent, selector: "gn-ui-thumbnail", inputs: ["thumbnailUrl", "fit"], outputs: ["placeholderShown"] }, { kind: "component", type: ContentGhostComponent, selector: "gn-ui-content-ghost", inputs: ["showContent", "ghostClass"] }] }); }
27285
- }
27286
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ImageOverlayPreviewComponent, decorators: [{
27287
- type: Component,
27288
- args: [{ selector: 'gn-ui-image-overlay-preview', template: "<gn-ui-content-ghost\n [showContent]=\"imageUrl !== undefined\"\n ghostClass=\"h-48 mb-3\"\n>\n <div\n *ngIf=\"imageUrl\"\n [showContent]=\"imageUrl !== undefined\"\n data-cy=\"record-thumbnail\"\n class=\"flex-shrink-0 bg-gray-100 rounded-lg overflow-hidden w-full border border-gray-300 group-hover:shadow-xl group-hover:border-0 h-48 mb-3\"\n >\n <gn-ui-thumbnail\n class=\"relative h-full w-full\"\n [thumbnailUrl]=\"imageUrl\"\n fit=\"cover\"\n (placeholderShown)=\"isPlaceholderShown.emit($event)\"\n ></gn-ui-thumbnail>\n <div class=\"relative\">\n <gn-ui-button\n class=\"absolute bottom-0 right-0 z-10 mr-2 mb-2\"\n [type]=\"'outline'\"\n [extraClass]=\"'!py-2 !px-0'\"\n (buttonClick)=\"openLightbox(imageUrl)\"\n >\n <mat-icon class=\"material-symbols-outlined font-extralight\"\n >zoom_out_map</mat-icon\n >\n </gn-ui-button>\n </div>\n </div>\n</gn-ui-content-ghost>\n" }]
27289
- }], propDecorators: { imageUrl: [{
27571
+ }], userFeedBacksAnswers: [{
27290
27572
  type: Input
27291
- }], isPlaceholderShown: [{
27573
+ }], isActiveUserEditor: [{
27574
+ type: Input
27575
+ }], activeUser: [{
27576
+ type: Input
27577
+ }], isLastComment: [{
27578
+ type: Input
27579
+ }], isAddUserFeedbackLoading: [{
27580
+ type: Input
27581
+ }], newUserFeedbackAnswer: [{
27292
27582
  type: Output
27293
27583
  }] } });
27294
27584
 
@@ -27313,6 +27603,7 @@ class UiElementsModule {
27313
27603
  PaginationButtonsComponent,
27314
27604
  MaxLinesComponent,
27315
27605
  RecordApiFormComponent,
27606
+ UserFeedbackItemComponent,
27316
27607
  ImageOverlayPreviewComponent], imports: [CommonModule,
27317
27608
  MatIconModule,
27318
27609
  MatTooltipModule,
@@ -27323,7 +27614,8 @@ class UiElementsModule {
27323
27614
  FormsModule,
27324
27615
  NgOptimizedImage,
27325
27616
  MarkdownParserComponent,
27326
- ThumbnailComponent], exports: [MetadataInfoComponent,
27617
+ ThumbnailComponent,
27618
+ TimeSincePipe], exports: [MetadataInfoComponent,
27327
27619
  ContentGhostComponent,
27328
27620
  DownloadItemComponent,
27329
27621
  DownloadsListComponent,
@@ -27343,6 +27635,7 @@ class UiElementsModule {
27343
27635
  MaxLinesComponent,
27344
27636
  RecordApiFormComponent,
27345
27637
  MarkdownParserComponent,
27638
+ UserFeedbackItemComponent,
27346
27639
  ImageOverlayPreviewComponent] }); }
27347
27640
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UiElementsModule, imports: [CommonModule,
27348
27641
  MatIconModule,
@@ -27373,6 +27666,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
27373
27666
  NgOptimizedImage,
27374
27667
  MarkdownParserComponent,
27375
27668
  ThumbnailComponent,
27669
+ TimeSincePipe,
27376
27670
  ],
27377
27671
  declarations: [
27378
27672
  MetadataInfoComponent,
@@ -27394,6 +27688,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
27394
27688
  PaginationButtonsComponent,
27395
27689
  MaxLinesComponent,
27396
27690
  RecordApiFormComponent,
27691
+ UserFeedbackItemComponent,
27397
27692
  ImageOverlayPreviewComponent,
27398
27693
  ],
27399
27694
  exports: [
@@ -27417,11 +27712,39 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
27417
27712
  MaxLinesComponent,
27418
27713
  RecordApiFormComponent,
27419
27714
  MarkdownParserComponent,
27715
+ UserFeedbackItemComponent,
27420
27716
  ImageOverlayPreviewComponent,
27421
27717
  ],
27422
27718
  }]
27423
27719
  }] });
27424
27720
 
27721
+ class NotificationComponent {
27722
+ constructor() {
27723
+ this.type = 'info';
27724
+ this.notificationClose = new EventEmitter();
27725
+ }
27726
+ handleClose(event) {
27727
+ event?.preventDefault();
27728
+ this.notificationClose.emit();
27729
+ }
27730
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: NotificationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27731
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: NotificationComponent, isStandalone: true, selector: "gn-ui-notification", inputs: { type: "type", title: "title", text: "text", closeMessage: "closeMessage" }, outputs: { notificationClose: "notificationClose" }, ngImport: i0, template: "<div\n class=\"p-[16px] flex flex-row gap-[16px] items-start border border-gray-200 shadow-md rounded bg-background\"\n>\n <div\n role=\"alert\"\n class=\"rounded-full text-white p-[6px] w-[32px] h-[32px] flex shrink-0\"\n [ngClass]=\"{\n 'bg-red-500': type === 'error',\n 'bg-yellow-500': type === 'warning',\n 'bg-green-500': type === 'success',\n 'bg-blue-500': type === 'info'\n }\"\n [ngSwitch]=\"type\"\n >\n <mat-icon class=\"material-symbols-outlined !w-[18px] !h-[18px] text-[20px]\">\n <ng-container *ngSwitchCase=\"'success'\">check_circle</ng-container>\n <ng-container *ngSwitchCase=\"'info'\">info</ng-container>\n <ng-container *ngSwitchCase=\"'warning'\">warning</ng-container>\n <ng-container *ngSwitchCase=\"'error'\">error</ng-container>\n </mat-icon>\n </div>\n <div\n class=\"flex flex-col items-start gap-[4px] pt-[3px] grow shrink overflow-hidden\"\n >\n <div class=\"font-bold text-[16px] text-gray-900\">\n {{ title }}\n </div>\n <div class=\"text-[14px] text-gray-800\">\n {{ text }}\n </div>\n <a\n href\n *ngIf=\"closeMessage\"\n class=\"text-[14px] gn-ui-link\"\n (click)=\"handleClose($event)\"\n >\n {{ closeMessage }}\n </a>\n </div>\n <gn-ui-button\n type=\"light\"\n class=\"shrink-0\"\n (buttonClick)=\"handleClose()\"\n [style.--gn-ui-button-padding]=\"0\"\n [style.--gn-ui-button-width]=\"'21px'\"\n [style.--gn-ui-button-height]=\"'21px'\"\n >\n <mat-icon class=\"material-symbols-outlined text-[22px] !w-[21px] !h-[21px]\"\n >close</mat-icon\n >\n </gn-ui-button>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$3.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1$3.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
27732
+ }
27733
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: NotificationComponent, decorators: [{
27734
+ type: Component,
27735
+ args: [{ selector: 'gn-ui-notification', standalone: true, imports: [CommonModule, MatIconModule, ButtonComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"p-[16px] flex flex-row gap-[16px] items-start border border-gray-200 shadow-md rounded bg-background\"\n>\n <div\n role=\"alert\"\n class=\"rounded-full text-white p-[6px] w-[32px] h-[32px] flex shrink-0\"\n [ngClass]=\"{\n 'bg-red-500': type === 'error',\n 'bg-yellow-500': type === 'warning',\n 'bg-green-500': type === 'success',\n 'bg-blue-500': type === 'info'\n }\"\n [ngSwitch]=\"type\"\n >\n <mat-icon class=\"material-symbols-outlined !w-[18px] !h-[18px] text-[20px]\">\n <ng-container *ngSwitchCase=\"'success'\">check_circle</ng-container>\n <ng-container *ngSwitchCase=\"'info'\">info</ng-container>\n <ng-container *ngSwitchCase=\"'warning'\">warning</ng-container>\n <ng-container *ngSwitchCase=\"'error'\">error</ng-container>\n </mat-icon>\n </div>\n <div\n class=\"flex flex-col items-start gap-[4px] pt-[3px] grow shrink overflow-hidden\"\n >\n <div class=\"font-bold text-[16px] text-gray-900\">\n {{ title }}\n </div>\n <div class=\"text-[14px] text-gray-800\">\n {{ text }}\n </div>\n <a\n href\n *ngIf=\"closeMessage\"\n class=\"text-[14px] gn-ui-link\"\n (click)=\"handleClose($event)\"\n >\n {{ closeMessage }}\n </a>\n </div>\n <gn-ui-button\n type=\"light\"\n class=\"shrink-0\"\n (buttonClick)=\"handleClose()\"\n [style.--gn-ui-button-padding]=\"0\"\n [style.--gn-ui-button-width]=\"'21px'\"\n [style.--gn-ui-button-height]=\"'21px'\"\n >\n <mat-icon class=\"material-symbols-outlined text-[22px] !w-[21px] !h-[21px]\"\n >close</mat-icon\n >\n </gn-ui-button>\n</div>\n" }]
27736
+ }], propDecorators: { type: [{
27737
+ type: Input
27738
+ }], title: [{
27739
+ type: Input
27740
+ }], text: [{
27741
+ type: Input
27742
+ }], closeMessage: [{
27743
+ type: Input
27744
+ }], notificationClose: [{
27745
+ type: Output
27746
+ }] } });
27747
+
27425
27748
  class UiSearchModule {
27426
27749
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UiSearchModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
27427
27750
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.1.7", ngImport: i0, type: UiSearchModule, declarations: [RecordPreviewComponent,
@@ -29577,7 +29900,7 @@ class ResultsTableComponent {
29577
29900
  }));
29578
29901
  }
29579
29902
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ResultsTableComponent, deps: [{ token: SearchFacade }, { token: SearchService }, { token: SelectionService }], target: i0.ɵɵFactoryTarget.Component }); }
29580
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: ResultsTableComponent, isStandalone: true, selector: "gn-ui-results-table", outputs: { recordClick: "recordClick" }, ngImport: i0, template: "<gn-ui-interactive-table\n [items]=\"records$ | async\"\n (itemClick)=\"handleRecordClick($event)\"\n>\n <!-- SELECTED COLUMN -->\n <gn-ui-interactive-table-column>\n <ng-template #header>\n <gn-ui-checkbox\n [checked]=\"isAllSelected() | async\"\n [indeterminate]=\"isSomeSelected() | async\"\n (changed)=\"toggleSelectAll()\"\n type=\"default\"\n class=\"-m-2 mr-3\"\n >\n </gn-ui-checkbox>\n </ng-template>\n <ng-template #cell let-item>\n <gn-ui-checkbox\n [checked]=\"isChecked(item) | async\"\n (changed)=\"handleRecordSelectedChange($event, item)\"\n class=\"-m-2\"\n type=\"default\"\n ></gn-ui-checkbox>\n </ng-template>\n </gn-ui-interactive-table-column>\n\n <!-- TITLE COLUMN -->\n <gn-ui-interactive-table-column\n [sortable]=\"true\"\n [activeSort]=\"isSortedBy('resourceTitleObject.default.keyword') | async\"\n (sortChange)=\"setSortBy('resourceTitleObject.default.keyword', $event)\"\n >\n <ng-template #header>\n <span translate>record.metadata.title</span>\n </ng-template>\n <ng-template #cell let-item>\n {{ item.title }}\n </ng-template>\n </gn-ui-interactive-table-column>\n\n <!-- FORMATS COLUMN -->\n <gn-ui-interactive-table-column>\n <ng-template #header>\n <span translate>record.metadata.formats</span>\n </ng-template>\n <ng-template #cell let-item>\n <div\n class=\"flex justify-start items-center gap-2\"\n *ngIf=\"getRecordFormats(item) as formats\"\n [title]=\"formats.join(', ')\"\n >\n <span\n class=\"badge-btn min-w-[45px] text-sm text-white px-2 flex-shrink-0\"\n [style.background-color]=\"getBadgeColor(formats[0])\"\n *ngIf=\"formats[0]\"\n >\n {{ formats[0] }}\n </span>\n <span\n class=\"badge-btn min-w-[45px] text-sm text-white px-2 flex-shrink-0\"\n [style.background-color]=\"getBadgeColor(formats[1])\"\n *ngIf=\"formats[1]\"\n >\n {{ formats[1] }}\n </span>\n <div class=\"flex-shrink-0\" *ngIf=\"formats.slice(2).length > 0\">\n <span>+{{ formats.slice(2).length }}</span>\n </div>\n </div>\n <div *ngIf=\"!getRecordFormats(item)\"></div>\n </ng-template>\n </gn-ui-interactive-table-column>\n\n <!-- OWNER COLUMN -->\n <gn-ui-interactive-table-column\n [sortable]=\"true\"\n [activeSort]=\"isSortedBy('recordOwner') | async\"\n (sortChange)=\"setSortBy('recordOwner', $event)\"\n >\n <ng-template #header>\n <span translate>record.metadata.author</span>\n </ng-template>\n <ng-template #cell let-item>\n <mat-icon class=\"material-symbols-outlined\">person</mat-icon>\n <span>{{ formatUserInfo(item.extras?.ownerInfo) }}</span>\n </ng-template>\n </gn-ui-interactive-table-column>\n\n <!-- STATUS COLUMN -->\n <gn-ui-interactive-table-column>\n <ng-template #header>\n <span translate>record.metadata.status</span>\n </ng-template>\n <ng-template #cell let-item>\n {{ item.status }}\n </ng-template>\n </gn-ui-interactive-table-column>\n\n <!-- UPDATE DATE COLUMN -->\n <gn-ui-interactive-table-column\n [sortable]=\"true\"\n [activeSort]=\"isSortedBy('changeDate') | async\"\n (sortChange)=\"setSortBy('changeDate', $event)\"\n >\n <ng-template #header>\n <span translate>record.metadata.updatedOn</span>\n </ng-template>\n <ng-template #cell let-item>\n {{ dateToString(item.recordUpdated) }}\n </ng-template>\n </gn-ui-interactive-table-column>\n</gn-ui-interactive-table>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1$3.AsyncPipe, name: "async" }, { kind: "ngmodule", type: UiInputsModule }, { kind: "component", type: CheckboxComponent, selector: "gn-ui-checkbox", inputs: ["type", "checked", "indeterminate"], outputs: ["changed"] }, { kind: "component", type: InteractiveTableComponent, selector: "gn-ui-interactive-table", inputs: ["items"], outputs: ["itemClick"] }, { kind: "component", type: InteractiveTableColumnComponent, selector: "gn-ui-interactive-table-column", inputs: ["grow", "sortable", "activeSort"], outputs: ["sortChange"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }] }); }
29903
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: ResultsTableComponent, isStandalone: true, selector: "gn-ui-results-table", outputs: { recordClick: "recordClick" }, ngImport: i0, template: "<gn-ui-interactive-table\n [items]=\"records$ | async\"\n (itemClick)=\"handleRecordClick($event)\"\n>\n <!-- SELECTED COLUMN -->\n <gn-ui-interactive-table-column>\n <ng-template #header>\n <gn-ui-checkbox\n [checked]=\"isAllSelected() | async\"\n [indeterminate]=\"isSomeSelected() | async\"\n (changed)=\"toggleSelectAll()\"\n type=\"default\"\n class=\"-m-2 mr-3\"\n >\n </gn-ui-checkbox>\n </ng-template>\n <ng-template #cell let-item>\n <gn-ui-checkbox\n [checked]=\"isChecked(item) | async\"\n (changed)=\"handleRecordSelectedChange($event, item)\"\n class=\"-m-2\"\n type=\"default\"\n ></gn-ui-checkbox>\n </ng-template>\n </gn-ui-interactive-table-column>\n\n <!-- TITLE COLUMN -->\n <gn-ui-interactive-table-column\n [sortable]=\"true\"\n [activeSort]=\"isSortedBy('resourceTitleObject.default.keyword') | async\"\n (sortChange)=\"setSortBy('resourceTitleObject.default.keyword', $event)\"\n >\n <ng-template #header>\n <span translate>record.metadata.title</span>\n </ng-template>\n <ng-template #cell let-item>\n {{ item.title }}\n </ng-template>\n </gn-ui-interactive-table-column>\n\n <!-- FORMATS COLUMN -->\n <gn-ui-interactive-table-column>\n <ng-template #header>\n <span translate>record.metadata.formats</span>\n </ng-template>\n <ng-template #cell let-item>\n <div\n class=\"flex justify-start items-center gap-2\"\n *ngIf=\"getRecordFormats(item) as formats\"\n [title]=\"formats.join(', ')\"\n >\n <span\n class=\"badge-btn min-w-[45px] text-sm text-white px-2 shrink-0\"\n [style.background-color]=\"getBadgeColor(formats[0])\"\n *ngIf=\"formats[0]\"\n >\n {{ formats[0] }}\n </span>\n <span\n class=\"badge-btn min-w-[45px] text-sm text-white px-2 shrink-0\"\n [style.background-color]=\"getBadgeColor(formats[1])\"\n *ngIf=\"formats[1]\"\n >\n {{ formats[1] }}\n </span>\n <div class=\"shrink-0\" *ngIf=\"formats.slice(2).length > 0\">\n <span>+{{ formats.slice(2).length }}</span>\n </div>\n </div>\n <div *ngIf=\"!getRecordFormats(item)\"></div>\n </ng-template>\n </gn-ui-interactive-table-column>\n\n <!-- OWNER COLUMN -->\n <gn-ui-interactive-table-column\n [sortable]=\"true\"\n [activeSort]=\"isSortedBy('recordOwner') | async\"\n (sortChange)=\"setSortBy('recordOwner', $event)\"\n >\n <ng-template #header>\n <span translate>record.metadata.author</span>\n </ng-template>\n <ng-template #cell let-item>\n <mat-icon class=\"material-symbols-outlined\">person</mat-icon>\n <span>{{ formatUserInfo(item.extras?.ownerInfo) }}</span>\n </ng-template>\n </gn-ui-interactive-table-column>\n\n <!-- STATUS COLUMN -->\n <gn-ui-interactive-table-column>\n <ng-template #header>\n <span translate>record.metadata.status</span>\n </ng-template>\n <ng-template #cell let-item>\n {{ item.status }}\n </ng-template>\n </gn-ui-interactive-table-column>\n\n <!-- UPDATE DATE COLUMN -->\n <gn-ui-interactive-table-column\n [sortable]=\"true\"\n [activeSort]=\"isSortedBy('changeDate') | async\"\n (sortChange)=\"setSortBy('changeDate', $event)\"\n >\n <ng-template #header>\n <span translate>record.metadata.updatedOn</span>\n </ng-template>\n <ng-template #cell let-item>\n {{ dateToString(item.recordUpdated) }}\n </ng-template>\n </gn-ui-interactive-table-column>\n</gn-ui-interactive-table>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1$3.AsyncPipe, name: "async" }, { kind: "ngmodule", type: UiInputsModule }, { kind: "component", type: CheckboxComponent, selector: "gn-ui-checkbox", inputs: ["type", "checked", "indeterminate"], outputs: ["changed"] }, { kind: "component", type: InteractiveTableComponent, selector: "gn-ui-interactive-table", inputs: ["items"], outputs: ["itemClick"] }, { kind: "component", type: InteractiveTableColumnComponent, selector: "gn-ui-interactive-table-column", inputs: ["grow", "sortable", "activeSort"], outputs: ["sortChange"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }] }); }
29581
29904
  }
29582
29905
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ResultsTableComponent, decorators: [{
29583
29906
  type: Component,
@@ -29588,7 +29911,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
29588
29911
  InteractiveTableColumnComponent,
29589
29912
  MatIconModule,
29590
29913
  TranslateModule,
29591
- ], template: "<gn-ui-interactive-table\n [items]=\"records$ | async\"\n (itemClick)=\"handleRecordClick($event)\"\n>\n <!-- SELECTED COLUMN -->\n <gn-ui-interactive-table-column>\n <ng-template #header>\n <gn-ui-checkbox\n [checked]=\"isAllSelected() | async\"\n [indeterminate]=\"isSomeSelected() | async\"\n (changed)=\"toggleSelectAll()\"\n type=\"default\"\n class=\"-m-2 mr-3\"\n >\n </gn-ui-checkbox>\n </ng-template>\n <ng-template #cell let-item>\n <gn-ui-checkbox\n [checked]=\"isChecked(item) | async\"\n (changed)=\"handleRecordSelectedChange($event, item)\"\n class=\"-m-2\"\n type=\"default\"\n ></gn-ui-checkbox>\n </ng-template>\n </gn-ui-interactive-table-column>\n\n <!-- TITLE COLUMN -->\n <gn-ui-interactive-table-column\n [sortable]=\"true\"\n [activeSort]=\"isSortedBy('resourceTitleObject.default.keyword') | async\"\n (sortChange)=\"setSortBy('resourceTitleObject.default.keyword', $event)\"\n >\n <ng-template #header>\n <span translate>record.metadata.title</span>\n </ng-template>\n <ng-template #cell let-item>\n {{ item.title }}\n </ng-template>\n </gn-ui-interactive-table-column>\n\n <!-- FORMATS COLUMN -->\n <gn-ui-interactive-table-column>\n <ng-template #header>\n <span translate>record.metadata.formats</span>\n </ng-template>\n <ng-template #cell let-item>\n <div\n class=\"flex justify-start items-center gap-2\"\n *ngIf=\"getRecordFormats(item) as formats\"\n [title]=\"formats.join(', ')\"\n >\n <span\n class=\"badge-btn min-w-[45px] text-sm text-white px-2 flex-shrink-0\"\n [style.background-color]=\"getBadgeColor(formats[0])\"\n *ngIf=\"formats[0]\"\n >\n {{ formats[0] }}\n </span>\n <span\n class=\"badge-btn min-w-[45px] text-sm text-white px-2 flex-shrink-0\"\n [style.background-color]=\"getBadgeColor(formats[1])\"\n *ngIf=\"formats[1]\"\n >\n {{ formats[1] }}\n </span>\n <div class=\"flex-shrink-0\" *ngIf=\"formats.slice(2).length > 0\">\n <span>+{{ formats.slice(2).length }}</span>\n </div>\n </div>\n <div *ngIf=\"!getRecordFormats(item)\"></div>\n </ng-template>\n </gn-ui-interactive-table-column>\n\n <!-- OWNER COLUMN -->\n <gn-ui-interactive-table-column\n [sortable]=\"true\"\n [activeSort]=\"isSortedBy('recordOwner') | async\"\n (sortChange)=\"setSortBy('recordOwner', $event)\"\n >\n <ng-template #header>\n <span translate>record.metadata.author</span>\n </ng-template>\n <ng-template #cell let-item>\n <mat-icon class=\"material-symbols-outlined\">person</mat-icon>\n <span>{{ formatUserInfo(item.extras?.ownerInfo) }}</span>\n </ng-template>\n </gn-ui-interactive-table-column>\n\n <!-- STATUS COLUMN -->\n <gn-ui-interactive-table-column>\n <ng-template #header>\n <span translate>record.metadata.status</span>\n </ng-template>\n <ng-template #cell let-item>\n {{ item.status }}\n </ng-template>\n </gn-ui-interactive-table-column>\n\n <!-- UPDATE DATE COLUMN -->\n <gn-ui-interactive-table-column\n [sortable]=\"true\"\n [activeSort]=\"isSortedBy('changeDate') | async\"\n (sortChange)=\"setSortBy('changeDate', $event)\"\n >\n <ng-template #header>\n <span translate>record.metadata.updatedOn</span>\n </ng-template>\n <ng-template #cell let-item>\n {{ dateToString(item.recordUpdated) }}\n </ng-template>\n </gn-ui-interactive-table-column>\n</gn-ui-interactive-table>\n" }]
29914
+ ], template: "<gn-ui-interactive-table\n [items]=\"records$ | async\"\n (itemClick)=\"handleRecordClick($event)\"\n>\n <!-- SELECTED COLUMN -->\n <gn-ui-interactive-table-column>\n <ng-template #header>\n <gn-ui-checkbox\n [checked]=\"isAllSelected() | async\"\n [indeterminate]=\"isSomeSelected() | async\"\n (changed)=\"toggleSelectAll()\"\n type=\"default\"\n class=\"-m-2 mr-3\"\n >\n </gn-ui-checkbox>\n </ng-template>\n <ng-template #cell let-item>\n <gn-ui-checkbox\n [checked]=\"isChecked(item) | async\"\n (changed)=\"handleRecordSelectedChange($event, item)\"\n class=\"-m-2\"\n type=\"default\"\n ></gn-ui-checkbox>\n </ng-template>\n </gn-ui-interactive-table-column>\n\n <!-- TITLE COLUMN -->\n <gn-ui-interactive-table-column\n [sortable]=\"true\"\n [activeSort]=\"isSortedBy('resourceTitleObject.default.keyword') | async\"\n (sortChange)=\"setSortBy('resourceTitleObject.default.keyword', $event)\"\n >\n <ng-template #header>\n <span translate>record.metadata.title</span>\n </ng-template>\n <ng-template #cell let-item>\n {{ item.title }}\n </ng-template>\n </gn-ui-interactive-table-column>\n\n <!-- FORMATS COLUMN -->\n <gn-ui-interactive-table-column>\n <ng-template #header>\n <span translate>record.metadata.formats</span>\n </ng-template>\n <ng-template #cell let-item>\n <div\n class=\"flex justify-start items-center gap-2\"\n *ngIf=\"getRecordFormats(item) as formats\"\n [title]=\"formats.join(', ')\"\n >\n <span\n class=\"badge-btn min-w-[45px] text-sm text-white px-2 shrink-0\"\n [style.background-color]=\"getBadgeColor(formats[0])\"\n *ngIf=\"formats[0]\"\n >\n {{ formats[0] }}\n </span>\n <span\n class=\"badge-btn min-w-[45px] text-sm text-white px-2 shrink-0\"\n [style.background-color]=\"getBadgeColor(formats[1])\"\n *ngIf=\"formats[1]\"\n >\n {{ formats[1] }}\n </span>\n <div class=\"shrink-0\" *ngIf=\"formats.slice(2).length > 0\">\n <span>+{{ formats.slice(2).length }}</span>\n </div>\n </div>\n <div *ngIf=\"!getRecordFormats(item)\"></div>\n </ng-template>\n </gn-ui-interactive-table-column>\n\n <!-- OWNER COLUMN -->\n <gn-ui-interactive-table-column\n [sortable]=\"true\"\n [activeSort]=\"isSortedBy('recordOwner') | async\"\n (sortChange)=\"setSortBy('recordOwner', $event)\"\n >\n <ng-template #header>\n <span translate>record.metadata.author</span>\n </ng-template>\n <ng-template #cell let-item>\n <mat-icon class=\"material-symbols-outlined\">person</mat-icon>\n <span>{{ formatUserInfo(item.extras?.ownerInfo) }}</span>\n </ng-template>\n </gn-ui-interactive-table-column>\n\n <!-- STATUS COLUMN -->\n <gn-ui-interactive-table-column>\n <ng-template #header>\n <span translate>record.metadata.status</span>\n </ng-template>\n <ng-template #cell let-item>\n {{ item.status }}\n </ng-template>\n </gn-ui-interactive-table-column>\n\n <!-- UPDATE DATE COLUMN -->\n <gn-ui-interactive-table-column\n [sortable]=\"true\"\n [activeSort]=\"isSortedBy('changeDate') | async\"\n (sortChange)=\"setSortBy('changeDate', $event)\"\n >\n <ng-template #header>\n <span translate>record.metadata.updatedOn</span>\n </ng-template>\n <ng-template #cell let-item>\n {{ dateToString(item.recordUpdated) }}\n </ng-template>\n </gn-ui-interactive-table-column>\n</gn-ui-interactive-table>\n" }]
29592
29915
  }], ctorParameters: function () { return [{ type: SearchFacade }, { type: SearchService }, { type: SelectionService }]; }, propDecorators: { recordClick: [{
29593
29916
  type: Output
29594
29917
  }] } });
@@ -29719,7 +30042,7 @@ class AddLayerFromWmsComponent {
29719
30042
  this.mapFacade.addLayer({ ...layerToAdd, title: layer.title });
29720
30043
  }
29721
30044
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: AddLayerFromWmsComponent, deps: [{ token: MapFacade }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
29722
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: AddLayerFromWmsComponent, selector: "gn-ui-add-layer-from-wms", ngImport: i0, template: "<div class=\"flex items-center mb-5\">\n <gn-ui-text-input\n [(value)]=\"wmsUrl\"\n (valueChange)=\"urlChange.next($event)\"\n [hint]=\"'map.wms.urlInput.hint' | translate\"\n class=\"w-96\"\n >\n </gn-ui-text-input>\n</div>\n\n<div *ngIf=\"errorMessage\" class=\"text-red-500 mt-2\">\n {{ errorMessage }}\n</div>\n\n<div *ngIf=\"loading\">\n <p class=\"loading-message\" translate>map.loading.service</p>\n</div>\n\n<div *ngIf=\"!loading && layers.length > 0\">\n <h2 class=\"font-bold\" translate>map.layers.available</h2>\n <ng-container\n *ngFor=\"let layer of layers\"\n [ngTemplateOutlet]=\"layerTreeItem\"\n [ngTemplateOutletContext]=\"{\n layer: layer\n }\"\n ></ng-container>\n</div>\n\n<ng-template #layerTreeItem let-layer=\"layer\">\n <div class=\"flex items-center justify-between layer-tree-item my-2\">\n <p class=\"max-w-xs overflow-hidden overflow-ellipsis whitespace-nowrap\">\n {{ layer.title }}\n </p>\n <gn-ui-button\n *ngIf=\"layer.name\"\n class=\"layer-add-btn\"\n type=\"primary\"\n (buttonClick)=\"addLayer(layer)\"\n extraClass=\"text-sm !px-2 !py-1\"\n translate\n ><span translate> map.layer.add </span></gn-ui-button\n >\n </div>\n <div *ngIf=\"layer.children?.length > 0\" class=\"ml-4\">\n <ng-container\n *ngFor=\"let child of layer.children\"\n [ngTemplateOutlet]=\"layerTreeItem\"\n [ngTemplateOutletContext]=\"{\n layer: child\n }\"\n >\n </ng-container>\n </div>\n</ng-template>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: TextInputComponent, selector: "gn-ui-text-input", inputs: ["value", "hint", "required"], outputs: ["valueChange"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] }); }
30045
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: AddLayerFromWmsComponent, selector: "gn-ui-add-layer-from-wms", ngImport: i0, template: "<div class=\"flex items-center mb-5\">\n <gn-ui-text-input\n [(value)]=\"wmsUrl\"\n (valueChange)=\"urlChange.next($event)\"\n [hint]=\"'map.wms.urlInput.hint' | translate\"\n class=\"w-96\"\n >\n </gn-ui-text-input>\n</div>\n\n<div *ngIf=\"errorMessage\" class=\"text-red-500 mt-2\">\n {{ errorMessage }}\n</div>\n\n<div *ngIf=\"loading\">\n <p class=\"loading-message\" translate>map.loading.service</p>\n</div>\n\n<div *ngIf=\"!loading && layers.length > 0\">\n <h2 class=\"font-bold\" translate>map.layers.available</h2>\n <ng-container\n *ngFor=\"let layer of layers\"\n [ngTemplateOutlet]=\"layerTreeItem\"\n [ngTemplateOutletContext]=\"{\n layer: layer\n }\"\n ></ng-container>\n</div>\n\n<ng-template #layerTreeItem let-layer=\"layer\">\n <div class=\"flex items-center justify-between layer-tree-item my-2\">\n <p class=\"max-w-xs overflow-hidden overflow-ellipsis whitespace-nowrap\">\n {{ layer.title }}\n </p>\n <gn-ui-button\n *ngIf=\"layer.name\"\n class=\"layer-add-btn\"\n type=\"primary\"\n (buttonClick)=\"addLayer(layer)\"\n extraClass=\"text-sm !px-2 !py-1\"\n translate\n ><span translate> map.layer.add </span></gn-ui-button\n >\n </div>\n <div *ngIf=\"layer.children?.length > 0\" class=\"ml-4\">\n <ng-container\n *ngFor=\"let child of layer.children\"\n [ngTemplateOutlet]=\"layerTreeItem\"\n [ngTemplateOutletContext]=\"{\n layer: child\n }\"\n >\n </ng-container>\n </div>\n</ng-template>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: TextInputComponent, selector: "gn-ui-text-input", inputs: ["value", "extraClass", "hint", "required"], outputs: ["valueChange"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] }); }
29723
30046
  }
29724
30047
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: AddLayerFromWmsComponent, decorators: [{
29725
30048
  type: Component,
@@ -29818,11 +30141,11 @@ class AddLayerFromFileComponent {
29818
30141
  }, 5000);
29819
30142
  }
29820
30143
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: AddLayerFromFileComponent, deps: [{ token: MapFacade }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
29821
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: AddLayerFromFileComponent, selector: "gn-ui-add-layer-from-file", ngImport: i0, template: "<div class=\"flex flex-col gap-2 my-2\">\n <div class=\"flex items-center gap-4\">\n <div class=\"flex-grow rounded-md border-2 border-gray-200\">\n <gn-ui-drag-and-drop-file-input\n (fileChange)=\"handleFileChange($event)\"\n [accept]=\"acceptedMimeType.join(',')\"\n [placeholder]=\"'map.addFromFile.placeholder' | translate\"\n class=\"placeholder-grey\"\n ></gn-ui-drag-and-drop-file-input>\n </div>\n </div>\n <p class=\"text-sm text-gray-600\" translate>map.help.addFromFile</p>\n</div>\n\n<div *ngIf=\"errorMessage\" class=\"text-red-500 mt-2\">\n {{ errorMessage }}\n</div>\n\n<div *ngIf=\"successMessage\" class=\"text-green-500 mt-2\">\n {{ successMessage }}\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: DragAndDropFileInputComponent, selector: "gn-ui-drag-and-drop-file-input", inputs: ["placeholder", "accept"], outputs: ["fileChange"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] }); }
30144
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: AddLayerFromFileComponent, selector: "gn-ui-add-layer-from-file", ngImport: i0, template: "<div class=\"flex flex-col gap-2 my-2\">\n <div class=\"flex items-center gap-4\">\n <div class=\"grow rounded-md border-2 border-gray-200\">\n <gn-ui-drag-and-drop-file-input\n (fileChange)=\"handleFileChange($event)\"\n [accept]=\"acceptedMimeType.join(',')\"\n [placeholder]=\"'map.addFromFile.placeholder' | translate\"\n class=\"placeholder-grey\"\n ></gn-ui-drag-and-drop-file-input>\n </div>\n </div>\n <p class=\"text-sm text-gray-600\" translate>map.help.addFromFile</p>\n</div>\n\n<div *ngIf=\"errorMessage\" class=\"text-red-500 mt-2\">\n {{ errorMessage }}\n</div>\n\n<div *ngIf=\"successMessage\" class=\"text-green-500 mt-2\">\n {{ successMessage }}\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: DragAndDropFileInputComponent, selector: "gn-ui-drag-and-drop-file-input", inputs: ["placeholder", "accept"], outputs: ["fileChange"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] }); }
29822
30145
  }
29823
30146
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: AddLayerFromFileComponent, decorators: [{
29824
30147
  type: Component,
29825
- args: [{ selector: 'gn-ui-add-layer-from-file', template: "<div class=\"flex flex-col gap-2 my-2\">\n <div class=\"flex items-center gap-4\">\n <div class=\"flex-grow rounded-md border-2 border-gray-200\">\n <gn-ui-drag-and-drop-file-input\n (fileChange)=\"handleFileChange($event)\"\n [accept]=\"acceptedMimeType.join(',')\"\n [placeholder]=\"'map.addFromFile.placeholder' | translate\"\n class=\"placeholder-grey\"\n ></gn-ui-drag-and-drop-file-input>\n </div>\n </div>\n <p class=\"text-sm text-gray-600\" translate>map.help.addFromFile</p>\n</div>\n\n<div *ngIf=\"errorMessage\" class=\"text-red-500 mt-2\">\n {{ errorMessage }}\n</div>\n\n<div *ngIf=\"successMessage\" class=\"text-green-500 mt-2\">\n {{ successMessage }}\n</div>\n" }]
30148
+ args: [{ selector: 'gn-ui-add-layer-from-file', template: "<div class=\"flex flex-col gap-2 my-2\">\n <div class=\"flex items-center gap-4\">\n <div class=\"grow rounded-md border-2 border-gray-200\">\n <gn-ui-drag-and-drop-file-input\n (fileChange)=\"handleFileChange($event)\"\n [accept]=\"acceptedMimeType.join(',')\"\n [placeholder]=\"'map.addFromFile.placeholder' | translate\"\n class=\"placeholder-grey\"\n ></gn-ui-drag-and-drop-file-input>\n </div>\n </div>\n <p class=\"text-sm text-gray-600\" translate>map.help.addFromFile</p>\n</div>\n\n<div *ngIf=\"errorMessage\" class=\"text-red-500 mt-2\">\n {{ errorMessage }}\n</div>\n\n<div *ngIf=\"successMessage\" class=\"text-green-500 mt-2\">\n {{ successMessage }}\n</div>\n" }]
29826
30149
  }], ctorParameters: function () { return [{ type: MapFacade }, { type: i0.ChangeDetectorRef }]; } });
29827
30150
 
29828
30151
  class AddLayerFromWfsComponent {
@@ -29870,7 +30193,7 @@ class AddLayerFromWfsComponent {
29870
30193
  this.mapFacade.addLayer({ ...layerToAdd, title: layer.title });
29871
30194
  }
29872
30195
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: AddLayerFromWfsComponent, deps: [{ token: MapFacade }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
29873
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: AddLayerFromWfsComponent, selector: "gn-ui-add-layer-from-wfs", ngImport: i0, template: "<div class=\"flex items-center mb-5\">\n <gn-ui-text-input\n [(value)]=\"wfsUrl\"\n (valueChange)=\"urlChange.next($event)\"\n [hint]=\"'map.wfs.urlInput.hint' | translate\"\n class=\"w-96\"\n >\n </gn-ui-text-input>\n</div>\n\n<div *ngIf=\"errorMessage\" class=\"text-red-500 mt-2\">\n {{ errorMessage }}\n</div>\n\n<div *ngIf=\"loading\">\n <p class=\"loading-message\" translate>map.loading.service</p>\n</div>\n\n<div *ngIf=\"!loading && layers.length > 0\">\n <h2 class=\"font-bold\" translate>map.layers.available</h2>\n <ng-container *ngFor=\"let layer of layers\">\n <div class=\"flex items-center justify-between my-2 layer-item-tree\">\n <p class=\"max-w-xs overflow-hidden overflow-ellipsis whitespace-nowrap\">\n {{ layer.title }}\n </p>\n <gn-ui-button\n *ngIf=\"layer.name\"\n class=\"layer-add-btn\"\n type=\"primary\"\n (buttonClick)=\"addLayer(layer)\"\n extraClass=\"text-sm !px-2 !py-1\"\n translate\n ><span translate> map.layer.add </span></gn-ui-button\n >\n </div>\n </ng-container>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: TextInputComponent, selector: "gn-ui-text-input", inputs: ["value", "hint", "required"], outputs: ["valueChange"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] }); }
30196
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: AddLayerFromWfsComponent, selector: "gn-ui-add-layer-from-wfs", ngImport: i0, template: "<div class=\"flex items-center mb-5\">\n <gn-ui-text-input\n [(value)]=\"wfsUrl\"\n (valueChange)=\"urlChange.next($event)\"\n [hint]=\"'map.wfs.urlInput.hint' | translate\"\n class=\"w-96\"\n >\n </gn-ui-text-input>\n</div>\n\n<div *ngIf=\"errorMessage\" class=\"text-red-500 mt-2\">\n {{ errorMessage }}\n</div>\n\n<div *ngIf=\"loading\">\n <p class=\"loading-message\" translate>map.loading.service</p>\n</div>\n\n<div *ngIf=\"!loading && layers.length > 0\">\n <h2 class=\"font-bold\" translate>map.layers.available</h2>\n <ng-container *ngFor=\"let layer of layers\">\n <div class=\"flex items-center justify-between my-2 layer-item-tree\">\n <p class=\"max-w-xs overflow-hidden overflow-ellipsis whitespace-nowrap\">\n {{ layer.title }}\n </p>\n <gn-ui-button\n *ngIf=\"layer.name\"\n class=\"layer-add-btn\"\n type=\"primary\"\n (buttonClick)=\"addLayer(layer)\"\n extraClass=\"text-sm !px-2 !py-1\"\n translate\n ><span translate> map.layer.add </span></gn-ui-button\n >\n </div>\n </ng-container>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: TextInputComponent, selector: "gn-ui-text-input", inputs: ["value", "extraClass", "hint", "required"], outputs: ["valueChange"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] }); }
29874
30197
  }
29875
30198
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: AddLayerFromWfsComponent, decorators: [{
29876
30199
  type: Component,
@@ -30183,31 +30506,143 @@ const DEFAULT_STYLE_HL_FIXTURE = new Style$1({
30183
30506
  }),
30184
30507
  });
30185
30508
 
30509
+ class NotificationsService {
30510
+ constructor() {
30511
+ this.notifications$ = new BehaviorSubject([]);
30512
+ }
30513
+ showNotification(content, timeoutMs) {
30514
+ const id = Math.floor(Math.random() * 1000000);
30515
+ this.notifications$.next([...this.notifications$.value, { ...content, id }]);
30516
+ if (typeof timeoutMs === 'undefined')
30517
+ return;
30518
+ setTimeout(() => {
30519
+ this.removeNotificationById(id);
30520
+ }, timeoutMs);
30521
+ }
30522
+ removeNotificationById(id) {
30523
+ this.notifications$.next(this.notifications$.value.filter((n) => n.id !== id));
30524
+ }
30525
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: NotificationsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
30526
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: NotificationsService, providedIn: 'root' }); }
30527
+ }
30528
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: NotificationsService, decorators: [{
30529
+ type: Injectable,
30530
+ args: [{
30531
+ providedIn: 'root',
30532
+ }]
30533
+ }] });
30534
+
30535
+ class FeatureNotificationsModule {
30536
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FeatureNotificationsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
30537
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.1.7", ngImport: i0, type: FeatureNotificationsModule }); }
30538
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FeatureNotificationsModule, providers: [NotificationsService] }); }
30539
+ }
30540
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FeatureNotificationsModule, decorators: [{
30541
+ type: NgModule,
30542
+ args: [{
30543
+ declarations: [],
30544
+ exports: [],
30545
+ imports: [],
30546
+ providers: [NotificationsService],
30547
+ }]
30548
+ }] });
30549
+
30550
+ class NotificationsContainerComponent {
30551
+ constructor(notificationsService) {
30552
+ this.notificationsService = notificationsService;
30553
+ }
30554
+ trackById(index, notification) {
30555
+ return notification.id;
30556
+ }
30557
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: NotificationsContainerComponent, deps: [{ token: NotificationsService }], target: i0.ɵɵFactoryTarget.Component }); }
30558
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: NotificationsContainerComponent, isStandalone: true, selector: "gn-ui-notifications-container", ngImport: i0, template: "<div class=\"flex flex-col gap-6 p-6 items-start pointer-events-none\">\n <gn-ui-notification\n *ngFor=\"\n let notification of notificationsService.notifications$ | async;\n trackBy: trackById\n \"\n class=\"max-w-full pointer-events-auto\"\n [text]=\"notification.text\"\n [type]=\"notification.type\"\n [title]=\"notification.title\"\n [closeMessage]=\"notification.closeMessage\"\n (notificationClose)=\"\n notificationsService.removeNotificationById(notification.id)\n \"\n [@enterExit]\n ></gn-ui-notification>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "pipe", type: i1$3.AsyncPipe, name: "async" }, { kind: "component", type: NotificationComponent, selector: "gn-ui-notification", inputs: ["type", "title", "text", "closeMessage"], outputs: ["notificationClose"] }], animations: [
30559
+ trigger('enterExit', [
30560
+ transition(':enter', [
30561
+ animate('150ms', keyframes([
30562
+ style({ transform: 'scale(1)', opacity: 0 }),
30563
+ style({ transform: 'scale(1.03)', opacity: 0.5 }),
30564
+ style({ transform: 'scale(1)', opacity: 1 }),
30565
+ ])),
30566
+ ]),
30567
+ transition(':leave', [
30568
+ animate('200ms', style({ transform: 'translateX(50px)', opacity: 0 })),
30569
+ ]),
30570
+ ]),
30571
+ ], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
30572
+ }
30573
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: NotificationsContainerComponent, decorators: [{
30574
+ type: Component,
30575
+ args: [{ selector: 'gn-ui-notifications-container', standalone: true, imports: [CommonModule, NotificationComponent], changeDetection: ChangeDetectionStrategy.OnPush, animations: [
30576
+ trigger('enterExit', [
30577
+ transition(':enter', [
30578
+ animate('150ms', keyframes([
30579
+ style({ transform: 'scale(1)', opacity: 0 }),
30580
+ style({ transform: 'scale(1.03)', opacity: 0.5 }),
30581
+ style({ transform: 'scale(1)', opacity: 1 }),
30582
+ ])),
30583
+ ]),
30584
+ transition(':leave', [
30585
+ animate('200ms', style({ transform: 'translateX(50px)', opacity: 0 })),
30586
+ ]),
30587
+ ]),
30588
+ ], template: "<div class=\"flex flex-col gap-6 p-6 items-start pointer-events-none\">\n <gn-ui-notification\n *ngFor=\"\n let notification of notificationsService.notifications$ | async;\n trackBy: trackById\n \"\n class=\"max-w-full pointer-events-auto\"\n [text]=\"notification.text\"\n [type]=\"notification.type\"\n [title]=\"notification.title\"\n [closeMessage]=\"notification.closeMessage\"\n (notificationClose)=\"\n notificationsService.removeNotificationById(notification.id)\n \"\n [@enterExit]\n ></gn-ui-notification>\n</div>\n" }]
30589
+ }], ctorParameters: function () { return [{ type: NotificationsService }]; } });
30590
+
30591
+ /*
30592
+ Metadata actions
30593
+ */
30186
30594
  const loadFullMetadata = createAction('[Metadata view] Load full metadata', props());
30187
30595
  const setIncompleteMetadata = createAction('[Metadata view] Set incomplete metadata', props());
30188
- const loadFullSuccess = createAction('[Metadata view] Load full success', props());
30189
- const loadFullFailure = createAction('[Metadata view] Load full failure', props());
30596
+ const loadFullMetadataSuccess = createAction('[Metadata view] Load full metadata success', props());
30597
+ const loadFullMetadataFailure = createAction('[Metadata view] Load full metadata failure', props());
30598
+ const closeMetadata = createAction('[Metadata view] close');
30599
+ /*
30600
+ Related actions
30601
+ */
30190
30602
  const setRelated = createAction('[Metadata view] Set related records', props());
30603
+ /*
30604
+ ChartConfig actions
30605
+ */
30191
30606
  const setChartConfig = createAction('[Metadata view] Set chart config', props());
30192
- const close = createAction('[Metadata view] close');
30607
+ /*
30608
+ User Feedbacks actions
30609
+ */
30610
+ const addUserFeedback = createAction('[Metadata view] Add UserFeedback', props());
30611
+ const addUserFeedbackSuccess = createAction('[Metadata view] Add UserFeedback Success', props());
30612
+ const addUserFeedbackFailure = createAction('[Metadata view] Add UserFeedback Failure', props());
30613
+ const loadUserFeedbacks = createAction('[Metadata view] Load UserFeedbacks', props());
30614
+ const loadUserFeedbacksSuccess = createAction('[Metadata view] Load UserFeedbacks Success', props());
30615
+ const loadUserFeedbacksFailure = createAction('[Metadata view] Load UserFeedbacks Failure', props());
30193
30616
 
30194
30617
  var mdview_actions = /*#__PURE__*/Object.freeze({
30195
30618
  __proto__: null,
30196
- close: close,
30197
- loadFullFailure: loadFullFailure,
30619
+ addUserFeedback: addUserFeedback,
30620
+ addUserFeedbackFailure: addUserFeedbackFailure,
30621
+ addUserFeedbackSuccess: addUserFeedbackSuccess,
30622
+ closeMetadata: closeMetadata,
30198
30623
  loadFullMetadata: loadFullMetadata,
30199
- loadFullSuccess: loadFullSuccess,
30624
+ loadFullMetadataFailure: loadFullMetadataFailure,
30625
+ loadFullMetadataSuccess: loadFullMetadataSuccess,
30626
+ loadUserFeedbacks: loadUserFeedbacks,
30627
+ loadUserFeedbacksFailure: loadUserFeedbacksFailure,
30628
+ loadUserFeedbacksSuccess: loadUserFeedbacksSuccess,
30200
30629
  setChartConfig: setChartConfig,
30201
30630
  setIncompleteMetadata: setIncompleteMetadata,
30202
30631
  setRelated: setRelated
30203
30632
  });
30204
30633
 
30205
- const MD_VIEW_FEATURE_STATE_KEY = 'mdView';
30206
- const initialMdviewState = {
30634
+ const METADATA_VIEW_FEATURE_STATE_KEY = 'metadataView';
30635
+ const initialMetadataViewState = {
30207
30636
  error: null,
30208
30637
  loadingFull: false,
30638
+ allUserFeedbacksLoading: false,
30639
+ addUserFeedbackLoading: false,
30209
30640
  };
30210
- const mdViewReducer = createReducer(initialMdviewState, on(loadFullMetadata, (state) => ({
30641
+ const metadataViewReducer = createReducer(initialMetadataViewState,
30642
+ /*
30643
+ Metadata reducers
30644
+ */
30645
+ on(loadFullMetadata, (state) => ({
30211
30646
  ...state,
30212
30647
  error: null,
30213
30648
  loadingFull: true,
@@ -30215,38 +30650,82 @@ const mdViewReducer = createReducer(initialMdviewState, on(loadFullMetadata, (st
30215
30650
  ...state,
30216
30651
  error: null,
30217
30652
  metadata: incomplete,
30218
- })), on(loadFullSuccess, (state, { full }) => ({
30653
+ })), on(loadFullMetadataSuccess, (state, { full }) => ({
30219
30654
  ...state,
30220
30655
  error: null,
30221
30656
  metadata: full,
30222
30657
  loadingFull: false,
30223
- })), on(loadFullFailure, (state, { otherError, notFound }) => ({
30658
+ })), on(loadFullMetadataFailure, (state, { otherError, notFound }) => ({
30224
30659
  ...state,
30225
30660
  error: { otherError, notFound },
30226
30661
  loadingFull: false,
30227
- })), on(setRelated, (state, { related }) => ({
30662
+ })), on(closeMetadata, (state) => {
30663
+ const { metadata, related, userFeedbacks, ...stateWithoutMetadata } = state;
30664
+ return stateWithoutMetadata;
30665
+ }),
30666
+ /*
30667
+ Related reducers
30668
+ */
30669
+ on(setRelated, (state, { related }) => ({
30228
30670
  ...state,
30229
30671
  related,
30230
- })), on(setChartConfig, (state, { chartConfig }) => ({
30672
+ })),
30673
+ /*
30674
+ ChartConfig reducers
30675
+ */
30676
+ on(setChartConfig, (state, { chartConfig }) => ({
30231
30677
  ...state,
30232
30678
  chartConfig,
30233
- })), on(close, (state) => {
30234
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
30235
- const { metadata, related, ...stateWithoutMd } = state;
30236
- return stateWithoutMd;
30237
- }));
30238
- function reducer$1(state, action) {
30239
- return mdViewReducer(state, action);
30679
+ })),
30680
+ /*
30681
+ UserFeedbacks reducers
30682
+ */
30683
+ on(loadUserFeedbacks, (state) => ({
30684
+ ...state,
30685
+ error: null,
30686
+ allUserFeedbacksLoading: true,
30687
+ })), on(addUserFeedback, (state) => ({
30688
+ ...state,
30689
+ addUserFeedbackLoading: true,
30690
+ })), on(loadUserFeedbacksSuccess, (state, { userFeedbacks }) => ({
30691
+ ...state,
30692
+ error: null,
30693
+ userFeedbacks: userFeedbacks,
30694
+ addUserFeedbackLoading: false,
30695
+ allUserFeedbacksLoading: false,
30696
+ })), on(loadUserFeedbacksFailure, (state, { otherError, notFound }) => ({
30697
+ ...state,
30698
+ error: { otherError, notFound },
30699
+ addUserFeedbackLoading: false,
30700
+ allUserFeedbacksLoading: false,
30701
+ })));
30702
+ function reducer$1(metadataViewState, action) {
30703
+ return metadataViewReducer(metadataViewState, action);
30240
30704
  }
30241
30705
 
30242
- const getMdViewState = createFeatureSelector(MD_VIEW_FEATURE_STATE_KEY);
30706
+ const getMdViewState = createFeatureSelector(METADATA_VIEW_FEATURE_STATE_KEY);
30707
+ /*
30708
+ Metadata selectors
30709
+ */
30243
30710
  const getMetadataUuid = createSelector(getMdViewState, (state) => state.metadata ? state.metadata.uniqueIdentifier : null);
30244
30711
  const getMetadata = createSelector(getMdViewState, (state) => state.metadata);
30245
30712
  const getMetadataIsIncomplete = createSelector(getMdViewState, (state) => (state.metadata ? state.loadingFull : null));
30246
30713
  const getMetadataIsLoading = createSelector(getMdViewState, (state) => state.loadingFull);
30247
30714
  const getMetadataError = createSelector(getMdViewState, (state) => state.error);
30715
+ /*
30716
+ Related selectors
30717
+ */
30248
30718
  const getRelated = createSelector(getMdViewState, (state) => state.related);
30719
+ /*
30720
+ Metadata selectors
30721
+ */
30249
30722
  const getChartConfig = createSelector(getMdViewState, (state) => state.chartConfig);
30723
+ /*
30724
+ UserFeedback selectors
30725
+ */
30726
+ const getUserFeedbacks = createSelector(getMdViewState, (state) => state.userFeedbacks);
30727
+ const getAllUserFeedbacksLoading = createSelector(getMdViewState, (state) => state.allUserFeedbacksLoading);
30728
+ const getAddUserFeedbacksLoading = createSelector(getMdViewState, (state) => state.addUserFeedbackLoading);
30250
30729
 
30251
30730
  /**
30252
30731
  * The Metadata View Facade is used to render complete metadata records.
@@ -30255,11 +30734,12 @@ const getChartConfig = createSelector(getMdViewState, (state) => state.chartConf
30255
30734
  * To clear the current record use the `close()` method.
30256
30735
  */
30257
30736
  class MdViewFacade {
30258
- constructor(store, linkClassifier) {
30737
+ constructor(store, linkClassifier, avatarService) {
30259
30738
  this.store = store;
30260
30739
  this.linkClassifier = linkClassifier;
30740
+ this.avatarService = avatarService;
30261
30741
  this.isPresent$ = this.store.pipe(select(getMetadataUuid), map$1((uuid) => !!uuid));
30262
- this.isLoading$ = this.store.pipe(select(getMetadataIsLoading));
30742
+ this.isMetadataLoading$ = this.store.pipe(select(getMetadataIsLoading));
30263
30743
  this.metadata$ = this.store.pipe(select(getMetadata), filter((md) => !!md));
30264
30744
  this.isIncomplete$ = this.store.pipe(select(getMetadataIsIncomplete), filter((incomplete) => incomplete !== null));
30265
30745
  this.error$ = this.store.pipe(select(getMetadataError));
@@ -30273,6 +30753,9 @@ class MdViewFacade {
30273
30753
  this.geoDataLinks$ = this.allLinks$.pipe(map$1((links) => links.filter((link) => this.linkClassifier.hasUsage(link, LinkUsage.GEODATA))));
30274
30754
  this.landingPageLinks$ = this.metadata$.pipe(map$1((record) => ('landingPage' in record ? [record.landingPage] : [])));
30275
30755
  this.otherLinks$ = this.allLinks$.pipe(map$1((links) => links.filter((link) => this.linkClassifier.hasUsage(link, LinkUsage.UNKNOWN))));
30756
+ this.userFeedbacks$ = this.store.pipe(select(getUserFeedbacks));
30757
+ this.isAllUserFeedbackLoading$ = this.store.pipe(select(getAllUserFeedbacksLoading));
30758
+ this.isAddUserFeedbackLoading$ = this.store.pipe(select(getAddUserFeedbacksLoading));
30276
30759
  }
30277
30760
  /**
30278
30761
  * This will show an incomplete record (e.g. from a search result) as a preview
@@ -30287,39 +30770,73 @@ class MdViewFacade {
30287
30770
  loadFull(uuid) {
30288
30771
  this.store.dispatch(loadFullMetadata({ uuid }));
30289
30772
  }
30290
- close() {
30291
- this.store.dispatch(close());
30773
+ closeMetadata() {
30774
+ this.store.dispatch(closeMetadata());
30292
30775
  }
30293
30776
  setChartConfig(chartConfig) {
30294
30777
  this.store.dispatch(setChartConfig({ chartConfig }));
30295
30778
  }
30296
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MdViewFacade, deps: [{ token: i1$2.Store }, { token: LinkClassifierService }], target: i0.ɵɵFactoryTarget.Injectable }); }
30779
+ /**
30780
+ * UserFeedbacks
30781
+ */
30782
+ addUserFeedback(userFeedback) {
30783
+ this.store.dispatch(addUserFeedback({ userFeedback }));
30784
+ }
30785
+ loadUserFeedbacks(datasetUuid) {
30786
+ this.store.dispatch(loadUserFeedbacks({ datasetUuid }));
30787
+ }
30788
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MdViewFacade, deps: [{ token: i1$2.Store }, { token: LinkClassifierService }, { token: AvatarServiceInterface }], target: i0.ɵɵFactoryTarget.Injectable }); }
30297
30789
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MdViewFacade }); }
30298
30790
  }
30299
30791
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MdViewFacade, decorators: [{
30300
30792
  type: Injectable
30301
- }], ctorParameters: function () { return [{ type: i1$2.Store }, { type: LinkClassifierService }]; } });
30793
+ }], ctorParameters: function () { return [{ type: i1$2.Store }, { type: LinkClassifierService }, { type: AvatarServiceInterface }]; } });
30302
30794
 
30303
30795
  class MdViewEffects {
30304
- constructor(actions$, recordsRepository) {
30796
+ constructor(actions$, recordsRepository, platformServiceInterface) {
30305
30797
  this.actions$ = actions$;
30306
30798
  this.recordsRepository = recordsRepository;
30307
- this.loadFull$ = createEffect(() => this.actions$.pipe(ofType(loadFullMetadata), switchMap$1(({ uuid }) => this.recordsRepository.getByUniqueIdentifier(uuid)), map$1((record) => {
30799
+ this.platformServiceInterface = platformServiceInterface;
30800
+ /*
30801
+ Metadata effects
30802
+ */
30803
+ this.loadFullMetadata$ = createEffect(() => this.actions$.pipe(ofType(loadFullMetadata), switchMap$1(({ uuid }) => this.recordsRepository.getByUniqueIdentifier(uuid)), map$1((record) => {
30308
30804
  if (record === null) {
30309
- return loadFullFailure({ notFound: true });
30805
+ return loadFullMetadataFailure({ notFound: true });
30310
30806
  }
30311
- return loadFullSuccess({ full: record });
30312
- }), catchError((error) => of(loadFullFailure({ otherError: error.message })))));
30313
- this.loadRelatedRecords$ = createEffect(() => this.actions$.pipe(ofType(loadFullSuccess), switchMap$1(({ full }) => this.recordsRepository.getSimilarRecords(full)), map$1((related) => {
30807
+ return loadFullMetadataSuccess({ full: record });
30808
+ }), catchError((error) => of(loadFullMetadataFailure({ otherError: error.message })))));
30809
+ /*
30810
+ Related effects
30811
+ */
30812
+ this.loadRelatedRecords$ = createEffect(() => this.actions$.pipe(ofType(loadFullMetadataSuccess), switchMap$1(({ full }) => this.recordsRepository.getSimilarRecords(full)), map$1((related) => {
30314
30813
  return setRelated({ related });
30315
30814
  }), catchError((error) => of(setRelated({ related: null })))));
30815
+ /*
30816
+ UserFeedback effects
30817
+ */
30818
+ this.loadUserFeedbacks$ = createEffect(() => this.actions$.pipe(ofType(loadUserFeedbacks), exhaustMap(({ datasetUuid }) => this.platformServiceInterface.getUserFeedbacks(datasetUuid).pipe(map$1((userFeedbacks) => loadUserFeedbacksSuccess({ userFeedbacks })), catchError((error) => of(loadUserFeedbacksFailure({
30819
+ otherError: error.message,
30820
+ })))))));
30821
+ this.reloadUserFeedbacks$ = createEffect(() => this.actions$.pipe(ofType(addUserFeedbackSuccess), exhaustMap(({ datasetUuid }) => this.platformServiceInterface.getUserFeedbacks(datasetUuid).pipe(map$1((userFeedbacks) => loadUserFeedbacksSuccess({ userFeedbacks })), catchError((error) => of(loadUserFeedbacksFailure({
30822
+ otherError: error.message,
30823
+ })))))));
30824
+ this.addUserFeedback$ = createEffect(() => this.actions$.pipe(ofType(addUserFeedback), mergeMap$1((action) => this.platformServiceInterface
30825
+ .postUserFeedbacks(action.userFeedback)
30826
+ .pipe(map$1(() => addUserFeedbackSuccess({
30827
+ datasetUuid: action.userFeedback.metadataUUID,
30828
+ })), catchError((error) => {
30829
+ return of(addUserFeedbackFailure({
30830
+ otherError: error.message,
30831
+ }));
30832
+ })))));
30316
30833
  }
30317
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MdViewEffects, deps: [{ token: i1$8.Actions }, { token: RecordsRepositoryInterface }], target: i0.ɵɵFactoryTarget.Injectable }); }
30834
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MdViewEffects, deps: [{ token: i1$8.Actions }, { token: RecordsRepositoryInterface }, { token: PlatformServiceInterface }], target: i0.ɵɵFactoryTarget.Injectable }); }
30318
30835
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MdViewEffects }); }
30319
30836
  }
30320
30837
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MdViewEffects, decorators: [{
30321
30838
  type: Injectable
30322
- }], ctorParameters: function () { return [{ type: i1$8.Actions }, { type: RecordsRepositoryInterface }]; } });
30839
+ }], ctorParameters: function () { return [{ type: i1$8.Actions }, { type: RecordsRepositoryInterface }, { type: PlatformServiceInterface }]; } });
30323
30840
 
30324
30841
  class FigureComponent {
30325
30842
  constructor() {
@@ -32105,11 +32622,11 @@ class OrganisationPreviewComponent {
32105
32622
  this.clickedOrganisation.emit(this.organisation);
32106
32623
  }
32107
32624
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: OrganisationPreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
32108
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: OrganisationPreviewComponent, selector: "gn-ui-organisation-preview", inputs: { organisation: "organisation", organisationUrl: "organisationUrl" }, outputs: { clickedOrganisation: "clickedOrganisation" }, ngImport: i0, template: "<a href (click)=\"clickOrganisation($event)\" [attr.href]=\"organisationUrl\">\n <div\n class=\"group cursor-pointer rounded-lg h-full flex flex-col\"\n [title]=\"organisation.name\"\n >\n <div\n class=\"flex-shrink-0 bg-gray-100 rounded-lg overflow-hidden w-full border border-gray-300 h-36\"\n >\n <gn-ui-thumbnail\n class=\"relative h-full w-full\"\n [thumbnailUrl]=\"organisation.logoUrl\"\n [fit]=\"'contain'\"\n >\n </gn-ui-thumbnail>\n </div>\n <div class=\"px-3 pb-2 capitalize flex flex-col flex-grow overflow-hidden\">\n <span\n class=\"flex-shrink-0 mb-3 mt-5 font-title text-21 text-title group-hover:text-primary line-clamp-2 sm:mt-2 transition-colors\"\n data-cy=\"organizationName\"\n >\n {{ organisation.name }}</span\n >\n <p\n class=\"abstract mt-4 mb-5 sm:mb-2 sm:mt-0 flex-grow flex-shrink-1 overflow-hidden\"\n data-cy=\"organizationDesc\"\n >\n {{ organisation.description }}\n </p>\n <div class=\"flex-shrink-0 text-primary opacity-50 flex leading-6\">\n <mat-icon class=\"material-symbols-outlined text-primary opacity-50 mr-1\"\n >folder_open\n </mat-icon>\n <span class=\"mx-1\" data-cy=\"organizationRecordsCount\">{{\n organisation.recordCount\n }}</span>\n <span translate>record.metadata.publications</span>\n </div>\n </div>\n </div>\n</a>\n", styles: [".abstract{position:relative}.abstract:after{content:\"\";position:absolute;bottom:0;left:0;right:0;background:linear-gradient(0deg,white,transparent);height:10px}\n"], dependencies: [{ kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: ThumbnailComponent, selector: "gn-ui-thumbnail", inputs: ["thumbnailUrl", "fit"], outputs: ["placeholderShown"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
32625
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: OrganisationPreviewComponent, selector: "gn-ui-organisation-preview", inputs: { organisation: "organisation", organisationUrl: "organisationUrl" }, outputs: { clickedOrganisation: "clickedOrganisation" }, ngImport: i0, template: "<a href (click)=\"clickOrganisation($event)\" [attr.href]=\"organisationUrl\">\n <div\n class=\"group cursor-pointer rounded-lg h-full flex flex-col\"\n [title]=\"organisation.name\"\n >\n <div\n class=\"shrink-0 bg-gray-100 rounded-lg overflow-hidden w-full border border-gray-300 h-36\"\n >\n <gn-ui-thumbnail\n class=\"relative h-full w-full\"\n [thumbnailUrl]=\"organisation.logoUrl\"\n [fit]=\"'contain'\"\n >\n </gn-ui-thumbnail>\n </div>\n <div class=\"px-3 pb-2 capitalize flex flex-col grow overflow-hidden\">\n <span\n class=\"shrink-0 mb-3 mt-5 font-title text-21 text-title group-hover:text-primary line-clamp-2 sm:mt-2 transition-colors\"\n data-cy=\"organizationName\"\n >\n {{ organisation.name }}</span\n >\n <p\n class=\"abstract mt-4 mb-5 sm:mb-2 sm:mt-0 grow shrink-1 overflow-hidden\"\n data-cy=\"organizationDesc\"\n >\n {{ organisation.description }}\n </p>\n <div class=\"shrink-0 text-primary opacity-50 flex leading-6\">\n <mat-icon class=\"material-symbols-outlined text-primary opacity-50 mr-1\"\n >folder_open\n </mat-icon>\n <span class=\"mx-1\" data-cy=\"organizationRecordsCount\">{{\n organisation.recordCount\n }}</span>\n <span translate>record.metadata.publications</span>\n </div>\n </div>\n </div>\n</a>\n", styles: [".abstract{position:relative}.abstract:after{content:\"\";position:absolute;bottom:0;left:0;right:0;background:linear-gradient(0deg,white,transparent);height:10px}\n"], dependencies: [{ kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: ThumbnailComponent, selector: "gn-ui-thumbnail", inputs: ["thumbnailUrl", "fit"], outputs: ["placeholderShown"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
32109
32626
  }
32110
32627
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: OrganisationPreviewComponent, decorators: [{
32111
32628
  type: Component,
32112
- args: [{ selector: 'gn-ui-organisation-preview', changeDetection: ChangeDetectionStrategy.OnPush, template: "<a href (click)=\"clickOrganisation($event)\" [attr.href]=\"organisationUrl\">\n <div\n class=\"group cursor-pointer rounded-lg h-full flex flex-col\"\n [title]=\"organisation.name\"\n >\n <div\n class=\"flex-shrink-0 bg-gray-100 rounded-lg overflow-hidden w-full border border-gray-300 h-36\"\n >\n <gn-ui-thumbnail\n class=\"relative h-full w-full\"\n [thumbnailUrl]=\"organisation.logoUrl\"\n [fit]=\"'contain'\"\n >\n </gn-ui-thumbnail>\n </div>\n <div class=\"px-3 pb-2 capitalize flex flex-col flex-grow overflow-hidden\">\n <span\n class=\"flex-shrink-0 mb-3 mt-5 font-title text-21 text-title group-hover:text-primary line-clamp-2 sm:mt-2 transition-colors\"\n data-cy=\"organizationName\"\n >\n {{ organisation.name }}</span\n >\n <p\n class=\"abstract mt-4 mb-5 sm:mb-2 sm:mt-0 flex-grow flex-shrink-1 overflow-hidden\"\n data-cy=\"organizationDesc\"\n >\n {{ organisation.description }}\n </p>\n <div class=\"flex-shrink-0 text-primary opacity-50 flex leading-6\">\n <mat-icon class=\"material-symbols-outlined text-primary opacity-50 mr-1\"\n >folder_open\n </mat-icon>\n <span class=\"mx-1\" data-cy=\"organizationRecordsCount\">{{\n organisation.recordCount\n }}</span>\n <span translate>record.metadata.publications</span>\n </div>\n </div>\n </div>\n</a>\n", styles: [".abstract{position:relative}.abstract:after{content:\"\";position:absolute;bottom:0;left:0;right:0;background:linear-gradient(0deg,white,transparent);height:10px}\n"] }]
32629
+ args: [{ selector: 'gn-ui-organisation-preview', changeDetection: ChangeDetectionStrategy.OnPush, template: "<a href (click)=\"clickOrganisation($event)\" [attr.href]=\"organisationUrl\">\n <div\n class=\"group cursor-pointer rounded-lg h-full flex flex-col\"\n [title]=\"organisation.name\"\n >\n <div\n class=\"shrink-0 bg-gray-100 rounded-lg overflow-hidden w-full border border-gray-300 h-36\"\n >\n <gn-ui-thumbnail\n class=\"relative h-full w-full\"\n [thumbnailUrl]=\"organisation.logoUrl\"\n [fit]=\"'contain'\"\n >\n </gn-ui-thumbnail>\n </div>\n <div class=\"px-3 pb-2 capitalize flex flex-col grow overflow-hidden\">\n <span\n class=\"shrink-0 mb-3 mt-5 font-title text-21 text-title group-hover:text-primary line-clamp-2 sm:mt-2 transition-colors\"\n data-cy=\"organizationName\"\n >\n {{ organisation.name }}</span\n >\n <p\n class=\"abstract mt-4 mb-5 sm:mb-2 sm:mt-0 grow shrink-1 overflow-hidden\"\n data-cy=\"organizationDesc\"\n >\n {{ organisation.description }}\n </p>\n <div class=\"shrink-0 text-primary opacity-50 flex leading-6\">\n <mat-icon class=\"material-symbols-outlined text-primary opacity-50 mr-1\"\n >folder_open\n </mat-icon>\n <span class=\"mx-1\" data-cy=\"organizationRecordsCount\">{{\n organisation.recordCount\n }}</span>\n <span translate>record.metadata.publications</span>\n </div>\n </div>\n </div>\n</a>\n", styles: [".abstract{position:relative}.abstract:after{content:\"\";position:absolute;bottom:0;left:0;right:0;background:linear-gradient(0deg,white,transparent);height:10px}\n"] }]
32113
32630
  }], propDecorators: { organisation: [{
32114
32631
  type: Input
32115
32632
  }], organisationUrl: [{
@@ -32638,7 +33155,7 @@ class FeatureRecordModule {
32638
33155
  DataViewWebComponentComponent,
32639
33156
  DataViewShareComponent] }); }
32640
33157
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FeatureRecordModule, providers: [MdViewFacade], imports: [CommonModule,
32641
- StoreModule.forFeature(MD_VIEW_FEATURE_STATE_KEY, reducer$1),
33158
+ StoreModule.forFeature(METADATA_VIEW_FEATURE_STATE_KEY, reducer$1),
32642
33159
  EffectsModule.forFeature([MdViewEffects]),
32643
33160
  UiLayoutModule,
32644
33161
  FeatureMapModule,
@@ -32666,7 +33183,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
32666
33183
  ],
32667
33184
  imports: [
32668
33185
  CommonModule,
32669
- StoreModule.forFeature(MD_VIEW_FEATURE_STATE_KEY, reducer$1),
33186
+ StoreModule.forFeature(METADATA_VIEW_FEATURE_STATE_KEY, reducer$1),
32670
33187
  EffectsModule.forFeature([MdViewEffects]),
32671
33188
  UiLayoutModule,
32672
33189
  FeatureMapModule,
@@ -32731,6 +33248,13 @@ const DEFAULT_FIELDS = [
32731
33248
  },
32732
33249
  onSaveProcess: '${dateNow()}',
32733
33250
  },
33251
+ {
33252
+ model: 'licenses',
33253
+ formFieldConfig: {
33254
+ labelKey: marker('editor.record.form.license'),
33255
+ type: 'list',
33256
+ },
33257
+ },
32734
33258
  ];
32735
33259
 
32736
33260
  const EDITOR_FEATURE_KEY = 'editor';
@@ -32786,9 +33310,11 @@ const selectRecordFields = createSelector(selectEditorState, (state) => state.fi
32786
33310
  class EditorFacade {
32787
33311
  constructor() {
32788
33312
  this.store = inject(Store);
33313
+ this.actions$ = inject(Actions);
32789
33314
  this.record$ = this.store.pipe(select(selectRecord));
32790
33315
  this.saving$ = this.store.pipe(select(selectRecordSaving));
32791
- this.saveError$ = this.store.pipe(select(selectRecordSaveError));
33316
+ this.saveError$ = this.store.pipe(select(selectRecordSaveError), filter$1((error) => !!error));
33317
+ this.saveSuccess$ = this.actions$.pipe(ofType(saveRecordSuccess));
32792
33318
  this.changedSinceSave$ = this.store.pipe(select(selectRecordChangedSinceSave));
32793
33319
  this.recordFields$ = this.store.pipe(select(selectRecordFields));
32794
33320
  }
@@ -32808,6 +33334,99 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
32808
33334
  type: Injectable
32809
33335
  }] });
32810
33336
 
33337
+ function evaluate(expression) {
33338
+ if (expression.match(/^\${.*}$/)) {
33339
+ return evaluate(expression.slice(2, -1));
33340
+ }
33341
+ const operator = expression.split('(')[0];
33342
+ switch (operator) {
33343
+ case 'dateNow':
33344
+ return () => new Date();
33345
+ default:
33346
+ throw new Error(`Unknown operator: ${operator}`);
33347
+ }
33348
+ }
33349
+
33350
+ class EditorService {
33351
+ constructor(http, apiConfiguration) {
33352
+ this.http = http;
33353
+ this.apiConfiguration = apiConfiguration;
33354
+ this.apiUrl = `${this.apiConfiguration?.basePath || '/geonetwork/srv/api'}`;
33355
+ }
33356
+ // TODO: use the catalog repository instead
33357
+ loadRecordByUuid(uuid) {
33358
+ return this.http
33359
+ .get(`${this.apiUrl}/records/${uuid}/formatters/xml`, {
33360
+ responseType: 'text',
33361
+ headers: {
33362
+ Accept: 'application/xml',
33363
+ },
33364
+ })
33365
+ .pipe(switchMap$1((response) => findConverterForDocument(response).readRecord(response.toString())));
33366
+ }
33367
+ // returns the record as it was when saved
33368
+ saveRecord(record, fieldsConfig) {
33369
+ const savedRecord = { ...record };
33370
+ // run onSave processes
33371
+ for (const field of fieldsConfig) {
33372
+ if (field.onSaveProcess && field.model) {
33373
+ const evaluator = evaluate(field.onSaveProcess);
33374
+ savedRecord[field.model] = evaluator({
33375
+ config: field,
33376
+ value: record[field.model],
33377
+ });
33378
+ }
33379
+ }
33380
+ // TODO: use the catalog repository instead
33381
+ // TODO: use converter based on the format of the record before change
33382
+ return from(new Iso19139Converter().writeRecord(savedRecord)).pipe(switchMap$1((recordXml) => this.http.put(`${this.apiUrl}/records?metadataType=METADATA&uuidProcessing=OVERWRITE&transformWith=_none_&publishToAll=on`, recordXml, {
33383
+ headers: {
33384
+ 'Content-Type': 'application/xml',
33385
+ },
33386
+ withCredentials: true,
33387
+ })), map$1(() => savedRecord));
33388
+ }
33389
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: EditorService, deps: [{ token: i1.HttpClient }, { token: Configuration, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
33390
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: EditorService, providedIn: 'root' }); }
33391
+ }
33392
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: EditorService, decorators: [{
33393
+ type: Injectable,
33394
+ args: [{
33395
+ providedIn: 'root',
33396
+ }]
33397
+ }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: Configuration, decorators: [{
33398
+ type: Optional
33399
+ }, {
33400
+ type: Inject,
33401
+ args: [Configuration]
33402
+ }] }]; } });
33403
+
33404
+ class EditorEffects {
33405
+ constructor() {
33406
+ this.actions$ = inject(Actions);
33407
+ this.editorService = inject(EditorService);
33408
+ this.store = inject(Store);
33409
+ this.saveRecord$ = createEffect(() => this.actions$.pipe(ofType(saveRecord), withLatestFrom$1(this.store.select(selectRecord), this.store.select(selectRecordFieldsConfig)), switchMap$1(([, record, fieldsConfig]) => this.editorService.saveRecord(record, fieldsConfig).pipe(switchMap$1((newRecord) => of(saveRecordSuccess(), openRecord({ record: newRecord }))), catchError((error) => of(saveRecordFailure({
33410
+ error: error.message,
33411
+ })))))));
33412
+ this.markAsChanged$ = createEffect(() => this.actions$.pipe(ofType(updateRecordField), map$1(() => markRecordAsChanged())));
33413
+ }
33414
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: EditorEffects, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
33415
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: EditorEffects }); }
33416
+ }
33417
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: EditorEffects, decorators: [{
33418
+ type: Injectable
33419
+ }] });
33420
+
33421
+ var WizardFieldType;
33422
+ (function (WizardFieldType) {
33423
+ WizardFieldType[WizardFieldType["TEXT"] = 0] = "TEXT";
33424
+ WizardFieldType[WizardFieldType["TEXT_AREA"] = 1] = "TEXT_AREA";
33425
+ WizardFieldType[WizardFieldType["CHIPS"] = 2] = "CHIPS";
33426
+ WizardFieldType[WizardFieldType["DATA_PICKER"] = 3] = "DATA_PICKER";
33427
+ WizardFieldType[WizardFieldType["DROPDOWN"] = 4] = "DROPDOWN";
33428
+ })(WizardFieldType || (WizardFieldType = {}));
33429
+
32811
33430
  class WizardService {
32812
33431
  constructor(translateService) {
32813
33432
  this.translateService = translateService;
@@ -32891,15 +33510,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
32891
33510
  }]
32892
33511
  }], ctorParameters: function () { return [{ type: i1$1.TranslateService }]; } });
32893
33512
 
32894
- var WizardFieldType;
32895
- (function (WizardFieldType) {
32896
- WizardFieldType[WizardFieldType["TEXT"] = 0] = "TEXT";
32897
- WizardFieldType[WizardFieldType["TEXT_AREA"] = 1] = "TEXT_AREA";
32898
- WizardFieldType[WizardFieldType["CHIPS"] = 2] = "CHIPS";
32899
- WizardFieldType[WizardFieldType["DATA_PICKER"] = 3] = "DATA_PICKER";
32900
- WizardFieldType[WizardFieldType["DROPDOWN"] = 4] = "DROPDOWN";
32901
- })(WizardFieldType || (WizardFieldType = {}));
32902
-
32903
33513
  marker('datafeeder.month.january');
32904
33514
  marker('datafeeder.month.february');
32905
33515
  marker('datafeeder.month.march');
@@ -33029,7 +33639,7 @@ class WizardFieldComponent {
33029
33639
  deps: [MAT_DATE_LOCALE, MAT_MOMENT_DATE_ADAPTER_OPTIONS],
33030
33640
  },
33031
33641
  { provide: MAT_DATE_FORMATS, useValue: MY_FORMATS },
33032
- ], viewQueries: [{ propertyName: "searchText", first: true, predicate: ["searchText"], descendants: true }, { propertyName: "chips", first: true, predicate: ["chips"], descendants: true }, { propertyName: "textArea", first: true, predicate: ["textArea"], descendants: true }, { propertyName: "dropdown", first: true, predicate: ["dropdown"], descendants: true }], ngImport: i0, template: "<div class=\"flex flex-1\">\n <span [class]=\"wizardFieldConfig.icon + ' pr-10'\"></span>\n <div class=\"flex flex-col flex-1\">\n <div translate class=\"text-xl font-bold pb-1\">\n {{ wizardFieldConfig.label }}\n </div>\n <div\n class=\"w-1/2 h-12\"\n *ngIf=\"wizardFieldType.TEXT === wizardFieldConfig.type\"\n >\n <gn-ui-text-input\n #searchText\n [id]=\"wizardFieldConfig.id\"\n [value]=\"wizardFieldData\"\n [required]=\"wizardFieldConfig.required || false\"\n hint=\"\"\n ></gn-ui-text-input>\n </div>\n <div\n class=\"flex-1 w-11/12\"\n *ngIf=\"wizardFieldType.CHIPS === wizardFieldConfig.type\"\n >\n <gn-ui-chips-input\n #chips\n [selectedItems]=\"wizardFieldData\"\n placeholder=\"\"\n [id]=\"wizardFieldConfig.id\"\n [url]=\"wizardFieldConfig.options.url\"\n [loadOnce]=\"wizardFieldConfig.options.loadOnce\"\n ></gn-ui-chips-input>\n </div>\n <div\n class=\"h-32 w-11/12\"\n *ngIf=\"wizardFieldType.TEXT_AREA === wizardFieldConfig.type\"\n >\n <gn-ui-text-area\n #textArea\n [id]=\"wizardFieldConfig.id\"\n [value]=\"wizardFieldData\"\n [required]=\"wizardFieldConfig.required || false\"\n placeholder=\"\"\n ></gn-ui-text-area>\n </div>\n <div\n class=\"w-1/2 h-12\"\n *ngIf=\"wizardFieldType.DATA_PICKER === wizardFieldConfig.type\"\n >\n <input\n [id]=\"wizardFieldConfig.id\"\n type=\"text\"\n (click)=\"datepicker.open()\"\n class=\"rounded p-2 text-gray-700 w-full leading-tight focus:outline-none focus:border-primary\"\n [value]=\"wizardFieldData\"\n [matDatepicker]=\"datepicker\"\n (dateChange)=\"onDateChange($event)\"\n />\n <mat-datepicker #datepicker></mat-datepicker>\n </div>\n <div\n class=\"w-1/2 h-12\"\n *ngIf=\"wizardFieldType.DROPDOWN === wizardFieldConfig.type\"\n >\n <gn-ui-dropdown-selector\n #dropdown\n [id]=\"wizardFieldConfig.id\"\n [title]=\"''\"\n [extraBtnClass]=\"'secondary min-w-full'\"\n [showTitle]=\"false\"\n [choices]=\"dropdownChoices\"\n [selected]=\"wizardFieldData\"\n ariaName=\"search-sort-by\"\n ></gn-ui-dropdown-selector>\n </div>\n </div>\n</div>\n", styles: [":host{display:flex;flex:1}gn-ui-text-input::ng-deep input,input[type=text]{height:100%;background:white;color:#000;font-style:italic;border-width:2px;border-color:var(--color-primary)}gn-ui-text-area::ng-deep textarea{border-width:2px;border-color:var(--color-primary)}gn-ui-dropdown-selector::ng-deep div{height:100%}gn-ui-dropdown-selector::ng-deep select{height:100%;border-width:2px;border-color:var(--color-primary);background-color:#fff}\n"], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: DropdownSelectorComponent, selector: "gn-ui-dropdown-selector", inputs: ["title", "showTitle", "ariaName", "choices", "selected", "maxRows", "extraBtnClass", "minWidth"], outputs: ["selectValue"] }, { kind: "component", type: TextInputComponent, selector: "gn-ui-text-input", inputs: ["value", "hint", "required"], outputs: ["valueChange"] }, { kind: "component", type: TextAreaComponent, selector: "gn-ui-text-area", inputs: ["value", "placeholder", "required"], outputs: ["valueChange"] }, { kind: "component", type: ChipsInputComponent, selector: "gn-ui-chips-input", inputs: ["url", "placeholder", "selectedItems", "required", "loadOnce", "autocompleteItems"], outputs: ["itemsChange"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: i3$2.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i3$2.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
33642
+ ], viewQueries: [{ propertyName: "searchText", first: true, predicate: ["searchText"], descendants: true }, { propertyName: "chips", first: true, predicate: ["chips"], descendants: true }, { propertyName: "textArea", first: true, predicate: ["textArea"], descendants: true }, { propertyName: "dropdown", first: true, predicate: ["dropdown"], descendants: true }], ngImport: i0, template: "<div class=\"flex flex-1\">\n <span [class]=\"wizardFieldConfig.icon + ' pr-10'\"></span>\n <div class=\"flex flex-col flex-1\">\n <div translate class=\"text-xl font-bold pb-1\">\n {{ wizardFieldConfig.label }}\n </div>\n <div\n class=\"w-1/2 h-12\"\n *ngIf=\"wizardFieldType.TEXT === wizardFieldConfig.type\"\n >\n <gn-ui-text-input\n #searchText\n [id]=\"wizardFieldConfig.id\"\n [value]=\"wizardFieldData\"\n [required]=\"wizardFieldConfig.required || false\"\n hint=\"\"\n ></gn-ui-text-input>\n </div>\n <div\n class=\"flex-1 w-11/12\"\n *ngIf=\"wizardFieldType.CHIPS === wizardFieldConfig.type\"\n >\n <gn-ui-chips-input\n #chips\n [selectedItems]=\"wizardFieldData\"\n placeholder=\"\"\n [id]=\"wizardFieldConfig.id\"\n [url]=\"wizardFieldConfig.options.url\"\n [loadOnce]=\"wizardFieldConfig.options.loadOnce\"\n ></gn-ui-chips-input>\n </div>\n <div\n class=\"h-32 w-11/12\"\n *ngIf=\"wizardFieldType.TEXT_AREA === wizardFieldConfig.type\"\n >\n <gn-ui-text-area\n #textArea\n [id]=\"wizardFieldConfig.id\"\n [value]=\"wizardFieldData\"\n [required]=\"wizardFieldConfig.required || false\"\n placeholder=\"\"\n ></gn-ui-text-area>\n </div>\n <div\n class=\"w-1/2 h-12\"\n *ngIf=\"wizardFieldType.DATA_PICKER === wizardFieldConfig.type\"\n >\n <input\n [id]=\"wizardFieldConfig.id\"\n type=\"text\"\n (click)=\"datepicker.open()\"\n class=\"rounded p-2 text-gray-700 w-full leading-tight focus:outline-none focus:border-primary\"\n [value]=\"wizardFieldData\"\n [matDatepicker]=\"datepicker\"\n (dateChange)=\"onDateChange($event)\"\n />\n <mat-datepicker #datepicker></mat-datepicker>\n </div>\n <div\n class=\"w-1/2 h-12\"\n *ngIf=\"wizardFieldType.DROPDOWN === wizardFieldConfig.type\"\n >\n <gn-ui-dropdown-selector\n #dropdown\n [id]=\"wizardFieldConfig.id\"\n [title]=\"''\"\n [extraBtnClass]=\"'secondary min-w-full'\"\n [showTitle]=\"false\"\n [choices]=\"dropdownChoices\"\n [selected]=\"wizardFieldData\"\n ariaName=\"search-sort-by\"\n ></gn-ui-dropdown-selector>\n </div>\n </div>\n</div>\n", styles: [":host{display:flex;flex:1}gn-ui-text-input::ng-deep input,input[type=text]{height:100%;background:white;color:#000;font-style:italic;border-width:2px;border-color:var(--color-primary)}gn-ui-text-area::ng-deep textarea{border-width:2px;border-color:var(--color-primary)}gn-ui-dropdown-selector::ng-deep div{height:100%}gn-ui-dropdown-selector::ng-deep select{height:100%;border-width:2px;border-color:var(--color-primary);background-color:#fff}\n"], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: DropdownSelectorComponent, selector: "gn-ui-dropdown-selector", inputs: ["title", "showTitle", "ariaName", "choices", "selected", "maxRows", "extraBtnClass", "minWidth"], outputs: ["selectValue"] }, { kind: "component", type: TextInputComponent, selector: "gn-ui-text-input", inputs: ["value", "extraClass", "hint", "required"], outputs: ["valueChange"] }, { kind: "component", type: TextAreaComponent, selector: "gn-ui-text-area", inputs: ["value", "disabled", "extraClass", "placeholder", "required"], outputs: ["valueChange"] }, { kind: "component", type: ChipsInputComponent, selector: "gn-ui-chips-input", inputs: ["url", "placeholder", "selectedItems", "required", "loadOnce", "autocompleteItems"], outputs: ["itemsChange"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: i3$2.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i3$2.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
33033
33643
  }
33034
33644
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: WizardFieldComponent, decorators: [{
33035
33645
  type: Component,
@@ -33058,6 +33668,52 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
33058
33668
  args: ['dropdown']
33059
33669
  }] } });
33060
33670
 
33671
+ class WizardSummarizeComponent {
33672
+ get title() {
33673
+ return this.wizardService.getWizardFieldData('title') || '';
33674
+ }
33675
+ get abstract() {
33676
+ return this.wizardService.getWizardFieldData('abstract') || '';
33677
+ }
33678
+ get tags() {
33679
+ if (!this.wizardService.getWizardFieldData('tags')) {
33680
+ return '';
33681
+ }
33682
+ return JSON.parse(this.wizardService.getWizardFieldData('tags'))
33683
+ .map((t) => t.display)
33684
+ .join(' - ');
33685
+ }
33686
+ get createdDate() {
33687
+ const time = this.wizardService.getWizardFieldData('datepicker');
33688
+ const locale = this.translateService.currentLang;
33689
+ return new Date(Number(time)).toLocaleDateString(locale, {
33690
+ year: 'numeric',
33691
+ month: 'long',
33692
+ day: 'numeric',
33693
+ });
33694
+ }
33695
+ get scale() {
33696
+ if (!this.wizardService.getWizardFieldData('dropdown')) {
33697
+ return '';
33698
+ }
33699
+ const scaleValue = JSON.parse(this.wizardService.getWizardFieldData('dropdown'));
33700
+ return `1:${scaleValue}`;
33701
+ }
33702
+ get description() {
33703
+ return this.wizardService.getWizardFieldData('description') || '';
33704
+ }
33705
+ constructor(wizardService, translateService) {
33706
+ this.wizardService = wizardService;
33707
+ this.translateService = translateService;
33708
+ }
33709
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: WizardSummarizeComponent, deps: [{ token: WizardService }, { token: i1$1.TranslateService }], target: i0.ɵɵFactoryTarget.Component }); }
33710
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: WizardSummarizeComponent, selector: "gn-ui-wizard-summarize", ngImport: i0, template: "<div>\n <div class=\"text-2xl font-bold title\">\n {{ title | uppercase }}\n </div>\n <div class=\"text-lg font-bold pt-2 abstract\">\n {{ abstract }}\n </div>\n <div class=\"text-lg font-normal\">\n <span translate>datafeeder.wizardSummarize.createdAt</span>\n &nbsp;<span class=\"date\">{{ createdDate }}</span> -\n <span translate>datafeeder.wizardSummarize.scale</span>\n &nbsp;<span class=\"scale\">{{ scale }}</span>\n </div>\n <div class=\"text-lg italic font-normal description\">\n {{ description }}\n </div>\n <div class=\"text-sm font-medium pt-4 tags\">\n <span class=\"icon-tag pr-2\"></span>\n {{ tags }}\n </div>\n</div>\n", styles: [".icon-tag:before{font-size:18px}\n"], dependencies: [{ kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "pipe", type: i1$3.UpperCasePipe, name: "uppercase" }] }); }
33711
+ }
33712
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: WizardSummarizeComponent, decorators: [{
33713
+ type: Component,
33714
+ args: [{ selector: 'gn-ui-wizard-summarize', template: "<div>\n <div class=\"text-2xl font-bold title\">\n {{ title | uppercase }}\n </div>\n <div class=\"text-lg font-bold pt-2 abstract\">\n {{ abstract }}\n </div>\n <div class=\"text-lg font-normal\">\n <span translate>datafeeder.wizardSummarize.createdAt</span>\n &nbsp;<span class=\"date\">{{ createdDate }}</span> -\n <span translate>datafeeder.wizardSummarize.scale</span>\n &nbsp;<span class=\"scale\">{{ scale }}</span>\n </div>\n <div class=\"text-lg italic font-normal description\">\n {{ description }}\n </div>\n <div class=\"text-sm font-medium pt-4 tags\">\n <span class=\"icon-tag pr-2\"></span>\n {{ tags }}\n </div>\n</div>\n", styles: [".icon-tag:before{font-size:18px}\n"] }]
33715
+ }], ctorParameters: function () { return [{ type: WizardService }, { type: i1$1.TranslateService }]; } });
33716
+
33061
33717
  class WizardComponent {
33062
33718
  constructor(wizardService, translate) {
33063
33719
  this.wizardService = wizardService;
@@ -33123,136 +33779,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
33123
33779
  args: ['wizardFields']
33124
33780
  }] } });
33125
33781
 
33126
- class WizardSummarizeComponent {
33127
- get title() {
33128
- return this.wizardService.getWizardFieldData('title') || '';
33129
- }
33130
- get abstract() {
33131
- return this.wizardService.getWizardFieldData('abstract') || '';
33132
- }
33133
- get tags() {
33134
- if (!this.wizardService.getWizardFieldData('tags')) {
33135
- return '';
33136
- }
33137
- return JSON.parse(this.wizardService.getWizardFieldData('tags'))
33138
- .map((t) => t.display)
33139
- .join(' - ');
33140
- }
33141
- get createdDate() {
33142
- const time = this.wizardService.getWizardFieldData('datepicker');
33143
- const locale = this.translateService.currentLang;
33144
- return new Date(Number(time)).toLocaleDateString(locale, {
33145
- year: 'numeric',
33146
- month: 'long',
33147
- day: 'numeric',
33148
- });
33149
- }
33150
- get scale() {
33151
- if (!this.wizardService.getWizardFieldData('dropdown')) {
33152
- return '';
33153
- }
33154
- const scaleValue = JSON.parse(this.wizardService.getWizardFieldData('dropdown'));
33155
- return `1:${scaleValue}`;
33156
- }
33157
- get description() {
33158
- return this.wizardService.getWizardFieldData('description') || '';
33159
- }
33160
- constructor(wizardService, translateService) {
33161
- this.wizardService = wizardService;
33162
- this.translateService = translateService;
33163
- }
33164
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: WizardSummarizeComponent, deps: [{ token: WizardService }, { token: i1$1.TranslateService }], target: i0.ɵɵFactoryTarget.Component }); }
33165
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: WizardSummarizeComponent, selector: "gn-ui-wizard-summarize", ngImport: i0, template: "<div>\n <div class=\"text-2xl font-bold title\">\n {{ title | uppercase }}\n </div>\n <div class=\"text-lg font-bold pt-2 abstract\">\n {{ abstract }}\n </div>\n <div class=\"text-lg font-normal\">\n <span translate>datafeeder.wizardSummarize.createdAt</span>\n &nbsp;<span class=\"date\">{{ createdDate }}</span> -\n <span translate>datafeeder.wizardSummarize.scale</span>\n &nbsp;<span class=\"scale\">{{ scale }}</span>\n </div>\n <div class=\"text-lg italic font-normal description\">\n {{ description }}\n </div>\n <div class=\"text-sm font-medium pt-4 tags\">\n <span class=\"icon-tag pr-2\"></span>\n {{ tags }}\n </div>\n</div>\n", styles: [".icon-tag:before{font-size:18px}\n"], dependencies: [{ kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "pipe", type: i1$3.UpperCasePipe, name: "uppercase" }] }); }
33166
- }
33167
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: WizardSummarizeComponent, decorators: [{
33168
- type: Component,
33169
- args: [{ selector: 'gn-ui-wizard-summarize', template: "<div>\n <div class=\"text-2xl font-bold title\">\n {{ title | uppercase }}\n </div>\n <div class=\"text-lg font-bold pt-2 abstract\">\n {{ abstract }}\n </div>\n <div class=\"text-lg font-normal\">\n <span translate>datafeeder.wizardSummarize.createdAt</span>\n &nbsp;<span class=\"date\">{{ createdDate }}</span> -\n <span translate>datafeeder.wizardSummarize.scale</span>\n &nbsp;<span class=\"scale\">{{ scale }}</span>\n </div>\n <div class=\"text-lg italic font-normal description\">\n {{ description }}\n </div>\n <div class=\"text-sm font-medium pt-4 tags\">\n <span class=\"icon-tag pr-2\"></span>\n {{ tags }}\n </div>\n</div>\n", styles: [".icon-tag:before{font-size:18px}\n"] }]
33170
- }], ctorParameters: function () { return [{ type: WizardService }, { type: i1$1.TranslateService }]; } });
33171
-
33172
- function evaluate(expression) {
33173
- if (expression.match(/^\${.*}$/)) {
33174
- return evaluate(expression.slice(2, -1));
33175
- }
33176
- const operator = expression.split('(')[0];
33177
- switch (operator) {
33178
- case 'dateNow':
33179
- return () => new Date();
33180
- default:
33181
- throw new Error(`Unknown operator: ${operator}`);
33182
- }
33183
- }
33184
-
33185
- class EditorService {
33186
- constructor(http, apiConfiguration) {
33187
- this.http = http;
33188
- this.apiConfiguration = apiConfiguration;
33189
- this.apiUrl = `${this.apiConfiguration?.basePath || '/geonetwork/srv/api'}`;
33190
- }
33191
- // TODO: use the catalog repository instead
33192
- loadRecordByUuid(uuid) {
33193
- return this.http
33194
- .get(`${this.apiUrl}/records/${uuid}/formatters/xml`, {
33195
- responseType: 'text',
33196
- headers: {
33197
- Accept: 'application/xml',
33198
- },
33199
- })
33200
- .pipe(switchMap$1((response) => findConverterForDocument(response).readRecord(response.toString())));
33201
- }
33202
- // returns the record as it was when saved
33203
- saveRecord(record, fieldsConfig) {
33204
- const savedRecord = { ...record };
33205
- // run onSave processes
33206
- for (const field of fieldsConfig) {
33207
- if (field.onSaveProcess && field.model) {
33208
- const evaluator = evaluate(field.onSaveProcess);
33209
- savedRecord[field.model] = evaluator({
33210
- config: field,
33211
- value: record[field.model],
33212
- });
33213
- }
33214
- }
33215
- // TODO: use the catalog repository instead
33216
- // TODO: use converter based on the format of the record before change
33217
- return from(new Iso19139Converter().writeRecord(savedRecord)).pipe(switchMap$1((recordXml) => this.http.put(`${this.apiUrl}/records?metadataType=METADATA&uuidProcessing=OVERWRITE&transformWith=_none_&publishToAll=on`, recordXml, {
33218
- headers: {
33219
- 'Content-Type': 'application/xml',
33220
- },
33221
- withCredentials: true,
33222
- })), map$1(() => savedRecord));
33223
- }
33224
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: EditorService, deps: [{ token: i1.HttpClient }, { token: Configuration, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
33225
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: EditorService, providedIn: 'root' }); }
33226
- }
33227
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: EditorService, decorators: [{
33228
- type: Injectable,
33229
- args: [{
33230
- providedIn: 'root',
33231
- }]
33232
- }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: Configuration, decorators: [{
33233
- type: Optional
33234
- }, {
33235
- type: Inject,
33236
- args: [Configuration]
33237
- }] }]; } });
33238
-
33239
- class EditorEffects {
33240
- constructor() {
33241
- this.actions$ = inject(Actions);
33242
- this.editorService = inject(EditorService);
33243
- this.store = inject(Store);
33244
- this.saveRecord$ = createEffect(() => this.actions$.pipe(ofType(saveRecord), withLatestFrom$1(this.store.select(selectRecord), this.store.select(selectRecordFieldsConfig)), switchMap$1(([, record, fieldsConfig]) => this.editorService.saveRecord(record, fieldsConfig).pipe(switchMap$1((newRecord) => of(saveRecordSuccess(), openRecord({ record: newRecord }))), catchError((error) => of(saveRecordFailure({
33245
- error: error.message,
33246
- })))))));
33247
- this.markAsChanged$ = createEffect(() => this.actions$.pipe(ofType(updateRecordField), map$1(() => markRecordAsChanged())));
33248
- }
33249
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: EditorEffects, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
33250
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: EditorEffects }); }
33251
- }
33252
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: EditorEffects, decorators: [{
33253
- type: Injectable
33254
- }] });
33255
-
33256
33782
  class FeatureEditorModule {
33257
33783
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FeatureEditorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
33258
33784
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.1.7", ngImport: i0, type: FeatureEditorModule, declarations: [WizardComponent,
@@ -33302,6 +33828,300 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
33302
33828
  }]
33303
33829
  }] });
33304
33830
 
33831
+ class FormFieldSimpleComponent {
33832
+ constructor() {
33833
+ this.readonly = false;
33834
+ this.invalid = false;
33835
+ this.placeholder = '';
33836
+ }
33837
+ get inputType() {
33838
+ switch (this.type) {
33839
+ case 'url':
33840
+ case 'text':
33841
+ return 'text';
33842
+ case 'date':
33843
+ return 'datetime-local';
33844
+ case 'number':
33845
+ return 'number';
33846
+ case 'toggle':
33847
+ return 'checkbox';
33848
+ default:
33849
+ return '';
33850
+ }
33851
+ }
33852
+ get isSelect() {
33853
+ return this.type === 'list';
33854
+ }
33855
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldSimpleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
33856
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: FormFieldSimpleComponent, isStandalone: true, selector: "gn-ui-form-field-simple", inputs: { type: "type", control: "control", readonly: "readonly", invalid: "invalid", placeholder: "placeholder", options: "options" }, ngImport: i0, template: "<input\n *ngIf=\"!isSelect\"\n [type]=\"inputType\"\n [readonly]=\"readonly\"\n [formControl]=\"control\"\n [placeholder]=\"placeholder\"\n class=\"border rounded-md p-3 w-full bg-white transition-colors\"\n [ngClass]=\"{\n 'border-pink-500': invalid,\n 'border-gray-200': !invalid,\n 'text-gray-600': readonly\n }\"\n/>\n<select\n *ngIf=\"isSelect\"\n [formControl]=\"control\"\n class=\"border rounded-md p-3 w-full bg-white transition-colors\"\n [ngClass]=\"{\n 'border-pink-500': invalid,\n 'border-gray-200': !invalid,\n 'text-gray-600': readonly\n }\"\n>\n <option *ngFor=\"let option of options\" [ngValue]=\"option.value\">\n {{ option.label }}\n </option>\n</select>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
33857
+ }
33858
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldSimpleComponent, decorators: [{
33859
+ type: Component,
33860
+ args: [{ selector: 'gn-ui-form-field-simple', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, ReactiveFormsModule], template: "<input\n *ngIf=\"!isSelect\"\n [type]=\"inputType\"\n [readonly]=\"readonly\"\n [formControl]=\"control\"\n [placeholder]=\"placeholder\"\n class=\"border rounded-md p-3 w-full bg-white transition-colors\"\n [ngClass]=\"{\n 'border-pink-500': invalid,\n 'border-gray-200': !invalid,\n 'text-gray-600': readonly\n }\"\n/>\n<select\n *ngIf=\"isSelect\"\n [formControl]=\"control\"\n class=\"border rounded-md p-3 w-full bg-white transition-colors\"\n [ngClass]=\"{\n 'border-pink-500': invalid,\n 'border-gray-200': !invalid,\n 'text-gray-600': readonly\n }\"\n>\n <option *ngFor=\"let option of options\" [ngValue]=\"option.value\">\n {{ option.label }}\n </option>\n</select>\n" }]
33861
+ }], propDecorators: { type: [{
33862
+ type: Input
33863
+ }], control: [{
33864
+ type: Input
33865
+ }], readonly: [{
33866
+ type: Input
33867
+ }], invalid: [{
33868
+ type: Input
33869
+ }], placeholder: [{
33870
+ type: Input
33871
+ }], options: [{
33872
+ type: Input
33873
+ }] } });
33874
+
33875
+ class FormFieldFileComponent {
33876
+ constructor() {
33877
+ this.readonly = false;
33878
+ this.invalid = false;
33879
+ this.placeholder = '';
33880
+ }
33881
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldFileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
33882
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: FormFieldFileComponent, isStandalone: true, selector: "gn-ui-form-field-file", inputs: { control: "control", readonly: "readonly", invalid: "invalid", placeholder: "placeholder" }, ngImport: i0, template: "<input\n type=\"file\"\n [readonly]=\"readonly\"\n [formControl]=\"control\"\n [placeholder]=\"placeholder\"\n class=\"border rounded-md p-3 w-full bg-white transition-colors\"\n [ngClass]=\"{\n 'border-pink-500': invalid,\n 'border-gray-200': !invalid,\n 'text-gray-600': readonly\n }\"\n/>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
33883
+ }
33884
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldFileComponent, decorators: [{
33885
+ type: Component,
33886
+ args: [{ selector: 'gn-ui-form-field-file', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, ReactiveFormsModule], template: "<input\n type=\"file\"\n [readonly]=\"readonly\"\n [formControl]=\"control\"\n [placeholder]=\"placeholder\"\n class=\"border rounded-md p-3 w-full bg-white transition-colors\"\n [ngClass]=\"{\n 'border-pink-500': invalid,\n 'border-gray-200': !invalid,\n 'text-gray-600': readonly\n }\"\n/>\n" }]
33887
+ }], propDecorators: { control: [{
33888
+ type: Input
33889
+ }], readonly: [{
33890
+ type: Input
33891
+ }], invalid: [{
33892
+ type: Input
33893
+ }], placeholder: [{
33894
+ type: Input
33895
+ }] } });
33896
+
33897
+ class FormFieldRichComponent {
33898
+ constructor() {
33899
+ this.placeholder = 'Votre texte ici'; //TODO: translate
33900
+ this.preview = false;
33901
+ }
33902
+ getButtonExtraClass() {
33903
+ return `${this.preview ? 'text-gray-200 bg-gray-900' : 'text-gray-900 bg-gray-200'} rounded-[1.25rem] p-[0.375rem] text-xs font-medium w-24`;
33904
+ }
33905
+ togglePreview() {
33906
+ this.preview = !this.preview;
33907
+ }
33908
+ handleTextContentChanged(textContent) {
33909
+ this.control.setValue(textContent);
33910
+ }
33911
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldRichComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
33912
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: FormFieldRichComponent, isStandalone: true, selector: "gn-ui-form-field-rich", inputs: { control: "control", label: "label", hint: "hint", helperText: "helperText", placeholder: "placeholder" }, ngImport: i0, template: "<gn-ui-form-field-wrapper [label]=\"label\" [hint]=\"hint\">\n <gn-ui-button\n form-field-interaction\n [extraClass]=\"getButtonExtraClass()\"\n (buttonClick)=\"togglePreview()\"\n >\n <span class=\"material-symbols-outlined mr-1 gn-ui-icon-small\">{{\n preview ? 'visibility' : 'visibility_off'\n }}</span>\n {{ preview ? 'WYSIWYG' : 'Markdown' }}\n </gn-ui-button>\n <gn-ui-markdown-editor\n class=\"h-full\"\n [preview]=\"preview\"\n [helperText]=\"helperText\"\n [placeholder]=\"placeholder\"\n [textContent]=\"control.value\"\n (textContentChanged)=\"handleTextContentChanged($event)\"\n ></gn-ui-markdown-editor>\n</gn-ui-form-field-wrapper>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: MarkdownEditorComponent, selector: "gn-ui-markdown-editor", inputs: ["preview", "helperText", "placeholder", "textContent"], outputs: ["textContentChanged"] }, { kind: "component", type: FormFieldWrapperComponent, selector: "gn-ui-form-field-wrapper", inputs: ["label", "hint"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
33913
+ }
33914
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldRichComponent, decorators: [{
33915
+ type: Component,
33916
+ args: [{ selector: 'gn-ui-form-field-rich', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
33917
+ CommonModule,
33918
+ ReactiveFormsModule,
33919
+ MarkdownEditorComponent,
33920
+ FormFieldWrapperComponent,
33921
+ ButtonComponent,
33922
+ ], template: "<gn-ui-form-field-wrapper [label]=\"label\" [hint]=\"hint\">\n <gn-ui-button\n form-field-interaction\n [extraClass]=\"getButtonExtraClass()\"\n (buttonClick)=\"togglePreview()\"\n >\n <span class=\"material-symbols-outlined mr-1 gn-ui-icon-small\">{{\n preview ? 'visibility' : 'visibility_off'\n }}</span>\n {{ preview ? 'WYSIWYG' : 'Markdown' }}\n </gn-ui-button>\n <gn-ui-markdown-editor\n class=\"h-full\"\n [preview]=\"preview\"\n [helperText]=\"helperText\"\n [placeholder]=\"placeholder\"\n [textContent]=\"control.value\"\n (textContentChanged)=\"handleTextContentChanged($event)\"\n ></gn-ui-markdown-editor>\n</gn-ui-form-field-wrapper>\n" }]
33923
+ }], propDecorators: { control: [{
33924
+ type: Input
33925
+ }], label: [{
33926
+ type: Input
33927
+ }], hint: [{
33928
+ type: Input
33929
+ }], helperText: [{
33930
+ type: Input
33931
+ }], placeholder: [{
33932
+ type: Input
33933
+ }] } });
33934
+
33935
+ class FormFieldObjectComponent {
33936
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldObjectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
33937
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: FormFieldObjectComponent, isStandalone: true, selector: "gn-ui-form-field-object", ngImport: i0, template: "<p>form-field-object works!</p>\n", styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
33938
+ }
33939
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldObjectComponent, decorators: [{
33940
+ type: Component,
33941
+ args: [{ selector: 'gn-ui-form-field-object', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<p>form-field-object works!</p>\n" }]
33942
+ }] });
33943
+
33944
+ class FormFieldArrayComponent {
33945
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldArrayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
33946
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: FormFieldArrayComponent, isStandalone: true, selector: "gn-ui-form-field-array", ngImport: i0, template: "<p>form-field-array works!</p>\n", styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
33947
+ }
33948
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldArrayComponent, decorators: [{
33949
+ type: Component,
33950
+ args: [{ selector: 'gn-ui-form-field-array', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<p>form-field-array works!</p>\n" }]
33951
+ }] });
33952
+
33953
+ class FormFieldSpatialExtentComponent {
33954
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldSpatialExtentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
33955
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: FormFieldSpatialExtentComponent, isStandalone: true, selector: "gn-ui-form-field-spatial-extent", ngImport: i0, template: "<p>form-field-spatial-extent works!</p>\n", styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
33956
+ }
33957
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldSpatialExtentComponent, decorators: [{
33958
+ type: Component,
33959
+ args: [{ selector: 'gn-ui-form-field-spatial-extent', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<p>form-field-spatial-extent works!</p>\n" }]
33960
+ }] });
33961
+
33962
+ class FormFieldTemporalExtentComponent {
33963
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldTemporalExtentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
33964
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: FormFieldTemporalExtentComponent, isStandalone: true, selector: "gn-ui-form-field-temporal-extent", ngImport: i0, template: "<p>form-field-temporal-extent works!</p>\n", styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
33965
+ }
33966
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldTemporalExtentComponent, decorators: [{
33967
+ type: Component,
33968
+ args: [{ selector: 'gn-ui-form-field-temporal-extent', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<p>form-field-temporal-extent works!</p>\n" }]
33969
+ }] });
33970
+
33971
+ class FormFieldLicenseComponent {
33972
+ constructor() {
33973
+ this.choices = [
33974
+ {
33975
+ value: 'cc-by',
33976
+ label: marker('editor.record.form.license.cc-by'),
33977
+ },
33978
+ {
33979
+ value: 'cc-by-sa',
33980
+ label: marker('editor.record.form.license.cc-by-sa'),
33981
+ },
33982
+ {
33983
+ value: 'cc-zero',
33984
+ label: marker('editor.record.form.license.cc-zero'),
33985
+ },
33986
+ {
33987
+ value: 'etalab',
33988
+ label: marker('editor.record.form.license.etalab'),
33989
+ },
33990
+ {
33991
+ value: 'etalab-v2',
33992
+ label: marker('editor.record.form.license.etalab-v2'),
33993
+ },
33994
+ {
33995
+ value: 'odbl',
33996
+ label: marker('editor.record.form.license.odbl'),
33997
+ },
33998
+ {
33999
+ value: 'odc-by',
34000
+ label: marker('editor.record.form.license.odc-by'),
34001
+ },
34002
+ {
34003
+ value: 'pddl',
34004
+ label: marker('editor.record.form.license.pddl'),
34005
+ },
34006
+ {
34007
+ value: 'unknown',
34008
+ label: marker('editor.record.form.license.unknown'),
34009
+ },
34010
+ ];
34011
+ }
34012
+ get selected() {
34013
+ return this.control.value[0]?.text;
34014
+ }
34015
+ onSelectValue(value) {
34016
+ this.control.setValue([{ text: value }]);
34017
+ }
34018
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldLicenseComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
34019
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: FormFieldLicenseComponent, isStandalone: true, selector: "gn-ui-form-field-license", inputs: { control: "control", label: "label" }, ngImport: i0, template: "<gn-ui-dropdown-selector\n [title]=\"label\"\n [showTitle]=\"false\"\n [choices]=\"choices\"\n [selected]=\"selected\"\n (selectValue)=\"onSelectValue($event)\"\n>\n</gn-ui-dropdown-selector>\n", styles: [""], dependencies: [{ kind: "component", type: DropdownSelectorComponent, selector: "gn-ui-dropdown-selector", inputs: ["title", "showTitle", "ariaName", "choices", "selected", "maxRows", "extraBtnClass", "minWidth"], outputs: ["selectValue"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
34020
+ }
34021
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldLicenseComponent, decorators: [{
34022
+ type: Component,
34023
+ args: [{ selector: 'gn-ui-form-field-license', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [DropdownSelectorComponent], template: "<gn-ui-dropdown-selector\n [title]=\"label\"\n [showTitle]=\"false\"\n [choices]=\"choices\"\n [selected]=\"selected\"\n (selectValue)=\"onSelectValue($event)\"\n>\n</gn-ui-dropdown-selector>\n" }]
34024
+ }], propDecorators: { control: [{
34025
+ type: Input
34026
+ }], label: [{
34027
+ type: Input
34028
+ }] } });
34029
+
34030
+ class FormFieldComponent {
34031
+ set value(v) {
34032
+ this.formControl.setValue(v, {
34033
+ emitEvent: false,
34034
+ });
34035
+ }
34036
+ constructor() {
34037
+ this.formControl = new FormControl();
34038
+ this.valueChange = this.formControl.valueChanges;
34039
+ }
34040
+ focusTitleInput() {
34041
+ this.titleInput.nativeElement.children[0].focus();
34042
+ }
34043
+ get simpleType() {
34044
+ return this.config.type;
34045
+ }
34046
+ get isSimpleField() {
34047
+ return (this.config.type === 'text' ||
34048
+ this.config.type === 'number' ||
34049
+ this.config.type === 'date' ||
34050
+ this.config.type === 'list' ||
34051
+ this.config.type === 'url' ||
34052
+ this.config.type === 'toggle');
34053
+ }
34054
+ get isFileField() {
34055
+ return this.config.type === 'file';
34056
+ }
34057
+ get isSpatialExtentField() {
34058
+ return this.config.type === 'spatial_extent';
34059
+ }
34060
+ get isTemporalExtentField() {
34061
+ return this.config.type === 'temporal_extent';
34062
+ }
34063
+ get isArrayField() {
34064
+ return this.config.type === 'array';
34065
+ }
34066
+ get isObjectField() {
34067
+ return this.config.type === 'object';
34068
+ }
34069
+ get isFieldOk() {
34070
+ return !this.config.locked && !this.config.invalid;
34071
+ }
34072
+ get isFieldLocked() {
34073
+ return this.config.locked;
34074
+ }
34075
+ get isFieldInvalid() {
34076
+ return !this.config.locked && this.config.invalid;
34077
+ }
34078
+ get isTitle() {
34079
+ return this.model === 'title';
34080
+ }
34081
+ get isAbstract() {
34082
+ return this.model === 'abstract';
34083
+ }
34084
+ get isLicenses() {
34085
+ return this.model === 'licenses';
34086
+ }
34087
+ get withoutWrapper() {
34088
+ return this.model === 'title' || this.model === 'abstract';
34089
+ }
34090
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
34091
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: FormFieldComponent, isStandalone: true, selector: "gn-ui-form-field", inputs: { model: "model", config: "config", value: "value" }, outputs: { valueChange: "valueChange" }, viewQueries: [{ propertyName: "titleInput", first: true, predicate: ["titleInput"], descendants: true }], ngImport: i0, template: "<div class=\"flex flex-col h-full\">\n <ng-container *ngIf=\"withoutWrapper; else withGenericWrapper\">\n <ng-container *ngTemplateOutlet=\"fieldContent\"></ng-container>\n </ng-container>\n <ng-template #withGenericWrapper>\n <gn-ui-form-field-wrapper\n [label]=\"config.labelKey | translate\"\n [hint]=\"config.hintKey | translate\"\n >\n <ng-container *ngTemplateOutlet=\"fieldContent\"></ng-container>\n </gn-ui-form-field-wrapper>\n </ng-template>\n</div>\n\n<ng-template #fieldContent>\n <ng-container *ngIf=\"isTitle\">\n <div class=\"flex justify-between items-center gap-3\">\n <h2\n #titleInput\n class=\"grow text-3xl font-normal\"\n [gnUiEditableLabel]=\"true\"\n (editableLabelChanged)=\"formControl.setValue($event)\"\n >\n {{ formControl.value }}\n </h2>\n <span\n class=\"material-symbols-outlined gn-ui-icon-small m-2 cursor-pointer\"\n (click)=\"focusTitleInput()\"\n >edit</span\n >\n <span\n class=\"material-symbols-outlined gn-ui-icon-small m-2\"\n [matTooltip]=\"config.hintKey | translate\"\n matTooltipPosition=\"above\"\n >\n help\n </span>\n </div>\n </ng-container>\n <ng-container *ngIf=\"isAbstract\">\n <gn-ui-form-field-rich\n class=\"h-[8rem]\"\n [control]=\"formControl\"\n [label]=\"config.labelKey | translate\"\n [hint]=\"config.hintKey | translate\"\n ></gn-ui-form-field-rich>\n </ng-container>\n <ng-container *ngIf=\"isLicenses\">\n <gn-ui-form-field-license\n [control]=\"formControl\"\n [label]=\"config.labelKey | translate\"\n ></gn-ui-form-field-license>\n </ng-container>\n <ng-container *ngIf=\"isSimpleField\">\n <gn-ui-form-field-simple\n [type]=\"simpleType\"\n [control]=\"formControl\"\n [readonly]=\"isFieldLocked\"\n [invalid]=\"isFieldInvalid\"\n ></gn-ui-form-field-simple>\n </ng-container>\n <ng-container *ngIf=\"isFileField\">\n <gn-ui-form-field-file\n [control]=\"formControl\"\n [readonly]=\"isFieldLocked\"\n [invalid]=\"isFieldInvalid\"\n ></gn-ui-form-field-file>\n </ng-container>\n <ng-container *ngIf=\"isArrayField\">\n <gn-ui-form-field-array></gn-ui-form-field-array>\n </ng-container>\n <ng-container *ngIf=\"isObjectField\">\n <gn-ui-form-field-object></gn-ui-form-field-object>\n </ng-container>\n <ng-container *ngIf=\"isSpatialExtentField\">\n <gn-ui-form-field-spatial-extent></gn-ui-form-field-spatial-extent>\n </ng-container>\n <ng-container *ngIf=\"isTemporalExtentField\">\n <gn-ui-form-field-temporal-extent></gn-ui-form-field-temporal-extent>\n </ng-container>\n <div\n *ngIf=\"isFieldInvalid && config.invalidHintKey\"\n class=\"mt-2 text-pink-500 text-sm field-invalid-hint\"\n >\n {{ config.invalidHintKey | translate }}\n </div>\n</ng-template>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: EditableLabelDirective, selector: "[gnUiEditableLabel]", inputs: ["gnUiEditableLabel"], outputs: ["editableLabelChanged"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: FormFieldWrapperComponent, selector: "gn-ui-form-field-wrapper", inputs: ["label", "hint"] }, { kind: "component", type: FormFieldSimpleComponent, selector: "gn-ui-form-field-simple", inputs: ["type", "control", "readonly", "invalid", "placeholder", "options"] }, { kind: "component", type: FormFieldRichComponent, selector: "gn-ui-form-field-rich", inputs: ["control", "label", "hint", "helperText", "placeholder"] }, { kind: "component", type: FormFieldObjectComponent, selector: "gn-ui-form-field-object" }, { kind: "component", type: FormFieldSpatialExtentComponent, selector: "gn-ui-form-field-spatial-extent" }, { kind: "component", type: FormFieldTemporalExtentComponent, selector: "gn-ui-form-field-temporal-extent" }, { kind: "component", type: FormFieldFileComponent, selector: "gn-ui-form-field-file", inputs: ["control", "readonly", "invalid", "placeholder"] }, { kind: "component", type: FormFieldArrayComponent, selector: "gn-ui-form-field-array" }, { kind: "component", type: FormFieldLicenseComponent, selector: "gn-ui-form-field-license", inputs: ["control", "label"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
34092
+ }
34093
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldComponent, decorators: [{
34094
+ type: Component,
34095
+ args: [{ selector: 'gn-ui-form-field', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
34096
+ CommonModule,
34097
+ ReactiveFormsModule,
34098
+ EditableLabelDirective,
34099
+ MatIconModule,
34100
+ MatTooltipModule,
34101
+ FormFieldWrapperComponent,
34102
+ FormFieldSimpleComponent,
34103
+ FormFieldRichComponent,
34104
+ FormFieldObjectComponent,
34105
+ FormFieldSpatialExtentComponent,
34106
+ FormFieldTemporalExtentComponent,
34107
+ FormFieldFileComponent,
34108
+ FormFieldArrayComponent,
34109
+ FormFieldLicenseComponent,
34110
+ TranslateModule,
34111
+ ], template: "<div class=\"flex flex-col h-full\">\n <ng-container *ngIf=\"withoutWrapper; else withGenericWrapper\">\n <ng-container *ngTemplateOutlet=\"fieldContent\"></ng-container>\n </ng-container>\n <ng-template #withGenericWrapper>\n <gn-ui-form-field-wrapper\n [label]=\"config.labelKey | translate\"\n [hint]=\"config.hintKey | translate\"\n >\n <ng-container *ngTemplateOutlet=\"fieldContent\"></ng-container>\n </gn-ui-form-field-wrapper>\n </ng-template>\n</div>\n\n<ng-template #fieldContent>\n <ng-container *ngIf=\"isTitle\">\n <div class=\"flex justify-between items-center gap-3\">\n <h2\n #titleInput\n class=\"grow text-3xl font-normal\"\n [gnUiEditableLabel]=\"true\"\n (editableLabelChanged)=\"formControl.setValue($event)\"\n >\n {{ formControl.value }}\n </h2>\n <span\n class=\"material-symbols-outlined gn-ui-icon-small m-2 cursor-pointer\"\n (click)=\"focusTitleInput()\"\n >edit</span\n >\n <span\n class=\"material-symbols-outlined gn-ui-icon-small m-2\"\n [matTooltip]=\"config.hintKey | translate\"\n matTooltipPosition=\"above\"\n >\n help\n </span>\n </div>\n </ng-container>\n <ng-container *ngIf=\"isAbstract\">\n <gn-ui-form-field-rich\n class=\"h-[8rem]\"\n [control]=\"formControl\"\n [label]=\"config.labelKey | translate\"\n [hint]=\"config.hintKey | translate\"\n ></gn-ui-form-field-rich>\n </ng-container>\n <ng-container *ngIf=\"isLicenses\">\n <gn-ui-form-field-license\n [control]=\"formControl\"\n [label]=\"config.labelKey | translate\"\n ></gn-ui-form-field-license>\n </ng-container>\n <ng-container *ngIf=\"isSimpleField\">\n <gn-ui-form-field-simple\n [type]=\"simpleType\"\n [control]=\"formControl\"\n [readonly]=\"isFieldLocked\"\n [invalid]=\"isFieldInvalid\"\n ></gn-ui-form-field-simple>\n </ng-container>\n <ng-container *ngIf=\"isFileField\">\n <gn-ui-form-field-file\n [control]=\"formControl\"\n [readonly]=\"isFieldLocked\"\n [invalid]=\"isFieldInvalid\"\n ></gn-ui-form-field-file>\n </ng-container>\n <ng-container *ngIf=\"isArrayField\">\n <gn-ui-form-field-array></gn-ui-form-field-array>\n </ng-container>\n <ng-container *ngIf=\"isObjectField\">\n <gn-ui-form-field-object></gn-ui-form-field-object>\n </ng-container>\n <ng-container *ngIf=\"isSpatialExtentField\">\n <gn-ui-form-field-spatial-extent></gn-ui-form-field-spatial-extent>\n </ng-container>\n <ng-container *ngIf=\"isTemporalExtentField\">\n <gn-ui-form-field-temporal-extent></gn-ui-form-field-temporal-extent>\n </ng-container>\n <div\n *ngIf=\"isFieldInvalid && config.invalidHintKey\"\n class=\"mt-2 text-pink-500 text-sm field-invalid-hint\"\n >\n {{ config.invalidHintKey | translate }}\n </div>\n</ng-template>\n" }]
34112
+ }], ctorParameters: function () { return []; }, propDecorators: { model: [{
34113
+ type: Input
34114
+ }], config: [{
34115
+ type: Input
34116
+ }], value: [{
34117
+ type: Input
34118
+ }], valueChange: [{
34119
+ type: Output
34120
+ }], titleInput: [{
34121
+ type: ViewChild,
34122
+ args: ['titleInput']
34123
+ }] } });
34124
+
33305
34125
  class RecordFormComponent {
33306
34126
  constructor(facade) {
33307
34127
  this.facade = facade;
@@ -33317,11 +34137,11 @@ class RecordFormComponent {
33317
34137
  return field.config.model;
33318
34138
  }
33319
34139
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: RecordFormComponent, deps: [{ token: EditorFacade }], target: i0.ɵɵFactoryTarget.Component }); }
33320
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: RecordFormComponent, isStandalone: true, selector: "gn-ui-record-form", ngImport: i0, template: "<div class=\"flex flex-col gap-6 p-6\">\n <ng-container *ngFor=\"let field of fields$ | async; trackBy: fieldTracker\">\n <gn-ui-form-field\n *ngIf=\"field.config.formFieldConfig && !field.config.hidden\"\n [config]=\"field.config.formFieldConfig\"\n [value]=\"field.value\"\n (valueChange)=\"handleFieldValueChange(field, $event)\"\n ></gn-ui-form-field>\n </ng-container>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1$3.AsyncPipe, name: "async" }, { kind: "ngmodule", type: UiInputsModule }, { kind: "component", type: FormFieldComponent, selector: "gn-ui-form-field", inputs: ["config", "value"], outputs: ["valueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
34140
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: RecordFormComponent, isStandalone: true, selector: "gn-ui-record-form", ngImport: i0, template: "<div class=\"flex flex-col gap-6 p-6\">\n <ng-container *ngFor=\"let field of fields$ | async; trackBy: fieldTracker\">\n <gn-ui-form-field\n *ngIf=\"field.config.formFieldConfig && !field.config.hidden\"\n [model]=\"field.config.model\"\n [config]=\"field.config.formFieldConfig\"\n [value]=\"field.value\"\n (valueChange)=\"handleFieldValueChange(field, $event)\"\n ></gn-ui-form-field>\n </ng-container>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1$3.AsyncPipe, name: "async" }, { kind: "component", type: FormFieldComponent, selector: "gn-ui-form-field", inputs: ["model", "config", "value"], outputs: ["valueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
33321
34141
  }
33322
34142
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: RecordFormComponent, decorators: [{
33323
34143
  type: Component,
33324
- args: [{ selector: 'gn-ui-record-form', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, UiInputsModule], template: "<div class=\"flex flex-col gap-6 p-6\">\n <ng-container *ngFor=\"let field of fields$ | async; trackBy: fieldTracker\">\n <gn-ui-form-field\n *ngIf=\"field.config.formFieldConfig && !field.config.hidden\"\n [config]=\"field.config.formFieldConfig\"\n [value]=\"field.value\"\n (valueChange)=\"handleFieldValueChange(field, $event)\"\n ></gn-ui-form-field>\n </ng-container>\n</div>\n" }]
34144
+ args: [{ selector: 'gn-ui-record-form', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, FormFieldComponent], template: "<div class=\"flex flex-col gap-6 p-6\">\n <ng-container *ngFor=\"let field of fields$ | async; trackBy: fieldTracker\">\n <gn-ui-form-field\n *ngIf=\"field.config.formFieldConfig && !field.config.hidden\"\n [model]=\"field.config.model\"\n [config]=\"field.config.formFieldConfig\"\n [value]=\"field.value\"\n (valueChange)=\"handleFieldValueChange(field, $event)\"\n ></gn-ui-form-field>\n </ng-container>\n</div>\n" }]
33325
34145
  }], ctorParameters: function () { return [{ type: EditorFacade }]; } });
33326
34146
 
33327
34147
  const ROUTER_STATE_KEY = 'router';
@@ -33619,7 +34439,7 @@ class RouterEffects {
33619
34439
  * the search results happens
33620
34440
  */
33621
34441
  this.navigateToSearch$ = createEffect(() => this._actions$.pipe(navigation(this.routerConfig.searchRouteComponent, {
33622
- run: () => close(),
34442
+ run: () => closeMetadata(),
33623
34443
  })));
33624
34444
  this.navigateBack$ = createEffect(() => this._actions$.pipe(ofType(backAction), tap$1(() => this._location.back())), { dispatch: false });
33625
34445
  this.navigateForward$ = createEffect(() => this._actions$.pipe(ofType(forwardAction), tap$1(() => this._location.forward())), { dispatch: false });
@@ -33689,5 +34509,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
33689
34509
  * Generated bundle index. Do not edit.
33690
34510
  */
33691
34511
 
33692
- export { ADD_RESULTS, ADD_SEARCH, AbstractAction, AddLayerFromCatalogComponent, AddLayerRecordPreviewComponent, AddResults, AddSearch, AnchorLinkDirective, ApiCardComponent, AuthService, AutocompleteComponent, AvatarComponent, AvatarServiceInterface, BLOCK_MODEL_FIXTURE, BadgeComponent, BaseReader, ButtonComponent, CLEAR_ERROR, CLEAR_RESULTS, CONFIG_MALFORMED, CONFIG_MINIMAL, CONFIG_MISSING_MANDATORY, CONFIG_OK, CONFIG_UNRECOGNIZED_KEYS, CONFIG_WITH_TRANSLATIONS, CONFIG_WRONG_LANGUAGE_CODE, CarouselComponent, CatalogTitleComponent, ChartComponent, ChartViewComponent, CheckToggleComponent, CheckboxComponent, ChipsInputComponent, ClearError, ClearResults, ColorScaleComponent, ContentGhostComponent, CopyTextButtonComponent, DEFAULT_BASELAYER_CONTEXT, DEFAULT_GN4_LOGIN_URL, DEFAULT_LANG, DEFAULT_PAGE_SIZE, DEFAULT_RESULTS_LAYOUT_CONFIG, DEFAULT_SEARCH_KEY, DEFAULT_STYLE_FIXTURE, DEFAULT_STYLE_HL_FIXTURE, DEFAULT_VIEW, DataService, DataViewComponent, DataViewPermalinkComponent, DataViewShareComponent, DataViewWebComponentComponent, DateRangePickerComponent, DefaultRouterModule, DownloadItemComponent, DownloadsListComponent, DragAndDropFileInputComponent, DropdownMultiselectComponent, DropdownSelectorComponent, EDITOR_FEATURE_KEY, EMPTY_BLOCK_MODEL_FIXTURE, ES_QUERY_FIELDS_PRIORITY, ES_RESOURCES_VALUES, ES_SOURCE_SUMMARY, EditableLabelDirective, EditorFacade, EditorService, ElasticsearchService, EmbeddedTranslateLoader, ErrorType, ExpandablePanelButtonComponent, ExpandablePanelComponent, ExternalViewerButtonComponent, FACET_ITEM_FIXTURE, FEATURE_MAP_OPTIONS, FIELDS_BRIEF, FIELDS_SUMMARY, FILTER_GEOMETRY, FORMATS, FacetBlockComponent, FacetBlockStubComponent, FacetItemComponent, FacetItemStubComponent, FacetListComponent, FacetsContainerComponent, FacetsModule, FavoriteStarComponent, FavoritesService, FeatureAuthModule, FeatureCatalogModule, FeatureDatavizModule, FeatureDetailComponent, FeatureEditorModule, FeatureInfoService, FeatureMapModule, FeatureRecordModule, FeatureSearchModule, FetchError, FieldsService, FigureComponent, FigureContainerComponent, FileTranslateLoader, FilterDropdownComponent, FormFieldArrayComponent, FormFieldComponent, FormFieldFileComponent, FormFieldObjectComponent, FormFieldRichComponent, FormFieldSimpleComponent, FormFieldSpatialExtentComponent, FormFieldTemporalExtentComponent, FuzzySearchComponent, GN_UI_VERSION, GeoTableViewComponent, GeocodingComponent, Gn4Converter, Gn4PlatformMapper, Gn4PlatformService, Gn4Repository, Gn4SettingsService, GravatarService, HttpLoaderFactory, I18nInterceptor, ImageFallbackDirective, ImageOverlayPreviewComponent, InteractiveTableColumnComponent, InteractiveTableComponent, Iso191153Converter, Iso19139Converter, LANGUAGES_LIST, LANGUAGE_NAMES, LANGUAGE_STORAGE_KEY, LANG_2_TO_3_MAPPER, LANG_3_TO_2_MAPPER, LOGIN_URL, LONLAT_CRS_CODES, LangService, LanguageSwitcherComponent, LayersPanelComponent, LinkCardComponent, LinkClassifierService, LinkUsage, LoadingMaskComponent, LogService, MAP_CONFIG_FIXTURE, MAP_FEATURE_KEY, METADATA_LANGUAGE, MY_FORMATS, MapComponent, MapContainerComponent, MapContextComponent, MapContextLayerTypeEnum, MapContextService, MapFacade, MapInstanceDirective, MapManagerService, MapStyleService, MapUtilsService, MapViewComponent, MarkdownParserComponent, MaxLinesComponent, mdview_actions as MdViewActions, MdViewFacade, MetadataCatalogComponent, MetadataContactComponent, MetadataInfoComponent, MetadataLinkType, MetadataQualityComponent, MetadataQualityItemComponent, MyOrgService, NavigationButtonComponent, ORGANIZATIONS_STRATEGY, ORGANIZATION_URL_TOKEN, OrganisationPreviewComponent, OrganisationsComponent, OrganisationsFilterComponent, OrganisationsResultComponent, OrganizationsFromGroupsService, OrganizationsFromMetadataService, PAGINATE, PARSE_DELIMITER, PATCH_RESULTS_AGGREGATIONS, PROXY_PATH, Paginate, PaginationButtonsComponent, PaginationComponent, PatchResultsAggregations, PopupAlertComponent, ProgressBarComponent, ProxyService, QUERY_FIELDS, RECORD_URL_TOKEN, REQUEST_MORE_ON_AGGREGATION, REQUEST_MORE_RESULTS, REQUEST_NEW_RESULTS, RESULTS_LAYOUT_CONFIG, ROUTER_CONFIG, ROUTER_ROUTE_DATASET, ROUTER_ROUTE_SEARCH, ROUTER_STATE_KEY, ROUTE_PARAMS, RecordApiFormComponent, RecordFormComponent, RecordMetricComponent, RecordPreviewCardComponent, RecordPreviewComponent, RecordPreviewFeedComponent, RecordPreviewListComponent, RecordPreviewRowComponent, RecordPreviewTextComponent, RecordPreviewTitleComponent, RecordsMetricsComponent, RecordsService, RelatedRecordCardComponent, RequestMoreOnAggregation, RequestMoreResults, RequestNewResults, ResultsHitsContainerComponent, ResultsHitsNumberComponent, ResultsLayoutComponent, ResultsLayoutConfigItem, ResultsListComponent, ResultsListContainerComponent, ResultsListItemComponent, ResultsTableComponent, RouterEffects, RouterFacade, RouterService, SEARCH_FEATURE_KEY, SET_CONFIG_AGGREGATIONS, SET_CONFIG_FILTERS, SET_CONFIG_REQUEST_FIELDS, SET_ERROR, SET_FAVORITES_ONLY, SET_FILTERS, SET_INCLUDE_ON_AGGREGATION, SET_PAGE_SIZE, SET_RESULTS_AGGREGATIONS, SET_RESULTS_HITS, SET_RESULTS_LAYOUT, SET_SEARCH, SET_SORT_BY, SET_SPATIAL_FILTER_ENABLED, SearchEffects, SearchFacade, SearchInputComponent, SearchResultsErrorComponent, SearchRouterContainerDirective, SearchService, SearchStateContainerDirective, SelectionService, SetConfigAggregations, SetConfigFilters, SetConfigRequestFields, SetError, SetFavoritesOnly, SetFilters, SetIncludeOnAggregation, SetPageSize, SetResultsAggregations, SetResultsHits, SetResultsLayout, SetSearch, SetSortBy, SetSpatialFilterEnabled, SiteTitleComponent, SortByComponent, SourceLabelComponent, SourcesService, SpinningLoaderComponent, StarToggleComponent, StepBarComponent, StickyHeaderComponent, SupportedTypes, TABLE_ITEM_FIXTURE, TABLE_ITEM_FIXTURE_HAB, THUMBNAIL_PLACEHOLDER, TRANSLATE_DEFAULT_CONFIG, TRANSLATE_WITH_OVERRIDES_CONFIG, TableComponent, TableViewComponent, TextAreaComponent, TextInputComponent, ThemeService, ThumbnailComponent, UPDATE_CONFIG_AGGREGATIONS, UPDATE_FILTERS, UPDATE_REQUEST_AGGREGATION_TERM, UiCatalogModule, UiDatavizModule, UiElementsModule, FacetsModule$1 as UiFacetsModule, UiInputsModule, UiLayoutModule, UiMapModule, UiSearchModule, UiWidgetsModule, UpdateConfigAggregations, UpdateFilters, UserPreviewComponent, UtilI18nModule, UtilSharedModule, ViewportIntersectorComponent, WEB_COMPONENT_EMBEDDER_URL, WFS_MAX_FEATURES, WizardComponent, WizardFieldComponent, WizardFieldType, WizardService, WizardSummarizeComponent, _reset, addLayer, changeLayerOrder, checkFileFormat, clearLayerError, createFuzzyFilter, currentPage, defaultMapOptions, downgradeImage, downsizeImage, dragPanCondition, dropEmptyTranslations, editorReducer, findConverterForDocument, getArrayItem, getAsArray, getAsUrl, getBadgeColor, getCustomTranslations, getError, getFavoritesOnly, getFileFormat, getFileFormatFromServiceOutput, getFirstValue, getFormatPriority, getGeometryFromGeoJSON, getGlobalConfig, getJsonDataItemsProxy, getLangFromBrowser, getLinkLabel, getLinkPriority, getMapLayers, getMapState, getMetadataQualityConfig, getMimeTypeForFormat, getOptionalMapConfig, getOptionalSearchConfig, getPageSize, getSearchConfigAggregations, getSearchFilters, getSearchResults, getSearchResultsAggregations, getSearchResultsHits, getSearchResultsLayout, getSearchResultsLoading, getSearchSortBy, getSearchState, getSearchStateSearch, getSpatialFilterEnabled, getTemporalRangeUnion, getThemeConfig, initSearch, initialEditorState, initialMapState, initialState, isConfigLoaded, isEndOfResults, isFormatInQueryParam, loadAppConfig, mapContact, mapKeywords, mapLogo, mapOrganization, mapReducer, markRecordAsChanged, megabytesToBytes, mimeTypeToFormat, mouseWheelZoomCondition, openDataset, openRecord, parse, placeholder, propagateToDocumentOnly, provideGn4, provideRepositoryUrl, readDataset, readDatasetHeaders, reducer$2 as reducer, reducerSearch, removeLayer, removeSearchParams, removeWhitespace, saveRecord, saveRecordFailure, saveRecordSuccess, selectEditorState, selectFallback, selectFallbackFields, selectField, selectRecord, selectRecordChangedSinceSave, selectRecordFields, selectRecordFieldsConfig, selectRecordSaveError, selectRecordSaving, selectTranslatedField, selectTranslatedValue, setLayerError, sortByFromString, sortByToString, sortByToStrings, stripHtml, toDate, totalPages, updateLayer, updateRecordField };
34512
+ export { ADD_RESULTS, ADD_SEARCH, AbstractAction, AddLayerFromCatalogComponent, AddLayerRecordPreviewComponent, AddResults, AddSearch, AnchorLinkDirective, ApiCardComponent, AuthService, AutocompleteComponent, AvatarComponent, AvatarServiceInterface, BLOCK_MODEL_FIXTURE, BadgeComponent, BaseReader, ButtonComponent, CLEAR_ERROR, CLEAR_RESULTS, CONFIG_MALFORMED, CONFIG_MINIMAL, CONFIG_MISSING_MANDATORY, CONFIG_OK, CONFIG_UNRECOGNIZED_KEYS, CONFIG_WITH_TRANSLATIONS, CONFIG_WRONG_LANGUAGE_CODE, CarouselComponent, CatalogTitleComponent, ChartComponent, ChartViewComponent, CheckToggleComponent, CheckboxComponent, ChipsInputComponent, ClearError, ClearResults, ColorScaleComponent, ContentGhostComponent, CopyTextButtonComponent, DEFAULT_BASELAYER_CONTEXT, DEFAULT_GN4_LOGIN_URL, DEFAULT_LANG, DEFAULT_PAGE_SIZE, DEFAULT_RESULTS_LAYOUT_CONFIG, DEFAULT_SEARCH_KEY, DEFAULT_STYLE_FIXTURE, DEFAULT_STYLE_HL_FIXTURE, DEFAULT_VIEW, DataService, DataViewComponent, DataViewPermalinkComponent, DataViewShareComponent, DataViewWebComponentComponent, DateRangePickerComponent, DefaultRouterModule, DownloadItemComponent, DownloadsListComponent, DragAndDropFileInputComponent, DropdownMultiselectComponent, DropdownSelectorComponent, EDITOR_FEATURE_KEY, EMPTY_BLOCK_MODEL_FIXTURE, ES_QUERY_FIELDS_PRIORITY, ES_RESOURCES_VALUES, ES_SOURCE_SUMMARY, EditableLabelDirective, EditorFacade, EditorService, ElasticsearchService, EmbeddedTranslateLoader, ErrorType, ExpandablePanelButtonComponent, ExpandablePanelComponent, ExternalViewerButtonComponent, FACET_ITEM_FIXTURE, FEATURE_MAP_OPTIONS, FIELDS_BRIEF, FIELDS_SUMMARY, FILTER_GEOMETRY, FORMATS, FacetBlockComponent, FacetBlockStubComponent, FacetItemComponent, FacetItemStubComponent, FacetListComponent, FacetsContainerComponent, FacetsModule, FavoriteStarComponent, FavoritesService, FeatureAuthModule, FeatureCatalogModule, FeatureDatavizModule, FeatureDetailComponent, FeatureEditorModule, FeatureInfoService, FeatureMapModule, FeatureNotificationsModule, FeatureRecordModule, FeatureSearchModule, FetchError, FieldsService, FigureComponent, FigureContainerComponent, FileTranslateLoader, FilterDropdownComponent, FormFieldWrapperComponent, FuzzySearchComponent, GN_UI_VERSION, GeoTableViewComponent, GeocodingComponent, Gn4Converter, Gn4PlatformMapper, Gn4PlatformService, Gn4Repository, Gn4SettingsService, GravatarService, HttpLoaderFactory, I18nInterceptor, ImageFallbackDirective, ImageOverlayPreviewComponent, InteractiveTableColumnComponent, InteractiveTableComponent, Iso191153Converter, Iso19139Converter, LANGUAGES_LIST, LANGUAGE_NAMES, LANGUAGE_STORAGE_KEY, LANG_2_TO_3_MAPPER, LANG_3_TO_2_MAPPER, LOGIN_URL, LONLAT_CRS_CODES, LangService, LanguageSwitcherComponent, LayersPanelComponent, LinkCardComponent, LinkClassifierService, LinkUsage, LoadingMaskComponent, LogService, MAP_CONFIG_FIXTURE, MAP_FEATURE_KEY, METADATA_LANGUAGE, MY_FORMATS, MapComponent, MapContainerComponent, MapContextComponent, MapContextLayerTypeEnum, MapContextService, MapFacade, MapInstanceDirective, MapManagerService, MapStyleService, MapUtilsService, MapViewComponent, MarkdownEditorComponent, MarkdownParserComponent, MaxLinesComponent, mdview_actions as MdViewActions, MdViewFacade, MetadataCatalogComponent, MetadataContactComponent, MetadataInfoComponent, MetadataLinkType, MetadataQualityComponent, MetadataQualityItemComponent, MyOrgService, NavigationButtonComponent, NotificationComponent, NotificationsContainerComponent, NotificationsService, ORGANIZATIONS_STRATEGY, ORGANIZATION_URL_TOKEN, OrganisationPreviewComponent, OrganisationsComponent, OrganisationsFilterComponent, OrganisationsResultComponent, OrganizationsFromGroupsService, OrganizationsFromMetadataService, PAGINATE, PARSE_DELIMITER, PATCH_RESULTS_AGGREGATIONS, PROXY_PATH, Paginate, PaginationButtonsComponent, PaginationComponent, PatchResultsAggregations, PopupAlertComponent, ProgressBarComponent, ProxyService, QUERY_FIELDS, RECORD_URL_TOKEN, REQUEST_MORE_ON_AGGREGATION, REQUEST_MORE_RESULTS, REQUEST_NEW_RESULTS, RESULTS_LAYOUT_CONFIG, ROUTER_CONFIG, ROUTER_ROUTE_DATASET, ROUTER_ROUTE_SEARCH, ROUTER_STATE_KEY, ROUTE_PARAMS, RecordApiFormComponent, RecordFormComponent, RecordMetricComponent, RecordPreviewCardComponent, RecordPreviewComponent, RecordPreviewFeedComponent, RecordPreviewListComponent, RecordPreviewRowComponent, RecordPreviewTextComponent, RecordPreviewTitleComponent, RecordsMetricsComponent, RecordsService, RelatedRecordCardComponent, RequestMoreOnAggregation, RequestMoreResults, RequestNewResults, ResultsHitsContainerComponent, ResultsHitsNumberComponent, ResultsLayoutComponent, ResultsLayoutConfigItem, ResultsListComponent, ResultsListContainerComponent, ResultsListItemComponent, ResultsTableComponent, RouterEffects, RouterFacade, RouterService, SEARCH_FEATURE_KEY, SET_CONFIG_AGGREGATIONS, SET_CONFIG_FILTERS, SET_CONFIG_REQUEST_FIELDS, SET_ERROR, SET_FAVORITES_ONLY, SET_FILTERS, SET_INCLUDE_ON_AGGREGATION, SET_PAGE_SIZE, SET_RESULTS_AGGREGATIONS, SET_RESULTS_HITS, SET_RESULTS_LAYOUT, SET_SEARCH, SET_SORT_BY, SET_SPATIAL_FILTER_ENABLED, SearchEffects, SearchFacade, SearchInputComponent, SearchResultsErrorComponent, SearchRouterContainerDirective, SearchService, SearchStateContainerDirective, SelectionService, SetConfigAggregations, SetConfigFilters, SetConfigRequestFields, SetError, SetFavoritesOnly, SetFilters, SetIncludeOnAggregation, SetPageSize, SetResultsAggregations, SetResultsHits, SetResultsLayout, SetSearch, SetSortBy, SetSpatialFilterEnabled, SiteTitleComponent, SortByComponent, SourceLabelComponent, SourcesService, SpinningLoaderComponent, StarToggleComponent, StepBarComponent, StickyHeaderComponent, SupportedTypes, TABLE_ITEM_FIXTURE, TABLE_ITEM_FIXTURE_HAB, THUMBNAIL_PLACEHOLDER, TRANSLATE_DEFAULT_CONFIG, TRANSLATE_WITH_OVERRIDES_CONFIG, TableComponent, TableViewComponent, TextAreaComponent, TextInputComponent, ThemeService, ThumbnailComponent, UPDATE_CONFIG_AGGREGATIONS, UPDATE_FILTERS, UPDATE_REQUEST_AGGREGATION_TERM, UiCatalogModule, UiDatavizModule, UiElementsModule, FacetsModule$1 as UiFacetsModule, UiInputsModule, UiLayoutModule, UiMapModule, UiSearchModule, UiWidgetsModule, UpdateConfigAggregations, UpdateFilters, UserPreviewComponent, UtilI18nModule, UtilSharedModule, ViewportIntersectorComponent, WEB_COMPONENT_EMBEDDER_URL, WFS_MAX_FEATURES, WizardComponent, WizardFieldComponent, WizardFieldType, WizardService, WizardSummarizeComponent, _reset, addLayer, changeLayerOrder, checkFileFormat, clearLayerError, createFuzzyFilter, currentPage, defaultMapOptions, downgradeImage, downsizeImage, dragPanCondition, dropEmptyTranslations, editorReducer, findConverterForDocument, getArrayItem, getAsArray, getAsUrl, getBadgeColor, getCustomTranslations, getError, getFavoritesOnly, getFileFormat, getFileFormatFromServiceOutput, getFirstValue, getFormatPriority, getGeometryFromGeoJSON, getGlobalConfig, getJsonDataItemsProxy, getLangFromBrowser, getLinkLabel, getLinkPriority, getMapLayers, getMapState, getMetadataQualityConfig, getMimeTypeForFormat, getOptionalMapConfig, getOptionalSearchConfig, getPageSize, getSearchConfigAggregations, getSearchFilters, getSearchResults, getSearchResultsAggregations, getSearchResultsHits, getSearchResultsLayout, getSearchResultsLoading, getSearchSortBy, getSearchState, getSearchStateSearch, getSpatialFilterEnabled, getTemporalRangeUnion, getThemeConfig, initSearch, initialEditorState, initialMapState, initialState, isConfigLoaded, isEndOfResults, isFormatInQueryParam, loadAppConfig, mapContact, mapKeywords, mapLogo, mapOrganization, mapReducer, markRecordAsChanged, megabytesToBytes, mimeTypeToFormat, mouseWheelZoomCondition, openDataset, openRecord, parse, placeholder, propagateToDocumentOnly, provideGn4, provideRepositoryUrl, readDataset, readDatasetHeaders, reducer$2 as reducer, reducerSearch, removeLayer, removeSearchParams, removeWhitespace, saveRecord, saveRecordFailure, saveRecordSuccess, selectEditorState, selectFallback, selectFallbackFields, selectField, selectRecord, selectRecordChangedSinceSave, selectRecordFields, selectRecordFieldsConfig, selectRecordSaveError, selectRecordSaving, selectTranslatedField, selectTranslatedValue, setLayerError, sortByFromString, sortByToString, sortByToStrings, stripHtml, toDate, totalPages, updateLayer, updateRecordField };
33693
34513
  //# sourceMappingURL=geonetwork-ui.mjs.map