@reltio/dashboard 1.4.1584 → 1.4.1586-mui5

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 (263) hide show
  1. package/.DS_Store +0 -0
  2. package/index.ts +12 -0
  3. package/package.json +42 -25
  4. package/public/bundle.js +205 -0
  5. package/public/bundle.js.LICENSE.txt +59 -0
  6. package/public/package.json +26 -0
  7. package/public/types/components/DashboardConfigItem/styles.d.ts +1 -0
  8. package/{types → public/types}/components/DashboardError/styles.d.ts +1 -1
  9. package/public/types/components/DashboardLayout/styles.d.ts +1 -0
  10. package/public/types/components/DashboardLayoutItem/styles.d.ts +1 -0
  11. package/public/types/components/DashboardLayoutPanel/styles.d.ts +1 -0
  12. package/public/types/components/DashboardLinearLoader/styles.d.ts +1 -0
  13. package/{types → public/types}/components/DashboardNoData/styles.d.ts +1 -1
  14. package/public/types/components/DashboardPerspectiveHeader/styles.d.ts +2 -0
  15. package/{types → public/types}/components/DashboardPopupMenu/DashboardPopupMenu.d.ts +1 -1
  16. package/public/types/components/DashboardPopupMenu/styles.d.ts +1 -0
  17. package/public/types/components/EntityTable/cell-renderers/styles.d.ts +1 -0
  18. package/{types → public/types}/components/EntityTable/styles.d.ts +1 -1
  19. package/public/types/components/LayoutItemContent/styles.d.ts +1 -0
  20. package/public/types/components/LayoutItemHeader/styles.d.ts +1 -0
  21. package/public/types/components/LayoutItemView/styles.d.ts +1 -0
  22. package/public/types/components/StatsChart/customized/styles.d.ts +1 -0
  23. package/public/types/components/WorkflowTaskItem/styles.d.ts +1 -0
  24. package/public/types/perspective/styles.d.ts +1 -0
  25. package/public/types/views/chartBased/styles.d.ts +1 -0
  26. package/public/types/views/custom/styles.d.ts +1 -0
  27. package/public/types/views/tableBased/styles.d.ts +1 -0
  28. package/scripts/build/index.js +21 -0
  29. package/src/HOCs/withPagination.tsx +39 -0
  30. package/src/components/DashboardConfigItem/DashboardConfigItem.tsx +101 -0
  31. package/src/components/DashboardConfigItem/__tests__/DashboardConfigItem.specs.tsx +81 -0
  32. package/src/components/DashboardConfigItem/icons/barChart.svg +12 -0
  33. package/src/components/DashboardConfigItem/icons/bubbleChart.svg +18 -0
  34. package/src/components/DashboardConfigItem/icons/customChart.svg +66 -0
  35. package/src/components/DashboardConfigItem/icons/donutChart.svg +33 -0
  36. package/src/components/DashboardConfigItem/icons/geomap.svg +23 -0
  37. package/src/components/DashboardConfigItem/icons/lineChart.svg +16 -0
  38. package/src/components/DashboardConfigItem/icons/pieChart.svg +27 -0
  39. package/src/components/DashboardConfigItem/icons/tableWithBars.svg +27 -0
  40. package/src/components/DashboardConfigItem/icons/treemap.svg +15 -0
  41. package/src/components/DashboardConfigItem/icons/wordCloud.svg +27 -0
  42. package/src/components/DashboardConfigItem/styles.ts +56 -0
  43. package/src/components/DashboardError/DashboardError.tsx +34 -0
  44. package/src/components/DashboardError/__tests__/DashboardError.test.js +34 -0
  45. package/src/components/DashboardError/icons/error.svg +113 -0
  46. package/src/components/DashboardError/styles.ts +30 -0
  47. package/src/components/DashboardLayout/DashboardLayout.tsx +59 -0
  48. package/src/components/DashboardLayout/__tests__/DashboardLayout.specs.tsx +56 -0
  49. package/src/components/DashboardLayout/styles.ts +30 -0
  50. package/src/components/DashboardLayoutItem/DashboardLayoutItem.tsx +59 -0
  51. package/src/components/DashboardLayoutItem/__tests__/DashboardLayoutItem.specs.tsx +145 -0
  52. package/src/components/DashboardLayoutItem/styles.ts +10 -0
  53. package/src/components/DashboardLayoutPanel/DashboardLayoutPanel.tsx +59 -0
  54. package/src/components/DashboardLayoutPanel/__tests__/DashboardLayoutPanel.specs.tsx +58 -0
  55. package/src/components/DashboardLayoutPanel/styles.ts +43 -0
  56. package/src/components/DashboardLinearLoader/DashboardLinearLoader.tsx +10 -0
  57. package/src/components/DashboardLinearLoader/__tests__/DashboardLinearLoader.test.js +12 -0
  58. package/src/components/DashboardLinearLoader/styles.ts +11 -0
  59. package/src/components/DashboardNoData/.DS_Store +0 -0
  60. package/src/components/DashboardNoData/DashboardNoData.tsx +21 -0
  61. package/src/components/DashboardNoData/__tests__/DashboardNoData.test.js +15 -0
  62. package/src/components/DashboardNoData/icons/noData.svg +68 -0
  63. package/src/components/DashboardNoData/styles.ts +21 -0
  64. package/src/components/DashboardPerspectiveHeader/DashboardPerspectiveHeader.tsx +43 -0
  65. package/src/components/DashboardPerspectiveHeader/__tests__/DashboardPerspectiveHeader.specs.tsx +41 -0
  66. package/src/components/DashboardPerspectiveHeader/styles.ts +24 -0
  67. package/src/components/DashboardPopupMenu/DashboardPopupMenu.tsx +75 -0
  68. package/src/components/DashboardPopupMenu/__tests__/DashboardPopupMenu.test.tsx +51 -0
  69. package/src/components/DashboardPopupMenu/styles.ts +20 -0
  70. package/src/components/EntityTable/EntityTable.tsx +49 -0
  71. package/src/components/EntityTable/__tests__/EntityTable.test.tsx +33 -0
  72. package/src/components/EntityTable/cell-renderers/EntityLabelRenderer.tsx +24 -0
  73. package/src/components/EntityTable/cell-renderers/HeadCellRenderer.tsx +34 -0
  74. package/src/components/EntityTable/cell-renderers/__tests__/EntityLabelRenderer.test.tsx +25 -0
  75. package/src/components/EntityTable/cell-renderers/styles.ts +46 -0
  76. package/src/components/EntityTable/styles.ts +19 -0
  77. package/src/components/LayoutItemContent/LayoutItemContent.tsx +63 -0
  78. package/src/components/LayoutItemContent/__tests__/LayoutItemContent.test.tsx +71 -0
  79. package/src/components/LayoutItemContent/styles.ts +36 -0
  80. package/src/components/LayoutItemHeader/LayoutItemHeader.tsx +86 -0
  81. package/src/components/LayoutItemHeader/__tests__/LayoutItemHeader.specs.tsx +48 -0
  82. package/src/components/LayoutItemHeader/styles.ts +44 -0
  83. package/src/components/LayoutItemView/LayoutItemView.tsx +24 -0
  84. package/src/components/LayoutItemView/styles.ts +11 -0
  85. package/src/components/StatsChart/StatsChart.tsx +77 -0
  86. package/src/components/StatsChart/__tests__/StatsChart.test.tsx +106 -0
  87. package/src/components/StatsChart/customized/CustomAxisTick.tsx +28 -0
  88. package/src/components/StatsChart/customized/CustomLegend.tsx +37 -0
  89. package/src/components/StatsChart/customized/CustomTooltip.tsx +41 -0
  90. package/src/components/StatsChart/customized/styles.ts +53 -0
  91. package/src/components/StatsChart/getStatsChartSettings.ts +65 -0
  92. package/src/components/WorkflowTaskItem/WorkflowTaskItem.tsx +67 -0
  93. package/src/components/WorkflowTaskItem/WorkflowTaskObject.tsx +54 -0
  94. package/src/components/WorkflowTaskItem/__tests__/WorkflowTaskItem.test.tsx +73 -0
  95. package/src/components/WorkflowTaskItem/__tests__/WorkflowTaskObject.test.tsx +95 -0
  96. package/src/components/WorkflowTaskItem/styles.ts +74 -0
  97. package/src/components/WorkflowTasksList/WorkflowTasksList.tsx +34 -0
  98. package/src/components/WorkflowTasksList/__tests__/WorkflowTasksList.test.tsx +98 -0
  99. package/src/components/index.ts +8 -0
  100. package/src/contexts/DashboardViewIdContext/index.ts +5 -0
  101. package/src/hooks/__tests__/useActivititesRequest.specs.tsx +106 -0
  102. package/src/hooks/__tests__/useEntityByTypeRequest.specs.tsx +280 -0
  103. package/src/hooks/__tests__/useFacetRequest.specs.tsx +437 -0
  104. package/src/hooks/__tests__/useFilteredEntitiesRequest.specs.tsx +103 -0
  105. package/src/hooks/__tests__/useSavedSearchesRequest.specs.tsx +201 -0
  106. package/src/hooks/__tests__/useStatsRequest.specs.tsx +212 -0
  107. package/src/hooks/__tests__/useWorkflowTasksRequest.specs.tsx +388 -0
  108. package/src/hooks/useActivitiesRequest.ts +50 -0
  109. package/src/hooks/useEntityByTypeRequest.ts +67 -0
  110. package/src/hooks/useFacetRequest.ts +117 -0
  111. package/src/hooks/useFilteredEntitiesRequest.ts +57 -0
  112. package/src/hooks/useSavedSearchesRequest.ts +82 -0
  113. package/src/hooks/useStatsRequest.ts +47 -0
  114. package/src/hooks/useWorkflowTasksRequest.ts +66 -0
  115. package/src/index.ts +25 -0
  116. package/src/perspective/DashboardPerspectiveView.tsx +132 -0
  117. package/src/perspective/__tests__/DashboardPerspectiveView.specs.tsx +276 -0
  118. package/src/perspective/__tests__/data/metadata.data.ts +33 -0
  119. package/src/perspective/__tests__/data/store.data.ts +15 -0
  120. package/src/perspective/__tests__/helpers.specs.ts +33 -0
  121. package/src/perspective/helpers.ts +19 -0
  122. package/src/perspective/index.tsx +65 -0
  123. package/src/perspective/styles.ts +16 -0
  124. package/src/services/__tests__/facets.specs.ts +42 -0
  125. package/src/services/__tests__/filters.specs.ts +60 -0
  126. package/src/services/__tests__/period.test.ts +33 -0
  127. package/src/services/__tests__/stats.test.ts +319 -0
  128. package/src/services/entityTypes.ts +66 -0
  129. package/src/services/facets.ts +178 -0
  130. package/src/services/filters.ts +87 -0
  131. package/src/services/period.ts +33 -0
  132. package/src/services/savedSearches.ts +20 -0
  133. package/src/services/stats.ts +191 -0
  134. package/src/services/workflowTasks.ts +116 -0
  135. package/src/types/ActivitiesViewFacetConfig.ts +5 -0
  136. package/src/types/CustomActionViewFacetConfig.ts +5 -0
  137. package/src/types/DashboardPerspectiveConfig.ts +18 -0
  138. package/src/types/DashboardSavedState.ts +7 -0
  139. package/src/types/EntityByTypeViewFacetConfig.ts +7 -0
  140. package/src/types/EntityData.ts +4 -0
  141. package/src/types/FilteredEntitiesFacetConfig.ts +6 -0
  142. package/src/types/FilteredSavedSearchesFacetConfig.ts +6 -0
  143. package/src/types/PeriodStep.ts +4 -0
  144. package/src/types/SavedSearchData.ts +6 -0
  145. package/src/types/SearchOptions.ts +10 -0
  146. package/src/types/StatsData.ts +14 -0
  147. package/src/types/WorkflowTasks.ts +26 -0
  148. package/src/types/index.ts +14 -0
  149. package/src/views/ViewsFactory.tsx +79 -0
  150. package/src/views/__tests__/ViewsFactory.specs.tsx +70 -0
  151. package/src/views/chartBased/DashboardFacet.tsx +71 -0
  152. package/src/views/chartBased/EntitiesByTypeViewFacet.tsx +60 -0
  153. package/src/views/chartBased/ProfileStatsFacet.tsx +54 -0
  154. package/src/views/chartBased/__tests__/DashboardFacet.specs.tsx +358 -0
  155. package/src/views/chartBased/__tests__/EntitiesByTypeViewFacet.specs.tsx +101 -0
  156. package/src/views/chartBased/__tests__/ProfileStatsFacet.specs.tsx +106 -0
  157. package/src/views/chartBased/styles.ts +13 -0
  158. package/src/views/custom/CustomActionViewFacet.tsx +36 -0
  159. package/src/views/custom/NotificationInboxFacet.tsx +86 -0
  160. package/src/views/custom/__tests__/CustomActionViewFacet.specs.tsx +35 -0
  161. package/src/views/custom/__tests__/NotificationInboxFacet.specs.tsx +144 -0
  162. package/src/views/custom/styles.ts +31 -0
  163. package/src/views/tableBased/ActivitiesViewFacet.tsx +79 -0
  164. package/src/views/tableBased/FilteredEntitiesViewFacet.tsx +67 -0
  165. package/src/views/tableBased/FilteredSavedSearchesFacet.tsx +85 -0
  166. package/src/views/tableBased/__tests__/ActivitiesViewFacet.specs.tsx +113 -0
  167. package/src/views/tableBased/__tests__/FIlteredEntitiesViewFacet.specs.tsx +90 -0
  168. package/src/views/tableBased/__tests__/FilteredSavedSearchesFacet.specs.tsx +133 -0
  169. package/src/views/tableBased/helpers.ts +8 -0
  170. package/src/views/tableBased/styles.ts +7 -0
  171. package/stories/Dashboards.stories.js +118 -0
  172. package/stories/utils/dashboardPerspectiveConfig.js +78 -0
  173. package/stories/utils/dashboardsViewConfig.js +17 -0
  174. package/stories/utils/mdmStore.js +73 -0
  175. package/stories/utils/responses.js +10 -0
  176. package/tsconfig.json +14 -0
  177. package/webpack.config.js +10 -0
  178. package/bundle.js +0 -2
  179. package/bundle.js.LICENSE.txt +0 -22
  180. package/types/components/DashboardConfigItem/styles.d.ts +0 -1
  181. package/types/components/DashboardLayout/styles.d.ts +0 -1
  182. package/types/components/DashboardLayoutItem/styles.d.ts +0 -1
  183. package/types/components/DashboardLayoutPanel/styles.d.ts +0 -1
  184. package/types/components/DashboardLinearLoader/styles.d.ts +0 -1
  185. package/types/components/DashboardPerspectiveHeader/styles.d.ts +0 -2
  186. package/types/components/DashboardPopupMenu/styles.d.ts +0 -1
  187. package/types/components/EntityTable/cell-renderers/styles.d.ts +0 -1
  188. package/types/components/LayoutItemContent/styles.d.ts +0 -1
  189. package/types/components/LayoutItemHeader/styles.d.ts +0 -1
  190. package/types/components/LayoutItemView/styles.d.ts +0 -1
  191. package/types/components/StatsChart/customized/styles.d.ts +0 -1
  192. package/types/components/WorkflowTaskItem/styles.d.ts +0 -1
  193. package/types/perspective/styles.d.ts +0 -1
  194. package/types/views/chartBased/styles.d.ts +0 -1
  195. package/types/views/custom/styles.d.ts +0 -1
  196. package/types/views/tableBased/styles.d.ts +0 -1
  197. /package/{types → public/types}/HOCs/withPagination.d.ts +0 -0
  198. /package/{types → public/types}/components/DashboardConfigItem/DashboardConfigItem.d.ts +0 -0
  199. /package/{types → public/types}/components/DashboardError/DashboardError.d.ts +0 -0
  200. /package/{types → public/types}/components/DashboardLayout/DashboardLayout.d.ts +0 -0
  201. /package/{types → public/types}/components/DashboardLayoutItem/DashboardLayoutItem.d.ts +0 -0
  202. /package/{types → public/types}/components/DashboardLayoutPanel/DashboardLayoutPanel.d.ts +0 -0
  203. /package/{types → public/types}/components/DashboardLinearLoader/DashboardLinearLoader.d.ts +0 -0
  204. /package/{types → public/types}/components/DashboardNoData/DashboardNoData.d.ts +0 -0
  205. /package/{types → public/types}/components/DashboardPerspectiveHeader/DashboardPerspectiveHeader.d.ts +0 -0
  206. /package/{types → public/types}/components/EntityTable/EntityTable.d.ts +0 -0
  207. /package/{types → public/types}/components/EntityTable/cell-renderers/EntityLabelRenderer.d.ts +0 -0
  208. /package/{types → public/types}/components/EntityTable/cell-renderers/HeadCellRenderer.d.ts +0 -0
  209. /package/{types → public/types}/components/LayoutItemContent/LayoutItemContent.d.ts +0 -0
  210. /package/{types → public/types}/components/LayoutItemHeader/LayoutItemHeader.d.ts +0 -0
  211. /package/{types → public/types}/components/LayoutItemView/LayoutItemView.d.ts +0 -0
  212. /package/{types → public/types}/components/StatsChart/StatsChart.d.ts +0 -0
  213. /package/{types → public/types}/components/StatsChart/customized/CustomAxisTick.d.ts +0 -0
  214. /package/{types → public/types}/components/StatsChart/customized/CustomLegend.d.ts +0 -0
  215. /package/{types → public/types}/components/StatsChart/customized/CustomTooltip.d.ts +0 -0
  216. /package/{types → public/types}/components/StatsChart/getStatsChartSettings.d.ts +0 -0
  217. /package/{types → public/types}/components/WorkflowTaskItem/WorkflowTaskItem.d.ts +0 -0
  218. /package/{types → public/types}/components/WorkflowTaskItem/WorkflowTaskObject.d.ts +0 -0
  219. /package/{types → public/types}/components/WorkflowTasksList/WorkflowTasksList.d.ts +0 -0
  220. /package/{types → public/types}/components/index.d.ts +0 -0
  221. /package/{types → public/types}/contexts/DashboardViewIdContext/index.d.ts +0 -0
  222. /package/{types → public/types}/hooks/useActivitiesRequest.d.ts +0 -0
  223. /package/{types → public/types}/hooks/useEntityByTypeRequest.d.ts +0 -0
  224. /package/{types → public/types}/hooks/useFacetRequest.d.ts +0 -0
  225. /package/{types → public/types}/hooks/useFilteredEntitiesRequest.d.ts +0 -0
  226. /package/{types → public/types}/hooks/useSavedSearchesRequest.d.ts +0 -0
  227. /package/{types → public/types}/hooks/useStatsRequest.d.ts +0 -0
  228. /package/{types → public/types}/hooks/useWorkflowTasksRequest.d.ts +0 -0
  229. /package/{types → public/types}/index.d.ts +0 -0
  230. /package/{types → public/types}/perspective/DashboardPerspectiveView.d.ts +0 -0
  231. /package/{types → public/types}/perspective/helpers.d.ts +0 -0
  232. /package/{types → public/types}/perspective/index.d.ts +0 -0
  233. /package/{types → public/types}/services/entityTypes.d.ts +0 -0
  234. /package/{types → public/types}/services/facets.d.ts +0 -0
  235. /package/{types → public/types}/services/filters.d.ts +0 -0
  236. /package/{types → public/types}/services/period.d.ts +0 -0
  237. /package/{types → public/types}/services/savedSearches.d.ts +0 -0
  238. /package/{types → public/types}/services/stats.d.ts +0 -0
  239. /package/{types → public/types}/services/workflowTasks.d.ts +0 -0
  240. /package/{types → public/types}/types/ActivitiesViewFacetConfig.d.ts +0 -0
  241. /package/{types → public/types}/types/CustomActionViewFacetConfig.d.ts +0 -0
  242. /package/{types → public/types}/types/DashboardPerspectiveConfig.d.ts +0 -0
  243. /package/{types → public/types}/types/DashboardSavedState.d.ts +0 -0
  244. /package/{types → public/types}/types/EntityByTypeViewFacetConfig.d.ts +0 -0
  245. /package/{types → public/types}/types/EntityData.d.ts +0 -0
  246. /package/{types → public/types}/types/FilteredEntitiesFacetConfig.d.ts +0 -0
  247. /package/{types → public/types}/types/FilteredSavedSearchesFacetConfig.d.ts +0 -0
  248. /package/{types → public/types}/types/PeriodStep.d.ts +0 -0
  249. /package/{types → public/types}/types/SavedSearchData.d.ts +0 -0
  250. /package/{types → public/types}/types/SearchOptions.d.ts +0 -0
  251. /package/{types → public/types}/types/StatsData.d.ts +0 -0
  252. /package/{types → public/types}/types/WorkflowTasks.d.ts +0 -0
  253. /package/{types → public/types}/types/index.d.ts +0 -0
  254. /package/{types → public/types}/views/ViewsFactory.d.ts +0 -0
  255. /package/{types → public/types}/views/chartBased/DashboardFacet.d.ts +0 -0
  256. /package/{types → public/types}/views/chartBased/EntitiesByTypeViewFacet.d.ts +0 -0
  257. /package/{types → public/types}/views/chartBased/ProfileStatsFacet.d.ts +0 -0
  258. /package/{types → public/types}/views/custom/CustomActionViewFacet.d.ts +0 -0
  259. /package/{types → public/types}/views/custom/NotificationInboxFacet.d.ts +0 -0
  260. /package/{types → public/types}/views/tableBased/ActivitiesViewFacet.d.ts +0 -0
  261. /package/{types → public/types}/views/tableBased/FilteredEntitiesViewFacet.d.ts +0 -0
  262. /package/{types → public/types}/views/tableBased/FilteredSavedSearchesFacet.d.ts +0 -0
  263. /package/{types → public/types}/views/tableBased/helpers.d.ts +0 -0
@@ -0,0 +1,82 @@
1
+ import {useCallback, useEffect, useState} from 'react';
2
+ import {RequestStates} from '@reltio/components';
3
+ import {assocPath} from 'ramda';
4
+ import {
5
+ getSavedSearches,
6
+ getTotalsForQuery,
7
+ promiseAllSettled,
8
+ replacePlaceholdersInQuery,
9
+ SavedSearchesOptions,
10
+ SavedSearchesResponse
11
+ } from '@reltio/mdm-sdk';
12
+ import {SavedSearchData} from '../types/SavedSearchData';
13
+
14
+ type Props = {
15
+ options: SavedSearchesOptions;
16
+ offset: number;
17
+ max: number;
18
+ };
19
+
20
+ export const useSavedSearchesRequest = ({options, offset, max}: Props) => {
21
+ const [data, setData] = useState<SavedSearchData[]>([]);
22
+ const [total, setTotal] = useState<number>(0);
23
+ const [requestState, setRequestState] = useState<RequestStates>(RequestStates.INIT);
24
+ const onError = (error) => {
25
+ console.error(error); // eslint-disable-line
26
+ setRequestState(RequestStates.ERROR);
27
+ setData([]);
28
+ };
29
+ const loadData = useCallback(() => {
30
+ setRequestState(RequestStates.LOADING);
31
+ const onRequestFinished = (data) => {
32
+ setData(data.result || []);
33
+ setTotal(data.total);
34
+ setRequestState(RequestStates.LOADED);
35
+ };
36
+ const {countResults, ...restOptions} = (options || {}) as Required<SavedSearchesOptions>;
37
+ const getData = async () => {
38
+ const {result = [], total}: SavedSearchesResponse = await getSavedSearches({
39
+ offset,
40
+ max,
41
+ ...restOptions
42
+ });
43
+ if (countResults) {
44
+ const totalRequests: Array<Promise<{total: number}>> = result.map((search) =>
45
+ getTotalsForQuery(replacePlaceholdersInQuery(search.query))
46
+ );
47
+ const totalResults = await promiseAllSettled(totalRequests);
48
+ const searchesWithCount: SavedSearchData[] = totalResults.reduce(
49
+ (searchesWithTotal, {status, value, reason}, searchIndex) => {
50
+ switch (status) {
51
+ case 'fulfilled':
52
+ return assocPath([searchIndex, 'count'], value.total, searchesWithTotal);
53
+ case 'rejected':
54
+ console.error(reason);
55
+ break;
56
+ }
57
+ return searchesWithTotal;
58
+ },
59
+ result
60
+ );
61
+ onRequestFinished({result: searchesWithCount, total});
62
+ } else {
63
+ onRequestFinished({result, total});
64
+ }
65
+ };
66
+ getData().catch(onError);
67
+ }, [options, max, offset]);
68
+
69
+ const refreshAction = () => {
70
+ try {
71
+ loadData();
72
+ } catch (e) {
73
+ onError(e);
74
+ }
75
+ };
76
+
77
+ useEffect(() => {
78
+ refreshAction();
79
+ }, [loadData]);
80
+
81
+ return {state: requestState, data, reload: refreshAction, total};
82
+ };
@@ -0,0 +1,47 @@
1
+ import {useCallback, useEffect, useState} from 'react';
2
+ import {andThen, otherwise, pipe} from 'ramda';
3
+ import {requestStats} from '../services/stats';
4
+ import {getStepForPeriod} from '../services/period';
5
+ import {StatsData} from '../types/StatsData';
6
+ import {DatePeriod} from '@reltio/mdm-sdk';
7
+ import {useSafePromise, RequestStates} from '@reltio/components';
8
+
9
+ export const useStatsRequest = (period: DatePeriod) => {
10
+ const [data, setData] = useState<StatsData[]>([]);
11
+ const [step, setStep] = useState(getStepForPeriod(period));
12
+ const [requestState, setRequestState] = useState<RequestStates>(RequestStates.INIT);
13
+ const safePromise = useSafePromise();
14
+
15
+ const onError = (error) => {
16
+ console.error(error); // eslint-disable-line
17
+ setRequestState(RequestStates.ERROR);
18
+ setData([]);
19
+ };
20
+
21
+ const loadData = useCallback(() => {
22
+ setRequestState(RequestStates.LOADING);
23
+ setStep(getStepForPeriod(period));
24
+ setData([]);
25
+ const onRequestFinished = (data: StatsData[]) => {
26
+ setRequestState(RequestStates.LOADED);
27
+ setData(data);
28
+ };
29
+
30
+ const getData = pipe(requestStats, safePromise, andThen(onRequestFinished), otherwise(onError));
31
+ getData(period);
32
+ }, [period.toString()]); // eslint-disable-line
33
+
34
+ const refreshAction = () => {
35
+ try {
36
+ loadData();
37
+ } catch (e) {
38
+ onError(e);
39
+ }
40
+ };
41
+
42
+ useEffect(() => {
43
+ refreshAction();
44
+ }, [loadData]);
45
+
46
+ return {state: requestState, data, step, reload: refreshAction};
47
+ };
@@ -0,0 +1,66 @@
1
+ import {useCallback, useEffect, useMemo, useState} from 'react';
2
+ import {useSelector} from 'react-redux';
3
+ import {andThen, otherwise, pipe, pick} from 'ramda';
4
+ import mdmModule from '@reltio/mdm-module';
5
+ import {useSafePromise, RequestStates} from '@reltio/components';
6
+ import {EnrichedWorkflowTaskData, WorkflowTasksCategories} from '../types/WorkflowTasks';
7
+
8
+ import {requestWorkflowTasks} from '../services/workflowTasks';
9
+
10
+ type Options = {
11
+ tasksCategory: WorkflowTasksCategories;
12
+ max?: number;
13
+ offset?: number;
14
+ };
15
+
16
+ export const useWorkflowTasksRequest = (options: Options) => {
17
+ const {tasksCategory} = options;
18
+ const requestParams = useMemo(() => pick(['max', 'offset'], options), [options]);
19
+ const [data, setData] = useState<EnrichedWorkflowTaskData[]>([]);
20
+ const [requestState, setRequestState] = useState<RequestStates>(RequestStates.INIT);
21
+ const [total, setTotal] = useState<number>();
22
+ const workflowPath = useSelector(mdmModule.selectors.getWorkflowPath);
23
+ const environment = useSelector(mdmModule.selectors.getWorkflowEnvironmentUrl);
24
+ const tenant = useSelector(mdmModule.selectors.getTenant);
25
+ const userName = useSelector(mdmModule.selectors.getUserName);
26
+
27
+ const assignee = tasksCategory === WorkflowTasksCategories.MY ? userName : undefined;
28
+ const safePromise = useSafePromise();
29
+
30
+ const onError = (error) => {
31
+ console.error(error); // eslint-disable-line
32
+ setRequestState(RequestStates.ERROR);
33
+ setData([]);
34
+ };
35
+
36
+ const loadData = useCallback(() => {
37
+ setRequestState(RequestStates.LOADING);
38
+ const onRequestFinished = ({data, total}: {data: EnrichedWorkflowTaskData[]; total?: number}) => {
39
+ setRequestState(RequestStates.LOADED);
40
+ setData(data);
41
+ setTotal(total);
42
+ };
43
+
44
+ const getData = pipe(
45
+ requestWorkflowTasks(tasksCategory),
46
+ safePromise,
47
+ andThen(onRequestFinished),
48
+ otherwise(onError)
49
+ );
50
+ getData({workflowPath, environment, tenant, assignee, ...requestParams});
51
+ }, [workflowPath, environment, tenant, tasksCategory, requestParams]); // eslint-disable-line
52
+
53
+ const refreshAction = () => {
54
+ try {
55
+ loadData();
56
+ } catch (e) {
57
+ onError(e);
58
+ }
59
+ };
60
+
61
+ useEffect(() => {
62
+ refreshAction();
63
+ }, [loadData]);
64
+
65
+ return {state: requestState, data, reload: refreshAction, total};
66
+ };
package/src/index.ts ADDED
@@ -0,0 +1,25 @@
1
+ import {DashboardPerspective} from './perspective';
2
+ import {
3
+ DashboardLayoutItemView,
4
+ DashboardLayoutItemHeader,
5
+ DashboardLayoutItemContent,
6
+ DashboardLinearLoader,
7
+ DashboardNoData,
8
+ DashboardError,
9
+ StatsChart
10
+ } from './components';
11
+ import ViewsFactory from './views/ViewsFactory';
12
+ import {useFacetRequest} from './hooks/useFacetRequest';
13
+
14
+ export {
15
+ DashboardPerspective,
16
+ DashboardLayoutItemView,
17
+ DashboardLayoutItemHeader,
18
+ DashboardLayoutItemContent,
19
+ DashboardLinearLoader,
20
+ DashboardNoData,
21
+ DashboardError,
22
+ ViewsFactory,
23
+ StatsChart,
24
+ useFacetRequest
25
+ };
@@ -0,0 +1,132 @@
1
+ import React, {memo, useCallback, useEffect, useMemo, useRef, useState} from 'react';
2
+ import {indexBy, prop, pipe, pick, map} from 'ramda';
3
+ import hash from 'object-hash';
4
+ import i18n from 'ui-i18n';
5
+
6
+ import {
7
+ DashboardPerspectiveConfig,
8
+ removeUnsupportedLayoutItems,
9
+ setMinHeightForDashboardWidgets,
10
+ ReltioGridLayoutItem,
11
+ debounce
12
+ } from '@reltio/mdm-sdk';
13
+ import {useConfigPermissions, useSavedState, useReloadAllFacets, useLayoutResetter} from '@reltio/components';
14
+ import {createReltioLayout, getViewStatus} from './helpers';
15
+ import DashboardLayout from '../components/DashboardLayout/DashboardLayout';
16
+ import {DashboardSavedState} from '../types/DashboardSavedState';
17
+ import {DashboardPerspectiveHeader} from '../components/DashboardPerspectiveHeader/DashboardPerspectiveHeader';
18
+
19
+ import {useStyles} from './styles';
20
+
21
+ type DashboardPerspectiveView = {
22
+ config: DashboardPerspectiveConfig;
23
+ saveState: (state: DashboardSavedState) => void;
24
+ getSavedState: () => Promise<DashboardSavedState>;
25
+ };
26
+
27
+ const SAVE_STATE_DEBOUNCE_DELAY = 100;
28
+
29
+ const DashboardPerspectiveView = ({config: dashboardConfig, saveState, getSavedState}: DashboardPerspectiveView) => {
30
+ const styles = useStyles();
31
+
32
+ const refreshAll = useReloadAllFacets();
33
+ const {canRead} = useConfigPermissions();
34
+ const {isLoaded, savedState} = useSavedState<DashboardSavedState>(getSavedState);
35
+ const debouncedSaveState = useCallback(debounce(saveState, SAVE_STATE_DEBOUNCE_DELAY), [saveState]) as (
36
+ state: DashboardSavedState
37
+ ) => void;
38
+
39
+ const config: DashboardPerspectiveConfig = useMemo(() => {
40
+ const validatedViews = dashboardConfig.views.filter((view) => canRead(view) && view.id);
41
+ const validatedLayout = removeUnsupportedLayoutItems(dashboardConfig.layout, validatedViews);
42
+ return {...dashboardConfig, views: validatedViews, layout: validatedLayout};
43
+ }, [dashboardConfig, canRead]);
44
+
45
+ const viewsHashMap = useMemo(() => pipe(indexBy(prop('id')), map(hash))(config.views), [config.views]);
46
+ const configHash = useMemo(() => pipe(pick(['views', 'layout', 'id']), hash)(config), [config]);
47
+ const dashboardViews = useMemo(
48
+ () =>
49
+ config.views.map((view) => ({
50
+ config: view,
51
+ status: getViewStatus(viewsHashMap[view.id], savedState.viewsHashMap?.[view.id])
52
+ })),
53
+ [config.views, viewsHashMap, savedState.viewsHashMap]
54
+ );
55
+
56
+ const [layout, setLayout] = useState<ReltioGridLayoutItem[]>();
57
+ const [openConfigPanel, setOpenConfigPanel] = useState<boolean>(false);
58
+
59
+ useEffect(() => {
60
+ if (isLoaded) {
61
+ const isConfigChanged = configHash !== savedState.configHash;
62
+ const newLayout = isConfigChanged ? config.layout : savedState.layout;
63
+ const resizedLayout = setMinHeightForDashboardWidgets(newLayout, config.views);
64
+ setLayout(resizedLayout);
65
+ }
66
+ }, [isLoaded]); // eslint-disable-line
67
+
68
+ useEffect(() => {
69
+ if (isLoaded) debouncedSaveState({layout, viewsHashMap, configHash});
70
+ }, [layout]); // eslint-disable-line
71
+
72
+ const handleLayoutChange = useCallback((layout: ReltioGridLayoutItem[]) => {
73
+ setLayout(layout);
74
+ }, []);
75
+
76
+ const handleRemove = useCallback(
77
+ (id: string) => setLayout((layout) => layout.filter((layout) => layout.id !== id)),
78
+ []
79
+ );
80
+ const handleAdd = useCallback((id: string) => setLayout((layout) => [...layout, createReltioLayout(id)]), []);
81
+
82
+ const handleCloseConfigPanel = useCallback(() => setOpenConfigPanel(false), []);
83
+
84
+ const tempLayout = useRef<ReltioGridLayoutItem[]>();
85
+ const onLayoutReset = useCallback(() => {
86
+ tempLayout.current = layout;
87
+ setLayout(setMinHeightForDashboardWidgets(config.layout, config.views));
88
+ }, [config, layout]);
89
+ const onResetUndo = useCallback(() => {
90
+ setLayout(tempLayout.current);
91
+ }, []);
92
+ const {SnackbarRenderer, resetLayout} = useLayoutResetter({onLayoutReset, onResetUndo});
93
+ const menuItems = useMemo(
94
+ () => [
95
+ {
96
+ primary: i18n.text('Refresh all'),
97
+ secondary: i18n.text('Update all facets'),
98
+ onClick: refreshAll
99
+ },
100
+ {
101
+ primary: i18n.text('Reset layout'),
102
+ secondary: i18n.text('Restore the default layout without saving any changes'),
103
+ onClick: resetLayout
104
+ }
105
+ ],
106
+ [refreshAll, resetLayout]
107
+ );
108
+
109
+ return (
110
+ <div className={styles.perspectiveView}>
111
+ <DashboardPerspectiveHeader
112
+ onToggleConfig={() => setOpenConfigPanel(!openConfigPanel)}
113
+ title={i18n.text('Profile stats')}
114
+ menuItems={menuItems}
115
+ />
116
+ {isLoaded && (
117
+ <DashboardLayout
118
+ layout={layout}
119
+ onLayoutChanged={handleLayoutChange}
120
+ views={dashboardViews}
121
+ openConfigPanel={openConfigPanel}
122
+ onCloseConfigPanel={handleCloseConfigPanel}
123
+ onAdd={handleAdd}
124
+ onRemove={handleRemove}
125
+ />
126
+ )}
127
+ <SnackbarRenderer />
128
+ </div>
129
+ );
130
+ };
131
+
132
+ export default memo(DashboardPerspectiveView);
@@ -0,0 +1,276 @@
1
+ import React, {ReactNode} from 'react';
2
+ import {indexBy, prop, pipe, pick, map} from 'ramda';
3
+ import {render, screen, act, within} from '@testing-library/react';
4
+ import userEvent from '@testing-library/user-event';
5
+ import hash from 'object-hash';
6
+ import {Provider} from 'react-redux';
7
+ import {getFacets} from '@reltio/mdm-sdk';
8
+ import {mockResizeObserver} from 'jsdom-testing-mocks';
9
+ import DashboardPerspectiveView from '../DashboardPerspectiveView';
10
+ import {createInitialState} from './data/store.data';
11
+ import {createTestStore} from '../../../../../__mocks__/store-utils';
12
+ import {ReloadFacetProvider} from '@reltio/components';
13
+
14
+ jest.mock('@reltio/mdm-sdk', () => ({
15
+ ...jest.requireActual<Record<string, unknown>>('@reltio/mdm-sdk'),
16
+ getFacets: jest.fn(),
17
+ debounce: (x) => x
18
+ }));
19
+
20
+ describe('DashboardPerspectiveView tests', () => {
21
+ const views = [
22
+ {
23
+ component: 'DashboardFacet',
24
+ attributeUri: 'configuration/entityTypes/HCP/attributes/CountryCode',
25
+ chartType: 'bar',
26
+ id: 'MyDashboard',
27
+ title: 'Country codes 1'
28
+ },
29
+ {
30
+ component: 'DashboardFacet',
31
+ attributeUri: 'configuration/entityTypes/HCP/attributes/CountryCode',
32
+ chartType: 'pie',
33
+ id: 'MyDashboard2',
34
+ title: 'Country codes 2'
35
+ },
36
+ {
37
+ component: 'DashboardFacet',
38
+ attributeUri: 'configuration/entityTypes/HCP/attributes/TypeCode',
39
+ chartType: 'bar',
40
+ id: 'ActiveHCPsByCustomer',
41
+ filters: [{attribute: 'attributes.CustomerStatusCode', type: 'not equals', value: 'ACTI'}],
42
+ title: 'Active HCPs'
43
+ }
44
+ ];
45
+ const layout = [
46
+ {minHeight: 10, x: 0, width: 2, y: 0, id: 'ActiveHCPsByCustomer', height: 10},
47
+ {minHeight: 10, x: 2, width: 2, y: 0, id: 'MyDashboard2', height: 10}
48
+ ];
49
+ const config = {id: 'com.reltio.plugins.newDashboard.NewDashboardView', layout, views};
50
+
51
+ const getSavedStateSpy = jest.fn();
52
+ const saveStateSpy = jest.fn();
53
+ const defaultProps = {config, getSavedState: getSavedStateSpy, saveState: saveStateSpy};
54
+ const resizeObserver = mockResizeObserver();
55
+
56
+ const configHash = pipe(pick(['views', 'layout', 'id']), hash)(config);
57
+ const viewsHashMap = map(hash, indexBy(prop('id'), views));
58
+
59
+ const setUp = async (props = {}, initialState = createInitialState()) => {
60
+ const user = userEvent.setup();
61
+ const store = createTestStore(initialState);
62
+ const Providers = ({children}: {children: ReactNode}) => (
63
+ <Provider store={store}>
64
+ <ReloadFacetProvider>{children}</ReloadFacetProvider>
65
+ </Provider>
66
+ );
67
+ const renderer = render(<DashboardPerspectiveView {...defaultProps} {...props} />, {wrapper: Providers});
68
+ const grid = await screen.findByTestId('reltio-dashboard-grid');
69
+ resizeObserver.mockElementSize(grid, {contentBoxSize: {inlineSize: 400, blockSize: 600}});
70
+ act(() => {
71
+ resizeObserver.resize();
72
+ });
73
+ const layoutItems = await screen.findAllByTestId('reltio-dashboard-layout-item');
74
+ return {user, layoutItems, ...renderer};
75
+ };
76
+
77
+ beforeEach(() => {
78
+ getSavedStateSpy.mockResolvedValue(null);
79
+ (getFacets as jest.Mock).mockResolvedValue(null);
80
+ });
81
+
82
+ afterEach(() => {
83
+ jest.clearAllMocks();
84
+ });
85
+
86
+ it('should render dashboard layout correctly', async () => {
87
+ const {user, layoutItems} = await setUp();
88
+
89
+ expect(screen.getByText('Profile stats')).toBeInTheDocument();
90
+ layoutItems.forEach((item, index) => {
91
+ const viewId = config.layout[index].id;
92
+ const title = views.find((view) => view.id === viewId)?.title as string;
93
+ expect(within(item).getByText(title)).toBeInTheDocument();
94
+ });
95
+
96
+ await user.click(screen.getByRole('button', {name: 'Add / remove charts'}));
97
+
98
+ const configItems = screen.getAllByTestId('reltio-dashboard-config-item');
99
+ configItems.forEach((item, index) => {
100
+ expect(within(item).getByText(views[index].title)).toBeInTheDocument();
101
+ expect(within(item).getByText('New')).toBeInTheDocument();
102
+ });
103
+ });
104
+
105
+ it('should apply layout on change', async () => {
106
+ getSavedStateSpy.mockResolvedValueOnce(null);
107
+ const {user, layoutItems} = await setUp();
108
+ expect(layoutItems).toHaveLength(2);
109
+ const menuButton = within(layoutItems[0]).getByRole('button', {name: ''});
110
+ await user.click(menuButton);
111
+ await user.click(screen.getByRole('menuitem', {name: 'Remove'}));
112
+ const newLayoutItem = await screen.findByTestId('reltio-dashboard-layout-item');
113
+ expect(within(newLayoutItem).getByText('Country codes 2'));
114
+ });
115
+
116
+ it('should filter not readable views, views without id and change layout', async () => {
117
+ const config = {
118
+ id: 'com.reltio.plugins.newDashboard.NewDashboardView',
119
+ layout: [
120
+ {minHeight: 10, x: 0, width: 2, y: 0, id: 'MyDashboard', height: 10},
121
+ {minHeight: 10, x: 2, width: 2, y: 0, id: 'MyDashboard2', height: 10}
122
+ ],
123
+ views: [
124
+ {
125
+ component: 'DashboardFacet',
126
+ attributeUri: 'configuration/entityTypes/HCP/attributes/CountryCode',
127
+ chartType: 'bar',
128
+ id: 'MyDashboard',
129
+ title: 'Country codes',
130
+ canRead: {
131
+ roles: ['UI_ADMIN']
132
+ }
133
+ },
134
+ {
135
+ component: 'DashboardFacet',
136
+ attributeUri: 'configuration/entityTypes/HCP/attributes/CountryCode',
137
+ chartType: 'pie',
138
+ title: 'No id'
139
+ },
140
+ {
141
+ component: 'DashboardFacet',
142
+ attributeUri: 'configuration/entityTypes/HCP/attributes/CountryCode',
143
+ chartType: 'pie',
144
+ id: 'MyDashboard2',
145
+ title: 'Country codes'
146
+ }
147
+ ]
148
+ };
149
+ const {user, layoutItems} = await setUp({config});
150
+
151
+ expect(layoutItems).toHaveLength(1);
152
+ expect(within(layoutItems[0]).getByText('Country codes')).toBeInTheDocument();
153
+
154
+ await user.click(screen.getByRole('button', {name: 'Add / remove charts'}));
155
+
156
+ const configItem = screen.getByTestId('reltio-dashboard-config-item');
157
+ expect(within(configItem).getByText('Country codes')).toBeInTheDocument();
158
+ });
159
+
160
+ it('should render Reset button and reset layout correct', async () => {
161
+ const savedState = {
162
+ layout: [{minHeight: 5, x: 0, width: 2, y: 0, id: 'MyDashboard', height: 5}],
163
+ configHash: '90794365b836fedf4384383c374eb0d7725e11be'
164
+ };
165
+ getSavedStateSpy.mockResolvedValueOnce(savedState);
166
+ const {user} = await setUp();
167
+
168
+ await screen.findByText('Country codes 1');
169
+ expect(screen.queryByText('Country codes 2')).not.toBeInTheDocument();
170
+
171
+ await user.click(screen.getByTestId('reltio-dashboard-header-menu'));
172
+ await user.click(
173
+ screen.getByRole('menuitem', {name: 'Reset layout Restore the default layout without saving any changes'})
174
+ );
175
+ await screen.findByText('Country codes 2');
176
+ expect(screen.queryByText('Country codes 1')).not.toBeInTheDocument();
177
+
178
+ await user.click(screen.getByRole('button', {name: 'Undo'}));
179
+ await screen.findByText('Country codes 1');
180
+ expect(screen.queryByText('Country codes 2')).not.toBeInTheDocument();
181
+ });
182
+
183
+ it('should reload facets on click Refresh all', async () => {
184
+ const {user} = await setUp();
185
+ (getFacets as jest.Mock).mockClear();
186
+ await user.click(screen.getByTestId('reltio-dashboard-header-menu'));
187
+ await user.click(screen.getByRole('menuitem', {name: 'Refresh all Update all facets'}));
188
+ expect(getFacets).toBeCalledTimes(layout.length);
189
+ });
190
+
191
+ describe('saved state scenario', () => {
192
+ it('should request saved state on mount', async () => {
193
+ await setUp();
194
+ expect(getSavedStateSpy).toBeCalled();
195
+ });
196
+
197
+ it('should apply saved layout if config has same hash', async () => {
198
+ const newLayout = [{minHeight: 10, x: 0, width: 1, y: 0, id: 'ActiveHCPsByCustomer', height: 10}];
199
+ getSavedStateSpy.mockResolvedValueOnce({layout: newLayout, configHash});
200
+ const {layoutItems} = await setUp();
201
+
202
+ expect(layoutItems).toHaveLength(1);
203
+ expect(within(layoutItems[0]).getByText('Active HCPs')).toBeInTheDocument();
204
+ });
205
+
206
+ it('should apply config layout if config has new hash', async () => {
207
+ const newLayout = [{minHeight: 10, x: 0, width: 1, y: 0, id: 'ActiveHCPsByCustomer', height: 10}];
208
+ getSavedStateSpy.mockResolvedValueOnce({layout: newLayout, configHash: 'newHash'});
209
+ const {layoutItems} = await setUp();
210
+ expect(layoutItems).toHaveLength(layout.length);
211
+ });
212
+
213
+ it('should save layout on mount and on change', async () => {
214
+ const staticLayout = layout.map((item) => ({...item, isStatic: false}));
215
+ const savedState = {layout: staticLayout, configHash, viewsHashMap};
216
+ getSavedStateSpy.mockResolvedValueOnce(savedState);
217
+ const {user, layoutItems} = await setUp();
218
+ expect(saveStateSpy).toBeCalledWith(savedState);
219
+ expect(layoutItems).toHaveLength(2);
220
+ const menuButton = within(layoutItems[0]).getByRole('button', {name: ''});
221
+ await user.click(menuButton);
222
+ await user.click(screen.getByRole('menuitem', {name: 'Remove'}));
223
+ const newLayoutItems = await screen.findAllByTestId('reltio-dashboard-layout-item');
224
+ expect(newLayoutItems).toHaveLength(1);
225
+ expect(saveStateSpy).toBeCalledWith({layout: [staticLayout[1]], configHash, viewsHashMap});
226
+ });
227
+
228
+ it('should add correct state to view', async () => {
229
+ const views = [
230
+ {
231
+ component: 'DashboardFacet',
232
+ chartType: 'bar',
233
+ id: 'MyDashboard',
234
+ attributeUri: 'configuration/entityTypes/HCP/attributes/CountryCode',
235
+ title: 'first'
236
+ },
237
+ {
238
+ component: 'DashboardFacet',
239
+ chartType: 'pie',
240
+ id: 'MyDashboard2',
241
+ attributeUri: 'configuration/entityTypes/HCP/attributes/CountryCode',
242
+ title: 'second'
243
+ },
244
+ {
245
+ component: 'DashboardFacet',
246
+ chartType: 'bar',
247
+ id: 'ActiveHCPsByCustomer',
248
+ attributeUri: 'configuration/entityTypes/HCP/attributes/CountryCode',
249
+ title: 'third'
250
+ }
251
+ ];
252
+ const savedViewHashMap = {MyDashboard: hash(views[0]), ActiveHCPsByCustomer: 'difHash'};
253
+ const savedState = {layout, configHash, viewsHashMap: savedViewHashMap};
254
+ getSavedStateSpy.mockResolvedValueOnce(savedState);
255
+ const {user, layoutItems} = await setUp({config: {...config, views}});
256
+
257
+ await user.click(screen.getByRole('button', {name: 'Add / remove charts'}));
258
+
259
+ expect(within(layoutItems[0]).getByText('third')).toBeInTheDocument();
260
+ expect(within(layoutItems[0]).getByText('Updated')).toBeInTheDocument();
261
+ expect(within(layoutItems[1]).getByText('second')).toBeInTheDocument();
262
+ expect(within(layoutItems[1]).queryByText('Updated')).not.toBeInTheDocument();
263
+
264
+ const configItems = screen.getAllByTestId('reltio-dashboard-config-item');
265
+ configItems.forEach((item, index) => {
266
+ const title = views[index].title;
267
+ expect(within(item).getByText(title)).toBeInTheDocument();
268
+ if (title === 'second') {
269
+ expect(within(item).getByText('New')).toBeInTheDocument();
270
+ } else {
271
+ expect(within(item).queryByText('New')).not.toBeInTheDocument();
272
+ }
273
+ });
274
+ });
275
+ });
276
+ });
@@ -0,0 +1,33 @@
1
+ export const getMetadata = ({tenant}) => ({
2
+ [tenant]: {
3
+ uri: 'configuration',
4
+ entityTypes: [
5
+ {
6
+ uri: 'configuration/entityTypes/HCP',
7
+ attributes: [
8
+ {
9
+ label: 'CountryCode',
10
+ name: 'CountryCode',
11
+ uri: 'configuration/entityTypes/HCP/attributes/CountryCode',
12
+ type: 'String',
13
+ required: true
14
+ },
15
+ {
16
+ label: 'TypeCode',
17
+ name: 'TypeCode',
18
+ uri: 'configuration/entityTypes/HCP/attributes/TypeCode',
19
+ type: 'String',
20
+ required: true
21
+ },
22
+ {
23
+ label: 'SimpleString',
24
+ name: 'SimpleString',
25
+ uri: 'configuration/entityTypes/HCP/attributes/SimpleString',
26
+ type: 'String'
27
+ }
28
+ ]
29
+ }
30
+ ],
31
+ relationTypes: []
32
+ }
33
+ });
@@ -0,0 +1,15 @@
1
+ import {getMetadata} from './metadata.data';
2
+
3
+ export const createInitialState = () => {
4
+ const tenant = 'alenat';
5
+
6
+ return {
7
+ metadata: getMetadata({tenant}),
8
+ tenant: {
9
+ id: tenant
10
+ },
11
+ user: {
12
+ roles: ['UI_USER']
13
+ }
14
+ };
15
+ };