geonetwork-ui 2.3.0-dev.b46332e6 → 2.3.0-dev.bc5d77f0

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 (209) hide show
  1. package/esm2022/index.mjs +2 -1
  2. package/esm2022/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.mjs +3 -3
  3. package/esm2022/libs/api/repository/src/lib/gn4/auth/avatar.service.interface.mjs +1 -1
  4. package/esm2022/libs/api/repository/src/lib/gn4/auth/gravatar.service.mjs +12 -1
  5. package/esm2022/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.mjs +36 -3
  6. package/esm2022/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.mjs +19 -7
  7. package/esm2022/libs/common/domain/src/lib/model/record/index.mjs +2 -1
  8. package/esm2022/libs/common/domain/src/lib/model/record/user-feedbacks.model.mjs +2 -0
  9. package/esm2022/libs/common/domain/src/lib/model/user/index.mjs +2 -0
  10. package/esm2022/libs/common/domain/src/lib/platform.service.interface.mjs +1 -1
  11. package/esm2022/libs/feature/editor/src/lib/+state/editor.facade.mjs +6 -2
  12. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.mjs +64 -0
  13. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-resource-updated/form-field-resource-updated.component.mjs +15 -0
  14. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.mjs +3 -3
  15. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.mjs +38 -10
  16. package/esm2022/libs/feature/editor/src/lib/components/record-form/record-form.component.mjs +3 -13
  17. package/esm2022/libs/feature/editor/src/lib/components/wizard-field/wizard-field.component.mjs +1 -1
  18. package/esm2022/libs/feature/editor/src/lib/fields.config.mjs +16 -1
  19. package/esm2022/libs/feature/map/src/lib/add-layer-from-file/add-layer-from-file.component.mjs +3 -3
  20. package/esm2022/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.mjs +1 -1
  21. package/esm2022/libs/feature/map/src/lib/add-layer-from-wfs/add-layer-from-wfs.component.mjs +1 -1
  22. package/esm2022/libs/feature/map/src/lib/add-layer-from-wms/add-layer-from-wms.component.mjs +1 -1
  23. package/esm2022/libs/feature/notifications/src/index.mjs +4 -0
  24. package/esm2022/libs/feature/notifications/src/lib/feature-notifications.module.mjs +18 -0
  25. package/esm2022/libs/feature/notifications/src/lib/notification.model.mjs +2 -0
  26. package/esm2022/libs/feature/notifications/src/lib/notifications-container/notifications-container.component.mjs +49 -0
  27. package/esm2022/libs/feature/notifications/src/lib/notifications.service.mjs +29 -0
  28. package/esm2022/libs/feature/record/src/lib/feature-record.module.mjs +4 -4
  29. package/esm2022/libs/feature/record/src/lib/state/mdview.actions.mjs +22 -4
  30. package/esm2022/libs/feature/record/src/lib/state/mdview.effects.mjs +37 -10
  31. package/esm2022/libs/feature/record/src/lib/state/mdview.facade.mjs +22 -7
  32. package/esm2022/libs/feature/record/src/lib/state/mdview.reducer.mjs +52 -17
  33. package/esm2022/libs/feature/record/src/lib/state/mdview.selectors.mjs +18 -3
  34. package/esm2022/libs/feature/router/src/lib/default/state/router.effects.mjs +2 -2
  35. package/esm2022/libs/feature/search/src/lib/results-table/results-table.component.mjs +3 -3
  36. package/esm2022/libs/ui/catalog/src/lib/organisation-preview/organisation-preview.component.mjs +3 -3
  37. package/esm2022/libs/ui/elements/src/index.mjs +2 -1
  38. package/esm2022/libs/ui/elements/src/lib/image-overlay-preview/image-overlay-preview.component.mjs +3 -3
  39. package/esm2022/libs/ui/elements/src/lib/markdown-editor/markdown-editor.component.mjs +2 -2
  40. package/esm2022/libs/ui/elements/src/lib/notification/notification.component.mjs +34 -0
  41. package/esm2022/libs/ui/elements/src/lib/record-api-form/record-api-form.component.mjs +3 -3
  42. package/esm2022/libs/ui/elements/src/lib/ui-elements.module.mjs +10 -2
  43. package/esm2022/libs/ui/elements/src/lib/user-feedback-item/time-since.pipe.mjs +59 -0
  44. package/esm2022/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.mjs +62 -0
  45. package/esm2022/libs/ui/inputs/src/index.mjs +15 -15
  46. package/esm2022/libs/ui/inputs/src/lib/date-picker/date-picker.component.mjs +22 -0
  47. package/esm2022/libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.mjs +7 -5
  48. package/esm2022/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.mjs +17 -8
  49. package/esm2022/libs/ui/inputs/src/lib/text-area/text-area.component.mjs +27 -4
  50. package/esm2022/libs/ui/inputs/src/lib/text-input/text-input.component.mjs +19 -3
  51. package/esm2022/libs/ui/inputs/src/lib/ui-inputs.module.mjs +11 -9
  52. package/esm2022/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.mjs +3 -3
  53. package/esm2022/translations/de.json +34 -0
  54. package/esm2022/translations/en.json +34 -0
  55. package/esm2022/translations/es.json +34 -0
  56. package/esm2022/translations/fr.json +34 -0
  57. package/esm2022/translations/it.json +34 -0
  58. package/esm2022/translations/nl.json +34 -0
  59. package/esm2022/translations/pt.json +34 -0
  60. package/fesm2022/geonetwork-ui.mjs +1529 -739
  61. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  62. package/index.d.ts +1 -0
  63. package/index.d.ts.map +1 -1
  64. package/index.ts +1 -0
  65. package/libs/api/repository/src/lib/gn4/auth/avatar.service.interface.d.ts +1 -0
  66. package/libs/api/repository/src/lib/gn4/auth/avatar.service.interface.d.ts.map +1 -1
  67. package/libs/api/repository/src/lib/gn4/auth/gravatar.service.d.ts +1 -0
  68. package/libs/api/repository/src/lib/gn4/auth/gravatar.service.d.ts.map +1 -1
  69. package/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.d.ts +6 -2
  70. package/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.d.ts.map +1 -1
  71. package/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.d.ts +9 -6
  72. package/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.d.ts.map +1 -1
  73. package/libs/common/domain/src/lib/model/record/index.d.ts +1 -0
  74. package/libs/common/domain/src/lib/model/record/index.d.ts.map +1 -1
  75. package/libs/common/domain/src/lib/model/record/user-feedbacks.model.d.ts +15 -0
  76. package/libs/common/domain/src/lib/model/record/user-feedbacks.model.d.ts.map +1 -0
  77. package/libs/common/domain/src/lib/model/user/index.d.ts +2 -0
  78. package/libs/common/domain/src/lib/model/user/index.d.ts.map +1 -0
  79. package/libs/common/domain/src/lib/platform.service.interface.d.ts +3 -0
  80. package/libs/common/domain/src/lib/platform.service.interface.d.ts.map +1 -1
  81. package/libs/feature/editor/src/lib/+state/editor.facade.d.ts +8 -5
  82. package/libs/feature/editor/src/lib/+state/editor.facade.d.ts.map +1 -1
  83. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.d.ts +39 -0
  84. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.d.ts.map +1 -0
  85. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-resource-updated/form-field-resource-updated.component.d.ts +8 -0
  86. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-resource-updated/form-field-resource-updated.component.d.ts.map +1 -0
  87. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts +8 -1
  88. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts.map +1 -1
  89. package/libs/feature/editor/src/lib/components/record-form/record-form.component.d.ts.map +1 -1
  90. package/libs/feature/editor/src/lib/fields.config.d.ts.map +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/feature/record/src/lib/feature-record.module.d.ts.map +1 -1
  102. package/libs/feature/record/src/lib/state/mdview.actions.d.ts +40 -6
  103. package/libs/feature/record/src/lib/state/mdview.actions.d.ts.map +1 -1
  104. package/libs/feature/record/src/lib/state/mdview.effects.d.ts +24 -4
  105. package/libs/feature/record/src/lib/state/mdview.effects.d.ts.map +1 -1
  106. package/libs/feature/record/src/lib/state/mdview.facade.d.ts +14 -4
  107. package/libs/feature/record/src/lib/state/mdview.facade.d.ts.map +1 -1
  108. package/libs/feature/record/src/lib/state/mdview.reducer.d.ts +8 -5
  109. package/libs/feature/record/src/lib/state/mdview.reducer.d.ts.map +1 -1
  110. package/libs/feature/record/src/lib/state/mdview.selectors.d.ts +12 -9
  111. package/libs/feature/record/src/lib/state/mdview.selectors.d.ts.map +1 -1
  112. package/libs/ui/elements/src/index.d.ts +1 -0
  113. package/libs/ui/elements/src/index.d.ts.map +1 -1
  114. package/libs/ui/elements/src/lib/notification/notification.component.d.ts +13 -0
  115. package/libs/ui/elements/src/lib/notification/notification.component.d.ts.map +1 -0
  116. package/libs/ui/elements/src/lib/ui-elements.module.d.ts +16 -14
  117. package/libs/ui/elements/src/lib/ui-elements.module.d.ts.map +1 -1
  118. package/libs/ui/elements/src/lib/user-feedback-item/time-since.pipe.d.ts +11 -0
  119. package/libs/ui/elements/src/lib/user-feedback-item/time-since.pipe.d.ts.map +1 -0
  120. package/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.d.ts +22 -0
  121. package/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.d.ts.map +1 -0
  122. package/libs/ui/inputs/src/index.d.ts +14 -14
  123. package/libs/ui/inputs/src/index.d.ts.map +1 -1
  124. package/libs/ui/inputs/src/lib/date-picker/date-picker.component.d.ts +9 -0
  125. package/libs/ui/inputs/src/lib/date-picker/date-picker.component.d.ts.map +1 -0
  126. package/libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.d.ts +1 -1
  127. package/libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.d.ts.map +1 -1
  128. package/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.d.ts +1 -1
  129. package/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.d.ts.map +1 -1
  130. package/libs/ui/inputs/src/lib/text-area/text-area.component.d.ts +7 -1
  131. package/libs/ui/inputs/src/lib/text-area/text-area.component.d.ts.map +1 -1
  132. package/libs/ui/inputs/src/lib/text-input/text-input.component.d.ts +4 -1
  133. package/libs/ui/inputs/src/lib/text-input/text-input.component.d.ts.map +1 -1
  134. package/libs/ui/inputs/src/lib/ui-inputs.module.d.ts +35 -35
  135. package/package.json +1 -1
  136. package/src/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts +2 -2
  137. package/src/libs/api/repository/src/lib/gn4/auth/avatar.service.interface.ts +1 -0
  138. package/src/libs/api/repository/src/lib/gn4/auth/gravatar.service.ts +12 -1
  139. package/src/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.ts +51 -1
  140. package/src/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.ts +34 -7
  141. package/src/libs/common/domain/src/lib/model/record/index.ts +1 -0
  142. package/src/libs/common/domain/src/lib/model/record/user-feedbacks.model.ts +15 -0
  143. package/src/libs/common/domain/src/lib/platform.service.interface.ts +3 -0
  144. package/src/libs/common/fixtures/src/index.ts +8 -6
  145. package/src/libs/common/fixtures/src/lib/records.fixtures.ts +3 -3
  146. package/src/libs/common/fixtures/src/lib/user-feedbacks.fixtures.ts +83 -0
  147. package/src/libs/feature/editor/src/lib/+state/editor.facade.ts +8 -1
  148. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.css +0 -0
  149. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.html +8 -0
  150. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.ts +64 -0
  151. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-resource-updated/form-field-resource-updated.component.css +0 -0
  152. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-resource-updated/form-field-resource-updated.component.html +4 -0
  153. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-resource-updated/form-field-resource-updated.component.ts +15 -0
  154. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.css +0 -5
  155. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.html +1 -1
  156. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html +57 -33
  157. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts +35 -4
  158. package/src/libs/feature/editor/src/lib/components/record-form/record-form.component.ts +2 -21
  159. package/src/libs/feature/editor/src/lib/fields.config.ts +15 -0
  160. package/src/libs/feature/map/src/lib/add-layer-from-file/add-layer-from-file.component.html +1 -1
  161. package/src/libs/feature/notifications/src/index.ts +3 -0
  162. package/src/libs/feature/notifications/src/lib/feature-notifications.module.ts +10 -0
  163. package/src/libs/feature/notifications/src/lib/notification.model.ts +6 -0
  164. package/src/libs/feature/notifications/src/lib/notifications-container/notifications-container.component.css +0 -0
  165. package/src/libs/feature/notifications/src/lib/notifications-container/notifications-container.component.html +17 -0
  166. package/src/libs/feature/notifications/src/lib/notifications-container/notifications-container.component.ts +44 -0
  167. package/src/libs/feature/notifications/src/lib/notifications.service.ts +27 -0
  168. package/src/libs/feature/record/src/lib/feature-record.module.ts +5 -2
  169. package/src/libs/feature/record/src/lib/state/mdview.actions.ts +51 -6
  170. package/src/libs/feature/record/src/lib/state/mdview.effects.ts +82 -7
  171. package/src/libs/feature/record/src/lib/state/mdview.facade.ts +49 -8
  172. package/src/libs/feature/record/src/lib/state/mdview.reducer.ts +81 -24
  173. package/src/libs/feature/record/src/lib/state/mdview.selectors.ts +40 -10
  174. package/src/libs/feature/router/src/lib/default/state/router.effects.ts +2 -2
  175. package/src/libs/feature/search/src/lib/results-table/results-table.component.html +3 -3
  176. package/src/libs/ui/catalog/src/lib/organisation-preview/organisation-preview.component.html +5 -5
  177. package/src/libs/ui/elements/src/index.ts +1 -0
  178. package/src/libs/ui/elements/src/lib/image-overlay-preview/image-overlay-preview.component.html +1 -1
  179. package/src/libs/ui/elements/src/lib/notification/notification.component.css +0 -0
  180. package/src/libs/ui/elements/src/lib/notification/notification.component.html +52 -0
  181. package/src/libs/ui/elements/src/lib/notification/notification.component.ts +31 -0
  182. package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.html +1 -1
  183. package/src/libs/ui/elements/src/lib/ui-elements.module.ts +5 -0
  184. package/src/libs/ui/elements/src/lib/user-feedback-item/time-since.pipe.ts +54 -0
  185. package/src/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.css +0 -0
  186. package/src/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.html +75 -0
  187. package/src/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.ts +63 -0
  188. package/src/libs/ui/inputs/src/index.ts +14 -14
  189. package/src/libs/ui/inputs/src/lib/date-picker/date-picker.component.css +3 -0
  190. package/src/libs/ui/inputs/src/lib/date-picker/date-picker.component.html +11 -0
  191. package/src/libs/ui/inputs/src/lib/date-picker/date-picker.component.ts +16 -0
  192. package/src/libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.ts +8 -1
  193. package/src/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.ts +13 -0
  194. package/src/libs/ui/inputs/src/lib/text-area/text-area.component.html +2 -1
  195. package/src/libs/ui/inputs/src/lib/text-area/text-area.component.ts +29 -0
  196. package/src/libs/ui/inputs/src/lib/text-input/text-input.component.html +1 -1
  197. package/src/libs/ui/inputs/src/lib/text-input/text-input.component.ts +16 -1
  198. package/src/libs/ui/inputs/src/lib/ui-inputs.module.ts +2 -2
  199. package/src/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.css +0 -5
  200. package/src/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.html +1 -1
  201. package/tailwind.base.css +36 -0
  202. package/translations/de.json +34 -0
  203. package/translations/en.json +34 -0
  204. package/translations/es.json +34 -0
  205. package/translations/fr.json +34 -0
  206. package/translations/it.json +34 -0
  207. package/translations/nl.json +34 -0
  208. package/translations/pt.json +34 -0
  209. package/translations/sk.json +34 -0
@@ -1,61 +1,118 @@
1
1
  import { Action, createReducer, on } from '@ngrx/store'
2
- import * as MdViewActions from './mdview.actions'
2
+ import * as MetadataViewActions from './mdview.actions'
3
3
  import { DatavizConfigurationModel } from '../../../../../../libs/common/domain/src/lib/model/dataviz/dataviz-configuration.model'
4
- import { CatalogRecord } from '../../../../../../libs/common/domain/src/lib/model/record'
4
+ import {
5
+ CatalogRecord,
6
+ UserFeedback,
7
+ } from '../../../../../../libs/common/domain/src/lib/model/record'
5
8
 
6
- export const MD_VIEW_FEATURE_STATE_KEY = 'mdView'
9
+ export const METADATA_VIEW_FEATURE_STATE_KEY = 'metadataView'
7
10
 
8
- export interface MdViewState {
11
+ export interface MetadataViewState {
9
12
  loadingFull: boolean
10
13
  error: { notFound?: boolean; otherError?: string } | null
11
14
  metadata?: Partial<CatalogRecord>
12
15
  related?: CatalogRecord[]
16
+ userFeedbacks?: UserFeedback[]
17
+ allUserFeedbacksLoading: boolean
18
+ addUserFeedbackLoading: boolean
13
19
  chartConfig?: DatavizConfigurationModel
14
20
  }
15
21
 
16
- export const initialMdviewState: MdViewState = {
22
+ export const initialMetadataViewState: MetadataViewState = {
17
23
  error: null,
18
24
  loadingFull: false,
25
+ allUserFeedbacksLoading: false,
26
+ addUserFeedbackLoading: false,
19
27
  }
20
28
 
21
- const mdViewReducer = createReducer(
22
- initialMdviewState,
23
- on(MdViewActions.loadFullMetadata, (state) => ({
29
+ const metadataViewReducer = createReducer(
30
+ initialMetadataViewState,
31
+
32
+ /*
33
+ Metadata reducers
34
+ */
35
+ on(MetadataViewActions.loadFullMetadata, (state) => ({
24
36
  ...state,
25
37
  error: null,
26
38
  loadingFull: true,
27
39
  })),
28
- on(MdViewActions.setIncompleteMetadata, (state, { incomplete }) => ({
40
+ on(MetadataViewActions.setIncompleteMetadata, (state, { incomplete }) => ({
29
41
  ...state,
30
42
  error: null,
31
43
  metadata: incomplete,
32
44
  })),
33
- on(MdViewActions.loadFullSuccess, (state, { full }) => ({
45
+ on(MetadataViewActions.loadFullMetadataSuccess, (state, { full }) => ({
34
46
  ...state,
35
47
  error: null,
36
48
  metadata: full,
37
49
  loadingFull: false,
38
50
  })),
39
- on(MdViewActions.loadFullFailure, (state, { otherError, notFound }) => ({
40
- ...state,
41
- error: { otherError, notFound },
42
- loadingFull: false,
43
- })),
44
- on(MdViewActions.setRelated, (state, { related }) => ({
51
+ on(
52
+ MetadataViewActions.loadFullMetadataFailure,
53
+ (state, { otherError, notFound }) => ({
54
+ ...state,
55
+ error: { otherError, notFound },
56
+ loadingFull: false,
57
+ })
58
+ ),
59
+ on(MetadataViewActions.closeMetadata, (state) => {
60
+ const { metadata, related, userFeedbacks, ...stateWithoutMetadata } = state
61
+ return stateWithoutMetadata
62
+ }),
63
+
64
+ /*
65
+ Related reducers
66
+ */
67
+ on(MetadataViewActions.setRelated, (state, { related }) => ({
45
68
  ...state,
46
69
  related,
47
70
  })),
48
- on(MdViewActions.setChartConfig, (state, { chartConfig }) => ({
71
+
72
+ /*
73
+ ChartConfig reducers
74
+ */
75
+ on(MetadataViewActions.setChartConfig, (state, { chartConfig }) => ({
49
76
  ...state,
50
77
  chartConfig,
51
78
  })),
52
- on(MdViewActions.close, (state) => {
53
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
54
- const { metadata, related, ...stateWithoutMd } = state
55
- return stateWithoutMd
56
- })
79
+
80
+ /*
81
+ UserFeedbacks reducers
82
+ */
83
+ on(MetadataViewActions.loadUserFeedbacks, (state) => ({
84
+ ...state,
85
+ error: null,
86
+ allUserFeedbacksLoading: true,
87
+ })),
88
+ on(MetadataViewActions.addUserFeedback, (state) => ({
89
+ ...state,
90
+ addUserFeedbackLoading: true,
91
+ })),
92
+ on(
93
+ MetadataViewActions.loadUserFeedbacksSuccess,
94
+ (state, { userFeedbacks }) => ({
95
+ ...state,
96
+ error: null,
97
+ userFeedbacks: userFeedbacks,
98
+ addUserFeedbackLoading: false,
99
+ allUserFeedbacksLoading: false,
100
+ })
101
+ ),
102
+ on(
103
+ MetadataViewActions.loadUserFeedbacksFailure,
104
+ (state, { otherError, notFound }) => ({
105
+ ...state,
106
+ error: { otherError, notFound },
107
+ addUserFeedbackLoading: false,
108
+ allUserFeedbacksLoading: false,
109
+ })
110
+ )
57
111
  )
58
112
 
59
- export function reducer(state: MdViewState | undefined, action: Action) {
60
- return mdViewReducer(state, action)
113
+ export function reducer(
114
+ metadataViewState: MetadataViewState | undefined,
115
+ action: Action
116
+ ) {
117
+ return metadataViewReducer(metadataViewState, action)
61
118
  }
@@ -1,36 +1,66 @@
1
1
  import { createFeatureSelector, createSelector } from '@ngrx/store'
2
- import { MD_VIEW_FEATURE_STATE_KEY, MdViewState } from './mdview.reducer'
2
+ import {
3
+ METADATA_VIEW_FEATURE_STATE_KEY,
4
+ MetadataViewState,
5
+ } from './mdview.reducer'
3
6
 
4
- export const getMdViewState = createFeatureSelector<MdViewState>(
5
- MD_VIEW_FEATURE_STATE_KEY
7
+ export const getMdViewState = createFeatureSelector<MetadataViewState>(
8
+ METADATA_VIEW_FEATURE_STATE_KEY
6
9
  )
7
10
 
11
+ /*
12
+ Metadata selectors
13
+ */
8
14
  export const getMetadataUuid = createSelector(
9
15
  getMdViewState,
10
- (state: MdViewState) =>
16
+ (state: MetadataViewState) =>
11
17
  state.metadata ? state.metadata.uniqueIdentifier : null
12
18
  )
13
19
  export const getMetadata = createSelector(
14
20
  getMdViewState,
15
- (state: MdViewState) => state.metadata
21
+ (state: MetadataViewState) => state.metadata
16
22
  )
17
23
  export const getMetadataIsIncomplete = createSelector(
18
24
  getMdViewState,
19
- (state: MdViewState) => (state.metadata ? state.loadingFull : null)
25
+ (state: MetadataViewState) => (state.metadata ? state.loadingFull : null)
20
26
  )
21
27
  export const getMetadataIsLoading = createSelector(
22
28
  getMdViewState,
23
- (state: MdViewState) => state.loadingFull
29
+ (state: MetadataViewState) => state.loadingFull
24
30
  )
25
31
  export const getMetadataError = createSelector(
26
32
  getMdViewState,
27
- (state: MdViewState) => state.error
33
+ (state: MetadataViewState) => state.error
28
34
  )
35
+
36
+ /*
37
+ Related selectors
38
+ */
29
39
  export const getRelated = createSelector(
30
40
  getMdViewState,
31
- (state: MdViewState) => state.related
41
+ (state: MetadataViewState) => state.related
32
42
  )
43
+
44
+ /*
45
+ Metadata selectors
46
+ */
33
47
  export const getChartConfig = createSelector(
34
48
  getMdViewState,
35
- (state: MdViewState) => state.chartConfig
49
+ (state: MetadataViewState) => state.chartConfig
50
+ )
51
+
52
+ /*
53
+ UserFeedback selectors
54
+ */
55
+ export const getUserFeedbacks = createSelector(
56
+ getMdViewState,
57
+ (state: MetadataViewState) => state.userFeedbacks
58
+ )
59
+ export const getAllUserFeedbacksLoading = createSelector(
60
+ getMdViewState,
61
+ (state: MetadataViewState) => state.allUserFeedbacksLoading
62
+ )
63
+ export const getAddUserFeedbacksLoading = createSelector(
64
+ getMdViewState,
65
+ (state: MetadataViewState) => state.addUserFeedbackLoading
36
66
  )
@@ -15,7 +15,7 @@ import {
15
15
  } from '../../../../../../../libs/common/domain/src/lib/model/search'
16
16
  import { Actions, createEffect, ofType } from '@ngrx/effects'
17
17
  import { navigation } from '@ngrx/router-store/data-persistence'
18
- import { of, pairwise, startWith, withLatestFrom } from 'rxjs'
18
+ import { of, pairwise, startWith } from 'rxjs'
19
19
  import { map, mergeMap, tap } from 'rxjs/operators'
20
20
  import * as RouterActions from './router.actions'
21
21
  import { RouterFacade } from './router.facade'
@@ -141,7 +141,7 @@ export class RouterEffects {
141
141
  navigateToSearch$ = createEffect(() =>
142
142
  this._actions$.pipe(
143
143
  navigation(this.routerConfig.searchRouteComponent, {
144
- run: () => MdViewActions.close(),
144
+ run: () => MdViewActions.closeMetadata(),
145
145
  })
146
146
  )
147
147
  )
@@ -50,20 +50,20 @@
50
50
  [title]="formats.join(', ')"
51
51
  >
52
52
  <span
53
- class="badge-btn min-w-[45px] text-sm text-white px-2 flex-shrink-0"
53
+ class="badge-btn min-w-[45px] text-sm text-white px-2 shrink-0"
54
54
  [style.background-color]="getBadgeColor(formats[0])"
55
55
  *ngIf="formats[0]"
56
56
  >
57
57
  {{ formats[0] }}
58
58
  </span>
59
59
  <span
60
- class="badge-btn min-w-[45px] text-sm text-white px-2 flex-shrink-0"
60
+ class="badge-btn min-w-[45px] text-sm text-white px-2 shrink-0"
61
61
  [style.background-color]="getBadgeColor(formats[1])"
62
62
  *ngIf="formats[1]"
63
63
  >
64
64
  {{ formats[1] }}
65
65
  </span>
66
- <div class="flex-shrink-0" *ngIf="formats.slice(2).length > 0">
66
+ <div class="shrink-0" *ngIf="formats.slice(2).length > 0">
67
67
  <span>+{{ formats.slice(2).length }}</span>
68
68
  </div>
69
69
  </div>
@@ -4,7 +4,7 @@
4
4
  [title]="organisation.name"
5
5
  >
6
6
  <div
7
- class="flex-shrink-0 bg-gray-100 rounded-lg overflow-hidden w-full border border-gray-300 h-36"
7
+ class="shrink-0 bg-gray-100 rounded-lg overflow-hidden w-full border border-gray-300 h-36"
8
8
  >
9
9
  <gn-ui-thumbnail
10
10
  class="relative h-full w-full"
@@ -13,20 +13,20 @@
13
13
  >
14
14
  </gn-ui-thumbnail>
15
15
  </div>
16
- <div class="px-3 pb-2 capitalize flex flex-col flex-grow overflow-hidden">
16
+ <div class="px-3 pb-2 capitalize flex flex-col grow overflow-hidden">
17
17
  <span
18
- 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"
18
+ 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"
19
19
  data-cy="organizationName"
20
20
  >
21
21
  {{ organisation.name }}</span
22
22
  >
23
23
  <p
24
- class="abstract mt-4 mb-5 sm:mb-2 sm:mt-0 flex-grow flex-shrink-1 overflow-hidden"
24
+ class="abstract mt-4 mb-5 sm:mb-2 sm:mt-0 grow shrink-1 overflow-hidden"
25
25
  data-cy="organizationDesc"
26
26
  >
27
27
  {{ organisation.description }}
28
28
  </p>
29
- <div class="flex-shrink-0 text-primary opacity-50 flex leading-6">
29
+ <div class="shrink-0 text-primary opacity-50 flex leading-6">
30
30
  <mat-icon class="material-symbols-outlined text-primary opacity-50 mr-1"
31
31
  >folder_open
32
32
  </mat-icon>
@@ -21,3 +21,4 @@ export * from './lib/search-results-error/search-results-error.component'
21
21
  export * from './lib/thumbnail/thumbnail.component'
22
22
  export * from './lib/ui-elements.module'
23
23
  export * from './lib/user-preview/user-preview.component'
24
+ export * from './lib/notification/notification.component'
@@ -6,7 +6,7 @@
6
6
  *ngIf="imageUrl"
7
7
  [showContent]="imageUrl !== undefined"
8
8
  data-cy="record-thumbnail"
9
- 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"
9
+ 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"
10
10
  >
11
11
  <gn-ui-thumbnail
12
12
  class="relative h-full w-full"
@@ -0,0 +1,52 @@
1
+ <div
2
+ class="p-[16px] flex flex-row gap-[16px] items-start border border-gray-200 shadow-md rounded bg-background"
3
+ >
4
+ <div
5
+ role="alert"
6
+ class="rounded-full text-white p-[6px] w-[32px] h-[32px] flex shrink-0"
7
+ [ngClass]="{
8
+ 'bg-red-500': type === 'error',
9
+ 'bg-yellow-500': type === 'warning',
10
+ 'bg-green-500': type === 'success',
11
+ 'bg-blue-500': type === 'info'
12
+ }"
13
+ [ngSwitch]="type"
14
+ >
15
+ <mat-icon class="material-symbols-outlined !w-[18px] !h-[18px] text-[20px]">
16
+ <ng-container *ngSwitchCase="'success'">check_circle</ng-container>
17
+ <ng-container *ngSwitchCase="'info'">info</ng-container>
18
+ <ng-container *ngSwitchCase="'warning'">warning</ng-container>
19
+ <ng-container *ngSwitchCase="'error'">error</ng-container>
20
+ </mat-icon>
21
+ </div>
22
+ <div
23
+ class="flex flex-col items-start gap-[4px] pt-[3px] grow shrink overflow-hidden"
24
+ >
25
+ <div class="font-bold text-[16px] text-gray-900">
26
+ {{ title }}
27
+ </div>
28
+ <div class="text-[14px] text-gray-800">
29
+ {{ text }}
30
+ </div>
31
+ <a
32
+ href
33
+ *ngIf="closeMessage"
34
+ class="text-[14px] gn-ui-link"
35
+ (click)="handleClose($event)"
36
+ >
37
+ {{ closeMessage }}
38
+ </a>
39
+ </div>
40
+ <gn-ui-button
41
+ type="light"
42
+ class="shrink-0"
43
+ (buttonClick)="handleClose()"
44
+ [style.--gn-ui-button-padding]="0"
45
+ [style.--gn-ui-button-width]="'21px'"
46
+ [style.--gn-ui-button-height]="'21px'"
47
+ >
48
+ <mat-icon class="material-symbols-outlined text-[22px] !w-[21px] !h-[21px]"
49
+ >close</mat-icon
50
+ >
51
+ </gn-ui-button>
52
+ </div>
@@ -0,0 +1,31 @@
1
+ import {
2
+ ChangeDetectionStrategy,
3
+ Component,
4
+ EventEmitter,
5
+ Input,
6
+ Output,
7
+ } from '@angular/core'
8
+ import { CommonModule } from '@angular/common'
9
+ import { MatIconModule } from '@angular/material/icon'
10
+ import { ButtonComponent } from '../../../../../../libs/ui/inputs/src'
11
+
12
+ @Component({
13
+ selector: 'gn-ui-notification',
14
+ standalone: true,
15
+ imports: [CommonModule, MatIconModule, ButtonComponent],
16
+ templateUrl: './notification.component.html',
17
+ styleUrls: ['./notification.component.css'],
18
+ changeDetection: ChangeDetectionStrategy.OnPush,
19
+ })
20
+ export class NotificationComponent {
21
+ @Input() type: 'info' | 'warning' | 'error' | 'success' = 'info'
22
+ @Input() title: string
23
+ @Input() text: string
24
+ @Input() closeMessage?: string
25
+ @Output() notificationClose = new EventEmitter<void>()
26
+
27
+ handleClose(event?: Event) {
28
+ event?.preventDefault()
29
+ this.notificationClose.emit()
30
+ }
31
+ }
@@ -13,7 +13,7 @@
13
13
  </p>
14
14
  </button>
15
15
  </div>
16
- <div class="flex flex-row flex-wrap justify-between flex-grow gap-5">
16
+ <div class="flex flex-row flex-wrap justify-between grow gap-5">
17
17
  <div class="flex flex-col gap-3">
18
18
  <p class="text-[14px]" translate>record.metadata.api.form.limit</p>
19
19
  <div class="flex flex-row items-center gap-2">
@@ -31,6 +31,8 @@ import { MaxLinesComponent } from './max-lines/max-lines.component'
31
31
  import { RecordApiFormComponent } from './record-api-form/record-api-form.component'
32
32
  import { MarkdownParserComponent } from './markdown-parser/markdown-parser.component'
33
33
  import { ImageOverlayPreviewComponent } from './image-overlay-preview/image-overlay-preview.component'
34
+ import { UserFeedbackItemComponent } from './user-feedback-item/user-feedback-item.component'
35
+ import { TimeSincePipe } from './user-feedback-item/time-since.pipe'
34
36
 
35
37
  @NgModule({
36
38
  imports: [
@@ -47,6 +49,7 @@ import { ImageOverlayPreviewComponent } from './image-overlay-preview/image-over
47
49
  NgOptimizedImage,
48
50
  MarkdownParserComponent,
49
51
  ThumbnailComponent,
52
+ TimeSincePipe,
50
53
  ],
51
54
  declarations: [
52
55
  MetadataInfoComponent,
@@ -68,6 +71,7 @@ import { ImageOverlayPreviewComponent } from './image-overlay-preview/image-over
68
71
  PaginationButtonsComponent,
69
72
  MaxLinesComponent,
70
73
  RecordApiFormComponent,
74
+ UserFeedbackItemComponent,
71
75
  ImageOverlayPreviewComponent,
72
76
  ],
73
77
  exports: [
@@ -91,6 +95,7 @@ import { ImageOverlayPreviewComponent } from './image-overlay-preview/image-over
91
95
  MaxLinesComponent,
92
96
  RecordApiFormComponent,
93
97
  MarkdownParserComponent,
98
+ UserFeedbackItemComponent,
94
99
  ImageOverlayPreviewComponent,
95
100
  ],
96
101
  })
@@ -0,0 +1,54 @@
1
+ import { Pipe, PipeTransform } from '@angular/core'
2
+ import { TranslateService } from '@ngx-translate/core'
3
+ import { formatDistance } from 'date-fns'
4
+ import { de, enUS, es, fr, it, nl, pt, sk } from 'date-fns/locale'
5
+
6
+ @Pipe({
7
+ name: 'timeSince',
8
+ standalone: true,
9
+ })
10
+ export class TimeSincePipe implements PipeTransform {
11
+ constructor(private translate: TranslateService) {}
12
+
13
+ transform(value: Date): string {
14
+ if (isNaN(value.getTime())) {
15
+ throw new Error('Invalid Date')
16
+ }
17
+
18
+ const maintenant = new Date()
19
+ let locale: Locale
20
+
21
+ switch (this.translate.currentLang) {
22
+ case 'fr':
23
+ locale = fr
24
+ break
25
+ case 'de':
26
+ locale = de
27
+ break
28
+ case 'es':
29
+ locale = es
30
+ break
31
+ case 'it':
32
+ locale = it
33
+ break
34
+ case 'nl':
35
+ locale = nl
36
+ break
37
+ case 'pt':
38
+ locale = pt
39
+ break
40
+ case 'sk':
41
+ locale = sk
42
+ break
43
+ case 'en':
44
+ default:
45
+ locale = enUS
46
+ break
47
+ }
48
+
49
+ return formatDistance(value, maintenant, {
50
+ addSuffix: true,
51
+ locale: locale,
52
+ })
53
+ }
54
+ }
@@ -0,0 +1,75 @@
1
+ <div
2
+ *ngIf="userFeedbackParent.published"
3
+ class="flex flex-col bg-white rounded w-full"
4
+ [ngClass]="[isAnAnswer ? 'ps-4 ' : 'p-4']"
5
+ >
6
+ <div class="flex flex-row">
7
+ <div class="avatar">
8
+ <img
9
+ class="rounded-full"
10
+ [src]="userFeedbackParent.avatarUrl"
11
+ alt="avatar"
12
+ />
13
+ </div>
14
+ <div class="p-4 flex flex-col">
15
+ <span>{{ userFeedbackParent.authorName }}</span>
16
+ <span> {{ userFeedbackParent.date | timeSince }}</span>
17
+ </div>
18
+ </div>
19
+ <div data-cy="commentText" class="mt-4 whitespace-pre-line">
20
+ {{ userFeedbackParent.comment }}
21
+ </div>
22
+ <div
23
+ class="w-full"
24
+ *ngFor="let userFeedBacksAnswer of userFeedBacksAnswers; let last = last"
25
+ >
26
+ <hr class="-mx-4 my-6" />
27
+ <gn-ui-user-feedback-item
28
+ [userFeedbackParent]="userFeedBacksAnswer"
29
+ [isLastComment]="last"
30
+ ></gn-ui-user-feedback-item>
31
+ </div>
32
+
33
+ <div *ngIf="isActiveUserEditor" class="mt-2 flex flex-col">
34
+ <hr class="-mx-4 my-4" />
35
+ <div
36
+ id="new-comment-buttons"
37
+ class="flex flex-row gap-2 items-center justify-end"
38
+ >
39
+ <gn-ui-text-area
40
+ [disabled]="isAddUserFeedbackLoading"
41
+ [(value)]="newAnswer"
42
+ (valueChange)="onNewAnswerValueChange()"
43
+ (keyup.control.enter)="publishNewAnswer()"
44
+ [placeholder]="
45
+ 'record.metadata.userFeedbacks.newAnswer.placeholder' | translate
46
+ "
47
+ class="grow"
48
+ extraClass="bg-transparent border-0 placeholder-primary-darker text-primary-darker h-9"
49
+ ></gn-ui-text-area>
50
+ <div *ngIf="!isAnswerEmpty" class="flex flex-row justify-end">
51
+ <gn-ui-button
52
+ [disabled]="isAddUserFeedbackLoading"
53
+ [type]="'outline'"
54
+ (buttonClick)="publishNewAnswer()"
55
+ [title]="
56
+ 'record.metadata.userFeedbacks.newAnswer.buttonTitle' | translate
57
+ "
58
+ extraClass="!p-[0.5em] text-primary-darker border-primary-darker h-9"
59
+ >
60
+ <mat-icon
61
+ class="material-symbols-outlined"
62
+ *ngIf="!isAddUserFeedbackLoading"
63
+ >
64
+ send
65
+ </mat-icon>
66
+ <ng-container *ngIf="isAddUserFeedbackLoading">
67
+ <div class="flex justify-center w-full">
68
+ <gn-ui-spinning-loader></gn-ui-spinning-loader>
69
+ </div>
70
+ </ng-container>
71
+ </gn-ui-button>
72
+ </div>
73
+ </div>
74
+ </div>
75
+ </div>
@@ -0,0 +1,63 @@
1
+ import {
2
+ ChangeDetectionStrategy,
3
+ Component,
4
+ EventEmitter,
5
+ Input,
6
+ OnInit,
7
+ Output,
8
+ } from '@angular/core'
9
+ import {
10
+ UserFeedback,
11
+ UserFeedbackViewModel,
12
+ } from '../../../../../../libs/common/domain/src/lib/model/record'
13
+ import { UserModel } from '../../../../../../libs/common/domain/src/lib/model/user'
14
+
15
+ @Component({
16
+ selector: 'gn-ui-user-feedback-item',
17
+ templateUrl: './user-feedback-item.component.html',
18
+ styleUrls: ['./user-feedback-item.component.css'],
19
+ changeDetection: ChangeDetectionStrategy.OnPush,
20
+ })
21
+ export class UserFeedbackItemComponent implements OnInit {
22
+ @Input() userFeedbackParent: UserFeedbackViewModel
23
+ @Input() userFeedBacksAnswers: UserFeedbackViewModel[]
24
+ @Input() isActiveUserEditor: boolean
25
+ @Input() activeUser: UserModel
26
+ @Input() isLastComment: boolean
27
+ @Input() isAddUserFeedbackLoading: boolean
28
+
29
+ @Output() newUserFeedbackAnswer = new EventEmitter<UserFeedback>()
30
+
31
+ isAnAnswer = false
32
+ newAnswer = ''
33
+ isAnswerEmpty = true
34
+
35
+ ngOnInit(): void {
36
+ this.isAnAnswer = !!this.userFeedbackParent.parentUuid
37
+ }
38
+
39
+ onNewAnswerValueChange() {
40
+ this.isAnswerEmpty = this.newAnswer.length === 0
41
+ }
42
+
43
+ publishNewAnswer() {
44
+ if (this.newAnswer.trim() === '') return
45
+
46
+ const newAnswer: UserFeedback = {
47
+ ...this.userFeedbackParent,
48
+ uuid: undefined,
49
+ published: true,
50
+ comment: this.newAnswer,
51
+ parentUuid: this.userFeedbackParent.uuid,
52
+ authorUserId: this.activeUser?.id,
53
+ authorEmail: this.activeUser?.email,
54
+ date: new Date(),
55
+ authorName: `${this.activeUser?.name} ${this.activeUser?.surname}`,
56
+ }
57
+
58
+ this.newUserFeedbackAnswer.emit(newAnswer)
59
+
60
+ this.newAnswer = ''
61
+ this.onNewAnswerValueChange()
62
+ }
63
+ }