geonetwork-ui 2.3.0-dev.6e2b8bea → 2.3.0-dev.c22cb78a

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 (246) hide show
  1. package/esm2022/index.mjs +2 -1
  2. package/esm2022/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.mjs +5 -1
  3. package/esm2022/libs/data-access/gn4/src/openapi/api/records.api.service.mjs +35 -7
  4. package/esm2022/libs/data-access/gn4/src/openapi/model/models.mjs +1 -2
  5. package/esm2022/libs/feature/dataviz/src/lib/service/data.service.mjs +2 -2
  6. package/esm2022/libs/feature/editor/src/index.mjs +2 -2
  7. package/esm2022/libs/feature/editor/src/lib/+state/editor.facade.mjs +6 -2
  8. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-array/form-field-array.component.mjs +11 -0
  9. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-file/form-field-file.component.mjs +28 -0
  10. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-object/form-field-object.component.mjs +11 -0
  11. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.mjs +45 -0
  12. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-simple/form-field-simple.component.mjs +50 -0
  13. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-spatial-extent/form-field-spatial-extent.component.mjs +11 -0
  14. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-temporal-extent/form-field-temporal-extent.component.mjs +11 -0
  15. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.mjs +107 -0
  16. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field.model.mjs +2 -0
  17. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/index.mjs +10 -0
  18. package/esm2022/libs/feature/editor/src/lib/components/record-form/record-form.component.mjs +29 -0
  19. package/esm2022/libs/feature/editor/src/lib/feature-editor.module.mjs +10 -10
  20. package/esm2022/libs/feature/editor/src/lib/models/fields.model.mjs +1 -1
  21. package/esm2022/libs/feature/map/src/lib/add-layer-from-file/add-layer-from-file.component.mjs +3 -3
  22. package/esm2022/libs/feature/notifications/src/index.mjs +4 -0
  23. package/esm2022/libs/feature/notifications/src/lib/feature-notifications.module.mjs +18 -0
  24. package/esm2022/libs/feature/notifications/src/lib/notification.model.mjs +2 -0
  25. package/esm2022/libs/feature/notifications/src/lib/notifications-container/notifications-container.component.mjs +49 -0
  26. package/esm2022/libs/feature/notifications/src/lib/notifications.service.mjs +29 -0
  27. package/esm2022/libs/feature/search/src/lib/results-table/results-table.component.mjs +3 -3
  28. package/esm2022/libs/ui/catalog/src/lib/organisation-preview/organisation-preview.component.mjs +3 -3
  29. package/esm2022/libs/ui/elements/src/index.mjs +15 -15
  30. package/esm2022/libs/ui/elements/src/lib/image-overlay-preview/image-overlay-preview.component.mjs +5 -5
  31. package/esm2022/libs/ui/elements/src/lib/markdown-editor/markdown-editor.component.mjs +45 -0
  32. package/esm2022/libs/ui/elements/src/lib/metadata-info/metadata-info.component.mjs +3 -3
  33. package/esm2022/libs/ui/elements/src/lib/notification/notification.component.mjs +34 -0
  34. package/esm2022/libs/ui/elements/src/lib/record-api-form/record-api-form.component.mjs +3 -3
  35. package/esm2022/libs/ui/elements/src/lib/thumbnail/thumbnail.component.mjs +4 -3
  36. package/esm2022/libs/ui/elements/src/lib/ui-elements.module.mjs +6 -5
  37. package/esm2022/libs/ui/inputs/src/index.mjs +1 -2
  38. package/esm2022/libs/ui/inputs/src/lib/button/button.component.mjs +2 -1
  39. package/esm2022/libs/ui/inputs/src/lib/files-drop/files-drop.directive.mjs +59 -0
  40. package/esm2022/libs/ui/inputs/src/lib/image-input/image-input.component.mjs +183 -0
  41. package/esm2022/libs/ui/inputs/src/lib/ui-inputs.module.mjs +10 -23
  42. package/esm2022/libs/ui/layout/src/index.mjs +6 -5
  43. package/esm2022/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.mjs +18 -0
  44. package/esm2022/libs/util/shared/src/lib/utils/bytes-convert.mjs +4 -0
  45. package/esm2022/libs/util/shared/src/lib/utils/image-resize.mjs +60 -0
  46. package/esm2022/libs/util/shared/src/lib/utils/index.mjs +8 -6
  47. package/esm2022/translations/de.json +18 -0
  48. package/esm2022/translations/en.json +18 -0
  49. package/esm2022/translations/es.json +18 -0
  50. package/esm2022/translations/fr.json +18 -0
  51. package/esm2022/translations/it.json +18 -0
  52. package/esm2022/translations/nl.json +18 -0
  53. package/esm2022/translations/pt.json +18 -0
  54. package/fesm2022/geonetwork-ui.mjs +1766 -1142
  55. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  56. package/index.d.ts +1 -0
  57. package/index.d.ts.map +1 -1
  58. package/index.ts +1 -0
  59. package/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.d.ts.map +1 -1
  60. package/libs/data-access/gn4/src/openapi/api/records.api.service.d.ts +9 -5
  61. package/libs/data-access/gn4/src/openapi/api/records.api.service.d.ts.map +1 -1
  62. package/libs/data-access/gn4/src/openapi/model/models.d.ts +0 -1
  63. package/libs/data-access/gn4/src/openapi/model/models.d.ts.map +1 -1
  64. package/libs/feature/editor/src/index.d.ts +1 -1
  65. package/libs/feature/editor/src/index.d.ts.map +1 -1
  66. package/libs/feature/editor/src/lib/+state/editor.facade.d.ts +8 -5
  67. package/libs/feature/editor/src/lib/+state/editor.facade.d.ts.map +1 -1
  68. 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
  69. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-array/form-field-array.component.d.ts.map +1 -0
  70. 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
  71. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-file/form-field-file.component.d.ts.map +1 -0
  72. 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
  73. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-object/form-field-object.component.d.ts.map +1 -0
  74. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.d.ts +16 -0
  75. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.d.ts.map +1 -0
  76. 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
  77. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-simple/form-field-simple.component.d.ts.map +1 -0
  78. 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
  79. 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
  80. 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
  81. 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
  82. package/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field.component.d.ts +8 -3
  83. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts.map +1 -0
  84. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.model.d.ts.map +1 -0
  85. package/libs/feature/editor/src/lib/components/record-form/form-field/index.d.ts.map +1 -0
  86. package/libs/feature/editor/src/lib/{record-form → components/record-form}/record-form.component.d.ts +3 -3
  87. package/libs/feature/editor/src/lib/components/record-form/record-form.component.d.ts.map +1 -0
  88. package/libs/feature/editor/src/lib/feature-editor.module.d.ts +1 -1
  89. package/libs/feature/editor/src/lib/feature-editor.module.d.ts.map +1 -1
  90. package/libs/feature/editor/src/lib/models/fields.model.d.ts +1 -1
  91. package/libs/feature/notifications/src/index.d.ts +4 -0
  92. package/libs/feature/notifications/src/index.d.ts.map +1 -0
  93. package/libs/feature/notifications/src/lib/feature-notifications.module.d.ts +7 -0
  94. package/libs/feature/notifications/src/lib/feature-notifications.module.d.ts.map +1 -0
  95. package/libs/feature/notifications/src/lib/notification.model.d.ts +7 -0
  96. package/libs/feature/notifications/src/lib/notification.model.d.ts.map +1 -0
  97. package/libs/feature/notifications/src/lib/notifications-container/notifications-container.component.d.ts +12 -0
  98. package/libs/feature/notifications/src/lib/notifications-container/notifications-container.component.d.ts.map +1 -0
  99. package/libs/feature/notifications/src/lib/notifications.service.d.ts +15 -0
  100. package/libs/feature/notifications/src/lib/notifications.service.d.ts.map +1 -0
  101. package/libs/ui/elements/src/index.d.ts +14 -14
  102. package/libs/ui/elements/src/index.d.ts.map +1 -1
  103. package/libs/ui/elements/src/lib/markdown-editor/markdown-editor.component.d.ts +13 -0
  104. package/libs/ui/elements/src/lib/markdown-editor/markdown-editor.component.d.ts.map +1 -0
  105. package/libs/ui/elements/src/lib/notification/notification.component.d.ts +13 -0
  106. package/libs/ui/elements/src/lib/notification/notification.component.d.ts.map +1 -0
  107. package/libs/ui/elements/src/lib/thumbnail/thumbnail.component.d.ts +1 -1
  108. package/libs/ui/elements/src/lib/thumbnail/thumbnail.component.d.ts.map +1 -1
  109. package/libs/ui/elements/src/lib/ui-elements.module.d.ts +20 -20
  110. package/libs/ui/inputs/src/index.d.ts +0 -1
  111. package/libs/ui/inputs/src/index.d.ts.map +1 -1
  112. package/libs/ui/inputs/src/lib/button/button.component.d.ts.map +1 -1
  113. package/libs/ui/inputs/src/lib/files-drop/files-drop.directive.d.ts +14 -0
  114. package/libs/ui/inputs/src/lib/files-drop/files-drop.directive.d.ts.map +1 -0
  115. package/libs/ui/inputs/src/lib/image-input/image-input.component.d.ts +44 -0
  116. package/libs/ui/inputs/src/lib/image-input/image-input.component.d.ts.map +1 -0
  117. package/libs/ui/inputs/src/lib/ui-inputs.module.d.ts +26 -33
  118. package/libs/ui/inputs/src/lib/ui-inputs.module.d.ts.map +1 -1
  119. package/libs/ui/layout/src/index.d.ts +5 -4
  120. package/libs/ui/layout/src/index.d.ts.map +1 -1
  121. package/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.d.ts +8 -0
  122. package/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.d.ts.map +1 -0
  123. package/libs/util/shared/src/lib/utils/bytes-convert.d.ts +2 -0
  124. package/libs/util/shared/src/lib/utils/bytes-convert.d.ts.map +1 -0
  125. package/libs/util/shared/src/lib/utils/image-resize.d.ts +3 -0
  126. package/libs/util/shared/src/lib/utils/image-resize.d.ts.map +1 -0
  127. package/libs/util/shared/src/lib/utils/index.d.ts +7 -5
  128. package/libs/util/shared/src/lib/utils/index.d.ts.map +1 -1
  129. package/package.json +1 -1
  130. package/src/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts +6 -0
  131. package/src/libs/data-access/gn4/src/openapi/api/records.api.service.ts +43 -12
  132. package/src/libs/data-access/gn4/src/openapi/model/models.ts +0 -1
  133. package/src/libs/data-access/gn4/src/spec.yaml +1 -1
  134. package/src/libs/feature/dataviz/src/lib/service/data.service.ts +1 -1
  135. package/src/libs/feature/editor/src/index.ts +1 -1
  136. package/src/libs/feature/editor/src/lib/+state/editor.facade.ts +8 -1
  137. package/src/libs/feature/editor/src/lib/components/overview-upload/overview-upload.component.html +8 -0
  138. package/src/libs/feature/editor/src/lib/components/overview-upload/overview-upload.component.ts +70 -0
  139. 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
  140. 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
  141. 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
  142. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.html +20 -0
  143. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.ts +44 -0
  144. 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
  145. 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
  146. 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
  147. package/src/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field.component.html +28 -4
  148. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts +121 -0
  149. package/src/libs/feature/editor/src/lib/components/record-form/record-form.component.css +0 -0
  150. package/src/libs/feature/editor/src/lib/{record-form → components/record-form}/record-form.component.html +1 -0
  151. package/src/libs/feature/editor/src/lib/{record-form → components/record-form}/record-form.component.ts +4 -4
  152. package/src/libs/feature/editor/src/lib/feature-editor.module.ts +9 -9
  153. package/src/libs/feature/editor/src/lib/models/fields.model.ts +1 -1
  154. package/src/libs/feature/map/src/lib/add-layer-from-file/add-layer-from-file.component.html +1 -1
  155. package/src/libs/feature/notifications/src/index.ts +3 -0
  156. package/src/libs/feature/notifications/src/lib/feature-notifications.module.ts +10 -0
  157. package/src/libs/feature/notifications/src/lib/notification.model.ts +6 -0
  158. package/src/libs/feature/notifications/src/lib/notifications-container/notifications-container.component.css +0 -0
  159. package/src/libs/feature/notifications/src/lib/notifications-container/notifications-container.component.html +17 -0
  160. package/src/libs/feature/notifications/src/lib/notifications-container/notifications-container.component.ts +44 -0
  161. package/src/libs/feature/notifications/src/lib/notifications.service.ts +27 -0
  162. package/src/libs/feature/search/src/lib/results-table/results-table.component.html +3 -3
  163. package/src/libs/ui/catalog/src/lib/organisation-preview/organisation-preview.component.html +5 -5
  164. package/src/libs/ui/elements/src/index.ts +14 -14
  165. package/src/libs/ui/elements/src/lib/image-overlay-preview/image-overlay-preview.component.html +1 -1
  166. package/src/libs/ui/elements/src/lib/markdown-editor/markdown-editor.component.css +0 -5
  167. package/src/libs/ui/elements/src/lib/markdown-editor/markdown-editor.component.html +0 -21
  168. package/src/libs/ui/elements/src/lib/markdown-editor/markdown-editor.component.ts +1 -14
  169. package/src/libs/ui/elements/src/lib/notification/notification.component.css +0 -0
  170. package/src/libs/ui/elements/src/lib/notification/notification.component.html +52 -0
  171. package/src/libs/ui/elements/src/lib/notification/notification.component.ts +31 -0
  172. package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.html +1 -1
  173. package/src/libs/ui/elements/src/lib/thumbnail/thumbnail.component.ts +5 -3
  174. package/src/libs/ui/elements/src/lib/ui-elements.module.ts +1 -1
  175. package/src/libs/ui/inputs/src/index.ts +0 -1
  176. package/src/libs/ui/inputs/src/lib/button/button.component.ts +1 -1
  177. package/src/libs/ui/inputs/src/lib/files-drop/files-drop.directive.ts +45 -0
  178. package/src/libs/ui/inputs/src/lib/image-input/image-input.component.css +0 -0
  179. package/src/libs/ui/inputs/src/lib/image-input/image-input.component.html +146 -0
  180. package/src/libs/ui/inputs/src/lib/image-input/image-input.component.ts +193 -0
  181. package/src/libs/ui/inputs/src/lib/ui-inputs.module.ts +3 -19
  182. package/src/libs/ui/layout/src/index.ts +5 -4
  183. package/src/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.css +0 -0
  184. package/src/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.html +18 -0
  185. package/src/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.ts +16 -0
  186. package/src/libs/util/shared/src/lib/utils/bytes-convert.ts +3 -0
  187. package/src/libs/util/shared/src/lib/utils/image-resize.ts +72 -0
  188. package/src/libs/util/shared/src/lib/utils/index.ts +7 -5
  189. package/tailwind.base.css +36 -0
  190. package/translations/de.json +18 -0
  191. package/translations/en.json +18 -0
  192. package/translations/es.json +18 -0
  193. package/translations/fr.json +18 -0
  194. package/translations/it.json +18 -0
  195. package/translations/nl.json +18 -0
  196. package/translations/pt.json +18 -0
  197. package/translations/sk.json +18 -0
  198. package/esm2022/libs/data-access/gn4/src/openapi/model/inlineObject3.api.model.mjs +0 -13
  199. package/esm2022/libs/feature/editor/src/lib/record-form/record-form.component.mjs +0 -30
  200. package/esm2022/libs/ui/inputs/src/lib/form-field/form-field-array/form-field-array.component.mjs +0 -11
  201. package/esm2022/libs/ui/inputs/src/lib/form-field/form-field-file/form-field-file.component.mjs +0 -27
  202. package/esm2022/libs/ui/inputs/src/lib/form-field/form-field-object/form-field-object.component.mjs +0 -11
  203. package/esm2022/libs/ui/inputs/src/lib/form-field/form-field-rich/form-field-rich.component.mjs +0 -27
  204. package/esm2022/libs/ui/inputs/src/lib/form-field/form-field-simple/form-field-simple.component.mjs +0 -49
  205. package/esm2022/libs/ui/inputs/src/lib/form-field/form-field-spatial-extent/form-field-spatial-extent.component.mjs +0 -11
  206. package/esm2022/libs/ui/inputs/src/lib/form-field/form-field-temporal-extent/form-field-temporal-extent.component.mjs +0 -11
  207. package/esm2022/libs/ui/inputs/src/lib/form-field/form-field.component.mjs +0 -76
  208. package/esm2022/libs/ui/inputs/src/lib/form-field/form-field.model.mjs +0 -2
  209. package/esm2022/libs/ui/inputs/src/lib/form-field/index.mjs +0 -10
  210. package/libs/data-access/gn4/src/openapi/model/inlineObject3.api.model.d.ts +0 -18
  211. package/libs/data-access/gn4/src/openapi/model/inlineObject3.api.model.d.ts.map +0 -1
  212. package/libs/feature/editor/src/lib/record-form/record-form.component.d.ts.map +0 -1
  213. package/libs/ui/inputs/src/lib/form-field/form-field-array/form-field-array.component.d.ts.map +0 -1
  214. package/libs/ui/inputs/src/lib/form-field/form-field-file/form-field-file.component.d.ts.map +0 -1
  215. package/libs/ui/inputs/src/lib/form-field/form-field-object/form-field-object.component.d.ts.map +0 -1
  216. package/libs/ui/inputs/src/lib/form-field/form-field-rich/form-field-rich.component.d.ts +0 -11
  217. package/libs/ui/inputs/src/lib/form-field/form-field-rich/form-field-rich.component.d.ts.map +0 -1
  218. package/libs/ui/inputs/src/lib/form-field/form-field-simple/form-field-simple.component.d.ts.map +0 -1
  219. package/libs/ui/inputs/src/lib/form-field/form-field-spatial-extent/form-field-spatial-extent.component.d.ts.map +0 -1
  220. package/libs/ui/inputs/src/lib/form-field/form-field-temporal-extent/form-field-temporal-extent.component.d.ts.map +0 -1
  221. package/libs/ui/inputs/src/lib/form-field/form-field.component.d.ts.map +0 -1
  222. package/libs/ui/inputs/src/lib/form-field/form-field.model.d.ts.map +0 -1
  223. package/libs/ui/inputs/src/lib/form-field/index.d.ts.map +0 -1
  224. package/src/libs/data-access/gn4/src/openapi/model/inlineObject3.api.model.ts +0 -18
  225. package/src/libs/ui/inputs/src/lib/form-field/form-field-rich/form-field-rich.component.html +0 -11
  226. package/src/libs/ui/inputs/src/lib/form-field/form-field-rich/form-field-rich.component.ts +0 -15
  227. package/src/libs/ui/inputs/src/lib/form-field/form-field.component.ts +0 -80
  228. /package/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field.model.d.ts +0 -0
  229. /package/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/index.d.ts +0 -0
  230. /package/src/libs/feature/editor/src/lib/{record-form/record-form.component.css → components/overview-upload/overview-upload.component.css} +0 -0
  231. /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
  232. /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
  233. /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
  234. /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
  235. /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
  236. /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
  237. /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
  238. /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
  239. /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
  240. /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
  241. /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
  242. /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
  243. /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
  244. /package/src/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field.component.css +0 -0
  245. /package/src/libs/{ui/inputs/src/lib → feature/editor/src/lib/components/record-form}/form-field/form-field.model.ts +0 -0
  246. /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, 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, 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, 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,16 @@ 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
76
  import * as i1$8 from '@ngrx/effects';
77
77
  import { createEffect, ofType, EffectsModule, Actions } from '@ngrx/effects';
78
78
  import tippy from 'tippy.js';
79
79
  import { valid as valid$1 } from 'geojson-validation';
80
80
  import { Polygon } from 'ol/geom';
81
81
  import { queryDataGouvFr, queryGeonames, queryGeoadmin } from '@geospatial-sdk/geocoding';
82
+ import { trigger, transition, animate, keyframes, style } from '@angular/animations';
82
83
  import { Chart, BarController, BarElement, CategoryScale, LinearScale, LineController, LineElement, PointElement, PieController, ArcElement, ScatterController, Tooltip, Colors, Legend } from 'chart.js';
83
84
  import * as i4$1 from '@angular/cdk/scrolling';
84
85
  import { ScrollingModule } from '@angular/cdk/scrolling';
@@ -6008,6 +6009,19 @@ class RecordsApiService {
6008
6009
  }
6009
6010
  this.encoder = this.configuration.encoder || new CustomHttpParameterCodec();
6010
6011
  }
6012
+ /**
6013
+ * @param consumes string[] mime-types
6014
+ * @return true: consumes contains 'multipart/form-data', false: otherwise
6015
+ */
6016
+ canConsumeForm(consumes) {
6017
+ const form = 'multipart/form-data';
6018
+ for (const consume of consumes) {
6019
+ if (form === consume) {
6020
+ return true;
6021
+ }
6022
+ }
6023
+ return false;
6024
+ }
6011
6025
  addToHttpParams(httpParams, value, key) {
6012
6026
  if (typeof value === 'object' && value instanceof Date === false) {
6013
6027
  httpParams = this.addToHttpParamsRecursive(httpParams, value);
@@ -8981,10 +8995,13 @@ class RecordsApiService {
8981
8995
  reportProgress: reportProgress,
8982
8996
  });
8983
8997
  }
8984
- putResource(metadataUuid, visibility, approved, inlineObject3ApiModel, observe = 'body', reportProgress = false, options) {
8998
+ putResource(metadataUuid, file, visibility, approved, observe = 'body', reportProgress = false, options) {
8985
8999
  if (metadataUuid === null || metadataUuid === undefined) {
8986
9000
  throw new Error('Required parameter metadataUuid was null or undefined when calling putResource.');
8987
9001
  }
9002
+ if (file === null || file === undefined) {
9003
+ throw new Error('Required parameter file was null or undefined when calling putResource.');
9004
+ }
8988
9005
  let queryParameters = new HttpParams({ encoder: this.encoder });
8989
9006
  if (visibility !== undefined && visibility !== null) {
8990
9007
  queryParameters = this.addToHttpParams(queryParameters, visibility, 'visibility');
@@ -9004,17 +9021,29 @@ class RecordsApiService {
9004
9021
  headers = headers.set('Accept', httpHeaderAcceptSelected);
9005
9022
  }
9006
9023
  // to determine the Content-Type header
9007
- const consumes = ['application/json'];
9008
- const httpContentTypeSelected = this.configuration.selectHeaderContentType(consumes);
9009
- if (httpContentTypeSelected !== undefined) {
9010
- headers = headers.set('Content-Type', httpContentTypeSelected);
9024
+ const consumes = ['multipart/form-data'];
9025
+ const canConsumeForm = this.canConsumeForm(consumes);
9026
+ let formParams;
9027
+ let useForm = false;
9028
+ let convertFormParamsToString = false;
9029
+ // use FormData to transmit files using content-type "multipart/form-data"
9030
+ // see https://stackoverflow.com/questions/4007969/application-x-www-form-urlencoded-or-multipart-form-data
9031
+ useForm = canConsumeForm;
9032
+ if (useForm) {
9033
+ formParams = new FormData();
9034
+ }
9035
+ else {
9036
+ formParams = new HttpParams({ encoder: this.encoder });
9037
+ }
9038
+ if (file !== undefined) {
9039
+ formParams = formParams.append('file', file) || formParams;
9011
9040
  }
9012
9041
  let responseType_ = 'json';
9013
9042
  if (httpHeaderAcceptSelected &&
9014
9043
  httpHeaderAcceptSelected.startsWith('text')) {
9015
9044
  responseType_ = 'text';
9016
9045
  }
9017
- return this.httpClient.post(`${this.configuration.basePath}/records/${encodeURIComponent(String(metadataUuid))}/attachments`, inlineObject3ApiModel, {
9046
+ return this.httpClient.post(`${this.configuration.basePath}/records/${encodeURIComponent(String(metadataUuid))}/attachments`, convertFormParamsToString ? formParams.toString() : formParams, {
9018
9047
  params: queryParameters,
9019
9048
  responseType: responseType_,
9020
9049
  withCredentials: this.configuration.withCredentials,
@@ -16236,18 +16265,6 @@ var GroupPrivilegeApiModel;
16236
16265
  * Do not edit the class manually.
16237
16266
  */
16238
16267
 
16239
- /**
16240
- * GeoNetwork 4.2.7 OpenAPI Documentation
16241
- * This is the description of the GeoNetwork OpenAPI. Use this API to manage your catalog.
16242
- *
16243
- * The version of the OpenAPI document: 4.2.7
16244
- * Contact: geonetwork-users@lists.sourceforge.net
16245
- *
16246
- * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
16247
- * https://openapi-generator.tech
16248
- * Do not edit the class manually.
16249
- */
16250
-
16251
16268
  /**
16252
16269
  * GeoNetwork 4.2.7 OpenAPI Documentation
16253
16270
  * This is the description of the GeoNetwork OpenAPI. Use this API to manage your catalog.
@@ -17399,7 +17416,15 @@ var de = {
17399
17416
  "downloads.format.unknown": "unbekannt",
17400
17417
  "downloads.wfs.featuretype.not.found": "Der Layer wurde nicht gefunden",
17401
17418
  dropFile: dropFile$6,
17419
+ "editor.record.loadError.body": "",
17420
+ "editor.record.loadError.closeMessage": "",
17421
+ "editor.record.loadError.title": "",
17402
17422
  "editor.record.publish": "",
17423
+ "editor.record.publishError.body": "",
17424
+ "editor.record.publishError.closeMessage": "",
17425
+ "editor.record.publishError.title": "",
17426
+ "editor.record.publishSuccess.body": "",
17427
+ "editor.record.publishSuccess.title": "",
17403
17428
  "editor.record.upToDate": "",
17404
17429
  "externalviewer.dataset.unnamed": "Datensatz aus dem Datahub",
17405
17430
  "facets.block.title.OrgForResource": "Organisation",
@@ -17414,6 +17439,16 @@ var de = {
17414
17439
  "facets.block.title.tag.default": "Stichwort",
17415
17440
  "facets.block.title.th_regions_tree.default": "Regionen",
17416
17441
  "favorite.not.authenticated.tooltip": "<div><a href=' {link} '>Anmelden</a>, um auf diese Funktion zuzugreifen</div>",
17442
+ "input.image.altTextPlaceholder": "",
17443
+ "input.image.delete": "",
17444
+ "input.image.displayAltTextInput": "",
17445
+ "input.image.displayUrlInput": "",
17446
+ "input.image.dropFileLabel": "",
17447
+ "input.image.selectFileLabel": "",
17448
+ "input.image.uploadErrorLabel": "",
17449
+ "input.image.uploadErrorRetry": "",
17450
+ "input.image.uploadProgressCancel": "",
17451
+ "input.image.uploadProgressLabel": "",
17417
17452
  "language.ca": "Katalanisch",
17418
17453
  "language.cs": "Tschechisch",
17419
17454
  "language.de": "Deutsch",
@@ -17751,7 +17786,15 @@ var en = {
17751
17786
  "downloads.format.unknown": "unknown",
17752
17787
  "downloads.wfs.featuretype.not.found": "The layer was not found",
17753
17788
  dropFile: dropFile$5,
17789
+ "editor.record.loadError.body": "The record could not be loaded:",
17790
+ "editor.record.loadError.closeMessage": "Understood",
17791
+ "editor.record.loadError.title": "Error loading record",
17754
17792
  "editor.record.publish": "Publish this record",
17793
+ "editor.record.publishError.body": "The record could not be published:",
17794
+ "editor.record.publishError.closeMessage": "Understood",
17795
+ "editor.record.publishError.title": "Error publishing record",
17796
+ "editor.record.publishSuccess.body": "The record was successfully published!",
17797
+ "editor.record.publishSuccess.title": "Publish success",
17755
17798
  "editor.record.upToDate": "This record is up to date",
17756
17799
  "externalviewer.dataset.unnamed": "Datahub layer",
17757
17800
  "facets.block.title.OrgForResource": "Organisation",
@@ -17766,6 +17809,16 @@ var en = {
17766
17809
  "facets.block.title.tag.default": "Tag",
17767
17810
  "facets.block.title.th_regions_tree.default": "Regions",
17768
17811
  "favorite.not.authenticated.tooltip": "<div><a href=' {link} '>Login</a> to access this feature</div>",
17812
+ "input.image.altTextPlaceholder": "Image alternate text",
17813
+ "input.image.delete": "Delete",
17814
+ "input.image.displayAltTextInput": "Alternate text",
17815
+ "input.image.displayUrlInput": "Enter a URL",
17816
+ "input.image.dropFileLabel": "or drop it here",
17817
+ "input.image.selectFileLabel": "Select an image",
17818
+ "input.image.uploadErrorLabel": "The image could not be uploaded",
17819
+ "input.image.uploadErrorRetry": "Retry",
17820
+ "input.image.uploadProgressCancel": "Cancel",
17821
+ "input.image.uploadProgressLabel": "Upload in progress...",
17769
17822
  "language.ca": "Catalan",
17770
17823
  "language.cs": "Czech",
17771
17824
  "language.de": "German",
@@ -18103,7 +18156,15 @@ var es = {
18103
18156
  "downloads.format.unknown": "",
18104
18157
  "downloads.wfs.featuretype.not.found": "",
18105
18158
  dropFile: dropFile$4,
18159
+ "editor.record.loadError.body": "",
18160
+ "editor.record.loadError.closeMessage": "",
18161
+ "editor.record.loadError.title": "",
18106
18162
  "editor.record.publish": "",
18163
+ "editor.record.publishError.body": "",
18164
+ "editor.record.publishError.closeMessage": "",
18165
+ "editor.record.publishError.title": "",
18166
+ "editor.record.publishSuccess.body": "",
18167
+ "editor.record.publishSuccess.title": "",
18107
18168
  "editor.record.upToDate": "",
18108
18169
  "externalviewer.dataset.unnamed": "",
18109
18170
  "facets.block.title.OrgForResource": "",
@@ -18118,6 +18179,16 @@ var es = {
18118
18179
  "facets.block.title.tag.default": "",
18119
18180
  "facets.block.title.th_regions_tree.default": "",
18120
18181
  "favorite.not.authenticated.tooltip": "",
18182
+ "input.image.altTextPlaceholder": "",
18183
+ "input.image.delete": "",
18184
+ "input.image.displayAltTextInput": "",
18185
+ "input.image.displayUrlInput": "",
18186
+ "input.image.dropFileLabel": "",
18187
+ "input.image.selectFileLabel": "",
18188
+ "input.image.uploadErrorLabel": "",
18189
+ "input.image.uploadErrorRetry": "",
18190
+ "input.image.uploadProgressCancel": "",
18191
+ "input.image.uploadProgressLabel": "",
18121
18192
  "language.ca": "Catalán",
18122
18193
  "language.cs": "Checo",
18123
18194
  "language.de": "Alemán",
@@ -18455,7 +18526,15 @@ var fr = {
18455
18526
  "downloads.format.unknown": "inconnu",
18456
18527
  "downloads.wfs.featuretype.not.found": "La couche n'a pas été retrouvée",
18457
18528
  dropFile: dropFile$3,
18529
+ "editor.record.loadError.body": "",
18530
+ "editor.record.loadError.closeMessage": "",
18531
+ "editor.record.loadError.title": "",
18458
18532
  "editor.record.publish": "",
18533
+ "editor.record.publishError.body": "",
18534
+ "editor.record.publishError.closeMessage": "",
18535
+ "editor.record.publishError.title": "",
18536
+ "editor.record.publishSuccess.body": "",
18537
+ "editor.record.publishSuccess.title": "",
18459
18538
  "editor.record.upToDate": "",
18460
18539
  "externalviewer.dataset.unnamed": "Couche du datahub",
18461
18540
  "facets.block.title.OrgForResource": "Organisation",
@@ -18470,6 +18549,16 @@ var fr = {
18470
18549
  "facets.block.title.tag.default": "Tag",
18471
18550
  "facets.block.title.th_regions_tree.default": "Régions",
18472
18551
  "favorite.not.authenticated.tooltip": "<div><a href=' {link} '>Connectez-vous</a> pour avoir accès à cette fonctionnalité</div>",
18552
+ "input.image.altTextPlaceholder": "Texte alternatif de l'image",
18553
+ "input.image.delete": "Supprimer",
18554
+ "input.image.displayAltTextInput": "Texte alternatif",
18555
+ "input.image.displayUrlInput": "Saisir une URL",
18556
+ "input.image.dropFileLabel": "ou la glisser ici",
18557
+ "input.image.selectFileLabel": "Sélectionner une image",
18558
+ "input.image.uploadErrorLabel": "L'image n'a pas pu être chargée",
18559
+ "input.image.uploadErrorRetry": "Réessayer",
18560
+ "input.image.uploadProgressCancel": "Annuler",
18561
+ "input.image.uploadProgressLabel": "Chargement en cours...",
18473
18562
  "language.ca": "Catalan",
18474
18563
  "language.cs": "Tchèque",
18475
18564
  "language.de": "Allemand",
@@ -18807,7 +18896,15 @@ var it = {
18807
18896
  "downloads.format.unknown": "sconosciuto",
18808
18897
  "downloads.wfs.featuretype.not.found": "Il layer non è stato trovato",
18809
18898
  dropFile: dropFile$2,
18899
+ "editor.record.loadError.body": "",
18900
+ "editor.record.loadError.closeMessage": "",
18901
+ "editor.record.loadError.title": "",
18810
18902
  "editor.record.publish": "",
18903
+ "editor.record.publishError.body": "",
18904
+ "editor.record.publishError.closeMessage": "",
18905
+ "editor.record.publishError.title": "",
18906
+ "editor.record.publishSuccess.body": "",
18907
+ "editor.record.publishSuccess.title": "",
18811
18908
  "editor.record.upToDate": "",
18812
18909
  "externalviewer.dataset.unnamed": "Layer del datahub",
18813
18910
  "facets.block.title.OrgForResource": "Organizzazione",
@@ -18822,6 +18919,16 @@ var it = {
18822
18919
  "facets.block.title.tag.default": "Tag",
18823
18920
  "facets.block.title.th_regions_tree.default": "Regioni",
18824
18921
  "favorite.not.authenticated.tooltip": "<div><a href=' {link} '>Login</a> per accedere a questa funzionalità</div>",
18922
+ "input.image.altTextPlaceholder": "",
18923
+ "input.image.delete": "",
18924
+ "input.image.displayAltTextInput": "",
18925
+ "input.image.displayUrlInput": "",
18926
+ "input.image.dropFileLabel": "",
18927
+ "input.image.selectFileLabel": "",
18928
+ "input.image.uploadErrorLabel": "",
18929
+ "input.image.uploadErrorRetry": "",
18930
+ "input.image.uploadProgressCancel": "",
18931
+ "input.image.uploadProgressLabel": "",
18825
18932
  "language.ca": "Catalano",
18826
18933
  "language.cs": "Ceco",
18827
18934
  "language.de": "Tedesco",
@@ -19159,7 +19266,15 @@ var nl = {
19159
19266
  "downloads.format.unknown": "",
19160
19267
  "downloads.wfs.featuretype.not.found": "",
19161
19268
  dropFile: dropFile$1,
19269
+ "editor.record.loadError.body": "",
19270
+ "editor.record.loadError.closeMessage": "",
19271
+ "editor.record.loadError.title": "",
19162
19272
  "editor.record.publish": "",
19273
+ "editor.record.publishError.body": "",
19274
+ "editor.record.publishError.closeMessage": "",
19275
+ "editor.record.publishError.title": "",
19276
+ "editor.record.publishSuccess.body": "",
19277
+ "editor.record.publishSuccess.title": "",
19163
19278
  "editor.record.upToDate": "",
19164
19279
  "externalviewer.dataset.unnamed": "",
19165
19280
  "facets.block.title.OrgForResource": "",
@@ -19174,6 +19289,16 @@ var nl = {
19174
19289
  "facets.block.title.tag.default": "",
19175
19290
  "facets.block.title.th_regions_tree.default": "",
19176
19291
  "favorite.not.authenticated.tooltip": "",
19292
+ "input.image.altTextPlaceholder": "",
19293
+ "input.image.delete": "",
19294
+ "input.image.displayAltTextInput": "",
19295
+ "input.image.displayUrlInput": "",
19296
+ "input.image.dropFileLabel": "",
19297
+ "input.image.selectFileLabel": "",
19298
+ "input.image.uploadErrorLabel": "",
19299
+ "input.image.uploadErrorRetry": "",
19300
+ "input.image.uploadProgressCancel": "",
19301
+ "input.image.uploadProgressLabel": "",
19177
19302
  "language.ca": "Catalaans",
19178
19303
  "language.cs": "Tsjechisch",
19179
19304
  "language.de": "Duits",
@@ -19511,7 +19636,15 @@ var pt = {
19511
19636
  "downloads.format.unknown": "",
19512
19637
  "downloads.wfs.featuretype.not.found": "",
19513
19638
  dropFile: dropFile,
19639
+ "editor.record.loadError.body": "",
19640
+ "editor.record.loadError.closeMessage": "",
19641
+ "editor.record.loadError.title": "",
19514
19642
  "editor.record.publish": "",
19643
+ "editor.record.publishError.body": "",
19644
+ "editor.record.publishError.closeMessage": "",
19645
+ "editor.record.publishError.title": "",
19646
+ "editor.record.publishSuccess.body": "",
19647
+ "editor.record.publishSuccess.title": "",
19515
19648
  "editor.record.upToDate": "",
19516
19649
  "externalviewer.dataset.unnamed": "",
19517
19650
  "facets.block.title.OrgForResource": "",
@@ -19526,6 +19659,16 @@ var pt = {
19526
19659
  "facets.block.title.tag.default": "",
19527
19660
  "facets.block.title.th_regions_tree.default": "",
19528
19661
  "favorite.not.authenticated.tooltip": "",
19662
+ "input.image.altTextPlaceholder": "",
19663
+ "input.image.delete": "",
19664
+ "input.image.displayAltTextInput": "",
19665
+ "input.image.displayUrlInput": "",
19666
+ "input.image.dropFileLabel": "",
19667
+ "input.image.selectFileLabel": "",
19668
+ "input.image.uploadErrorLabel": "",
19669
+ "input.image.uploadErrorRetry": "",
19670
+ "input.image.uploadProgressCancel": "",
19671
+ "input.image.uploadProgressLabel": "",
19529
19672
  "language.ca": "Catalão",
19530
19673
  "language.cs": "Tcheco",
19531
19674
  "language.de": "Alemão",
@@ -19796,6 +19939,10 @@ class Gn4FieldMapper {
19796
19939
  ...output,
19797
19940
  datasetCreated: toDate(getFirstValue(selectField(source, 'creationDateForResource'))),
19798
19941
  }),
19942
+ revisionDateForResource: (output, source) => ({
19943
+ ...output,
19944
+ datasetUpdated: toDate(getFirstValue(selectField(source, 'revisionDateForResource'))),
19945
+ }),
19799
19946
  createDate: (output, source) => ({
19800
19947
  ...output,
19801
19948
  recordCreated: toDate(selectField(source, 'createDate')),
@@ -21663,6 +21810,130 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
21663
21810
  args: [PROXY_PATH]
21664
21811
  }] }]; } });
21665
21812
 
21813
+ function megabytesToBytes(megabytes) {
21814
+ return megabytes * 1048576;
21815
+ }
21816
+
21817
+ /**
21818
+ * This should be called instead of event.stopPropagation()
21819
+ * to make sure that the document receives the event
21820
+ * @param event
21821
+ */
21822
+ function propagateToDocumentOnly(event) {
21823
+ event.stopPropagation();
21824
+ setTimeout(() => {
21825
+ window.document.dispatchEvent(event);
21826
+ }, 0);
21827
+ }
21828
+
21829
+ function normalize(input) {
21830
+ return input
21831
+ .toLowerCase()
21832
+ .normalize('NFD') // explode composite chars (e.g. é) into multiple chars
21833
+ .replace(/[\u0300-\u036f]/g, '') // remove accents
21834
+ .replace(/œ/g, 'oe') // remove accents
21835
+ .replace(/[^a-z0-9\s]/g, ' '); // replace special characters with space
21836
+ }
21837
+ function asNormalizedParts(input) {
21838
+ return normalize(input)
21839
+ .split(/\s+/)
21840
+ .map((part) => part.trim())
21841
+ .filter((part) => part.length > 0);
21842
+ }
21843
+ /**
21844
+ * This creates a filter function based on a pattern (typically a user-input
21845
+ * search text).
21846
+ * @param pattern
21847
+ */
21848
+ function createFuzzyFilter(pattern) {
21849
+ const patternParts = asNormalizedParts(pattern);
21850
+ return (input) => {
21851
+ const inputParts = asNormalizedParts(input);
21852
+ return patternParts.every((patternPart) => inputParts.some((part) => part.includes(patternPart)));
21853
+ };
21854
+ }
21855
+
21856
+ function getGeometryFromGeoJSON(data) {
21857
+ if (data.type === 'FeatureCollection') {
21858
+ return data?.features?.[0]?.geometry || null;
21859
+ }
21860
+ if (data.type === 'Feature') {
21861
+ return data?.geometry || null;
21862
+ }
21863
+ if (data.type === 'GeometryCollection') {
21864
+ return data?.geometries?.[0] || null;
21865
+ }
21866
+ if (data.type === 'Polygon' ||
21867
+ data.type === 'Point' ||
21868
+ data.type === 'LineString' ||
21869
+ data.type === 'MultiPolygon' ||
21870
+ data.type === 'MultiPoint' ||
21871
+ data.type === 'MultiLineString') {
21872
+ return data || null;
21873
+ }
21874
+ return null;
21875
+ }
21876
+
21877
+ function downsizeImage(blob, maxWidth, maxHeight) {
21878
+ return new Promise((resolve, reject) => {
21879
+ const image = new Image();
21880
+ image.src = URL.createObjectURL(blob);
21881
+ image.onload = () => {
21882
+ let width = image.width;
21883
+ let height = image.height;
21884
+ if (width > maxWidth || height > maxHeight) {
21885
+ if (width > height) {
21886
+ height = height * (maxWidth / width);
21887
+ width = maxWidth;
21888
+ }
21889
+ else {
21890
+ width = width * (maxHeight / height);
21891
+ height = maxHeight;
21892
+ }
21893
+ }
21894
+ const canvas = document.createElement('canvas');
21895
+ canvas.width = width;
21896
+ canvas.height = height;
21897
+ const context = canvas.getContext('2d');
21898
+ context.drawImage(image, 0, 0, width, height);
21899
+ canvas.toBlob(resolve, blob.type);
21900
+ };
21901
+ image.onerror = reject;
21902
+ });
21903
+ }
21904
+ function downgradeImage(blob, maxSizeBytes) {
21905
+ return new Promise((resolve, reject) => {
21906
+ const image = new Image();
21907
+ image.src = URL.createObjectURL(blob);
21908
+ image.onload = () => {
21909
+ const width = image.width;
21910
+ const height = image.height;
21911
+ let quality = 1.0;
21912
+ const canvas = document.createElement('canvas');
21913
+ canvas.width = width;
21914
+ canvas.height = height;
21915
+ const context = canvas.getContext('2d');
21916
+ context.drawImage(image, 0, 0, width, height);
21917
+ const compressAndResolveBlob = (blobToCompress) => {
21918
+ if (blobToCompress.size <= maxSizeBytes) {
21919
+ resolve(blobToCompress);
21920
+ }
21921
+ else {
21922
+ quality -= 0.1;
21923
+ if (quality >= 0) {
21924
+ canvas.toBlob(compressAndResolveBlob, blob.type, quality);
21925
+ }
21926
+ else {
21927
+ reject('Unable to compress image below max size');
21928
+ }
21929
+ }
21930
+ };
21931
+ canvas.toBlob(compressAndResolveBlob, blob.type, quality);
21932
+ };
21933
+ image.onerror = reject;
21934
+ });
21935
+ }
21936
+
21666
21937
  /*
21667
21938
  * Implement AngularJS $parse
21668
21939
  * delimiter is `^^^^` cause object properties can contain `.`
@@ -21696,38 +21967,10 @@ const parse = (path) => {
21696
21967
  return fn;
21697
21968
  };
21698
21969
 
21699
- const stripHtml = function (html) {
21700
- if (!html)
21701
- return undefined;
21702
- const doc = new DOMParser().parseFromString(html, 'text/html');
21703
- return doc.body.textContent || '';
21704
- };
21705
-
21706
21970
  const removeWhitespace = function (str) {
21707
21971
  return str?.replace(/\s+/g, ' ').trim();
21708
21972
  };
21709
21973
 
21710
- function getGeometryFromGeoJSON(data) {
21711
- if (data.type === 'FeatureCollection') {
21712
- return data?.features?.[0]?.geometry || null;
21713
- }
21714
- if (data.type === 'Feature') {
21715
- return data?.geometry || null;
21716
- }
21717
- if (data.type === 'GeometryCollection') {
21718
- return data?.geometries?.[0] || null;
21719
- }
21720
- if (data.type === 'Polygon' ||
21721
- data.type === 'Point' ||
21722
- data.type === 'LineString' ||
21723
- data.type === 'MultiPolygon' ||
21724
- data.type === 'MultiPoint' ||
21725
- data.type === 'MultiLineString') {
21726
- return data || null;
21727
- }
21728
- return null;
21729
- }
21730
-
21731
21974
  function sortByToStrings(sortBy) {
21732
21975
  const array = Array.isArray(sortBy[0]) ? sortBy : [sortBy];
21733
21976
  return array.map((param) => `${param[0] === 'desc' ? '-' : ''}${param[1]}`);
@@ -21742,62 +21985,12 @@ function sortByFromString(sortByString) {
21742
21985
  ];
21743
21986
  }
21744
21987
 
21745
- /**
21746
- * Removes the given search params from the URL completely; this is case-insensitive
21747
- * @param url
21748
- * @param searchParams
21749
- */
21750
- function removeSearchParams(url, searchParams) {
21751
- const toDelete = [];
21752
- const urlObj = new URL(url, window.location.toString());
21753
- const keysLower = searchParams.map((p) => p.toLowerCase());
21754
- for (const param of urlObj.searchParams.keys()) {
21755
- if (keysLower.indexOf(param.toLowerCase()) > -1) {
21756
- toDelete.push(param);
21757
- }
21758
- }
21759
- toDelete.map((param) => urlObj.searchParams.delete(param));
21760
- return urlObj.toString();
21761
- }
21762
-
21763
- /**
21764
- * This should be called instead of event.stopPropagation()
21765
- * to make sure that the document receives the event
21766
- * @param event
21767
- */
21768
- function propagateToDocumentOnly(event) {
21769
- event.stopPropagation();
21770
- setTimeout(() => {
21771
- window.document.dispatchEvent(event);
21772
- }, 0);
21773
- }
21774
-
21775
- function normalize(input) {
21776
- return input
21777
- .toLowerCase()
21778
- .normalize('NFD') // explode composite chars (e.g. é) into multiple chars
21779
- .replace(/[\u0300-\u036f]/g, '') // remove accents
21780
- .replace(/œ/g, 'oe') // remove accents
21781
- .replace(/[^a-z0-9\s]/g, ' '); // replace special characters with space
21782
- }
21783
- function asNormalizedParts(input) {
21784
- return normalize(input)
21785
- .split(/\s+/)
21786
- .map((part) => part.trim())
21787
- .filter((part) => part.length > 0);
21788
- }
21789
- /**
21790
- * This creates a filter function based on a pattern (typically a user-input
21791
- * search text).
21792
- * @param pattern
21793
- */
21794
- function createFuzzyFilter(pattern) {
21795
- const patternParts = asNormalizedParts(pattern);
21796
- return (input) => {
21797
- const inputParts = asNormalizedParts(input);
21798
- return patternParts.every((patternPart) => inputParts.some((part) => part.includes(patternPart)));
21799
- };
21800
- }
21988
+ const stripHtml = function (html) {
21989
+ if (!html)
21990
+ return undefined;
21991
+ const doc = new DOMParser().parseFromString(html, 'text/html');
21992
+ return doc.body.textContent || '';
21993
+ };
21801
21994
 
21802
21995
  function getTemporalRangeUnion(ranges) {
21803
21996
  let earliestStartDate = Infinity;
@@ -21831,6 +22024,24 @@ function getTemporalRangeUnion(ranges) {
21831
22024
  }
21832
22025
  }
21833
22026
 
22027
+ /**
22028
+ * Removes the given search params from the URL completely; this is case-insensitive
22029
+ * @param url
22030
+ * @param searchParams
22031
+ */
22032
+ function removeSearchParams(url, searchParams) {
22033
+ const toDelete = [];
22034
+ const urlObj = new URL(url, window.location.toString());
22035
+ const keysLower = searchParams.map((p) => p.toLowerCase());
22036
+ for (const param of urlObj.searchParams.keys()) {
22037
+ if (keysLower.indexOf(param.toLowerCase()) > -1) {
22038
+ toDelete.push(param);
22039
+ }
22040
+ }
22041
+ toDelete.map((param) => urlObj.searchParams.delete(param));
22042
+ return urlObj.toString();
22043
+ }
22044
+
21834
22045
  marker('downloads.wfs.featuretype.not.found');
21835
22046
  const FORMATS = {
21836
22047
  csv: {
@@ -23602,6 +23813,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
23602
23813
 
23603
23814
  class ButtonComponent {
23604
23815
  constructor() {
23816
+ this.btnClass = 'gn-ui-btn-default';
23605
23817
  this.disabled = false;
23606
23818
  this.extraClass = '';
23607
23819
  this.buttonClick = new EventEmitter();
@@ -24653,192 +24865,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
24653
24865
  }]
24654
24866
  }] });
24655
24867
 
24656
- class FormFieldSimpleComponent {
24657
- constructor() {
24658
- this.readonly = false;
24659
- this.invalid = false;
24660
- this.placeholder = '';
24661
- }
24662
- get inputType() {
24663
- switch (this.type) {
24664
- case 'url':
24665
- case 'text':
24666
- return 'text';
24667
- case 'date':
24668
- return 'datetime-local';
24669
- case 'number':
24670
- return 'number';
24671
- case 'toggle':
24672
- return 'checkbox';
24673
- default:
24674
- return '';
24675
- }
24676
- }
24677
- get isSelect() {
24678
- return this.type === 'list';
24679
- }
24680
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldSimpleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
24681
- 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 }); }
24682
- }
24683
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldSimpleComponent, decorators: [{
24684
- type: Component,
24685
- 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" }]
24686
- }], propDecorators: { type: [{
24687
- type: Input
24688
- }], control: [{
24689
- type: Input
24690
- }], readonly: [{
24691
- type: Input
24692
- }], invalid: [{
24693
- type: Input
24694
- }], placeholder: [{
24695
- type: Input
24696
- }], options: [{
24697
- type: Input
24698
- }] } });
24699
-
24700
- class FormFieldFileComponent {
24701
- constructor() {
24702
- this.readonly = false;
24703
- this.invalid = false;
24704
- this.placeholder = '';
24705
- }
24706
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldFileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
24707
- 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 }); }
24708
- }
24709
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldFileComponent, decorators: [{
24710
- type: Component,
24711
- 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" }]
24712
- }], propDecorators: { control: [{
24713
- type: Input
24714
- }], readonly: [{
24715
- type: Input
24716
- }], invalid: [{
24717
- type: Input
24718
- }], placeholder: [{
24719
- type: Input
24720
- }] } });
24721
-
24722
- class FormFieldRichComponent {
24723
- constructor() {
24724
- this.readonly = false;
24725
- this.invalid = false;
24726
- this.placeholder = '';
24727
- }
24728
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldRichComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
24729
- 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 }); }
24730
- }
24731
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldRichComponent, decorators: [{
24732
- type: Component,
24733
- 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" }]
24734
- }], propDecorators: { control: [{
24735
- type: Input
24736
- }], readonly: [{
24737
- type: Input
24738
- }], invalid: [{
24739
- type: Input
24740
- }], placeholder: [{
24741
- type: Input
24742
- }] } });
24743
-
24744
- class FormFieldObjectComponent {
24745
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldObjectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
24746
- 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 }); }
24747
- }
24748
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldObjectComponent, decorators: [{
24749
- type: Component,
24750
- args: [{ selector: 'gn-ui-form-field-object', changeDetection: ChangeDetectionStrategy.OnPush, template: "<p>form-field-object works!</p>\n" }]
24751
- }] });
24752
-
24753
- class FormFieldArrayComponent {
24754
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldArrayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
24755
- 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 }); }
24756
- }
24757
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldArrayComponent, decorators: [{
24758
- type: Component,
24759
- args: [{ selector: 'gn-ui-form-field-array', changeDetection: ChangeDetectionStrategy.OnPush, template: "<p>form-field-array works!</p>\n" }]
24760
- }] });
24761
-
24762
- class FormFieldSpatialExtentComponent {
24763
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldSpatialExtentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
24764
- 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 }); }
24765
- }
24766
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldSpatialExtentComponent, decorators: [{
24767
- type: Component,
24768
- args: [{ selector: 'gn-ui-form-field-spatial-extent', changeDetection: ChangeDetectionStrategy.OnPush, template: "<p>form-field-spatial-extent works!</p>\n" }]
24769
- }] });
24770
-
24771
- class FormFieldTemporalExtentComponent {
24772
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldTemporalExtentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
24773
- 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 }); }
24774
- }
24775
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldTemporalExtentComponent, decorators: [{
24776
- type: Component,
24777
- args: [{ selector: 'gn-ui-form-field-temporal-extent', changeDetection: ChangeDetectionStrategy.OnPush, template: "<p>form-field-temporal-extent works!</p>\n" }]
24778
- }] });
24779
-
24780
- class FormFieldComponent {
24781
- set value(v) {
24782
- this.formControl.setValue(v, {
24783
- emitEvent: false,
24784
- });
24785
- }
24786
- constructor() {
24787
- this.formControl = new FormControl();
24788
- this.valueChange = this.formControl.valueChanges;
24789
- }
24790
- get simpleType() {
24791
- return this.config.type;
24792
- }
24793
- get isSimpleField() {
24794
- return (this.config.type === 'text' ||
24795
- this.config.type === 'number' ||
24796
- this.config.type === 'date' ||
24797
- this.config.type === 'list' ||
24798
- this.config.type === 'url' ||
24799
- this.config.type === 'toggle');
24800
- }
24801
- get isRichField() {
24802
- return this.config.type === 'rich';
24803
- }
24804
- get isFileField() {
24805
- return this.config.type === 'file';
24806
- }
24807
- get isSpatialExtentField() {
24808
- return this.config.type === 'spatial_extent';
24809
- }
24810
- get isTemporalExtentField() {
24811
- return this.config.type === 'temporal_extent';
24812
- }
24813
- get isArrayField() {
24814
- return this.config.type === 'array';
24815
- }
24816
- get isObjectField() {
24817
- return this.config.type === 'object';
24818
- }
24819
- get isFieldOk() {
24820
- return !this.config.locked && !this.config.invalid;
24821
- }
24822
- get isFieldLocked() {
24823
- return this.config.locked;
24824
- }
24825
- get isFieldInvalid() {
24826
- return !this.config.locked && this.config.invalid;
24827
- }
24828
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
24829
- 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 }); }
24830
- }
24831
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldComponent, decorators: [{
24832
- type: Component,
24833
- 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" }]
24834
- }], ctorParameters: function () { return []; }, propDecorators: { config: [{
24835
- type: Input
24836
- }], value: [{
24837
- type: Input
24838
- }], valueChange: [{
24839
- type: Output
24840
- }] } });
24841
-
24842
24868
  class CopyTextButtonComponent {
24843
24869
  constructor() {
24844
24870
  this.displayText = true;
@@ -24983,6 +25009,229 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
24983
25009
  type: Input
24984
25010
  }] } });
24985
25011
 
25012
+ class FilesDropDirective {
25013
+ constructor() {
25014
+ this.dragFilesOver = new EventEmitter();
25015
+ this.dropFiles = new EventEmitter();
25016
+ this.dragEnterCounter = 0;
25017
+ }
25018
+ _onDragEnter(event) {
25019
+ event.preventDefault();
25020
+ this.dragEnterCounter++;
25021
+ this.dragFilesOver.emit(true);
25022
+ }
25023
+ _onDragOver(event) {
25024
+ event.preventDefault();
25025
+ }
25026
+ _onDragLeave(event) {
25027
+ event.preventDefault();
25028
+ this.dragEnterCounter = Math.max(0, this.dragEnterCounter - 1);
25029
+ if (this.dragEnterCounter === 0) {
25030
+ this.dragFilesOver.emit(false);
25031
+ }
25032
+ }
25033
+ _onDrop(event) {
25034
+ event.preventDefault();
25035
+ this.dragEnterCounter = 0;
25036
+ this.dragFilesOver.emit(false);
25037
+ const files = Array.from(event.dataTransfer.files);
25038
+ if (files.length > 0) {
25039
+ this.dropFiles.emit(files);
25040
+ }
25041
+ }
25042
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FilesDropDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
25043
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.1.7", type: FilesDropDirective, isStandalone: true, selector: "[gnUiFilesDrop]", outputs: { dragFilesOver: "dragFilesOver", dropFiles: "dropFiles" }, host: { listeners: { "dragenter": "_onDragEnter($event)", "dragover": "_onDragOver($event)", "dragleave": "_onDragLeave($event)", "drop": "_onDrop($event)" } }, ngImport: i0 }); }
25044
+ }
25045
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FilesDropDirective, decorators: [{
25046
+ type: Directive,
25047
+ args: [{
25048
+ selector: '[gnUiFilesDrop]',
25049
+ standalone: true,
25050
+ }]
25051
+ }], propDecorators: { dragFilesOver: [{
25052
+ type: Output
25053
+ }], dropFiles: [{
25054
+ type: Output
25055
+ }], _onDragEnter: [{
25056
+ type: HostListener,
25057
+ args: ['dragenter', ['$event']]
25058
+ }], _onDragOver: [{
25059
+ type: HostListener,
25060
+ args: ['dragover', ['$event']]
25061
+ }], _onDragLeave: [{
25062
+ type: HostListener,
25063
+ args: ['dragleave', ['$event']]
25064
+ }], _onDrop: [{
25065
+ type: HostListener,
25066
+ args: ['drop', ['$event']]
25067
+ }] } });
25068
+
25069
+ class ImageInputComponent {
25070
+ constructor(http, cd) {
25071
+ this.http = http;
25072
+ this.cd = cd;
25073
+ this.fileChange = new EventEmitter();
25074
+ this.urlChange = new EventEmitter();
25075
+ this.uploadCancel = new EventEmitter();
25076
+ this.delete = new EventEmitter();
25077
+ this.altTextChange = new EventEmitter();
25078
+ this.dragFilesOver = false;
25079
+ this.showUrlInput = false;
25080
+ this.downloadError = false;
25081
+ this.showAltTextInput = false;
25082
+ }
25083
+ getPrimaryText() {
25084
+ if (this.uploadError) {
25085
+ return marker('input.image.uploadErrorLabel');
25086
+ }
25087
+ if (this.uploadProgress) {
25088
+ return marker('input.image.uploadProgressLabel');
25089
+ }
25090
+ return marker('input.image.selectFileLabel');
25091
+ }
25092
+ getSecondaryText() {
25093
+ if (this.uploadError) {
25094
+ return marker('input.image.uploadErrorRetry');
25095
+ }
25096
+ if (this.uploadProgress) {
25097
+ return marker('input.image.uploadProgressCancel');
25098
+ }
25099
+ return marker('input.image.dropFileLabel');
25100
+ }
25101
+ handleDragFilesOver(dragFilesOver) {
25102
+ if (!this.showUrlInput) {
25103
+ this.dragFilesOver = dragFilesOver;
25104
+ this.cd.markForCheck();
25105
+ }
25106
+ }
25107
+ handleDropFiles(files) {
25108
+ if (!this.showUrlInput) {
25109
+ const validFiles = this.filterTypeImage(files);
25110
+ if (validFiles.length > 0) {
25111
+ this.resizeAndEmit(validFiles[0]);
25112
+ }
25113
+ }
25114
+ }
25115
+ handleFileInput(event) {
25116
+ const inputFiles = Array.from(event.target.files);
25117
+ const validFiles = this.filterTypeImage(inputFiles);
25118
+ if (validFiles.length > 0) {
25119
+ this.resizeAndEmit(validFiles[0]);
25120
+ }
25121
+ }
25122
+ displayUrlInput() {
25123
+ this.uploadCancel.emit();
25124
+ this.showUrlInput = true;
25125
+ }
25126
+ handleUrlChange(event) {
25127
+ this.downloadError = false;
25128
+ this.urlInputValue = event.target.value;
25129
+ }
25130
+ async downloadUrl() {
25131
+ const name = this.urlInputValue.split('/').pop();
25132
+ try {
25133
+ const response = await firstValueFrom(this.http.head(this.urlInputValue, { observe: 'response' }));
25134
+ if (response.headers.get('content-type')?.startsWith('image/') &&
25135
+ parseInt(response.headers.get('content-length')) <
25136
+ megabytesToBytes(this.maxSizeMB)) {
25137
+ this.http.get(this.urlInputValue, { responseType: 'blob' }).subscribe({
25138
+ next: (blob) => {
25139
+ this.cd.markForCheck();
25140
+ const file = new File([blob], name);
25141
+ this.fileChange.emit(file);
25142
+ },
25143
+ error: () => {
25144
+ this.downloadError = true;
25145
+ this.cd.markForCheck();
25146
+ this.urlChange.emit(this.urlInputValue);
25147
+ },
25148
+ });
25149
+ }
25150
+ }
25151
+ catch {
25152
+ this.downloadError = true;
25153
+ this.cd.markForCheck();
25154
+ return;
25155
+ }
25156
+ }
25157
+ handleSecondaryTextClick() {
25158
+ if (this.uploadError) {
25159
+ this.handleRetry();
25160
+ }
25161
+ else if (this.uploadProgress) {
25162
+ this.handleCancel();
25163
+ }
25164
+ }
25165
+ handleCancel() {
25166
+ this.uploadCancel.emit();
25167
+ }
25168
+ handleRetry() {
25169
+ switch (this.lastUploadType) {
25170
+ case 'file':
25171
+ this.fileChange.emit(this.lastUploadContent);
25172
+ break;
25173
+ case 'url':
25174
+ this.urlChange.emit(this.lastUploadContent);
25175
+ break;
25176
+ }
25177
+ }
25178
+ handleDelete() {
25179
+ this.delete.emit();
25180
+ }
25181
+ toggleAltTextInput() {
25182
+ this.showAltTextInput = !this.showAltTextInput;
25183
+ }
25184
+ handleAltTextChange(event) {
25185
+ const input = event.target;
25186
+ this.altTextChange.emit(input.value);
25187
+ }
25188
+ filterTypeImage(files) {
25189
+ return files.filter((file) => {
25190
+ return file.type.startsWith('image/');
25191
+ });
25192
+ }
25193
+ resizeAndEmit(imageToResize) {
25194
+ const maxSizeBytes = megabytesToBytes(this.maxSizeMB);
25195
+ downgradeImage(imageToResize, maxSizeBytes).then((resizedImage) => {
25196
+ const fileToEmit = new File([resizedImage], imageToResize.name);
25197
+ this.fileChange.emit(fileToEmit);
25198
+ });
25199
+ }
25200
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ImageInputComponent, deps: [{ token: i1.HttpClient }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
25201
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: ImageInputComponent, isStandalone: true, selector: "gn-ui-image-input", inputs: { maxSizeMB: "maxSizeMB", previewUrl: "previewUrl", altText: "altText", uploadProgress: "uploadProgress", uploadError: "uploadError" }, outputs: { fileChange: "fileChange", urlChange: "urlChange", uploadCancel: "uploadCancel", delete: "delete", altTextChange: "altTextChange" }, ngImport: i0, template: "<ng-container *ngIf=\"previewUrl; then withImage; else withoutImage\">\n</ng-container>\n\n<ng-template #withImage>\n <div class=\"w-full h-full flex flex-col gap-2\">\n <div class=\"flex-1 group relative\">\n <img\n class=\"w-full h-full object-cover border-2 border-gray-300 rounded-lg\"\n [alt]=\"altText\"\n loading=\"lazy\"\n [src]=\"previewUrl\"\n />\n <gn-ui-button\n [extraClass]=\"\n 'bg-gray-200 absolute right-2 bottom-2 invisible group-hover:visible'\n \"\n (buttonClick)=\"handleDelete()\"\n >\n <mat-icon class=\"material-symbols-outlined\">delete</mat-icon>\n </gn-ui-button>\n </div>\n <input\n *ngIf=\"showAltTextInput\"\n type=\"text\"\n class=\"py-3 px-2 border-2 border-gray-300 rounded-lg text-sm font-medium\"\n [placeholder]=\"'input.image.altTextPlaceholder' | translate\"\n [value]=\"altText\"\n (change)=\"handleAltTextChange($event)\"\n />\n <div class=\"flex flex-row gap-2\">\n <gn-ui-button\n [extraClass]=\"'bg-gray-200 font-bold'\"\n (buttonClick)=\"handleDelete()\"\n >\n <mat-icon class=\"material-symbols-outlined me-1\">delete</mat-icon>\n {{ 'input.image.delete' | translate }}\n </gn-ui-button>\n <gn-ui-button\n *ngIf=\"!showAltTextInput\"\n [extraClass]=\"'bg-gray-200 font-bold'\"\n (buttonClick)=\"toggleAltTextInput()\"\n >\n <mat-icon class=\"material-symbols-outlined me-1\">add</mat-icon>\n {{ 'input.image.displayAltTextInput' | translate }}\n </gn-ui-button>\n </div>\n </div>\n</ng-template>\n\n<ng-template #withoutImage>\n <div class=\"w-full h-full flex flex-col gap-2\">\n <label\n gnUiFilesDrop\n class=\"block flex-1 border-2 border-dashed border-gray-300 rounded-lg p-6 flex flex-col items-center justify-center gap-4\"\n (dragFilesOver)=\"handleDragFilesOver($event)\"\n (dropFiles)=\"handleDropFiles($event)\"\n >\n <div class=\"w-14 h-14 rounded-md bg-gray-200 grid\">\n <mat-icon\n *ngIf=\"!dragFilesOver && !uploadProgress && !uploadError\"\n class=\"material-symbols-outlined place-self-center text-blue-500\"\n >image</mat-icon\n >\n <mat-icon\n *ngIf=\"dragFilesOver && !uploadProgress && !uploadError\"\n class=\"material-symbols-outlined place-self-center text-blue-500\"\n >add_box</mat-icon\n >\n <div *ngIf=\"uploadProgress\">\n <mat-progress-spinner\n class=\"place-self-center\"\n [diameter]=\"56\"\n [mode]=\"'determinate'\"\n [value]=\"uploadProgress\"\n ></mat-progress-spinner>\n <span\n class=\"text-sm font-medium relative inline-block width-[30px] bottom-[40px] left-[15px]\"\n >\n {{ uploadProgress }}%\n </span>\n </div>\n <mat-icon\n *ngIf=\"uploadError\"\n class=\"material-symbols-outlined place-self-center text-rose-500\"\n >broken_image</mat-icon\n >\n </div>\n <div class=\"flex flex-col items-center gap-1\">\n <p class=\"font-medium\">{{ getPrimaryText() | translate }}</p>\n <p\n class=\"text-sm\"\n [class]=\"\n uploadProgress || uploadError\n ? 'font-bold text-blue-500 cursor-pointer'\n : 'font-medium text-gray-500'\n \"\n (click)=\"handleSecondaryTextClick()\"\n >\n {{ getSecondaryText() | translate }}\n </p>\n </div>\n <input\n type=\"file\"\n class=\"hidden\"\n (change)=\"handleFileInput($event)\"\n [disabled]=\"showUrlInput || uploadProgress || uploadError\"\n />\n </label>\n <div *ngIf=\"!showUrlInput\" class=\"flex-none\">\n <gn-ui-button\n [extraClass]=\"'bg-gray-200 font-bold'\"\n (buttonClick)=\"displayUrlInput()\"\n >\n <mat-icon class=\"material-symbols-outlined me-1\">link</mat-icon>\n {{ 'input.image.displayUrlInput' | translate }}\n </gn-ui-button>\n </div>\n <div *ngIf=\"showUrlInput\" class=\"flex-none flex flex-col gap-2\">\n <div class=\"h-2\"></div>\n <div class=\"flex gap-2 items-center\">\n <div class=\"flex-1 flex rounded-lg\">\n <span\n class=\"material-symbols-outlined px-4 inline-flex items-center min-w-fit rounded-s-lg border-2 border-e-0 border-gray-300\"\n >link</span\n >\n <input\n type=\"text\"\n class=\"py-3 ps-1 block w-full border-2 border-s-0 border-e-0 border-gray-300 text-sm font-medium\"\n placeholder=\"https://exemple.com/image.jpg\"\n (change)=\"handleUrlChange($event)\"\n />\n <gn-ui-button\n class=\"px-1 inline-flex items-center min-w-fit rounded-e-lg border-2 border-s-0 border-gray-300 text-white\"\n [extraClass]=\"\n urlInputValue && !downloadError ? 'bg-blue-500' : 'bg-gray-500'\n \"\n [disabled]=\"!urlInputValue || downloadError\"\n (buttonClick)=\"downloadUrl()\"\n >\n <mat-icon class=\"material-symbols-outlined\">arrow_upward</mat-icon>\n </gn-ui-button>\n </div>\n </div>\n </div>\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: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: FilesDropDirective, selector: "[gnUiFilesDrop]", outputs: ["dragFilesOver", "dropFiles"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i1$5.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
25202
+ }
25203
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ImageInputComponent, decorators: [{
25204
+ type: Component,
25205
+ args: [{ selector: 'gn-ui-image-input', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
25206
+ CommonModule,
25207
+ ButtonComponent,
25208
+ MatIconModule,
25209
+ FilesDropDirective,
25210
+ MatProgressSpinnerModule,
25211
+ TranslateModule,
25212
+ ], template: "<ng-container *ngIf=\"previewUrl; then withImage; else withoutImage\">\n</ng-container>\n\n<ng-template #withImage>\n <div class=\"w-full h-full flex flex-col gap-2\">\n <div class=\"flex-1 group relative\">\n <img\n class=\"w-full h-full object-cover border-2 border-gray-300 rounded-lg\"\n [alt]=\"altText\"\n loading=\"lazy\"\n [src]=\"previewUrl\"\n />\n <gn-ui-button\n [extraClass]=\"\n 'bg-gray-200 absolute right-2 bottom-2 invisible group-hover:visible'\n \"\n (buttonClick)=\"handleDelete()\"\n >\n <mat-icon class=\"material-symbols-outlined\">delete</mat-icon>\n </gn-ui-button>\n </div>\n <input\n *ngIf=\"showAltTextInput\"\n type=\"text\"\n class=\"py-3 px-2 border-2 border-gray-300 rounded-lg text-sm font-medium\"\n [placeholder]=\"'input.image.altTextPlaceholder' | translate\"\n [value]=\"altText\"\n (change)=\"handleAltTextChange($event)\"\n />\n <div class=\"flex flex-row gap-2\">\n <gn-ui-button\n [extraClass]=\"'bg-gray-200 font-bold'\"\n (buttonClick)=\"handleDelete()\"\n >\n <mat-icon class=\"material-symbols-outlined me-1\">delete</mat-icon>\n {{ 'input.image.delete' | translate }}\n </gn-ui-button>\n <gn-ui-button\n *ngIf=\"!showAltTextInput\"\n [extraClass]=\"'bg-gray-200 font-bold'\"\n (buttonClick)=\"toggleAltTextInput()\"\n >\n <mat-icon class=\"material-symbols-outlined me-1\">add</mat-icon>\n {{ 'input.image.displayAltTextInput' | translate }}\n </gn-ui-button>\n </div>\n </div>\n</ng-template>\n\n<ng-template #withoutImage>\n <div class=\"w-full h-full flex flex-col gap-2\">\n <label\n gnUiFilesDrop\n class=\"block flex-1 border-2 border-dashed border-gray-300 rounded-lg p-6 flex flex-col items-center justify-center gap-4\"\n (dragFilesOver)=\"handleDragFilesOver($event)\"\n (dropFiles)=\"handleDropFiles($event)\"\n >\n <div class=\"w-14 h-14 rounded-md bg-gray-200 grid\">\n <mat-icon\n *ngIf=\"!dragFilesOver && !uploadProgress && !uploadError\"\n class=\"material-symbols-outlined place-self-center text-blue-500\"\n >image</mat-icon\n >\n <mat-icon\n *ngIf=\"dragFilesOver && !uploadProgress && !uploadError\"\n class=\"material-symbols-outlined place-self-center text-blue-500\"\n >add_box</mat-icon\n >\n <div *ngIf=\"uploadProgress\">\n <mat-progress-spinner\n class=\"place-self-center\"\n [diameter]=\"56\"\n [mode]=\"'determinate'\"\n [value]=\"uploadProgress\"\n ></mat-progress-spinner>\n <span\n class=\"text-sm font-medium relative inline-block width-[30px] bottom-[40px] left-[15px]\"\n >\n {{ uploadProgress }}%\n </span>\n </div>\n <mat-icon\n *ngIf=\"uploadError\"\n class=\"material-symbols-outlined place-self-center text-rose-500\"\n >broken_image</mat-icon\n >\n </div>\n <div class=\"flex flex-col items-center gap-1\">\n <p class=\"font-medium\">{{ getPrimaryText() | translate }}</p>\n <p\n class=\"text-sm\"\n [class]=\"\n uploadProgress || uploadError\n ? 'font-bold text-blue-500 cursor-pointer'\n : 'font-medium text-gray-500'\n \"\n (click)=\"handleSecondaryTextClick()\"\n >\n {{ getSecondaryText() | translate }}\n </p>\n </div>\n <input\n type=\"file\"\n class=\"hidden\"\n (change)=\"handleFileInput($event)\"\n [disabled]=\"showUrlInput || uploadProgress || uploadError\"\n />\n </label>\n <div *ngIf=\"!showUrlInput\" class=\"flex-none\">\n <gn-ui-button\n [extraClass]=\"'bg-gray-200 font-bold'\"\n (buttonClick)=\"displayUrlInput()\"\n >\n <mat-icon class=\"material-symbols-outlined me-1\">link</mat-icon>\n {{ 'input.image.displayUrlInput' | translate }}\n </gn-ui-button>\n </div>\n <div *ngIf=\"showUrlInput\" class=\"flex-none flex flex-col gap-2\">\n <div class=\"h-2\"></div>\n <div class=\"flex gap-2 items-center\">\n <div class=\"flex-1 flex rounded-lg\">\n <span\n class=\"material-symbols-outlined px-4 inline-flex items-center min-w-fit rounded-s-lg border-2 border-e-0 border-gray-300\"\n >link</span\n >\n <input\n type=\"text\"\n class=\"py-3 ps-1 block w-full border-2 border-s-0 border-e-0 border-gray-300 text-sm font-medium\"\n placeholder=\"https://exemple.com/image.jpg\"\n (change)=\"handleUrlChange($event)\"\n />\n <gn-ui-button\n class=\"px-1 inline-flex items-center min-w-fit rounded-e-lg border-2 border-s-0 border-gray-300 text-white\"\n [extraClass]=\"\n urlInputValue && !downloadError ? 'bg-blue-500' : 'bg-gray-500'\n \"\n [disabled]=\"!urlInputValue || downloadError\"\n (buttonClick)=\"downloadUrl()\"\n >\n <mat-icon class=\"material-symbols-outlined\">arrow_upward</mat-icon>\n </gn-ui-button>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n" }]
25213
+ }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { maxSizeMB: [{
25214
+ type: Input
25215
+ }], previewUrl: [{
25216
+ type: Input
25217
+ }], altText: [{
25218
+ type: Input
25219
+ }], uploadProgress: [{
25220
+ type: Input
25221
+ }], uploadError: [{
25222
+ type: Input
25223
+ }], fileChange: [{
25224
+ type: Output
25225
+ }], urlChange: [{
25226
+ type: Output
25227
+ }], uploadCancel: [{
25228
+ type: Output
25229
+ }], delete: [{
25230
+ type: Output
25231
+ }], altTextChange: [{
25232
+ type: Output
25233
+ }] } });
25234
+
24986
25235
  class UiInputsModule {
24987
25236
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UiInputsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
24988
25237
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.1.7", ngImport: i0, type: UiInputsModule, declarations: [DropdownSelectorComponent,
@@ -24994,14 +25243,6 @@ class UiInputsModule {
24994
25243
  StarToggleComponent,
24995
25244
  DropdownMultiselectComponent,
24996
25245
  ViewportIntersectorComponent,
24997
- FormFieldComponent,
24998
- FormFieldSimpleComponent,
24999
- FormFieldArrayComponent,
25000
- FormFieldObjectComponent,
25001
- FormFieldRichComponent,
25002
- FormFieldFileComponent,
25003
- FormFieldSpatialExtentComponent,
25004
- FormFieldTemporalExtentComponent,
25005
25246
  CheckToggleComponent,
25006
25247
  CopyTextButtonComponent,
25007
25248
  CheckboxComponent,
@@ -25023,7 +25264,8 @@ class UiInputsModule {
25023
25264
  MatNativeDateModule,
25024
25265
  EditableLabelDirective,
25025
25266
  TextAreaComponent,
25026
- ButtonComponent], exports: [DropdownSelectorComponent,
25267
+ ButtonComponent,
25268
+ ImageInputComponent], exports: [DropdownSelectorComponent,
25027
25269
  AutocompleteComponent,
25028
25270
  ButtonComponent,
25029
25271
  TextInputComponent,
@@ -25034,13 +25276,13 @@ class UiInputsModule {
25034
25276
  StarToggleComponent,
25035
25277
  DropdownMultiselectComponent,
25036
25278
  ViewportIntersectorComponent,
25037
- FormFieldComponent,
25038
25279
  CheckToggleComponent,
25039
25280
  CopyTextButtonComponent,
25040
25281
  CheckboxComponent,
25041
25282
  SearchInputComponent,
25042
25283
  DateRangePickerComponent,
25043
- EditableLabelDirective] }); }
25284
+ EditableLabelDirective,
25285
+ ImageInputComponent] }); }
25044
25286
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UiInputsModule, imports: [CommonModule,
25045
25287
  TranslateModule.forChild(),
25046
25288
  NgxDropzoneModule,
@@ -25057,7 +25299,8 @@ class UiInputsModule {
25057
25299
  MatFormFieldModule,
25058
25300
  MatInputModule,
25059
25301
  MatDatepickerModule,
25060
- MatNativeDateModule] }); }
25302
+ MatNativeDateModule,
25303
+ ImageInputComponent] }); }
25061
25304
  }
25062
25305
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UiInputsModule, decorators: [{
25063
25306
  type: NgModule,
@@ -25072,14 +25315,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
25072
25315
  StarToggleComponent,
25073
25316
  DropdownMultiselectComponent,
25074
25317
  ViewportIntersectorComponent,
25075
- FormFieldComponent,
25076
- FormFieldSimpleComponent,
25077
- FormFieldArrayComponent,
25078
- FormFieldObjectComponent,
25079
- FormFieldRichComponent,
25080
- FormFieldFileComponent,
25081
- FormFieldSpatialExtentComponent,
25082
- FormFieldTemporalExtentComponent,
25083
25318
  CheckToggleComponent,
25084
25319
  CopyTextButtonComponent,
25085
25320
  CheckboxComponent,
@@ -25107,6 +25342,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
25107
25342
  EditableLabelDirective,
25108
25343
  TextAreaComponent,
25109
25344
  ButtonComponent,
25345
+ ImageInputComponent,
25110
25346
  ],
25111
25347
  exports: [
25112
25348
  DropdownSelectorComponent,
@@ -25120,13 +25356,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
25120
25356
  StarToggleComponent,
25121
25357
  DropdownMultiselectComponent,
25122
25358
  ViewportIntersectorComponent,
25123
- FormFieldComponent,
25124
25359
  CheckToggleComponent,
25125
25360
  CopyTextButtonComponent,
25126
25361
  CheckboxComponent,
25127
25362
  SearchInputComponent,
25128
25363
  DateRangePickerComponent,
25129
25364
  EditableLabelDirective,
25365
+ ImageInputComponent,
25130
25366
  ],
25131
25367
  }]
25132
25368
  }] });
@@ -25620,11 +25856,11 @@ class ThumbnailComponent {
25620
25856
  }
25621
25857
  }
25622
25858
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ThumbnailComponent, deps: [{ token: THUMBNAIL_PLACEHOLDER, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
25623
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: ThumbnailComponent, selector: "gn-ui-thumbnail", inputs: { thumbnailUrl: "thumbnailUrl", fit: "fit" }, outputs: { placeholderShown: "placeholderShown" }, viewQueries: [{ propertyName: "imgElement", first: true, predicate: ["imageElement"], descendants: true }, { propertyName: "containerElement", first: true, predicate: ["containerElement"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n #containerElement\n class=\"h-full w-full relative shrink-0 overflow-hidden flex items-center justify-center\"\n [ngClass]=\"isPlaceholder ? 'bg-gray-100' : 'bg-white'\"\n [attr.data-cy-is-placeholder]=\"isPlaceholder.toString()\"\n>\n <img\n #imageElement\n class=\"relative w-full object-center\"\n [ngClass]=\"imgFit === 'contain' ? 'h-4/5 w-4/5' : 'h-full'\"\n [ngStyle]=\"{ objectFit: imgFit }\"\n alt=\"thumbnail\"\n loading=\"lazy\"\n (load)=\"setObjectFit()\"\n [src]=\"imgUrl\"\n (error)=\"useFallback()\"\n />\n</div>\n", dependencies: [{ kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
25859
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: ThumbnailComponent, isStandalone: true, selector: "gn-ui-thumbnail", inputs: { thumbnailUrl: "thumbnailUrl", fit: "fit" }, outputs: { placeholderShown: "placeholderShown" }, viewQueries: [{ propertyName: "imgElement", first: true, predicate: ["imageElement"], descendants: true }, { propertyName: "containerElement", first: true, predicate: ["containerElement"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n #containerElement\n class=\"h-full w-full relative shrink-0 overflow-hidden flex items-center justify-center\"\n [ngClass]=\"isPlaceholder ? 'bg-gray-100' : 'bg-white'\"\n [attr.data-cy-is-placeholder]=\"isPlaceholder.toString()\"\n>\n <img\n #imageElement\n class=\"relative w-full object-center\"\n [ngClass]=\"imgFit === 'contain' ? 'h-4/5 w-4/5' : 'h-full'\"\n [ngStyle]=\"{ objectFit: imgFit }\"\n alt=\"thumbnail\"\n loading=\"lazy\"\n (load)=\"setObjectFit()\"\n [src]=\"imgUrl\"\n (error)=\"useFallback()\"\n />\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
25624
25860
  }
25625
25861
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ThumbnailComponent, decorators: [{
25626
25862
  type: Component,
25627
- args: [{ selector: 'gn-ui-thumbnail', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n #containerElement\n class=\"h-full w-full relative shrink-0 overflow-hidden flex items-center justify-center\"\n [ngClass]=\"isPlaceholder ? 'bg-gray-100' : 'bg-white'\"\n [attr.data-cy-is-placeholder]=\"isPlaceholder.toString()\"\n>\n <img\n #imageElement\n class=\"relative w-full object-center\"\n [ngClass]=\"imgFit === 'contain' ? 'h-4/5 w-4/5' : 'h-full'\"\n [ngStyle]=\"{ objectFit: imgFit }\"\n alt=\"thumbnail\"\n loading=\"lazy\"\n (load)=\"setObjectFit()\"\n [src]=\"imgUrl\"\n (error)=\"useFallback()\"\n />\n</div>\n" }]
25863
+ args: [{ selector: 'gn-ui-thumbnail', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule], template: "<div\n #containerElement\n class=\"h-full w-full relative shrink-0 overflow-hidden flex items-center justify-center\"\n [ngClass]=\"isPlaceholder ? 'bg-gray-100' : 'bg-white'\"\n [attr.data-cy-is-placeholder]=\"isPlaceholder.toString()\"\n>\n <img\n #imageElement\n class=\"relative w-full object-center\"\n [ngClass]=\"imgFit === 'contain' ? 'h-4/5 w-4/5' : 'h-full'\"\n [ngStyle]=\"{ objectFit: imgFit }\"\n alt=\"thumbnail\"\n loading=\"lazy\"\n (load)=\"setObjectFit()\"\n [src]=\"imgUrl\"\n (error)=\"useFallback()\"\n />\n</div>\n" }]
25628
25864
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
25629
25865
  type: Optional
25630
25866
  }, {
@@ -25919,44 +26155,52 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
25919
26155
  type: Output
25920
26156
  }] } });
25921
26157
 
25922
- class ExpandablePanelComponent {
26158
+ class ApiCardComponent {
25923
26159
  constructor() {
25924
- this.collapsed = true;
25925
- this.maxHeight = this.setMaxHeight();
26160
+ this.currentlyActive = false;
26161
+ this.openRecordApiForm = new EventEmitter();
25926
26162
  }
25927
- toggle() {
25928
- this.collapsed = !this.collapsed;
25929
- this.maxHeight = this.setMaxHeight();
26163
+ ngOnInit() {
26164
+ this.displayApiFormButton =
26165
+ this.link.accessServiceProtocol === 'ogcFeatures' ? true : false;
25930
26166
  }
25931
- setMaxHeight() {
25932
- return `${this.collapsed ? '0' : this.contentDiv.nativeElement.scrollHeight}px`;
26167
+ ngOnChanges(changes) {
26168
+ this.currentlyActive =
26169
+ changes.currentLink.currentValue === this.link ? true : false;
25933
26170
  }
25934
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ExpandablePanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
25935
- 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 }); }
26171
+ openRecordApiFormPanel() {
26172
+ if (this.displayApiFormButton) {
26173
+ this.currentlyActive = !this.currentlyActive;
26174
+ this.openRecordApiForm.emit(this.currentlyActive ? this.link : undefined);
26175
+ }
26176
+ }
26177
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ApiCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26178
+ 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 }); }
25936
26179
  }
25937
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ExpandablePanelComponent, decorators: [{
26180
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ApiCardComponent, decorators: [{
25938
26181
  type: Component,
25939
- 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" }]
25940
- }], propDecorators: { title: [{
26182
+ 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" }]
26183
+ }], propDecorators: { link: [{
25941
26184
  type: Input
25942
- }], collapsed: [{
26185
+ }], currentLink: [{
25943
26186
  type: Input
25944
- }], contentDiv: [{
25945
- type: ViewChild,
25946
- args: ['contentDiv']
26187
+ }], openRecordApiForm: [{
26188
+ type: Output
25947
26189
  }] } });
25948
26190
 
25949
- class MarkdownParserComponent {
25950
- get parsedMarkdown() {
25951
- return marked.parse(this.textContent);
26191
+ class AvatarComponent {
26192
+ hideImage() {
26193
+ this.avatarUrl = this.avatarPlaceholder;
25952
26194
  }
25953
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MarkdownParserComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
25954
- 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 }); }
26195
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: AvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26196
+ 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 }); }
25955
26197
  }
25956
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MarkdownParserComponent, decorators: [{
26198
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: AvatarComponent, decorators: [{
25957
26199
  type: Component,
25958
- 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"] }]
25959
- }], propDecorators: { textContent: [{
26200
+ 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" }]
26201
+ }], propDecorators: { avatarUrl: [{
26202
+ type: Input
26203
+ }], avatarPlaceholder: [{
25960
26204
  type: Input
25961
26205
  }] } });
25962
26206
 
@@ -25976,80 +26220,183 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
25976
26220
  type: Input
25977
26221
  }] } });
25978
26222
 
25979
- /* eslint-disable @angular-eslint/directive-selector */
25980
- class GnUiLinkifyDirective {
25981
- constructor(el, renderer) {
25982
- this.el = el;
25983
- this.renderer = renderer;
26223
+ class DownloadItemComponent {
26224
+ constructor() {
26225
+ this.exportUrl = new EventEmitter();
25984
26226
  }
25985
- ngOnInit() {
25986
- setTimeout(() => {
25987
- this.processLinks(this.el.nativeElement);
25988
- }, 0);
26227
+ openUrl() {
26228
+ this.exportUrl.emit(this.link.url.toString());
25989
26229
  }
25990
- processLinks(container) {
25991
- const nodes = Array.from(container.childNodes);
25992
- nodes.forEach((node) => {
25993
- if (node instanceof Text) {
25994
- const textNode = node;
25995
- const linkified = this.linkifyNode(textNode.nodeValue);
25996
- if (linkified) {
25997
- this.createLinkElements(container, linkified, node);
25998
- }
25999
- }
26000
- else if (node instanceof HTMLAnchorElement) {
26001
- const url = node.href;
26002
- const displayValue = node.innerHTML;
26003
- const linkified = this.linkifyNode(displayValue, url);
26004
- if (linkified) {
26005
- this.createLinkElements(container, linkified, node);
26006
- }
26007
- }
26008
- else {
26009
- this.processLinks(node);
26010
- }
26011
- });
26230
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: DownloadItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26231
+ 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 }); }
26232
+ }
26233
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: DownloadItemComponent, decorators: [{
26234
+ type: Component,
26235
+ 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" }]
26236
+ }], propDecorators: { link: [{
26237
+ type: Input
26238
+ }], color: [{
26239
+ type: Input
26240
+ }], format: [{
26241
+ type: Input
26242
+ }], isFromWfs: [{
26243
+ type: Input
26244
+ }], exportUrl: [{
26245
+ type: Output
26246
+ }] } });
26247
+
26248
+ marker('datahub.search.filter.all');
26249
+ marker('datahub.search.filter.others');
26250
+ const FILTER_FORMATS = ['all', 'csv', 'excel', 'json', 'shp', 'others'];
26251
+ class DownloadsListComponent {
26252
+ constructor(translateService) {
26253
+ this.translateService = translateService;
26254
+ this.activeFilterFormats = ['all'];
26012
26255
  }
26013
- linkifyNode(displayValue, url) {
26014
- if (url) {
26015
- displayValue = this.createLink(displayValue, url);
26256
+ get filteredLinks() {
26257
+ return this.links.filter((link) => this.activeFilterFormats.some((format) => this.isLinkOfFormat(link, format)));
26258
+ }
26259
+ get visibleFormats() {
26260
+ return FILTER_FORMATS.filter((format) => this.links.some((link) => this.isLinkOfFormat(link, format)));
26261
+ }
26262
+ toggleFilterFormat(format) {
26263
+ if (format === 'all') {
26264
+ this.activeFilterFormats = ['all'];
26265
+ return;
26266
+ }
26267
+ if (this.isFilterActive(format)) {
26268
+ this.activeFilterFormats = this.activeFilterFormats.filter((f) => format !== f);
26016
26269
  }
26017
26270
  else {
26018
- const urlRegex = /\bhttps?:\/\/(?:\([^\s()]+\)|[^\s()]+)+/g;
26019
- const matches = displayValue.match(urlRegex);
26020
- if (matches && matches.length > 0) {
26021
- matches.forEach((match) => {
26022
- url = match;
26023
- displayValue = displayValue.replace(match, (match) => {
26024
- return this.createLink(match, url);
26025
- });
26026
- });
26027
- }
26271
+ this.activeFilterFormats = [
26272
+ ...this.activeFilterFormats.filter((f) => f !== 'all'),
26273
+ format,
26274
+ ];
26275
+ }
26276
+ if (this.activeFilterFormats.length === 0) {
26277
+ this.activeFilterFormats = ['all'];
26028
26278
  }
26029
- return displayValue;
26030
26279
  }
26031
- createLinkElements(container, htmlContent, node) {
26032
- const div = this.renderer.createElement('div');
26033
- div.innerHTML = htmlContent;
26034
- const fragment = document.createDocumentFragment();
26035
- Array.from(div.childNodes).forEach((childNode) => {
26036
- fragment.appendChild(childNode);
26037
- });
26038
- container.insertBefore(fragment, node);
26039
- container.removeChild(node);
26280
+ isFilterActive(filter) {
26281
+ return this.activeFilterFormats.includes(filter);
26040
26282
  }
26041
- createLink(displayValue, url) {
26042
- 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>`;
26283
+ getFilterFormatTitle(format) {
26284
+ if (format === 'all' || format === 'others') {
26285
+ return this.translateService.instant(`datahub.search.filter.${format}`);
26286
+ }
26287
+ return format;
26043
26288
  }
26044
- 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 }); }
26045
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.1.7", type: GnUiLinkifyDirective, selector: "[gnUiLinkify]", ngImport: i0 }); }
26289
+ isLinkOfFormat(link, format) {
26290
+ if (format === 'all') {
26291
+ return true;
26292
+ }
26293
+ if (getFileFormat(link) === null) {
26294
+ return format === 'others';
26295
+ }
26296
+ if (format === 'others') {
26297
+ const knownFormats = FILTER_FORMATS.filter((format) => format !== 'all' && format !== 'others');
26298
+ return knownFormats.every((knownFormat) => !getFileFormat(link).includes(knownFormat));
26299
+ }
26300
+ return getFileFormat(link).includes(format);
26301
+ }
26302
+ getLinkFormat(link) {
26303
+ return getFileFormat(link);
26304
+ }
26305
+ getLinkColor(link) {
26306
+ return getBadgeColor(getFileFormat(link));
26307
+ }
26308
+ isFromWfs(link) {
26309
+ return link.type === 'service' && link.accessServiceProtocol === 'wfs';
26310
+ }
26311
+ 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 }); }
26312
+ 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 }); }
26046
26313
  }
26047
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: GnUiLinkifyDirective, decorators: [{
26048
- type: Directive,
26049
- args: [{
26050
- selector: '[gnUiLinkify]',
26051
- }]
26052
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }]; } });
26314
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: DownloadsListComponent, decorators: [{
26315
+ type: Component,
26316
+ 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" }]
26317
+ }], ctorParameters: function () { return [{ type: i1$1.TranslateService }]; }, propDecorators: { links: [{
26318
+ type: Input
26319
+ }] } });
26320
+
26321
+ class ImageOverlayPreviewComponent {
26322
+ constructor() {
26323
+ this.isPlaceholderShown = new EventEmitter();
26324
+ }
26325
+ openLightbox(src) {
26326
+ basicLightbox.create(`<img src="${src}"/>`).show();
26327
+ }
26328
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ImageOverlayPreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26329
+ 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"] }] }); }
26330
+ }
26331
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ImageOverlayPreviewComponent, decorators: [{
26332
+ type: Component,
26333
+ 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" }]
26334
+ }], propDecorators: { imageUrl: [{
26335
+ type: Input
26336
+ }], isPlaceholderShown: [{
26337
+ type: Output
26338
+ }] } });
26339
+
26340
+ class LinkCardComponent {
26341
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: LinkCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26342
+ 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 }); }
26343
+ }
26344
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: LinkCardComponent, decorators: [{
26345
+ type: Component,
26346
+ 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" }]
26347
+ }], propDecorators: { link: [{
26348
+ type: Input
26349
+ }] } });
26350
+
26351
+ class MarkdownParserComponent {
26352
+ get parsedMarkdown() {
26353
+ return marked.parse(this.textContent);
26354
+ }
26355
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MarkdownParserComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26356
+ 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 }); }
26357
+ }
26358
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MarkdownParserComponent, decorators: [{
26359
+ type: Component,
26360
+ 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"] }]
26361
+ }], propDecorators: { textContent: [{
26362
+ type: Input
26363
+ }] } });
26364
+
26365
+ class MarkdownEditorComponent {
26366
+ constructor() {
26367
+ this.preview = false;
26368
+ this.textContentChanged = new EventEmitter();
26369
+ }
26370
+ textContentChangedHandler(textContent) {
26371
+ this.textContent = textContent;
26372
+ this.textContentChanged.emit(this.textContent);
26373
+ }
26374
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MarkdownEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26375
+ 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", "placeholder", "required"], outputs: ["valueChange"] }, { kind: "component", type: MarkdownParserComponent, selector: "gn-ui-markdown-parser", inputs: ["textContent"] }, { kind: "ngmodule", type: TranslateModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26376
+ }
26377
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MarkdownEditorComponent, decorators: [{
26378
+ type: Component,
26379
+ args: [{ selector: 'gn-ui-markdown-editor', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
26380
+ CommonModule,
26381
+ FormsModule,
26382
+ MatIconModule,
26383
+ MatTooltipModule,
26384
+ ButtonComponent,
26385
+ TextAreaComponent,
26386
+ MarkdownParserComponent,
26387
+ TranslateModule,
26388
+ ], 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" }]
26389
+ }], propDecorators: { preview: [{
26390
+ type: Input
26391
+ }], helperText: [{
26392
+ type: Input
26393
+ }], placeholder: [{
26394
+ type: Input
26395
+ }], textContent: [{
26396
+ type: Input
26397
+ }], textContentChanged: [{
26398
+ type: Output
26399
+ }] } });
26053
26400
 
26054
26401
  class MaxLinesComponent {
26055
26402
  constructor(cdr) {
@@ -26116,6 +26463,155 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
26116
26463
  args: ['container']
26117
26464
  }] } });
26118
26465
 
26466
+ class MetadataCatalogComponent {
26467
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MetadataCatalogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26468
+ 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 }); }
26469
+ }
26470
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MetadataCatalogComponent, decorators: [{
26471
+ type: Component,
26472
+ 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" }]
26473
+ }], propDecorators: { sourceLabel: [{
26474
+ type: Input
26475
+ }] } });
26476
+
26477
+ class MetadataContactComponent {
26478
+ constructor() {
26479
+ this.organizationClick = new EventEmitter();
26480
+ this.contactClick = new EventEmitter();
26481
+ }
26482
+ get shownOrganization() {
26483
+ return this.metadata.ownerOrganization;
26484
+ }
26485
+ get contacts() {
26486
+ return ((this.metadata.kind === 'dataset'
26487
+ ? this.metadata.contactsForResource
26488
+ : this.metadata.contacts) || []);
26489
+ }
26490
+ get address() {
26491
+ const addressParts = this.contacts[0].address
26492
+ .split(',')
26493
+ .map((part) => part.trim());
26494
+ return addressParts;
26495
+ }
26496
+ onOrganizationClick() {
26497
+ this.organizationClick.emit(this.shownOrganization);
26498
+ }
26499
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MetadataContactComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26500
+ 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 }); }
26501
+ }
26502
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MetadataContactComponent, decorators: [{
26503
+ type: Component,
26504
+ 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" }]
26505
+ }], propDecorators: { metadata: [{
26506
+ type: Input
26507
+ }], organizationClick: [{
26508
+ type: Output
26509
+ }], contactClick: [{
26510
+ type: Output
26511
+ }] } });
26512
+
26513
+ class ExpandablePanelComponent {
26514
+ constructor() {
26515
+ this.collapsed = true;
26516
+ this.maxHeight = this.setMaxHeight();
26517
+ }
26518
+ toggle() {
26519
+ this.collapsed = !this.collapsed;
26520
+ this.maxHeight = this.setMaxHeight();
26521
+ }
26522
+ setMaxHeight() {
26523
+ return `${this.collapsed ? '0' : this.contentDiv.nativeElement.scrollHeight}px`;
26524
+ }
26525
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ExpandablePanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26526
+ 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 }); }
26527
+ }
26528
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ExpandablePanelComponent, decorators: [{
26529
+ type: Component,
26530
+ 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" }]
26531
+ }], propDecorators: { title: [{
26532
+ type: Input
26533
+ }], collapsed: [{
26534
+ type: Input
26535
+ }], contentDiv: [{
26536
+ type: ViewChild,
26537
+ args: ['contentDiv']
26538
+ }] } });
26539
+
26540
+ /* eslint-disable @angular-eslint/directive-selector */
26541
+ class GnUiLinkifyDirective {
26542
+ constructor(el, renderer) {
26543
+ this.el = el;
26544
+ this.renderer = renderer;
26545
+ }
26546
+ ngOnInit() {
26547
+ setTimeout(() => {
26548
+ this.processLinks(this.el.nativeElement);
26549
+ }, 0);
26550
+ }
26551
+ processLinks(container) {
26552
+ const nodes = Array.from(container.childNodes);
26553
+ nodes.forEach((node) => {
26554
+ if (node instanceof Text) {
26555
+ const textNode = node;
26556
+ const linkified = this.linkifyNode(textNode.nodeValue);
26557
+ if (linkified) {
26558
+ this.createLinkElements(container, linkified, node);
26559
+ }
26560
+ }
26561
+ else if (node instanceof HTMLAnchorElement) {
26562
+ const url = node.href;
26563
+ const displayValue = node.innerHTML;
26564
+ const linkified = this.linkifyNode(displayValue, url);
26565
+ if (linkified) {
26566
+ this.createLinkElements(container, linkified, node);
26567
+ }
26568
+ }
26569
+ else {
26570
+ this.processLinks(node);
26571
+ }
26572
+ });
26573
+ }
26574
+ linkifyNode(displayValue, url) {
26575
+ if (url) {
26576
+ displayValue = this.createLink(displayValue, url);
26577
+ }
26578
+ else {
26579
+ const urlRegex = /\bhttps?:\/\/(?:\([^\s()]+\)|[^\s()]+)+/g;
26580
+ const matches = displayValue.match(urlRegex);
26581
+ if (matches && matches.length > 0) {
26582
+ matches.forEach((match) => {
26583
+ url = match;
26584
+ displayValue = displayValue.replace(match, (match) => {
26585
+ return this.createLink(match, url);
26586
+ });
26587
+ });
26588
+ }
26589
+ }
26590
+ return displayValue;
26591
+ }
26592
+ createLinkElements(container, htmlContent, node) {
26593
+ const div = this.renderer.createElement('div');
26594
+ div.innerHTML = htmlContent;
26595
+ const fragment = document.createDocumentFragment();
26596
+ Array.from(div.childNodes).forEach((childNode) => {
26597
+ fragment.appendChild(childNode);
26598
+ });
26599
+ container.insertBefore(fragment, node);
26600
+ container.removeChild(node);
26601
+ }
26602
+ createLink(displayValue, url) {
26603
+ 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>`;
26604
+ }
26605
+ 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 }); }
26606
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.1.7", type: GnUiLinkifyDirective, selector: "[gnUiLinkify]", ngImport: i0 }); }
26607
+ }
26608
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: GnUiLinkifyDirective, decorators: [{
26609
+ type: Directive,
26610
+ args: [{
26611
+ selector: '[gnUiLinkify]',
26612
+ }]
26613
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }]; } });
26614
+
26119
26615
  class MetadataInfoComponent {
26120
26616
  constructor() {
26121
26617
  this.keyword = new EventEmitter();
@@ -26180,7 +26676,7 @@ class MetadataInfoComponent {
26180
26676
  this.keyword.emit(keyword);
26181
26677
  }
26182
26678
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MetadataInfoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26183
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: MetadataInfoComponent, selector: "gn-ui-metadata-info", inputs: { metadata: "metadata", incomplete: "incomplete" }, outputs: { keyword: "keyword" }, ngImport: i0, template: "<div class=\"mb-6 md-description sm:mb-4 sm:pr-16\">\n <gn-ui-content-ghost ghostClass=\"h-32\" [showContent]=\"fieldReady('abstract')\">\n <gn-ui-max-lines [maxLines]=\"6\" *ngIf=\"metadata.abstract\">\n <div>\n <gn-ui-markdown-parser\n [textContent]=\"metadata.abstract\"\n ></gn-ui-markdown-parser>\n </div>\n </gn-ui-max-lines>\n <div *ngIf=\"metadata.keywords?.length\">\n <p class=\"mt-6 mb-3 font-medium text-primary text-sm\" translate>\n record.metadata.keywords\n </p>\n <div class=\"sm:pb-4 flex flex-wrap gap-2\">\n <gn-ui-badge\n class=\"inline-block lowercase\"\n (click)=\"onKeywordClick(keyword)\"\n [clickable]=\"true\"\n *ngFor=\"let keyword of metadata.keywords\"\n >{{ keyword.label }}</gn-ui-badge\n >\n </div>\n </div>\n </gn-ui-content-ghost>\n</div>\n\n<gn-ui-expandable-panel [title]=\"'record.metadata.usage' | translate\">\n <div class=\"flex flex-col gap-[10px] mr-4 py-[12px] rounded text-gray-900\">\n <ng-container *ngFor=\"let license of licenses\">\n <div *ngIf=\"license.url; else noUrl\" class=\"text-primary\">\n <a\n [href]=\"license.url\"\n target=\"_blank\"\n class=\"cursor-pointer hover:underline transition-all\"\n >\n {{ license.text }}\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 <ng-template #noUrl>\n <div class=\"text-primary\" gnUiLinkify>\n {{ license.text }}\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"legalConstraints.length\">\n <gn-ui-markdown-parser\n *ngFor=\"let constraint of legalConstraints\"\n [textContent]=\"constraint\"\n >\n </gn-ui-markdown-parser>\n </ng-container>\n <ng-container *ngIf=\"otherConstraints.length\">\n <div gnUiLinkify *ngFor=\"let constraint of otherConstraints\">\n <h5 translate class=\"font-medium text-black text-sm mb-[2px] mt-[16px]\">\n record.metadata.otherConstraints\n </h5>\n <gn-ui-markdown-parser [textContent]=\"constraint\">\n </gn-ui-markdown-parser>\n </div>\n </ng-container>\n\n <span class=\"noUsage\" *ngIf=\"!hasUsage\">\n {{ 'record.metadata.noUsage' | translate }}\n </span>\n </div>\n</gn-ui-expandable-panel>\n<gn-ui-expandable-panel\n *ngIf=\"\n metadata.lineage ||\n metadata.recordUpdated ||\n metadata.updateFrequency ||\n metadata.status\n \"\n [title]=\"'record.metadata.details' | translate\"\n>\n <div *ngIf=\"metadata.lineage\" class=\"text-gray-900 flex flex-col mt-4 gap-2\">\n <p class=\"whitespace-pre-line break-words text-gray-900\" gnUiLinkify>\n {{ metadata.lineage }}\n </p>\n </div>\n <div class=\"flex flex-row gap-6 mt-5 mb-8\" *ngIf=\"resourceContact\">\n <div\n *ngIf=\"resourceContact.organization?.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]=\"resourceContact.organization.logoUrl.href\"\n fit=\"contain\"\n ></gn-ui-thumbnail>\n </div>\n <div class=\"flex flex-col gap-1\">\n <p class=\"text-sm font-medium\" translate>record.metadata.producer</p>\n <div\n class=\"text-primary font-title text-21 mr-2 cursor-pointer hover:underline\"\n data-cy=\"organization-name\"\n >\n {{ resourceContact.organization?.name }}\n </div>\n <div *ngIf=\"resourceContact.organization?.website\">\n <a\n [href]=\"resourceContact.organization.website\"\n target=\"_blank\"\n class=\"contact-website text-primary text-sm cursor-pointer hover:underline transition-all\"\n >{{ resourceContact.organization.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 class=\"mt-4\" *ngIf=\"resourceContact.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=\"resourceContact.email\"\n [href]=\"'mailto:' + resourceContact.email\"\n class=\"text-sm hover:underline ml-2\"\n target=\"_blank\"\n data-cy=\"contact-email\"\n >{{ resourceContact?.email }}</a\n >\n </div>\n </div>\n </div>\n </div>\n <div\n class=\"py-6 px-6 rounded bg-gray-100 grid grid-cols-2 gap-y-6 gap-x-[20px] text-gray-700\"\n >\n <div *ngIf=\"metadata.recordCreated\">\n <p class=\"text-sm\" translate>record.metadata.creation</p>\n <p class=\"text-primary font-medium mt-1\">\n {{ metadata.recordCreated.toLocaleDateString() }}\n </p>\n </div>\n <div *ngIf=\"metadata.recordPublished\">\n <p class=\"text-sm\" translate>record.metadata.publication</p>\n <p class=\"text-primary font-medium mt-1\">\n {{ metadata.recordPublished.toLocaleDateString() }}\n </p>\n </div>\n <div *ngIf=\"updateFrequency\">\n <p class=\"text-sm\" translate>record.metadata.updateFrequency</p>\n <p\n class=\"text-primary font-medium mt-1 updateFrequency\"\n translate\n [translateParams]=\"{ count: updatedTimes }\"\n >\n {{ updateFrequency }}\n </p>\n </div>\n <div *ngIf=\"metadata.languages\">\n <p class=\"text-sm mb-1\" translate>record.metadata.languages</p>\n <div class=\"flex flex-row gap-1 flex-wrap\">\n <p\n class=\"text-primary font-medium\"\n translate\n *ngFor=\"let language of metadata.languages\"\n >\n language.{{ language }}\n </p>\n </div>\n </div>\n <div *ngIf=\"temporalExtent\">\n <p class=\"text-sm\" translate>record.metadata.temporalExtent</p>\n <div class=\"flex flex-row gap-1 mb-1 text-primary font-medium\">\n <p\n *ngIf=\"temporalExtent.start && temporalExtent.end\"\n translate\n [translateParams]=\"{\n start: temporalExtent.start,\n end: temporalExtent.end\n }\"\n >\n record.metadata.temporalExtent.fromDateToDate\n </p>\n <p\n *ngIf=\"temporalExtent.start && !temporalExtent.end\"\n translate\n [translateParams]=\"{ start: temporalExtent.start }\"\n >\n record.metadata.temporalExtent.sinceDate\n </p>\n <p\n *ngIf=\"!temporalExtent.start && temporalExtent.end\"\n translate\n [translateParams]=\"{ end: temporalExtent.end }\"\n >\n record.metadata.temporalExtent.untilDate\n </p>\n </div>\n </div>\n </div>\n</gn-ui-expandable-panel>\n<gn-ui-expandable-panel\n *ngIf=\"metadata.landingPage\"\n [title]=\"'record.metadata.technical' | translate\"\n>\n <div class=\"flex flex-col gap-4 mr-4 py-5 rounded text-gray-700\">\n <div *ngIf=\"metadata.recordUpdated\">\n <p class=\"text-sm\" translate>record.metadata.updatedOn</p>\n <p class=\"text-primary font-medium\">\n {{ metadata.recordUpdated && metadata.recordUpdated.toLocaleString() }}\n </p>\n </div>\n <div *ngIf=\"metadata.landingPage\">\n <p class=\"text-sm\" translate>record.metadata.sheet</p>\n <p class=\"text-primary font-medium\" translate>\n <a [href]=\"metadata.landingPage\" target=\"_blank\">\n <span class=\"break-all\" gnUiLinkify>{{ metadata.landingPage }}</span>\n </a>\n </p>\n </div>\n <div *ngIf=\"metadata.ownerOrganization\">\n <p class=\"text-sm\" translate>record.metadata.owner</p>\n <p class=\"text-primary font-medium\">\n {{ metadata.ownerOrganization.name }}\n </p>\n </div>\n <div *ngIf=\"metadata.uniqueIdentifier\">\n <p class=\"text-sm\" translate>record.metadata.uniqueId</p>\n <div class=\"flex flex-row content-align items-end gap-1\">\n <gn-ui-copy-text-button\n [text]=\"metadata.uniqueIdentifier\"\n [tooltipText]=\"'tooltip.id.copy' | translate\"\n [displayText]=\"false\"\n ></gn-ui-copy-text-button>\n <p class=\"text-primary font-medium\">\n {{ metadata.uniqueIdentifier }}\n </p>\n </div>\n </div>\n <div *ngIf=\"metadata.topics?.length\">\n <p class=\"text-sm mb-1\" translate>record.metadata.topics</p>\n <div class=\"sm:pb-4 sm:pr-16\">\n <gn-ui-badge\n class=\"inline-block mr-2 mb-2 lowercase\"\n *ngFor=\"let topic of metadata.topics\"\n >{{ topic }}</gn-ui-badge\n >\n </div>\n </div>\n </div>\n</gn-ui-expandable-panel>\n", styles: [".md-description ::ng-deep a{@apply underline text-blue-600 hover:text-blue-800;}.info-grid>:nth-last-child(n+3){padding-bottom:10px;@apply border-b border-gray-300;}:host ::ng-deep gn-ui-copy-text-button button mat-icon{transform:scale(.8)}\n"], 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: BadgeComponent, selector: "gn-ui-badge", inputs: ["clickable"] }, { kind: "component", type: ExpandablePanelComponent, selector: "gn-ui-expandable-panel", inputs: ["title", "collapsed"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: CopyTextButtonComponent, selector: "gn-ui-copy-text-button", inputs: ["text", "tooltipText", "displayText", "rows"] }, { kind: "component", type: MarkdownParserComponent, selector: "gn-ui-markdown-parser", inputs: ["textContent"] }, { kind: "component", type: ContentGhostComponent, selector: "gn-ui-content-ghost", inputs: ["showContent", "ghostClass"] }, { kind: "component", type: ThumbnailComponent, selector: "gn-ui-thumbnail", inputs: ["thumbnailUrl", "fit"], outputs: ["placeholderShown"] }, { kind: "directive", type: GnUiLinkifyDirective, selector: "[gnUiLinkify]" }, { kind: "component", type: MaxLinesComponent, selector: "gn-ui-max-lines", inputs: ["maxLines"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26679
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: MetadataInfoComponent, selector: "gn-ui-metadata-info", inputs: { metadata: "metadata", incomplete: "incomplete" }, outputs: { keyword: "keyword" }, ngImport: i0, template: "<div class=\"mb-6 md-description sm:mb-4 sm:pr-16\">\n <gn-ui-content-ghost ghostClass=\"h-32\" [showContent]=\"fieldReady('abstract')\">\n <gn-ui-max-lines [maxLines]=\"6\" *ngIf=\"metadata.abstract\">\n <div>\n <gn-ui-markdown-parser\n [textContent]=\"metadata.abstract\"\n ></gn-ui-markdown-parser>\n </div>\n </gn-ui-max-lines>\n <div *ngIf=\"metadata.keywords?.length\">\n <p class=\"mt-6 mb-3 font-medium text-primary text-sm\" translate>\n record.metadata.keywords\n </p>\n <div class=\"sm:pb-4 flex flex-wrap gap-2\">\n <gn-ui-badge\n class=\"inline-block lowercase\"\n (click)=\"onKeywordClick(keyword)\"\n [clickable]=\"true\"\n *ngFor=\"let keyword of metadata.keywords\"\n >{{ keyword.label }}</gn-ui-badge\n >\n </div>\n </div>\n </gn-ui-content-ghost>\n</div>\n\n<gn-ui-expandable-panel [title]=\"'record.metadata.usage' | translate\">\n <div class=\"flex flex-col gap-[10px] mr-4 py-[12px] rounded text-gray-900\">\n <ng-container *ngFor=\"let license of licenses\">\n <div *ngIf=\"license.url; else noUrl\" class=\"text-primary\">\n <a\n [href]=\"license.url\"\n target=\"_blank\"\n class=\"cursor-pointer hover:underline transition-all\"\n >\n {{ license.text }}\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 <ng-template #noUrl>\n <div class=\"text-primary\" gnUiLinkify>\n {{ license.text }}\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"legalConstraints.length\">\n <gn-ui-markdown-parser\n *ngFor=\"let constraint of legalConstraints\"\n [textContent]=\"constraint\"\n >\n </gn-ui-markdown-parser>\n </ng-container>\n <ng-container *ngIf=\"otherConstraints.length\">\n <div gnUiLinkify *ngFor=\"let constraint of otherConstraints\">\n <h5 translate class=\"font-medium text-black text-sm mb-[2px] mt-[16px]\">\n record.metadata.otherConstraints\n </h5>\n <gn-ui-markdown-parser [textContent]=\"constraint\">\n </gn-ui-markdown-parser>\n </div>\n </ng-container>\n\n <span class=\"noUsage\" *ngIf=\"!hasUsage\">\n {{ 'record.metadata.noUsage' | translate }}\n </span>\n </div>\n</gn-ui-expandable-panel>\n<gn-ui-expandable-panel\n *ngIf=\"\n metadata.lineage ||\n metadata.recordUpdated ||\n metadata.updateFrequency ||\n metadata.status\n \"\n [title]=\"'record.metadata.details' | translate\"\n>\n <div *ngIf=\"metadata.lineage\" class=\"text-gray-900 flex flex-col mt-4 gap-2\">\n <p class=\"whitespace-pre-line break-words text-gray-900\" gnUiLinkify>\n {{ metadata.lineage }}\n </p>\n </div>\n <div class=\"flex flex-row gap-6 mt-5 mb-8\" *ngIf=\"resourceContact\">\n <div\n *ngIf=\"resourceContact.organization?.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]=\"resourceContact.organization.logoUrl.href\"\n fit=\"contain\"\n ></gn-ui-thumbnail>\n </div>\n <div class=\"flex flex-col gap-1\">\n <p class=\"text-sm font-medium\" translate>record.metadata.producer</p>\n <div\n class=\"text-primary font-title text-21 mr-2 cursor-pointer hover:underline\"\n data-cy=\"organization-name\"\n >\n {{ resourceContact.organization?.name }}\n </div>\n <div *ngIf=\"resourceContact.organization?.website\">\n <a\n [href]=\"resourceContact.organization.website\"\n target=\"_blank\"\n class=\"contact-website text-primary text-sm cursor-pointer hover:underline transition-all\"\n >{{ resourceContact.organization.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 class=\"mt-4\" *ngIf=\"resourceContact.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=\"resourceContact.email\"\n [href]=\"'mailto:' + resourceContact.email\"\n class=\"text-sm hover:underline ml-2\"\n target=\"_blank\"\n data-cy=\"contact-email\"\n >{{ resourceContact?.email }}</a\n >\n </div>\n </div>\n </div>\n </div>\n <div\n class=\"py-6 px-6 rounded bg-gray-100 grid grid-cols-2 gap-y-6 gap-x-[20px] text-gray-700\"\n >\n <div *ngIf=\"metadata.recordCreated\">\n <p class=\"text-sm\" translate>record.metadata.creation</p>\n <p class=\"text-primary font-medium mt-1\">\n {{ metadata.recordCreated.toLocaleDateString() }}\n </p>\n </div>\n <div *ngIf=\"metadata.recordPublished\">\n <p class=\"text-sm\" translate>record.metadata.publication</p>\n <p class=\"text-primary font-medium mt-1\">\n {{ metadata.recordPublished.toLocaleDateString() }}\n </p>\n </div>\n <div *ngIf=\"updateFrequency\">\n <p class=\"text-sm\" translate>record.metadata.updateFrequency</p>\n <p\n class=\"text-primary font-medium mt-1 updateFrequency\"\n translate\n [translateParams]=\"{ count: updatedTimes }\"\n >\n {{ updateFrequency }}\n </p>\n </div>\n <div *ngIf=\"metadata.languages\">\n <p class=\"text-sm mb-1\" translate>record.metadata.languages</p>\n <div class=\"flex flex-row gap-1 flex-wrap\">\n <p\n class=\"text-primary font-medium\"\n translate\n *ngFor=\"let language of metadata.languages\"\n >\n language.{{ language }}\n </p>\n </div>\n </div>\n <div *ngIf=\"temporalExtent\">\n <p class=\"text-sm\" translate>record.metadata.temporalExtent</p>\n <div class=\"flex flex-row gap-1 mb-1 text-primary font-medium\">\n <p\n *ngIf=\"temporalExtent.start && temporalExtent.end\"\n translate\n [translateParams]=\"{\n start: temporalExtent.start,\n end: temporalExtent.end\n }\"\n >\n record.metadata.temporalExtent.fromDateToDate\n </p>\n <p\n *ngIf=\"temporalExtent.start && !temporalExtent.end\"\n translate\n [translateParams]=\"{ start: temporalExtent.start }\"\n >\n record.metadata.temporalExtent.sinceDate\n </p>\n <p\n *ngIf=\"!temporalExtent.start && temporalExtent.end\"\n translate\n [translateParams]=\"{ end: temporalExtent.end }\"\n >\n record.metadata.temporalExtent.untilDate\n </p>\n </div>\n </div>\n </div>\n</gn-ui-expandable-panel>\n<gn-ui-expandable-panel\n *ngIf=\"metadata.landingPage\"\n [title]=\"'record.metadata.technical' | translate\"\n>\n <div class=\"flex flex-col gap-4 mr-4 py-5 rounded text-gray-700\">\n <div *ngIf=\"metadata.recordUpdated\">\n <p class=\"text-sm\" translate>record.metadata.updatedOn</p>\n <p class=\"text-primary font-medium\">\n {{ metadata.recordUpdated && metadata.recordUpdated.toLocaleString() }}\n </p>\n </div>\n <div *ngIf=\"metadata.landingPage\">\n <p class=\"text-sm\" translate>record.metadata.sheet</p>\n <p class=\"text-primary font-medium\" translate>\n <a [href]=\"metadata.landingPage\" target=\"_blank\">\n <span class=\"break-all\" gnUiLinkify>{{ metadata.landingPage }}</span>\n </a>\n </p>\n </div>\n <div *ngIf=\"metadata.ownerOrganization\">\n <p class=\"text-sm\" translate>record.metadata.owner</p>\n <p class=\"text-primary font-medium\">\n {{ metadata.ownerOrganization.name }}\n </p>\n </div>\n <div *ngIf=\"metadata.uniqueIdentifier\">\n <p class=\"text-sm\" translate>record.metadata.uniqueId</p>\n <div class=\"flex flex-row content-align items-end gap-1\">\n <gn-ui-copy-text-button\n [text]=\"metadata.uniqueIdentifier\"\n [tooltipText]=\"'tooltip.id.copy' | translate\"\n [displayText]=\"false\"\n ></gn-ui-copy-text-button>\n <p class=\"text-primary font-medium\">\n {{ metadata.uniqueIdentifier }}\n </p>\n </div>\n </div>\n <div *ngIf=\"metadata.topics?.length\">\n <p class=\"text-sm mb-1\" translate>record.metadata.topics</p>\n <div class=\"sm:pb-4 sm:pr-16\">\n <gn-ui-badge\n class=\"inline-block mr-2 mb-2 lowercase\"\n *ngFor=\"let topic of metadata.topics\"\n >{{ topic }}</gn-ui-badge\n >\n </div>\n </div>\n </div>\n</gn-ui-expandable-panel>\n", styles: [".md-description ::ng-deep a{@apply underline text-blue-600 hover:text-blue-800;}.info-grid>:nth-last-child(n+3){padding-bottom:10px;@apply border-b border-gray-300;}:host ::ng-deep gn-ui-copy-text-button button mat-icon{transform:scale(.8)}\n"], 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: BadgeComponent, selector: "gn-ui-badge", inputs: ["clickable"] }, { kind: "component", type: ExpandablePanelComponent, selector: "gn-ui-expandable-panel", inputs: ["title", "collapsed"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: CopyTextButtonComponent, selector: "gn-ui-copy-text-button", inputs: ["text", "tooltipText", "displayText", "rows"] }, { kind: "component", type: MarkdownParserComponent, selector: "gn-ui-markdown-parser", inputs: ["textContent"] }, { 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"] }, { kind: "directive", type: GnUiLinkifyDirective, selector: "[gnUiLinkify]" }, { kind: "component", type: MaxLinesComponent, selector: "gn-ui-max-lines", inputs: ["maxLines"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26184
26680
  }
26185
26681
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MetadataInfoComponent, decorators: [{
26186
26682
  type: Component,
@@ -26193,504 +26689,67 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
26193
26689
  type: Output
26194
26690
  }] } });
26195
26691
 
26196
- class DownloadItemComponent {
26692
+ class PaginationButtonsComponent {
26197
26693
  constructor() {
26198
- this.exportUrl = new EventEmitter();
26199
- }
26200
- openUrl() {
26201
- this.exportUrl.emit(this.link.url.toString());
26202
- }
26203
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: DownloadItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26204
- 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 }); }
26205
- }
26206
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: DownloadItemComponent, decorators: [{
26207
- type: Component,
26208
- 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" }]
26209
- }], propDecorators: { link: [{
26210
- type: Input
26211
- }], color: [{
26212
- type: Input
26213
- }], format: [{
26214
- type: Input
26215
- }], isFromWfs: [{
26216
- type: Input
26217
- }], exportUrl: [{
26218
- type: Output
26219
- }] } });
26220
-
26221
- marker('datahub.search.filter.all');
26222
- marker('datahub.search.filter.others');
26223
- const FILTER_FORMATS = ['all', 'csv', 'excel', 'json', 'shp', 'others'];
26224
- class DownloadsListComponent {
26225
- constructor(translateService) {
26226
- this.translateService = translateService;
26227
- this.activeFilterFormats = ['all'];
26228
- }
26229
- get filteredLinks() {
26230
- return this.links.filter((link) => this.activeFilterFormats.some((format) => this.isLinkOfFormat(link, format)));
26231
- }
26232
- get visibleFormats() {
26233
- return FILTER_FORMATS.filter((format) => this.links.some((link) => this.isLinkOfFormat(link, format)));
26234
- }
26235
- toggleFilterFormat(format) {
26236
- if (format === 'all') {
26237
- this.activeFilterFormats = ['all'];
26238
- return;
26239
- }
26240
- if (this.isFilterActive(format)) {
26241
- this.activeFilterFormats = this.activeFilterFormats.filter((f) => format !== f);
26242
- }
26243
- else {
26244
- this.activeFilterFormats = [
26245
- ...this.activeFilterFormats.filter((f) => f !== 'all'),
26246
- format,
26247
- ];
26248
- }
26249
- if (this.activeFilterFormats.length === 0) {
26250
- this.activeFilterFormats = ['all'];
26251
- }
26252
- }
26253
- isFilterActive(filter) {
26254
- return this.activeFilterFormats.includes(filter);
26694
+ this.visiblePages = [];
26695
+ this.newCurrentPageEvent = new EventEmitter();
26255
26696
  }
26256
- getFilterFormatTitle(format) {
26257
- if (format === 'all' || format === 'others') {
26258
- return this.translateService.instant(`datahub.search.filter.${format}`);
26259
- }
26260
- return format;
26697
+ ngOnChanges() {
26698
+ this.calculateVisiblePages();
26261
26699
  }
26262
- isLinkOfFormat(link, format) {
26263
- if (format === 'all') {
26264
- return true;
26265
- }
26266
- if (getFileFormat(link) === null) {
26267
- return format === 'others';
26700
+ calculateVisiblePages() {
26701
+ const maxVisiblePages = 5;
26702
+ const halfVisible = Math.floor(maxVisiblePages / 2);
26703
+ const startPage = Math.max(this.currentPage - halfVisible, 1);
26704
+ const endPage = Math.min(this.currentPage + halfVisible, this.totalPages);
26705
+ const visiblePages = [];
26706
+ if (startPage > 1) {
26707
+ visiblePages.push(1);
26708
+ if (startPage > 2) {
26709
+ visiblePages.push('...');
26710
+ }
26268
26711
  }
26269
- if (format === 'others') {
26270
- const knownFormats = FILTER_FORMATS.filter((format) => format !== 'all' && format !== 'others');
26271
- return knownFormats.every((knownFormat) => !getFileFormat(link).includes(knownFormat));
26712
+ for (let page = startPage; page <= endPage; page++) {
26713
+ visiblePages.push(page);
26272
26714
  }
26273
- return getFileFormat(link).includes(format);
26274
- }
26275
- getLinkFormat(link) {
26276
- return getFileFormat(link);
26277
- }
26278
- getLinkColor(link) {
26279
- return getBadgeColor(getFileFormat(link));
26280
- }
26281
- isFromWfs(link) {
26282
- return link.type === 'service' && link.accessServiceProtocol === 'wfs';
26283
- }
26284
- 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 }); }
26285
- 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 }); }
26286
- }
26287
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: DownloadsListComponent, decorators: [{
26288
- type: Component,
26289
- 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" }]
26290
- }], ctorParameters: function () { return [{ type: i1$1.TranslateService }]; }, propDecorators: { links: [{
26291
- type: Input
26292
- }] } });
26293
-
26294
- class ApiCardComponent {
26295
- constructor() {
26296
- this.currentlyActive = false;
26297
- this.openRecordApiForm = new EventEmitter();
26298
- }
26299
- ngOnInit() {
26300
- this.displayApiFormButton =
26301
- this.link.accessServiceProtocol === 'ogcFeatures' ? true : false;
26302
- }
26303
- ngOnChanges(changes) {
26304
- this.currentlyActive =
26305
- changes.currentLink.currentValue === this.link ? true : false;
26306
- }
26307
- openRecordApiFormPanel() {
26308
- if (this.displayApiFormButton) {
26309
- this.currentlyActive = !this.currentlyActive;
26310
- this.openRecordApiForm.emit(this.currentlyActive ? this.link : undefined);
26715
+ if (endPage < this.totalPages) {
26716
+ if (endPage < this.totalPages - 1) {
26717
+ visiblePages.push('...');
26718
+ }
26719
+ visiblePages.push(this.totalPages);
26311
26720
  }
26721
+ this.visiblePages = visiblePages;
26312
26722
  }
26313
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ApiCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26314
- 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
- }
26316
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ApiCardComponent, decorators: [{
26317
- type: Component,
26318
- 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" }]
26319
- }], propDecorators: { link: [{
26320
- type: Input
26321
- }], currentLink: [{
26322
- type: Input
26323
- }], openRecordApiForm: [{
26324
- type: Output
26325
- }] } });
26326
-
26327
- /**
26328
- * This component will make a block that will stay sticky on the top of the page,
26329
- * but will also shrink down to a minimum height when scrolling.
26330
- * The ratio between minimum and nominal height is stored in the shrinkRatio
26331
- * property, and can be used to change e.g. the opacity or size of child elements.
26332
- * This component renders at z-index: 50 by default.
26333
- * The first parent element with an overflow of `scroll` or `overflow` is considered
26334
- * for scroll events.
26335
- */
26336
- class StickyHeaderComponent {
26337
- constructor(changeDetector, hostEl, zone) {
26338
- this.changeDetector = changeDetector;
26339
- this.hostEl = hostEl;
26340
- this.zone = zone;
26341
- }
26342
- ngAfterViewInit() {
26343
- this.scrollSub = fromEvent(window, 'scroll', {
26344
- passive: true,
26345
- })
26346
- .pipe(throttleTime(0, animationFrameScheduler, {
26347
- leading: true,
26348
- trailing: true,
26349
- }))
26350
- .subscribe(this.updateSize.bind(this));
26351
- }
26352
- ngOnInit() {
26353
- this.placeholderEl = document.createElement('div');
26354
- this.placeholderEl.style.position = 'absolute';
26355
- this.placeholderEl.classList.add('sticky-header-placeholder');
26356
- this.hostEl.nativeElement.insertAdjacentElement('beforebegin', this.placeholderEl);
26357
- }
26358
- ngAfterViewChecked() {
26359
- this.updateSize();
26360
- }
26361
- ngOnDestroy() {
26362
- this.scrollSub.unsubscribe();
26363
- this.placeholderEl.remove();
26364
- }
26365
- updateSize() {
26366
- this.zone.runOutsideAngular(() => {
26367
- if (window.scrollY === this.parentScroll)
26368
- return;
26369
- this.parentScroll = window.scrollY;
26370
- const offsetTop = Math.max(0, this.parentScroll - this.placeholderEl.offsetTop);
26371
- const newHeightPx = Math.max(this.minHeightPx, this.fullHeightPx - offsetTop);
26372
- this.innerContainer.nativeElement.style.transform = `translate(0, ${newHeightPx - this.fullHeightPx}px)`;
26373
- this.expandRatio =
26374
- (newHeightPx - this.minHeightPx) /
26375
- (this.fullHeightPx - this.minHeightPx);
26376
- this.changeDetector.detectChanges();
26377
- });
26378
- }
26379
- 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 }); }
26380
- 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 }); }
26381
- }
26382
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: StickyHeaderComponent, decorators: [{
26383
- type: Component,
26384
- 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" }]
26385
- }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef, decorators: [{
26386
- type: Host
26387
- }] }, { type: i0.NgZone }]; }, propDecorators: { minHeightPx: [{
26388
- type: Input
26389
- }], fullHeightPx: [{
26390
- type: Input
26391
- }], template: [{
26392
- type: ContentChild,
26393
- args: [TemplateRef]
26394
- }], outerContainer: [{
26395
- type: ViewChild,
26396
- args: ['outerContainer']
26397
- }], innerContainer: [{
26398
- type: ViewChild,
26399
- args: ['innerContainer']
26400
- }] } });
26401
-
26402
- class AnchorLinkDirective {
26403
- get elementClass() {
26404
- return this.disabled ? this.disabledClass : this.enabledClass;
26405
- }
26406
- constructor(changeDetector) {
26407
- this.changeDetector = changeDetector;
26408
- this.disabled = false;
26409
- this.observer = new MutationObserver(() => {
26410
- this.refreshDisabledState();
26411
- });
26412
- }
26413
- ngOnInit() {
26414
- this.observer.observe(document.body, {
26415
- childList: true,
26416
- subtree: true,
26417
- });
26418
- this.refreshDisabledState();
26723
+ changePage(page) {
26724
+ this.setPage(page);
26419
26725
  }
26420
- ngOnDestroy() {
26421
- this.observer.disconnect();
26726
+ nextPage() {
26727
+ this.setPage(this.currentPage + 1);
26422
26728
  }
26423
- refreshDisabledState() {
26424
- const targetNotPresent = !document.getElementById(this.targetId);
26425
- if (targetNotPresent !== this.disabled) {
26426
- this.disabled = targetNotPresent;
26427
- this.changeDetector.detectChanges();
26428
- }
26729
+ previousPage() {
26730
+ this.setPage(this.currentPage - 1);
26429
26731
  }
26430
- scrollToTarget() {
26431
- const target = document.getElementById(this.targetId);
26432
- if (!target)
26732
+ setPage(newPage) {
26733
+ if (!Number.isInteger(newPage))
26433
26734
  return;
26434
- target.scrollIntoView({
26435
- behavior: 'smooth',
26436
- block: 'start',
26437
- });
26438
- }
26439
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: AnchorLinkDirective, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive }); }
26440
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.1.7", type: AnchorLinkDirective, selector: "[gnUiAnchorLink]", inputs: { targetId: ["gnUiAnchorLink", "targetId"], disabledClass: ["gnUiAnchorLinkDisabledClass", "disabledClass"], enabledClass: ["gnUiAnchorLinkEnabledClass", "enabledClass"] }, host: { listeners: { "click": "scrollToTarget()" }, properties: { "class": "this.elementClass" } }, ngImport: i0 }); }
26441
- }
26442
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: AnchorLinkDirective, decorators: [{
26443
- type: Directive,
26444
- args: [{
26445
- selector: '[gnUiAnchorLink]',
26446
- }]
26447
- }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { targetId: [{
26448
- type: Input,
26449
- args: ['gnUiAnchorLink']
26450
- }], disabledClass: [{
26451
- type: Input,
26452
- args: ['gnUiAnchorLinkDisabledClass']
26453
- }], enabledClass: [{
26454
- type: Input,
26455
- args: ['gnUiAnchorLinkEnabledClass']
26456
- }], elementClass: [{
26457
- type: HostBinding,
26458
- args: ['class']
26459
- }], scrollToTarget: [{
26460
- type: HostListener,
26461
- args: ['click']
26462
- }] } });
26463
-
26464
- class CarouselComponent {
26465
- constructor(changeDetector) {
26466
- this.changeDetector = changeDetector;
26467
- this.containerClass = '';
26468
- this.stepsContainerClass = '';
26469
- this.steps = [];
26470
- this.selectedStep = -1;
26471
- }
26472
- ngAfterViewInit() {
26473
- this.emblaApi = EmblaCarousel(this.carouselOverflowContainer.nativeElement, {
26474
- duration: 15,
26475
- });
26476
- const refreshSteps = () => {
26477
- this.steps = this.emblaApi.scrollSnapList();
26478
- this.selectedStep = this.emblaApi.selectedScrollSnap();
26479
- this.changeDetector.detectChanges();
26480
- };
26481
- this.emblaApi
26482
- .on('init', refreshSteps)
26483
- .on('reInit', refreshSteps)
26484
- .on('select', refreshSteps);
26485
- }
26486
- scrollToStep(stepIndex) {
26487
- this.emblaApi.scrollTo(stepIndex);
26488
- }
26489
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: CarouselComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
26490
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: CarouselComponent, selector: "gn-ui-carousel", inputs: { containerClass: "containerClass", stepsContainerClass: "stepsContainerClass" }, viewQueries: [{ propertyName: "carouselOverflowContainer", first: true, predicate: ["carouselOverflowContainer"], descendants: true }], ngImport: i0, template: "<div #carouselOverflowContainer class=\"overflow-hidden h-full w-full\">\n <div class=\"carousel-container flex flex-row\" [ngClass]=\"containerClass\">\n <ng-content></ng-content>\n </div>\n</div>\n<div\n *ngIf=\"steps.length > 1\"\n class=\"absolute right-0 top-0 flex flex-row justify-center gap-[10px] p-1\"\n [ngClass]=\"stepsContainerClass\"\n>\n <button\n *ngFor=\"let step of steps; let i = index\"\n class=\"carousel-step-dot\"\n (click)=\"scrollToStep(i)\"\n [ngClass]=\"selectedStep === i ? 'bg-secondary' : 'bg-gray-400'\"\n ></button>\n</div>\n", styles: [":host .carousel-container ::ng-deep>*{flex-shrink:0}:host{position:relative}.carousel-step-dot{width:6px;height:6px;border-radius:6px;position:relative}.carousel-step-dot:after{content:\"\";position:absolute;left:-4px;top:-4px;width:14px;height:14px}\n"], 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26491
- }
26492
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: CarouselComponent, decorators: [{
26493
- type: Component,
26494
- args: [{ selector: 'gn-ui-carousel', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div #carouselOverflowContainer class=\"overflow-hidden h-full w-full\">\n <div class=\"carousel-container flex flex-row\" [ngClass]=\"containerClass\">\n <ng-content></ng-content>\n </div>\n</div>\n<div\n *ngIf=\"steps.length > 1\"\n class=\"absolute right-0 top-0 flex flex-row justify-center gap-[10px] p-1\"\n [ngClass]=\"stepsContainerClass\"\n>\n <button\n *ngFor=\"let step of steps; let i = index\"\n class=\"carousel-step-dot\"\n (click)=\"scrollToStep(i)\"\n [ngClass]=\"selectedStep === i ? 'bg-secondary' : 'bg-gray-400'\"\n ></button>\n</div>\n", styles: [":host .carousel-container ::ng-deep>*{flex-shrink:0}:host{position:relative}.carousel-step-dot{width:6px;height:6px;border-radius:6px;position:relative}.carousel-step-dot:after{content:\"\";position:absolute;left:-4px;top:-4px;width:14px;height:14px}\n"] }]
26495
- }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { containerClass: [{
26496
- type: Input
26497
- }], stepsContainerClass: [{
26498
- type: Input
26499
- }], carouselOverflowContainer: [{
26500
- type: ViewChild,
26501
- args: ['carouselOverflowContainer']
26502
- }] } });
26503
-
26504
- class UiLayoutModule {
26505
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UiLayoutModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
26506
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.1.7", ngImport: i0, type: UiLayoutModule, declarations: [ExpandablePanelComponent,
26507
- StickyHeaderComponent,
26508
- AnchorLinkDirective,
26509
- ExpandablePanelButtonComponent,
26510
- CarouselComponent], imports: [CommonModule, MatIconModule, i1$1.TranslateModule], exports: [ExpandablePanelComponent,
26511
- StickyHeaderComponent,
26512
- AnchorLinkDirective,
26513
- ExpandablePanelButtonComponent,
26514
- CarouselComponent] }); }
26515
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UiLayoutModule, imports: [CommonModule, MatIconModule, TranslateModule.forChild()] }); }
26516
- }
26517
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UiLayoutModule, decorators: [{
26518
- type: NgModule,
26519
- args: [{
26520
- imports: [CommonModule, MatIconModule, TranslateModule.forChild()],
26521
- declarations: [
26522
- ExpandablePanelComponent,
26523
- StickyHeaderComponent,
26524
- AnchorLinkDirective,
26525
- ExpandablePanelButtonComponent,
26526
- CarouselComponent,
26527
- ],
26528
- exports: [
26529
- ExpandablePanelComponent,
26530
- StickyHeaderComponent,
26531
- AnchorLinkDirective,
26532
- ExpandablePanelButtonComponent,
26533
- CarouselComponent,
26534
- ],
26535
- }]
26536
- }] });
26537
-
26538
- class InteractiveTableColumnComponent {
26539
- constructor() {
26540
- this.grow = false;
26541
- this.sortable = false;
26542
- this.activeSort = null;
26543
- this.sortChange = new EventEmitter();
26544
- }
26545
- handleSortChange() {
26546
- this.activeSort = this.activeSort === 'asc' ? 'desc' : 'asc';
26547
- this.sortChange.emit(this.activeSort);
26548
- }
26549
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: InteractiveTableColumnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26550
- 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 }); }
26551
- }
26552
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: InteractiveTableColumnComponent, decorators: [{
26553
- type: Component,
26554
- args: [{ selector: 'gn-ui-interactive-table-column', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<span>empty</span>\n" }]
26555
- }], propDecorators: { header: [{
26556
- type: ContentChild,
26557
- args: ['header']
26558
- }], cell: [{
26559
- type: ContentChild,
26560
- args: ['cell']
26561
- }], grow: [{
26562
- type: Input
26563
- }], sortable: [{
26564
- type: Input
26565
- }], activeSort: [{
26566
- type: Input
26567
- }], sortChange: [{
26568
- type: Output
26569
- }] } });
26570
-
26571
- class InteractiveTableComponent {
26572
- constructor() {
26573
- this.items = [];
26574
- this.itemClick = new EventEmitter();
26575
- }
26576
- get gridStyle() {
26577
- return {
26578
- 'grid-template-columns': this.columns
26579
- .map((column) => column.grow ? `minmax(0px,1fr)` : `minmax(0px,max-content)`)
26580
- .join(' '),
26581
- };
26582
- }
26583
- handleRowClick(item) {
26584
- this.itemClick.emit(item);
26735
+ this.currentPage = newPage;
26736
+ this.calculateVisiblePages();
26737
+ this.newCurrentPageEvent.emit(this.currentPage);
26585
26738
  }
26586
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: InteractiveTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26587
- 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 }); }
26588
- }
26589
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: InteractiveTableComponent, decorators: [{
26590
- type: Component,
26591
- 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"] }]
26592
- }], propDecorators: { columns: [{
26593
- type: ContentChildren,
26594
- args: [InteractiveTableColumnComponent]
26595
- }], items: [{
26596
- type: Input
26597
- }], itemClick: [{
26598
- type: Output
26599
- }] } });
26600
-
26601
- class LinkCardComponent {
26602
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: LinkCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26603
- 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 }); }
26604
- }
26605
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: LinkCardComponent, decorators: [{
26606
- type: Component,
26607
- 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" }]
26608
- }], propDecorators: { link: [{
26609
- type: Input
26610
- }] } });
26611
-
26612
- class RelatedRecordCardComponent {
26613
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: RelatedRecordCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26614
- 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 }); }
26739
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: PaginationButtonsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26740
+ 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"] }] }); }
26615
26741
  }
26616
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: RelatedRecordCardComponent, decorators: [{
26742
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: PaginationButtonsComponent, decorators: [{
26617
26743
  type: Component,
26618
- 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" }]
26619
- }], propDecorators: { record: [{
26744
+ 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" }]
26745
+ }], propDecorators: { currentPage: [{
26620
26746
  type: Input
26621
- }] } });
26622
-
26623
- class MetadataContactComponent {
26624
- constructor() {
26625
- this.organizationClick = new EventEmitter();
26626
- this.contactClick = new EventEmitter();
26627
- }
26628
- get shownOrganization() {
26629
- return this.metadata.ownerOrganization;
26630
- }
26631
- get contacts() {
26632
- return ((this.metadata.kind === 'dataset'
26633
- ? this.metadata.contactsForResource
26634
- : this.metadata.contacts) || []);
26635
- }
26636
- get address() {
26637
- const addressParts = this.contacts[0].address
26638
- .split(',')
26639
- .map((part) => part.trim());
26640
- return addressParts;
26641
- }
26642
- onOrganizationClick() {
26643
- this.organizationClick.emit(this.shownOrganization);
26644
- }
26645
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MetadataContactComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26646
- 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 }); }
26647
- }
26648
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MetadataContactComponent, decorators: [{
26649
- type: Component,
26650
- 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" }]
26651
- }], propDecorators: { metadata: [{
26747
+ }], totalPages: [{
26652
26748
  type: Input
26653
- }], organizationClick: [{
26654
- type: Output
26655
- }], contactClick: [{
26749
+ }], newCurrentPageEvent: [{
26656
26750
  type: Output
26657
26751
  }] } });
26658
26752
 
26659
- class MetadataCatalogComponent {
26660
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MetadataCatalogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26661
- 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 }); }
26662
- }
26663
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MetadataCatalogComponent, decorators: [{
26664
- type: Component,
26665
- 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" }]
26666
- }], propDecorators: { sourceLabel: [{
26667
- type: Input
26668
- }] } });
26669
-
26670
- var ErrorType;
26671
- (function (ErrorType) {
26672
- ErrorType[ErrorType["COULD_NOT_REACH_API"] = 0] = "COULD_NOT_REACH_API";
26673
- ErrorType[ErrorType["RECEIVED_ERROR"] = 1] = "RECEIVED_ERROR";
26674
- ErrorType[ErrorType["RECORD_NOT_FOUND"] = 2] = "RECORD_NOT_FOUND";
26675
- })(ErrorType || (ErrorType = {}));
26676
- class SearchResultsErrorComponent {
26677
- constructor() {
26678
- this.types = ErrorType;
26679
- }
26680
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SearchResultsErrorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26681
- 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 }); }
26682
- }
26683
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SearchResultsErrorComponent, decorators: [{
26684
- type: Component,
26685
- 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"] }]
26686
- }], propDecorators: { type: [{
26687
- type: Input
26688
- }], error: [{
26689
- type: Input
26690
- }], recordId: [{
26691
- type: Input
26692
- }] } });
26693
-
26694
26753
  class PaginationComponent {
26695
26754
  constructor() {
26696
26755
  this.currentPage = 1;
@@ -26738,99 +26797,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
26738
26797
  type: Output
26739
26798
  }] } });
26740
26799
 
26741
- class AvatarComponent {
26742
- hideImage() {
26743
- this.avatarUrl = this.avatarPlaceholder;
26744
- }
26745
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: AvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26746
- 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 }); }
26747
- }
26748
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: AvatarComponent, decorators: [{
26749
- type: Component,
26750
- 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" }]
26751
- }], propDecorators: { avatarUrl: [{
26752
- type: Input
26753
- }], avatarPlaceholder: [{
26754
- type: Input
26755
- }] } });
26756
-
26757
- class UserPreviewComponent {
26758
- get userFullName() {
26759
- return (this.user.name + ' ' + this.user.surname).trim();
26760
- }
26761
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UserPreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26762
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: UserPreviewComponent, selector: "gn-ui-user-preview", inputs: { user: "user", avatarPlaceholder: "avatarPlaceholder" }, ngImport: i0, template: "<figure class=\"text-center\">\n <div\n class=\"w-12 h-12 border border-primary rounded-full capitalize\"\n [matTooltip]=\"userFullName\"\n >\n <gn-ui-avatar\n [avatarUrl]=\"user.profileIcon\"\n [avatarPlaceholder]=\"avatarPlaceholder\"\n ></gn-ui-avatar>\n </div>\n</figure>\n", dependencies: [{ kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: AvatarComponent, selector: "gn-ui-avatar", inputs: ["avatarUrl", "avatarPlaceholder"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26763
- }
26764
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UserPreviewComponent, decorators: [{
26765
- type: Component,
26766
- args: [{ selector: 'gn-ui-user-preview', changeDetection: ChangeDetectionStrategy.OnPush, template: "<figure class=\"text-center\">\n <div\n class=\"w-12 h-12 border border-primary rounded-full capitalize\"\n [matTooltip]=\"userFullName\"\n >\n <gn-ui-avatar\n [avatarUrl]=\"user.profileIcon\"\n [avatarPlaceholder]=\"avatarPlaceholder\"\n ></gn-ui-avatar>\n </div>\n</figure>\n" }]
26767
- }], propDecorators: { user: [{
26768
- type: Input
26769
- }], avatarPlaceholder: [{
26770
- type: Input
26771
- }] } });
26772
-
26773
- class PaginationButtonsComponent {
26774
- constructor() {
26775
- this.visiblePages = [];
26776
- this.newCurrentPageEvent = new EventEmitter();
26777
- }
26778
- ngOnChanges() {
26779
- this.calculateVisiblePages();
26780
- }
26781
- calculateVisiblePages() {
26782
- const maxVisiblePages = 5;
26783
- const halfVisible = Math.floor(maxVisiblePages / 2);
26784
- const startPage = Math.max(this.currentPage - halfVisible, 1);
26785
- const endPage = Math.min(this.currentPage + halfVisible, this.totalPages);
26786
- const visiblePages = [];
26787
- if (startPage > 1) {
26788
- visiblePages.push(1);
26789
- if (startPage > 2) {
26790
- visiblePages.push('...');
26791
- }
26792
- }
26793
- for (let page = startPage; page <= endPage; page++) {
26794
- visiblePages.push(page);
26795
- }
26796
- if (endPage < this.totalPages) {
26797
- if (endPage < this.totalPages - 1) {
26798
- visiblePages.push('...');
26799
- }
26800
- visiblePages.push(this.totalPages);
26801
- }
26802
- this.visiblePages = visiblePages;
26803
- }
26804
- changePage(page) {
26805
- this.setPage(page);
26806
- }
26807
- nextPage() {
26808
- this.setPage(this.currentPage + 1);
26809
- }
26810
- previousPage() {
26811
- this.setPage(this.currentPage - 1);
26812
- }
26813
- setPage(newPage) {
26814
- if (!Number.isInteger(newPage))
26815
- return;
26816
- this.currentPage = newPage;
26817
- this.calculateVisiblePages();
26818
- this.newCurrentPageEvent.emit(this.currentPage);
26819
- }
26820
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: PaginationButtonsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26821
- 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"] }] }); }
26822
- }
26823
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: PaginationButtonsComponent, decorators: [{
26824
- type: Component,
26825
- 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" }]
26826
- }], propDecorators: { currentPage: [{
26827
- type: Input
26828
- }], totalPages: [{
26829
- type: Input
26830
- }], newCurrentPageEvent: [{
26831
- type: Output
26832
- }] } });
26833
-
26834
26800
  const DEFAULT_PARAMS = {
26835
26801
  OFFSET: '',
26836
26802
  LIMIT: '-1',
@@ -26885,34 +26851,353 @@ class RecordApiFormComponent {
26885
26851
  this.format$.next(DEFAULT_PARAMS.FORMAT);
26886
26852
  }
26887
26853
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: RecordApiFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26888
- 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 }); }
26854
+ 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", "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 }); }
26889
26855
  }
26890
26856
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: RecordApiFormComponent, decorators: [{
26891
26857
  type: Component,
26892
- 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"] }]
26858
+ 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"] }]
26893
26859
  }], propDecorators: { apiLink: [{
26894
26860
  type: Input
26895
26861
  }] } });
26896
26862
 
26897
- class ImageOverlayPreviewComponent {
26863
+ class RelatedRecordCardComponent {
26864
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: RelatedRecordCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26865
+ 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 }); }
26866
+ }
26867
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: RelatedRecordCardComponent, decorators: [{
26868
+ type: Component,
26869
+ 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" }]
26870
+ }], propDecorators: { record: [{
26871
+ type: Input
26872
+ }] } });
26873
+
26874
+ var ErrorType;
26875
+ (function (ErrorType) {
26876
+ ErrorType[ErrorType["COULD_NOT_REACH_API"] = 0] = "COULD_NOT_REACH_API";
26877
+ ErrorType[ErrorType["RECEIVED_ERROR"] = 1] = "RECEIVED_ERROR";
26878
+ ErrorType[ErrorType["RECORD_NOT_FOUND"] = 2] = "RECORD_NOT_FOUND";
26879
+ })(ErrorType || (ErrorType = {}));
26880
+ class SearchResultsErrorComponent {
26898
26881
  constructor() {
26899
- this.isPlaceholderShown = new EventEmitter();
26882
+ this.types = ErrorType;
26900
26883
  }
26901
- openLightbox(src) {
26902
- basicLightbox.create(`<img src="${src}"/>`).show();
26884
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SearchResultsErrorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26885
+ 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 }); }
26886
+ }
26887
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SearchResultsErrorComponent, decorators: [{
26888
+ type: Component,
26889
+ 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"] }]
26890
+ }], propDecorators: { type: [{
26891
+ type: Input
26892
+ }], error: [{
26893
+ type: Input
26894
+ }], recordId: [{
26895
+ type: Input
26896
+ }] } });
26897
+
26898
+ class AnchorLinkDirective {
26899
+ get elementClass() {
26900
+ return this.disabled ? this.disabledClass : this.enabledClass;
26903
26901
  }
26904
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ImageOverlayPreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26905
- 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: ContentGhostComponent, selector: "gn-ui-content-ghost", inputs: ["showContent", "ghostClass"] }, { kind: "component", type: ThumbnailComponent, selector: "gn-ui-thumbnail", inputs: ["thumbnailUrl", "fit"], outputs: ["placeholderShown"] }] }); }
26902
+ constructor(changeDetector) {
26903
+ this.changeDetector = changeDetector;
26904
+ this.disabled = false;
26905
+ this.observer = new MutationObserver(() => {
26906
+ this.refreshDisabledState();
26907
+ });
26908
+ }
26909
+ ngOnInit() {
26910
+ this.observer.observe(document.body, {
26911
+ childList: true,
26912
+ subtree: true,
26913
+ });
26914
+ this.refreshDisabledState();
26915
+ }
26916
+ ngOnDestroy() {
26917
+ this.observer.disconnect();
26918
+ }
26919
+ refreshDisabledState() {
26920
+ const targetNotPresent = !document.getElementById(this.targetId);
26921
+ if (targetNotPresent !== this.disabled) {
26922
+ this.disabled = targetNotPresent;
26923
+ this.changeDetector.detectChanges();
26924
+ }
26925
+ }
26926
+ scrollToTarget() {
26927
+ const target = document.getElementById(this.targetId);
26928
+ if (!target)
26929
+ return;
26930
+ target.scrollIntoView({
26931
+ behavior: 'smooth',
26932
+ block: 'start',
26933
+ });
26934
+ }
26935
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: AnchorLinkDirective, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive }); }
26936
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.1.7", type: AnchorLinkDirective, selector: "[gnUiAnchorLink]", inputs: { targetId: ["gnUiAnchorLink", "targetId"], disabledClass: ["gnUiAnchorLinkDisabledClass", "disabledClass"], enabledClass: ["gnUiAnchorLinkEnabledClass", "enabledClass"] }, host: { listeners: { "click": "scrollToTarget()" }, properties: { "class": "this.elementClass" } }, ngImport: i0 }); }
26906
26937
  }
26907
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ImageOverlayPreviewComponent, decorators: [{
26938
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: AnchorLinkDirective, decorators: [{
26939
+ type: Directive,
26940
+ args: [{
26941
+ selector: '[gnUiAnchorLink]',
26942
+ }]
26943
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { targetId: [{
26944
+ type: Input,
26945
+ args: ['gnUiAnchorLink']
26946
+ }], disabledClass: [{
26947
+ type: Input,
26948
+ args: ['gnUiAnchorLinkDisabledClass']
26949
+ }], enabledClass: [{
26950
+ type: Input,
26951
+ args: ['gnUiAnchorLinkEnabledClass']
26952
+ }], elementClass: [{
26953
+ type: HostBinding,
26954
+ args: ['class']
26955
+ }], scrollToTarget: [{
26956
+ type: HostListener,
26957
+ args: ['click']
26958
+ }] } });
26959
+
26960
+ class CarouselComponent {
26961
+ constructor(changeDetector) {
26962
+ this.changeDetector = changeDetector;
26963
+ this.containerClass = '';
26964
+ this.stepsContainerClass = '';
26965
+ this.steps = [];
26966
+ this.selectedStep = -1;
26967
+ }
26968
+ ngAfterViewInit() {
26969
+ this.emblaApi = EmblaCarousel(this.carouselOverflowContainer.nativeElement, {
26970
+ duration: 15,
26971
+ });
26972
+ const refreshSteps = () => {
26973
+ this.steps = this.emblaApi.scrollSnapList();
26974
+ this.selectedStep = this.emblaApi.selectedScrollSnap();
26975
+ this.changeDetector.detectChanges();
26976
+ };
26977
+ this.emblaApi
26978
+ .on('init', refreshSteps)
26979
+ .on('reInit', refreshSteps)
26980
+ .on('select', refreshSteps);
26981
+ }
26982
+ scrollToStep(stepIndex) {
26983
+ this.emblaApi.scrollTo(stepIndex);
26984
+ }
26985
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: CarouselComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
26986
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: CarouselComponent, selector: "gn-ui-carousel", inputs: { containerClass: "containerClass", stepsContainerClass: "stepsContainerClass" }, viewQueries: [{ propertyName: "carouselOverflowContainer", first: true, predicate: ["carouselOverflowContainer"], descendants: true }], ngImport: i0, template: "<div #carouselOverflowContainer class=\"overflow-hidden h-full w-full\">\n <div class=\"carousel-container flex flex-row\" [ngClass]=\"containerClass\">\n <ng-content></ng-content>\n </div>\n</div>\n<div\n *ngIf=\"steps.length > 1\"\n class=\"absolute right-0 top-0 flex flex-row justify-center gap-[10px] p-1\"\n [ngClass]=\"stepsContainerClass\"\n>\n <button\n *ngFor=\"let step of steps; let i = index\"\n class=\"carousel-step-dot\"\n (click)=\"scrollToStep(i)\"\n [ngClass]=\"selectedStep === i ? 'bg-secondary' : 'bg-gray-400'\"\n ></button>\n</div>\n", styles: [":host .carousel-container ::ng-deep>*{flex-shrink:0}:host{position:relative}.carousel-step-dot{width:6px;height:6px;border-radius:6px;position:relative}.carousel-step-dot:after{content:\"\";position:absolute;left:-4px;top:-4px;width:14px;height:14px}\n"], 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
26987
+ }
26988
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: CarouselComponent, decorators: [{
26908
26989
  type: Component,
26909
- 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" }]
26910
- }], propDecorators: { imageUrl: [{
26990
+ args: [{ selector: 'gn-ui-carousel', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div #carouselOverflowContainer class=\"overflow-hidden h-full w-full\">\n <div class=\"carousel-container flex flex-row\" [ngClass]=\"containerClass\">\n <ng-content></ng-content>\n </div>\n</div>\n<div\n *ngIf=\"steps.length > 1\"\n class=\"absolute right-0 top-0 flex flex-row justify-center gap-[10px] p-1\"\n [ngClass]=\"stepsContainerClass\"\n>\n <button\n *ngFor=\"let step of steps; let i = index\"\n class=\"carousel-step-dot\"\n (click)=\"scrollToStep(i)\"\n [ngClass]=\"selectedStep === i ? 'bg-secondary' : 'bg-gray-400'\"\n ></button>\n</div>\n", styles: [":host .carousel-container ::ng-deep>*{flex-shrink:0}:host{position:relative}.carousel-step-dot{width:6px;height:6px;border-radius:6px;position:relative}.carousel-step-dot:after{content:\"\";position:absolute;left:-4px;top:-4px;width:14px;height:14px}\n"] }]
26991
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { containerClass: [{
26911
26992
  type: Input
26912
- }], isPlaceholderShown: [{
26993
+ }], stepsContainerClass: [{
26994
+ type: Input
26995
+ }], carouselOverflowContainer: [{
26996
+ type: ViewChild,
26997
+ args: ['carouselOverflowContainer']
26998
+ }] } });
26999
+
27000
+ class FormFieldWrapperComponent {
27001
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27002
+ 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 }); }
27003
+ }
27004
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldWrapperComponent, decorators: [{
27005
+ type: Component,
27006
+ 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" }]
27007
+ }], propDecorators: { label: [{
27008
+ type: Input
27009
+ }], hint: [{
27010
+ type: Input
27011
+ }] } });
27012
+
27013
+ class InteractiveTableColumnComponent {
27014
+ constructor() {
27015
+ this.grow = false;
27016
+ this.sortable = false;
27017
+ this.activeSort = null;
27018
+ this.sortChange = new EventEmitter();
27019
+ }
27020
+ handleSortChange() {
27021
+ this.activeSort = this.activeSort === 'asc' ? 'desc' : 'asc';
27022
+ this.sortChange.emit(this.activeSort);
27023
+ }
27024
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: InteractiveTableColumnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27025
+ 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 }); }
27026
+ }
27027
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: InteractiveTableColumnComponent, decorators: [{
27028
+ type: Component,
27029
+ args: [{ selector: 'gn-ui-interactive-table-column', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<span>empty</span>\n" }]
27030
+ }], propDecorators: { header: [{
27031
+ type: ContentChild,
27032
+ args: ['header']
27033
+ }], cell: [{
27034
+ type: ContentChild,
27035
+ args: ['cell']
27036
+ }], grow: [{
27037
+ type: Input
27038
+ }], sortable: [{
27039
+ type: Input
27040
+ }], activeSort: [{
27041
+ type: Input
27042
+ }], sortChange: [{
26913
27043
  type: Output
26914
27044
  }] } });
26915
27045
 
27046
+ class InteractiveTableComponent {
27047
+ constructor() {
27048
+ this.items = [];
27049
+ this.itemClick = new EventEmitter();
27050
+ }
27051
+ get gridStyle() {
27052
+ return {
27053
+ 'grid-template-columns': this.columns
27054
+ .map((column) => column.grow ? `minmax(0px,1fr)` : `minmax(0px,max-content)`)
27055
+ .join(' '),
27056
+ };
27057
+ }
27058
+ handleRowClick(item) {
27059
+ this.itemClick.emit(item);
27060
+ }
27061
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: InteractiveTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27062
+ 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 }); }
27063
+ }
27064
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: InteractiveTableComponent, decorators: [{
27065
+ type: Component,
27066
+ 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"] }]
27067
+ }], propDecorators: { columns: [{
27068
+ type: ContentChildren,
27069
+ args: [InteractiveTableColumnComponent]
27070
+ }], items: [{
27071
+ type: Input
27072
+ }], itemClick: [{
27073
+ type: Output
27074
+ }] } });
27075
+
27076
+ /**
27077
+ * This component will make a block that will stay sticky on the top of the page,
27078
+ * but will also shrink down to a minimum height when scrolling.
27079
+ * The ratio between minimum and nominal height is stored in the shrinkRatio
27080
+ * property, and can be used to change e.g. the opacity or size of child elements.
27081
+ * This component renders at z-index: 50 by default.
27082
+ * The first parent element with an overflow of `scroll` or `overflow` is considered
27083
+ * for scroll events.
27084
+ */
27085
+ class StickyHeaderComponent {
27086
+ constructor(changeDetector, hostEl, zone) {
27087
+ this.changeDetector = changeDetector;
27088
+ this.hostEl = hostEl;
27089
+ this.zone = zone;
27090
+ }
27091
+ ngAfterViewInit() {
27092
+ this.scrollSub = fromEvent(window, 'scroll', {
27093
+ passive: true,
27094
+ })
27095
+ .pipe(throttleTime(0, animationFrameScheduler, {
27096
+ leading: true,
27097
+ trailing: true,
27098
+ }))
27099
+ .subscribe(this.updateSize.bind(this));
27100
+ }
27101
+ ngOnInit() {
27102
+ this.placeholderEl = document.createElement('div');
27103
+ this.placeholderEl.style.position = 'absolute';
27104
+ this.placeholderEl.classList.add('sticky-header-placeholder');
27105
+ this.hostEl.nativeElement.insertAdjacentElement('beforebegin', this.placeholderEl);
27106
+ }
27107
+ ngAfterViewChecked() {
27108
+ this.updateSize();
27109
+ }
27110
+ ngOnDestroy() {
27111
+ this.scrollSub.unsubscribe();
27112
+ this.placeholderEl.remove();
27113
+ }
27114
+ updateSize() {
27115
+ this.zone.runOutsideAngular(() => {
27116
+ if (window.scrollY === this.parentScroll)
27117
+ return;
27118
+ this.parentScroll = window.scrollY;
27119
+ const offsetTop = Math.max(0, this.parentScroll - this.placeholderEl.offsetTop);
27120
+ const newHeightPx = Math.max(this.minHeightPx, this.fullHeightPx - offsetTop);
27121
+ this.innerContainer.nativeElement.style.transform = `translate(0, ${newHeightPx - this.fullHeightPx}px)`;
27122
+ this.expandRatio =
27123
+ (newHeightPx - this.minHeightPx) /
27124
+ (this.fullHeightPx - this.minHeightPx);
27125
+ this.changeDetector.detectChanges();
27126
+ });
27127
+ }
27128
+ 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 }); }
27129
+ 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 }); }
27130
+ }
27131
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: StickyHeaderComponent, decorators: [{
27132
+ type: Component,
27133
+ 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" }]
27134
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef, decorators: [{
27135
+ type: Host
27136
+ }] }, { type: i0.NgZone }]; }, propDecorators: { minHeightPx: [{
27137
+ type: Input
27138
+ }], fullHeightPx: [{
27139
+ type: Input
27140
+ }], template: [{
27141
+ type: ContentChild,
27142
+ args: [TemplateRef]
27143
+ }], outerContainer: [{
27144
+ type: ViewChild,
27145
+ args: ['outerContainer']
27146
+ }], innerContainer: [{
27147
+ type: ViewChild,
27148
+ args: ['innerContainer']
27149
+ }] } });
27150
+
27151
+ class UiLayoutModule {
27152
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UiLayoutModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
27153
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.1.7", ngImport: i0, type: UiLayoutModule, declarations: [ExpandablePanelComponent,
27154
+ StickyHeaderComponent,
27155
+ AnchorLinkDirective,
27156
+ ExpandablePanelButtonComponent,
27157
+ CarouselComponent], imports: [CommonModule, MatIconModule, i1$1.TranslateModule], exports: [ExpandablePanelComponent,
27158
+ StickyHeaderComponent,
27159
+ AnchorLinkDirective,
27160
+ ExpandablePanelButtonComponent,
27161
+ CarouselComponent] }); }
27162
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UiLayoutModule, imports: [CommonModule, MatIconModule, TranslateModule.forChild()] }); }
27163
+ }
27164
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UiLayoutModule, decorators: [{
27165
+ type: NgModule,
27166
+ args: [{
27167
+ imports: [CommonModule, MatIconModule, TranslateModule.forChild()],
27168
+ declarations: [
27169
+ ExpandablePanelComponent,
27170
+ StickyHeaderComponent,
27171
+ AnchorLinkDirective,
27172
+ ExpandablePanelButtonComponent,
27173
+ CarouselComponent,
27174
+ ],
27175
+ exports: [
27176
+ ExpandablePanelComponent,
27177
+ StickyHeaderComponent,
27178
+ AnchorLinkDirective,
27179
+ ExpandablePanelButtonComponent,
27180
+ CarouselComponent,
27181
+ ],
27182
+ }]
27183
+ }] });
27184
+
27185
+ class UserPreviewComponent {
27186
+ get userFullName() {
27187
+ return (this.user.name + ' ' + this.user.surname).trim();
27188
+ }
27189
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UserPreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27190
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: UserPreviewComponent, selector: "gn-ui-user-preview", inputs: { user: "user", avatarPlaceholder: "avatarPlaceholder" }, ngImport: i0, template: "<figure class=\"text-center\">\n <div\n class=\"w-12 h-12 border border-primary rounded-full capitalize\"\n [matTooltip]=\"userFullName\"\n >\n <gn-ui-avatar\n [avatarUrl]=\"user.profileIcon\"\n [avatarPlaceholder]=\"avatarPlaceholder\"\n ></gn-ui-avatar>\n </div>\n</figure>\n", dependencies: [{ kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: AvatarComponent, selector: "gn-ui-avatar", inputs: ["avatarUrl", "avatarPlaceholder"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
27191
+ }
27192
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UserPreviewComponent, decorators: [{
27193
+ type: Component,
27194
+ args: [{ selector: 'gn-ui-user-preview', changeDetection: ChangeDetectionStrategy.OnPush, template: "<figure class=\"text-center\">\n <div\n class=\"w-12 h-12 border border-primary rounded-full capitalize\"\n [matTooltip]=\"userFullName\"\n >\n <gn-ui-avatar\n [avatarUrl]=\"user.profileIcon\"\n [avatarPlaceholder]=\"avatarPlaceholder\"\n ></gn-ui-avatar>\n </div>\n</figure>\n" }]
27195
+ }], propDecorators: { user: [{
27196
+ type: Input
27197
+ }], avatarPlaceholder: [{
27198
+ type: Input
27199
+ }] } });
27200
+
26916
27201
  class UiElementsModule {
26917
27202
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UiElementsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
26918
27203
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.1.7", ngImport: i0, type: UiElementsModule, declarations: [MetadataInfoComponent,
@@ -26928,7 +27213,6 @@ class UiElementsModule {
26928
27213
  MetadataQualityItemComponent,
26929
27214
  SearchResultsErrorComponent,
26930
27215
  PaginationComponent,
26931
- ThumbnailComponent,
26932
27216
  AvatarComponent,
26933
27217
  UserPreviewComponent,
26934
27218
  GnUiLinkifyDirective,
@@ -26944,7 +27228,8 @@ class UiElementsModule {
26944
27228
  UiInputsModule,
26945
27229
  FormsModule,
26946
27230
  NgOptimizedImage,
26947
- MarkdownParserComponent], exports: [MetadataInfoComponent,
27231
+ MarkdownParserComponent,
27232
+ ThumbnailComponent], exports: [MetadataInfoComponent,
26948
27233
  ContentGhostComponent,
26949
27234
  DownloadItemComponent,
26950
27235
  DownloadsListComponent,
@@ -26974,7 +27259,8 @@ class UiElementsModule {
26974
27259
  UtilSharedModule,
26975
27260
  RouterModule,
26976
27261
  UiInputsModule,
26977
- FormsModule] }); }
27262
+ FormsModule,
27263
+ ThumbnailComponent] }); }
26978
27264
  }
26979
27265
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UiElementsModule, decorators: [{
26980
27266
  type: NgModule,
@@ -26992,6 +27278,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
26992
27278
  FormsModule,
26993
27279
  NgOptimizedImage,
26994
27280
  MarkdownParserComponent,
27281
+ ThumbnailComponent,
26995
27282
  ],
26996
27283
  declarations: [
26997
27284
  MetadataInfoComponent,
@@ -27007,7 +27294,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
27007
27294
  MetadataQualityItemComponent,
27008
27295
  SearchResultsErrorComponent,
27009
27296
  PaginationComponent,
27010
- ThumbnailComponent,
27011
27297
  AvatarComponent,
27012
27298
  UserPreviewComponent,
27013
27299
  GnUiLinkifyDirective,
@@ -27042,6 +27328,33 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
27042
27328
  }]
27043
27329
  }] });
27044
27330
 
27331
+ class NotificationComponent {
27332
+ constructor() {
27333
+ this.type = 'info';
27334
+ this.notificationClose = new EventEmitter();
27335
+ }
27336
+ handleClose(event) {
27337
+ event?.preventDefault();
27338
+ this.notificationClose.emit();
27339
+ }
27340
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: NotificationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27341
+ 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 }); }
27342
+ }
27343
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: NotificationComponent, decorators: [{
27344
+ type: Component,
27345
+ 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" }]
27346
+ }], propDecorators: { type: [{
27347
+ type: Input
27348
+ }], title: [{
27349
+ type: Input
27350
+ }], text: [{
27351
+ type: Input
27352
+ }], closeMessage: [{
27353
+ type: Input
27354
+ }], notificationClose: [{
27355
+ type: Output
27356
+ }] } });
27357
+
27045
27358
  class UiSearchModule {
27046
27359
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: UiSearchModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
27047
27360
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.1.7", ngImport: i0, type: UiSearchModule, declarations: [RecordPreviewComponent,
@@ -29197,7 +29510,7 @@ class ResultsTableComponent {
29197
29510
  }));
29198
29511
  }
29199
29512
  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 }); }
29200
- 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"] }] }); }
29513
+ 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"] }] }); }
29201
29514
  }
29202
29515
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ResultsTableComponent, decorators: [{
29203
29516
  type: Component,
@@ -29208,7 +29521,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
29208
29521
  InteractiveTableColumnComponent,
29209
29522
  MatIconModule,
29210
29523
  TranslateModule,
29211
- ], 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" }]
29524
+ ], 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" }]
29212
29525
  }], ctorParameters: function () { return [{ type: SearchFacade }, { type: SearchService }, { type: SelectionService }]; }, propDecorators: { recordClick: [{
29213
29526
  type: Output
29214
29527
  }] } });
@@ -29438,11 +29751,11 @@ class AddLayerFromFileComponent {
29438
29751
  }, 5000);
29439
29752
  }
29440
29753
  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 }); }
29441
- 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" }] }); }
29754
+ 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" }] }); }
29442
29755
  }
29443
29756
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: AddLayerFromFileComponent, decorators: [{
29444
29757
  type: Component,
29445
- 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" }]
29758
+ 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" }]
29446
29759
  }], ctorParameters: function () { return [{ type: MapFacade }, { type: i0.ChangeDetectorRef }]; } });
29447
29760
 
29448
29761
  class AddLayerFromWfsComponent {
@@ -29803,6 +30116,88 @@ const DEFAULT_STYLE_HL_FIXTURE = new Style$1({
29803
30116
  }),
29804
30117
  });
29805
30118
 
30119
+ class NotificationsService {
30120
+ constructor() {
30121
+ this.notifications$ = new BehaviorSubject([]);
30122
+ }
30123
+ showNotification(content, timeoutMs) {
30124
+ const id = Math.floor(Math.random() * 1000000);
30125
+ this.notifications$.next([...this.notifications$.value, { ...content, id }]);
30126
+ if (typeof timeoutMs === 'undefined')
30127
+ return;
30128
+ setTimeout(() => {
30129
+ this.removeNotificationById(id);
30130
+ }, timeoutMs);
30131
+ }
30132
+ removeNotificationById(id) {
30133
+ this.notifications$.next(this.notifications$.value.filter((n) => n.id !== id));
30134
+ }
30135
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: NotificationsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
30136
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: NotificationsService, providedIn: 'root' }); }
30137
+ }
30138
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: NotificationsService, decorators: [{
30139
+ type: Injectable,
30140
+ args: [{
30141
+ providedIn: 'root',
30142
+ }]
30143
+ }] });
30144
+
30145
+ class FeatureNotificationsModule {
30146
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FeatureNotificationsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
30147
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.1.7", ngImport: i0, type: FeatureNotificationsModule }); }
30148
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FeatureNotificationsModule, providers: [NotificationsService] }); }
30149
+ }
30150
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FeatureNotificationsModule, decorators: [{
30151
+ type: NgModule,
30152
+ args: [{
30153
+ declarations: [],
30154
+ exports: [],
30155
+ imports: [],
30156
+ providers: [NotificationsService],
30157
+ }]
30158
+ }] });
30159
+
30160
+ class NotificationsContainerComponent {
30161
+ constructor(notificationsService) {
30162
+ this.notificationsService = notificationsService;
30163
+ }
30164
+ trackById(index, notification) {
30165
+ return notification.id;
30166
+ }
30167
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: NotificationsContainerComponent, deps: [{ token: NotificationsService }], target: i0.ɵɵFactoryTarget.Component }); }
30168
+ 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: [
30169
+ trigger('enterExit', [
30170
+ transition(':enter', [
30171
+ animate('150ms', keyframes([
30172
+ style({ transform: 'scale(1)', opacity: 0 }),
30173
+ style({ transform: 'scale(1.03)', opacity: 0.5 }),
30174
+ style({ transform: 'scale(1)', opacity: 1 }),
30175
+ ])),
30176
+ ]),
30177
+ transition(':leave', [
30178
+ animate('200ms', style({ transform: 'translateX(50px)', opacity: 0 })),
30179
+ ]),
30180
+ ]),
30181
+ ], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
30182
+ }
30183
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: NotificationsContainerComponent, decorators: [{
30184
+ type: Component,
30185
+ args: [{ selector: 'gn-ui-notifications-container', standalone: true, imports: [CommonModule, NotificationComponent], changeDetection: ChangeDetectionStrategy.OnPush, animations: [
30186
+ trigger('enterExit', [
30187
+ transition(':enter', [
30188
+ animate('150ms', keyframes([
30189
+ style({ transform: 'scale(1)', opacity: 0 }),
30190
+ style({ transform: 'scale(1.03)', opacity: 0.5 }),
30191
+ style({ transform: 'scale(1)', opacity: 1 }),
30192
+ ])),
30193
+ ]),
30194
+ transition(':leave', [
30195
+ animate('200ms', style({ transform: 'translateX(50px)', opacity: 0 })),
30196
+ ]),
30197
+ ]),
30198
+ ], 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" }]
30199
+ }], ctorParameters: function () { return [{ type: NotificationsService }]; } });
30200
+
29806
30201
  const loadFullMetadata = createAction('[Metadata view] Load full metadata', props());
29807
30202
  const setIncompleteMetadata = createAction('[Metadata view] Set incomplete metadata', props());
29808
30203
  const loadFullSuccess = createAction('[Metadata view] Load full success', props());
@@ -31092,7 +31487,7 @@ class DataService {
31092
31487
  }), {}),
31093
31488
  geojson: endpoint.supportsJson(featureType.name)
31094
31489
  ? endpoint.getFeatureUrl(featureType.name, {
31095
- outputFormat: 'application/json',
31490
+ asJson: true,
31096
31491
  outputCrs: 'EPSG:4326',
31097
31492
  })
31098
31493
  : null,
@@ -31725,11 +32120,11 @@ class OrganisationPreviewComponent {
31725
32120
  this.clickedOrganisation.emit(this.organisation);
31726
32121
  }
31727
32122
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: OrganisationPreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
31728
- 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 }); }
32123
+ 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 }); }
31729
32124
  }
31730
32125
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: OrganisationPreviewComponent, decorators: [{
31731
32126
  type: Component,
31732
- 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"] }]
32127
+ 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"] }]
31733
32128
  }], propDecorators: { organisation: [{
31734
32129
  type: Input
31735
32130
  }], organisationUrl: [{
@@ -32406,9 +32801,11 @@ const selectRecordFields = createSelector(selectEditorState, (state) => state.fi
32406
32801
  class EditorFacade {
32407
32802
  constructor() {
32408
32803
  this.store = inject(Store);
32804
+ this.actions$ = inject(Actions);
32409
32805
  this.record$ = this.store.pipe(select(selectRecord));
32410
32806
  this.saving$ = this.store.pipe(select(selectRecordSaving));
32411
- this.saveError$ = this.store.pipe(select(selectRecordSaveError));
32807
+ this.saveError$ = this.store.pipe(select(selectRecordSaveError), filter$1((error) => !!error));
32808
+ this.saveSuccess$ = this.actions$.pipe(ofType(saveRecordSuccess));
32412
32809
  this.changedSinceSave$ = this.store.pipe(select(selectRecordChangedSinceSave));
32413
32810
  this.recordFields$ = this.store.pipe(select(selectRecordFields));
32414
32811
  }
@@ -32428,6 +32825,99 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
32428
32825
  type: Injectable
32429
32826
  }] });
32430
32827
 
32828
+ function evaluate(expression) {
32829
+ if (expression.match(/^\${.*}$/)) {
32830
+ return evaluate(expression.slice(2, -1));
32831
+ }
32832
+ const operator = expression.split('(')[0];
32833
+ switch (operator) {
32834
+ case 'dateNow':
32835
+ return () => new Date();
32836
+ default:
32837
+ throw new Error(`Unknown operator: ${operator}`);
32838
+ }
32839
+ }
32840
+
32841
+ class EditorService {
32842
+ constructor(http, apiConfiguration) {
32843
+ this.http = http;
32844
+ this.apiConfiguration = apiConfiguration;
32845
+ this.apiUrl = `${this.apiConfiguration?.basePath || '/geonetwork/srv/api'}`;
32846
+ }
32847
+ // TODO: use the catalog repository instead
32848
+ loadRecordByUuid(uuid) {
32849
+ return this.http
32850
+ .get(`${this.apiUrl}/records/${uuid}/formatters/xml`, {
32851
+ responseType: 'text',
32852
+ headers: {
32853
+ Accept: 'application/xml',
32854
+ },
32855
+ })
32856
+ .pipe(switchMap$1((response) => findConverterForDocument(response).readRecord(response.toString())));
32857
+ }
32858
+ // returns the record as it was when saved
32859
+ saveRecord(record, fieldsConfig) {
32860
+ const savedRecord = { ...record };
32861
+ // run onSave processes
32862
+ for (const field of fieldsConfig) {
32863
+ if (field.onSaveProcess && field.model) {
32864
+ const evaluator = evaluate(field.onSaveProcess);
32865
+ savedRecord[field.model] = evaluator({
32866
+ config: field,
32867
+ value: record[field.model],
32868
+ });
32869
+ }
32870
+ }
32871
+ // TODO: use the catalog repository instead
32872
+ // TODO: use converter based on the format of the record before change
32873
+ 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, {
32874
+ headers: {
32875
+ 'Content-Type': 'application/xml',
32876
+ },
32877
+ withCredentials: true,
32878
+ })), map$1(() => savedRecord));
32879
+ }
32880
+ 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 }); }
32881
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: EditorService, providedIn: 'root' }); }
32882
+ }
32883
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: EditorService, decorators: [{
32884
+ type: Injectable,
32885
+ args: [{
32886
+ providedIn: 'root',
32887
+ }]
32888
+ }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: Configuration, decorators: [{
32889
+ type: Optional
32890
+ }, {
32891
+ type: Inject,
32892
+ args: [Configuration]
32893
+ }] }]; } });
32894
+
32895
+ class EditorEffects {
32896
+ constructor() {
32897
+ this.actions$ = inject(Actions);
32898
+ this.editorService = inject(EditorService);
32899
+ this.store = inject(Store);
32900
+ 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({
32901
+ error: error.message,
32902
+ })))))));
32903
+ this.markAsChanged$ = createEffect(() => this.actions$.pipe(ofType(updateRecordField), map$1(() => markRecordAsChanged())));
32904
+ }
32905
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: EditorEffects, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
32906
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: EditorEffects }); }
32907
+ }
32908
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: EditorEffects, decorators: [{
32909
+ type: Injectable
32910
+ }] });
32911
+
32912
+ var WizardFieldType;
32913
+ (function (WizardFieldType) {
32914
+ WizardFieldType[WizardFieldType["TEXT"] = 0] = "TEXT";
32915
+ WizardFieldType[WizardFieldType["TEXT_AREA"] = 1] = "TEXT_AREA";
32916
+ WizardFieldType[WizardFieldType["CHIPS"] = 2] = "CHIPS";
32917
+ WizardFieldType[WizardFieldType["DATA_PICKER"] = 3] = "DATA_PICKER";
32918
+ WizardFieldType[WizardFieldType["DROPDOWN"] = 4] = "DROPDOWN";
32919
+ })(WizardFieldType || (WizardFieldType = {}));
32920
+
32431
32921
  class WizardService {
32432
32922
  constructor(translateService) {
32433
32923
  this.translateService = translateService;
@@ -32511,15 +33001,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
32511
33001
  }]
32512
33002
  }], ctorParameters: function () { return [{ type: i1$1.TranslateService }]; } });
32513
33003
 
32514
- var WizardFieldType;
32515
- (function (WizardFieldType) {
32516
- WizardFieldType[WizardFieldType["TEXT"] = 0] = "TEXT";
32517
- WizardFieldType[WizardFieldType["TEXT_AREA"] = 1] = "TEXT_AREA";
32518
- WizardFieldType[WizardFieldType["CHIPS"] = 2] = "CHIPS";
32519
- WizardFieldType[WizardFieldType["DATA_PICKER"] = 3] = "DATA_PICKER";
32520
- WizardFieldType[WizardFieldType["DROPDOWN"] = 4] = "DROPDOWN";
32521
- })(WizardFieldType || (WizardFieldType = {}));
32522
-
32523
33004
  marker('datafeeder.month.january');
32524
33005
  marker('datafeeder.month.february');
32525
33006
  marker('datafeeder.month.march');
@@ -32678,6 +33159,52 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
32678
33159
  args: ['dropdown']
32679
33160
  }] } });
32680
33161
 
33162
+ class WizardSummarizeComponent {
33163
+ get title() {
33164
+ return this.wizardService.getWizardFieldData('title') || '';
33165
+ }
33166
+ get abstract() {
33167
+ return this.wizardService.getWizardFieldData('abstract') || '';
33168
+ }
33169
+ get tags() {
33170
+ if (!this.wizardService.getWizardFieldData('tags')) {
33171
+ return '';
33172
+ }
33173
+ return JSON.parse(this.wizardService.getWizardFieldData('tags'))
33174
+ .map((t) => t.display)
33175
+ .join(' - ');
33176
+ }
33177
+ get createdDate() {
33178
+ const time = this.wizardService.getWizardFieldData('datepicker');
33179
+ const locale = this.translateService.currentLang;
33180
+ return new Date(Number(time)).toLocaleDateString(locale, {
33181
+ year: 'numeric',
33182
+ month: 'long',
33183
+ day: 'numeric',
33184
+ });
33185
+ }
33186
+ get scale() {
33187
+ if (!this.wizardService.getWizardFieldData('dropdown')) {
33188
+ return '';
33189
+ }
33190
+ const scaleValue = JSON.parse(this.wizardService.getWizardFieldData('dropdown'));
33191
+ return `1:${scaleValue}`;
33192
+ }
33193
+ get description() {
33194
+ return this.wizardService.getWizardFieldData('description') || '';
33195
+ }
33196
+ constructor(wizardService, translateService) {
33197
+ this.wizardService = wizardService;
33198
+ this.translateService = translateService;
33199
+ }
33200
+ 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 }); }
33201
+ 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" }] }); }
33202
+ }
33203
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: WizardSummarizeComponent, decorators: [{
33204
+ type: Component,
33205
+ 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"] }]
33206
+ }], ctorParameters: function () { return [{ type: WizardService }, { type: i1$1.TranslateService }]; } });
33207
+
32681
33208
  class WizardComponent {
32682
33209
  constructor(wizardService, translate) {
32683
33210
  this.wizardService = wizardService;
@@ -32743,136 +33270,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
32743
33270
  args: ['wizardFields']
32744
33271
  }] } });
32745
33272
 
32746
- class WizardSummarizeComponent {
32747
- get title() {
32748
- return this.wizardService.getWizardFieldData('title') || '';
32749
- }
32750
- get abstract() {
32751
- return this.wizardService.getWizardFieldData('abstract') || '';
32752
- }
32753
- get tags() {
32754
- if (!this.wizardService.getWizardFieldData('tags')) {
32755
- return '';
32756
- }
32757
- return JSON.parse(this.wizardService.getWizardFieldData('tags'))
32758
- .map((t) => t.display)
32759
- .join(' - ');
32760
- }
32761
- get createdDate() {
32762
- const time = this.wizardService.getWizardFieldData('datepicker');
32763
- const locale = this.translateService.currentLang;
32764
- return new Date(Number(time)).toLocaleDateString(locale, {
32765
- year: 'numeric',
32766
- month: 'long',
32767
- day: 'numeric',
32768
- });
32769
- }
32770
- get scale() {
32771
- if (!this.wizardService.getWizardFieldData('dropdown')) {
32772
- return '';
32773
- }
32774
- const scaleValue = JSON.parse(this.wizardService.getWizardFieldData('dropdown'));
32775
- return `1:${scaleValue}`;
32776
- }
32777
- get description() {
32778
- return this.wizardService.getWizardFieldData('description') || '';
32779
- }
32780
- constructor(wizardService, translateService) {
32781
- this.wizardService = wizardService;
32782
- this.translateService = translateService;
32783
- }
32784
- 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 }); }
32785
- 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" }] }); }
32786
- }
32787
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: WizardSummarizeComponent, decorators: [{
32788
- type: Component,
32789
- 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"] }]
32790
- }], ctorParameters: function () { return [{ type: WizardService }, { type: i1$1.TranslateService }]; } });
32791
-
32792
- function evaluate(expression) {
32793
- if (expression.match(/^\${.*}$/)) {
32794
- return evaluate(expression.slice(2, -1));
32795
- }
32796
- const operator = expression.split('(')[0];
32797
- switch (operator) {
32798
- case 'dateNow':
32799
- return () => new Date();
32800
- default:
32801
- throw new Error(`Unknown operator: ${operator}`);
32802
- }
32803
- }
32804
-
32805
- class EditorService {
32806
- constructor(http, apiConfiguration) {
32807
- this.http = http;
32808
- this.apiConfiguration = apiConfiguration;
32809
- this.apiUrl = `${this.apiConfiguration?.basePath || '/geonetwork/srv/api'}`;
32810
- }
32811
- // TODO: use the catalog repository instead
32812
- loadRecordByUuid(uuid) {
32813
- return this.http
32814
- .get(`${this.apiUrl}/records/${uuid}/formatters/xml`, {
32815
- responseType: 'text',
32816
- headers: {
32817
- Accept: 'application/xml',
32818
- },
32819
- })
32820
- .pipe(switchMap$1((response) => findConverterForDocument(response).readRecord(response.toString())));
32821
- }
32822
- // returns the record as it was when saved
32823
- saveRecord(record, fieldsConfig) {
32824
- const savedRecord = { ...record };
32825
- // run onSave processes
32826
- for (const field of fieldsConfig) {
32827
- if (field.onSaveProcess && field.model) {
32828
- const evaluator = evaluate(field.onSaveProcess);
32829
- savedRecord[field.model] = evaluator({
32830
- config: field,
32831
- value: record[field.model],
32832
- });
32833
- }
32834
- }
32835
- // TODO: use the catalog repository instead
32836
- // TODO: use converter based on the format of the record before change
32837
- 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, {
32838
- headers: {
32839
- 'Content-Type': 'application/xml',
32840
- },
32841
- withCredentials: true,
32842
- })), map$1(() => savedRecord));
32843
- }
32844
- 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 }); }
32845
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: EditorService, providedIn: 'root' }); }
32846
- }
32847
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: EditorService, decorators: [{
32848
- type: Injectable,
32849
- args: [{
32850
- providedIn: 'root',
32851
- }]
32852
- }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: Configuration, decorators: [{
32853
- type: Optional
32854
- }, {
32855
- type: Inject,
32856
- args: [Configuration]
32857
- }] }]; } });
32858
-
32859
- class EditorEffects {
32860
- constructor() {
32861
- this.actions$ = inject(Actions);
32862
- this.editorService = inject(EditorService);
32863
- this.store = inject(Store);
32864
- 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({
32865
- error: error.message,
32866
- })))))));
32867
- this.markAsChanged$ = createEffect(() => this.actions$.pipe(ofType(updateRecordField), map$1(() => markRecordAsChanged())));
32868
- }
32869
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: EditorEffects, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
32870
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: EditorEffects }); }
32871
- }
32872
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: EditorEffects, decorators: [{
32873
- type: Injectable
32874
- }] });
32875
-
32876
33273
  class FeatureEditorModule {
32877
33274
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FeatureEditorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
32878
33275
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.1.7", ngImport: i0, type: FeatureEditorModule, declarations: [WizardComponent,
@@ -32922,6 +33319,233 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
32922
33319
  }]
32923
33320
  }] });
32924
33321
 
33322
+ class FormFieldSimpleComponent {
33323
+ constructor() {
33324
+ this.readonly = false;
33325
+ this.invalid = false;
33326
+ this.placeholder = '';
33327
+ }
33328
+ get inputType() {
33329
+ switch (this.type) {
33330
+ case 'url':
33331
+ case 'text':
33332
+ return 'text';
33333
+ case 'date':
33334
+ return 'datetime-local';
33335
+ case 'number':
33336
+ return 'number';
33337
+ case 'toggle':
33338
+ return 'checkbox';
33339
+ default:
33340
+ return '';
33341
+ }
33342
+ }
33343
+ get isSelect() {
33344
+ return this.type === 'list';
33345
+ }
33346
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldSimpleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
33347
+ 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 }); }
33348
+ }
33349
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldSimpleComponent, decorators: [{
33350
+ type: Component,
33351
+ 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" }]
33352
+ }], propDecorators: { type: [{
33353
+ type: Input
33354
+ }], control: [{
33355
+ type: Input
33356
+ }], readonly: [{
33357
+ type: Input
33358
+ }], invalid: [{
33359
+ type: Input
33360
+ }], placeholder: [{
33361
+ type: Input
33362
+ }], options: [{
33363
+ type: Input
33364
+ }] } });
33365
+
33366
+ class FormFieldFileComponent {
33367
+ constructor() {
33368
+ this.readonly = false;
33369
+ this.invalid = false;
33370
+ this.placeholder = '';
33371
+ }
33372
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldFileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
33373
+ 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 }); }
33374
+ }
33375
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldFileComponent, decorators: [{
33376
+ type: Component,
33377
+ 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" }]
33378
+ }], propDecorators: { control: [{
33379
+ type: Input
33380
+ }], readonly: [{
33381
+ type: Input
33382
+ }], invalid: [{
33383
+ type: Input
33384
+ }], placeholder: [{
33385
+ type: Input
33386
+ }] } });
33387
+
33388
+ class FormFieldRichComponent {
33389
+ constructor() {
33390
+ this.placeholder = 'Votre texte ici'; //TODO: translate
33391
+ this.preview = false;
33392
+ }
33393
+ getButtonExtraClass() {
33394
+ 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`;
33395
+ }
33396
+ togglePreview() {
33397
+ this.preview = !this.preview;
33398
+ }
33399
+ handleTextContentChanged(textContent) {
33400
+ this.control.setValue(textContent);
33401
+ }
33402
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldRichComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
33403
+ 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 }); }
33404
+ }
33405
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldRichComponent, decorators: [{
33406
+ type: Component,
33407
+ args: [{ selector: 'gn-ui-form-field-rich', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
33408
+ CommonModule,
33409
+ ReactiveFormsModule,
33410
+ MarkdownEditorComponent,
33411
+ FormFieldWrapperComponent,
33412
+ ButtonComponent,
33413
+ ], 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" }]
33414
+ }], propDecorators: { control: [{
33415
+ type: Input
33416
+ }], label: [{
33417
+ type: Input
33418
+ }], hint: [{
33419
+ type: Input
33420
+ }], helperText: [{
33421
+ type: Input
33422
+ }], placeholder: [{
33423
+ type: Input
33424
+ }] } });
33425
+
33426
+ class FormFieldObjectComponent {
33427
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldObjectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
33428
+ 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 }); }
33429
+ }
33430
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldObjectComponent, decorators: [{
33431
+ type: Component,
33432
+ args: [{ selector: 'gn-ui-form-field-object', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<p>form-field-object works!</p>\n" }]
33433
+ }] });
33434
+
33435
+ class FormFieldArrayComponent {
33436
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldArrayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
33437
+ 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 }); }
33438
+ }
33439
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldArrayComponent, decorators: [{
33440
+ type: Component,
33441
+ args: [{ selector: 'gn-ui-form-field-array', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<p>form-field-array works!</p>\n" }]
33442
+ }] });
33443
+
33444
+ class FormFieldSpatialExtentComponent {
33445
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldSpatialExtentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
33446
+ 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 }); }
33447
+ }
33448
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldSpatialExtentComponent, decorators: [{
33449
+ type: Component,
33450
+ args: [{ selector: 'gn-ui-form-field-spatial-extent', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<p>form-field-spatial-extent works!</p>\n" }]
33451
+ }] });
33452
+
33453
+ class FormFieldTemporalExtentComponent {
33454
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldTemporalExtentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
33455
+ 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 }); }
33456
+ }
33457
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldTemporalExtentComponent, decorators: [{
33458
+ type: Component,
33459
+ args: [{ selector: 'gn-ui-form-field-temporal-extent', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<p>form-field-temporal-extent works!</p>\n" }]
33460
+ }] });
33461
+
33462
+ class FormFieldComponent {
33463
+ set value(v) {
33464
+ this.formControl.setValue(v, {
33465
+ emitEvent: false,
33466
+ });
33467
+ }
33468
+ constructor() {
33469
+ this.formControl = new FormControl();
33470
+ this.valueChange = this.formControl.valueChanges;
33471
+ }
33472
+ focusTitleInput() {
33473
+ this.titleInput.nativeElement.children[0].focus();
33474
+ }
33475
+ get simpleType() {
33476
+ return this.config.type;
33477
+ }
33478
+ get isSimpleField() {
33479
+ return (this.config.type === 'text' ||
33480
+ this.config.type === 'number' ||
33481
+ this.config.type === 'date' ||
33482
+ this.config.type === 'list' ||
33483
+ this.config.type === 'url' ||
33484
+ this.config.type === 'toggle');
33485
+ }
33486
+ get isFileField() {
33487
+ return this.config.type === 'file';
33488
+ }
33489
+ get isSpatialExtentField() {
33490
+ return this.config.type === 'spatial_extent';
33491
+ }
33492
+ get isTemporalExtentField() {
33493
+ return this.config.type === 'temporal_extent';
33494
+ }
33495
+ get isArrayField() {
33496
+ return this.config.type === 'array';
33497
+ }
33498
+ get isObjectField() {
33499
+ return this.config.type === 'object';
33500
+ }
33501
+ get isFieldOk() {
33502
+ return !this.config.locked && !this.config.invalid;
33503
+ }
33504
+ get isFieldLocked() {
33505
+ return this.config.locked;
33506
+ }
33507
+ get isFieldInvalid() {
33508
+ return !this.config.locked && this.config.invalid;
33509
+ }
33510
+ get isTitle() {
33511
+ return this.model === 'title';
33512
+ }
33513
+ get isAbstract() {
33514
+ return this.model === 'abstract';
33515
+ }
33516
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
33517
+ 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 <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=\"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=\"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=\"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=\"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: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: EditableLabelDirective, selector: "[gnUiEditableLabel]", inputs: ["gnUiEditableLabel"], outputs: ["editableLabelChanged"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { 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: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
33518
+ }
33519
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FormFieldComponent, decorators: [{
33520
+ type: Component,
33521
+ args: [{ selector: 'gn-ui-form-field', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
33522
+ CommonModule,
33523
+ ReactiveFormsModule,
33524
+ EditableLabelDirective,
33525
+ MatIconModule,
33526
+ MatTooltipModule,
33527
+ FormFieldSimpleComponent,
33528
+ FormFieldRichComponent,
33529
+ FormFieldObjectComponent,
33530
+ FormFieldSpatialExtentComponent,
33531
+ FormFieldTemporalExtentComponent,
33532
+ FormFieldFileComponent,
33533
+ FormFieldArrayComponent,
33534
+ TranslateModule,
33535
+ ], 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=\"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=\"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=\"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=\"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" }]
33536
+ }], ctorParameters: function () { return []; }, propDecorators: { model: [{
33537
+ type: Input
33538
+ }], config: [{
33539
+ type: Input
33540
+ }], value: [{
33541
+ type: Input
33542
+ }], valueChange: [{
33543
+ type: Output
33544
+ }], titleInput: [{
33545
+ type: ViewChild,
33546
+ args: ['titleInput']
33547
+ }] } });
33548
+
32925
33549
  class RecordFormComponent {
32926
33550
  constructor(facade) {
32927
33551
  this.facade = facade;
@@ -32937,11 +33561,11 @@ class RecordFormComponent {
32937
33561
  return field.config.model;
32938
33562
  }
32939
33563
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: RecordFormComponent, deps: [{ token: EditorFacade }], target: i0.ɵɵFactoryTarget.Component }); }
32940
- 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 }); }
33564
+ 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 }); }
32941
33565
  }
32942
33566
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: RecordFormComponent, decorators: [{
32943
33567
  type: Component,
32944
- 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" }]
33568
+ 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" }]
32945
33569
  }], ctorParameters: function () { return [{ type: EditorFacade }]; } });
32946
33570
 
32947
33571
  const ROUTER_STATE_KEY = 'router';
@@ -33309,5 +33933,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
33309
33933
  * Generated bundle index. Do not edit.
33310
33934
  */
33311
33935
 
33312
- 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, 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, 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 };
33936
+ 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 };
33313
33937
  //# sourceMappingURL=geonetwork-ui.mjs.map