@truedat/core 7.5.9 → 7.5.10

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 (277) hide show
  1. package/package.json +34 -68
  2. package/src/__tests__/routesTree.spec.js +108 -0
  3. package/src/api/queries.js +10 -0
  4. package/src/api.js +3 -0
  5. package/src/components/AddMemberForm.js +10 -10
  6. package/src/components/AddResourceMember.js +0 -2
  7. package/src/components/AdminMenu.js +0 -1
  8. package/src/components/AiMenu.js +0 -1
  9. package/src/components/Alert.js +1 -1
  10. package/src/components/AlertExporter.js +0 -1
  11. package/src/components/ArrayDecorator.js +0 -1
  12. package/src/components/Authorized.js +2 -2
  13. package/src/components/AvailableFilters.js +1 -2
  14. package/src/components/CSVFileModal.js +1 -1
  15. package/src/components/CardGroupsAccordion.js +1 -1
  16. package/src/components/CatalogMenu.js +1 -2
  17. package/src/components/CommentRow.js +7 -8
  18. package/src/components/Comments.js +3 -4
  19. package/src/components/CommentsForm.js +2 -2
  20. package/src/components/ConfirmModal.js +0 -1
  21. package/src/components/CursorPagination.js +1 -2
  22. package/src/components/DashboardMenu.js +0 -1
  23. package/src/components/Date.js +0 -1
  24. package/src/components/DateFilter.js +1 -1
  25. package/src/components/DateRangeFilter.js +1 -1
  26. package/src/components/DateTime.js +0 -1
  27. package/src/components/DescriptionInput.js +1 -1
  28. package/src/components/DomainSelector.js +2 -3
  29. package/src/components/DropdownMenuItem.js +0 -1
  30. package/src/components/ErrorBoundary.js +8 -7
  31. package/src/components/FieldLabel.js +0 -1
  32. package/src/components/FilterDropdown.js +3 -3
  33. package/src/components/FilterItem.js +0 -1
  34. package/src/components/FilterMultilevelDropdown.js +1 -1
  35. package/src/components/GenericCrumbs.js +3 -4
  36. package/src/components/GlossaryMenu.js +24 -31
  37. package/src/components/GrantMenu.js +0 -1
  38. package/src/components/GroupActions.js +15 -15
  39. package/src/components/Hierarchy.js +7 -10
  40. package/src/components/HierarchyFilterDropdown.js +1 -2
  41. package/src/components/HierarchyNodeFinder.js +4 -4
  42. package/src/components/HierarchySelector.js +1 -2
  43. package/src/components/HistoryBackButton.js +6 -6
  44. package/src/components/IngestMenu.js +0 -1
  45. package/src/components/LanguagesTabs.js +4 -4
  46. package/src/components/LineageMenu.js +0 -1
  47. package/src/components/Loading.js +1 -2
  48. package/src/components/MembersMenu.js +0 -1
  49. package/src/components/ModalSaveFilter.js +1 -1
  50. package/src/components/NodeOpenActions.js +0 -1
  51. package/src/components/OptionGroup.js +1 -2
  52. package/src/components/OptionModal.js +0 -1
  53. package/src/components/Pagination.js +0 -1
  54. package/src/components/QualityMenu.js +0 -1
  55. package/src/components/QxMenu.js +0 -1
  56. package/src/components/Redirector.js +3 -3
  57. package/src/components/ResourceMember.js +1 -2
  58. package/src/components/ResourceMembers.js +3 -3
  59. package/src/components/ResourceMembersActions.js +1 -2
  60. package/src/components/RichTextEditor.js +7 -8
  61. package/src/components/RouteListener.js +11 -32
  62. package/src/components/SafeLink.js +0 -1
  63. package/src/components/ScrollToTop.js +13 -16
  64. package/src/components/SearchFilterDropdown.js +1 -1
  65. package/src/components/SearchInput.js +3 -3
  66. package/src/components/SearchMenu.js +0 -1
  67. package/src/components/SelectedFilters.js +1 -2
  68. package/src/components/SideMenu.js +0 -1
  69. package/src/components/SidebarToggle.js +2 -2
  70. package/src/components/StructureFilterItem.js +0 -1
  71. package/src/components/Submenu.js +8 -7
  72. package/src/components/SystemsLoader.js +27 -0
  73. package/src/components/TaxonomyMenu.js +0 -1
  74. package/src/components/TemplateSelector.js +1 -1
  75. package/src/components/TemplatesLoader.js +24 -0
  76. package/src/components/TreeSelector.js +4 -4
  77. package/src/components/Unauthorized.js +0 -1
  78. package/src/components/UploadModal.js +152 -176
  79. package/src/components/UserFilter.js +0 -2
  80. package/src/components/UserFilters.js +0 -2
  81. package/src/components/__tests__/AddMemberForm.spec.js +26 -38
  82. package/src/components/__tests__/AddResourceMember.spec.js +0 -1
  83. package/src/components/__tests__/AdminMenu.spec.js +0 -1
  84. package/src/components/__tests__/Alert.spec.js +17 -21
  85. package/src/components/__tests__/AvailableFilters.spec.js +19 -14
  86. package/src/components/__tests__/CardGroupsAccordion.spec.js +24 -15
  87. package/src/components/__tests__/CatalogMenu.spec.js +27 -45
  88. package/src/components/__tests__/CommentsLoader.spec.js +17 -14
  89. package/src/components/__tests__/CursorPagination.spec.js +0 -1
  90. package/src/components/__tests__/DashboardMenu.spec.js +0 -1
  91. package/src/components/__tests__/DateFilter.spec.js +6 -28
  92. package/src/components/__tests__/DateTime.spec.js +0 -1
  93. package/src/components/__tests__/DomainSelector.spec.js +4 -4
  94. package/src/components/__tests__/DropdownMenuItem.spec.js +0 -1
  95. package/src/components/__tests__/FilterDropdown.spec.js +28 -27
  96. package/src/components/__tests__/FilterItem.spec.js +19 -20
  97. package/src/components/__tests__/FilterMultilevelDropdown.spec.js +16 -16
  98. package/src/components/__tests__/FiltersLoader.spec.js +25 -20
  99. package/src/components/__tests__/GenericCrumbs.spec.js +0 -1
  100. package/src/components/__tests__/GlossaryMenu.spec.js +0 -1
  101. package/src/components/__tests__/GrantMenu.spec.js +0 -1
  102. package/src/components/__tests__/GroupActions.spec.js +0 -1
  103. package/src/components/__tests__/Hierarchy.spec.js +0 -1
  104. package/src/components/__tests__/HierarchyFilterDropdown.spec.js +16 -14
  105. package/src/components/__tests__/HierarchyNodeFinder.spec.js +0 -1
  106. package/src/components/__tests__/HierarchySelector.spec.js +28 -35
  107. package/src/components/__tests__/HistoryBackButton.spec.js +23 -23
  108. package/src/components/__tests__/IngestMenu.spec.js +0 -1
  109. package/src/components/__tests__/LineageMenu.spec.js +0 -1
  110. package/src/components/__tests__/Loading.spec.js +4 -5
  111. package/src/components/__tests__/MembersMenu.spec.js +0 -1
  112. package/src/components/__tests__/ModalSaveFilter.spec.js +0 -1
  113. package/src/components/__tests__/OptionGroup.spec.js +5 -7
  114. package/src/components/__tests__/Pagination.spec.js +22 -16
  115. package/src/components/__tests__/QualityMenu.spec.js +0 -1
  116. package/src/components/__tests__/Redirector.spec.js +5 -10
  117. package/src/components/__tests__/ResourceMembers.spec.js +36 -27
  118. package/src/components/__tests__/ResourceMembersAction.spec.js +1 -2
  119. package/src/components/__tests__/RouteListener.spec.js +25 -26
  120. package/src/components/__tests__/SafeLink.spec.js +0 -1
  121. package/src/components/__tests__/SearchDateFilter.spec.js +0 -1
  122. package/src/components/__tests__/SearchFilterDropdown.spec.js +32 -24
  123. package/src/components/__tests__/SearchInput.spec.js +5 -5
  124. package/src/components/__tests__/SearchMenu.spec.js +0 -1
  125. package/src/components/__tests__/SelectedFilters.spec.js +50 -47
  126. package/src/components/__tests__/SideMenu.spec.js +5 -8
  127. package/src/components/__tests__/StructureFilterItem.spec.js +13 -11
  128. package/src/components/__tests__/Submenu.spec.js +0 -1
  129. package/src/components/__tests__/SystemsLoader.spec.js +40 -0
  130. package/src/components/__tests__/TaxonomyMenu.spec.js +0 -1
  131. package/src/components/__tests__/TemplateSelector.spec.js +27 -29
  132. package/src/components/__tests__/TemplatesLoader.spec.js +30 -0
  133. package/src/components/__tests__/TreeSelector.spec.js +110 -83
  134. package/src/components/__tests__/UploadModal.spec.js +171 -0
  135. package/src/components/__tests__/UserFilters.spec.js +44 -37
  136. package/src/components/__tests__/__snapshots__/AddMemberForm.spec.js.snap +1 -0
  137. package/src/components/__tests__/__snapshots__/AddResourceMember.spec.js.snap +10 -9
  138. package/src/components/__tests__/__snapshots__/AdminMenu.spec.js.snap +22 -11
  139. package/src/components/__tests__/__snapshots__/Alert.spec.js.snap +29 -17
  140. package/src/components/__tests__/__snapshots__/AvailableFilters.spec.js.snap +1 -1
  141. package/src/components/__tests__/__snapshots__/CatalogMenu.spec.js.snap +18 -8
  142. package/src/components/__tests__/__snapshots__/CursorPagination.spec.js.snap +3 -0
  143. package/src/components/__tests__/__snapshots__/DateFilter.spec.js.snap +165 -107
  144. package/src/components/__tests__/__snapshots__/DomainSelector.spec.js.snap +1 -1
  145. package/src/components/__tests__/__snapshots__/FilterItem.spec.js.snap +13 -20
  146. package/src/components/__tests__/__snapshots__/GlossaryMenu.spec.js.snap +8 -0
  147. package/src/components/__tests__/__snapshots__/GrantMenu.spec.js.snap +14 -7
  148. package/src/components/__tests__/__snapshots__/GroupActions.spec.js.snap +0 -1
  149. package/src/components/__tests__/__snapshots__/Hierarchy.spec.js.snap +0 -1
  150. package/src/components/__tests__/__snapshots__/HierarchySelector.spec.js.snap +1 -1
  151. package/src/components/__tests__/__snapshots__/HistoryBackButton.spec.js.snap +10 -20
  152. package/src/components/__tests__/__snapshots__/IngestMenu.spec.js.snap +3 -1
  153. package/src/components/__tests__/__snapshots__/LineageMenu.spec.js.snap +6 -3
  154. package/src/components/__tests__/__snapshots__/Loading.spec.js.snap +5 -4
  155. package/src/components/__tests__/__snapshots__/MembersMenu.spec.js.snap +6 -3
  156. package/src/components/__tests__/__snapshots__/OptionGroup.spec.js.snap +38 -28
  157. package/src/components/__tests__/__snapshots__/Pagination.spec.js.snap +213 -64
  158. package/src/components/__tests__/__snapshots__/QualityMenu.spec.js.snap +14 -8
  159. package/src/components/__tests__/__snapshots__/ResourceMembers.spec.js.snap +1 -0
  160. package/src/components/__tests__/__snapshots__/ResourceMembersAction.spec.js.snap +2 -1
  161. package/src/components/__tests__/__snapshots__/RouteListener.spec.js.snap +1 -1
  162. package/src/components/__tests__/__snapshots__/SearchInput.spec.js.snap +10 -12
  163. package/src/components/__tests__/__snapshots__/SearchMenu.spec.js.snap +3 -1
  164. package/src/components/__tests__/__snapshots__/SelectedFilters.spec.js.snap +8 -8
  165. package/src/components/__tests__/__snapshots__/SideMenu.spec.js.snap +112 -50
  166. package/src/components/__tests__/__snapshots__/Submenu.spec.js.snap +3 -0
  167. package/src/components/__tests__/__snapshots__/SystemsLoader.spec.js.snap +3 -0
  168. package/src/components/__tests__/__snapshots__/TaxonomyMenu.spec.js.snap +3 -1
  169. package/src/components/__tests__/__snapshots__/TemplateSelector.spec.js.snap +7 -7
  170. package/src/components/common/SearchContextWrapper.js +1 -4
  171. package/src/hooks/__mocks__/useAuthorized.js +2 -0
  172. package/src/hooks/__mocks__/useUserFilters.js +17 -0
  173. package/src/hooks/__tests__/{useAclEntries.spec.js → useAclEntries.spec.js.disabled} +1 -1
  174. package/src/hooks/__tests__/useAuthorized.spec.js +1 -1
  175. package/src/hooks/useAclEntries.js +6 -3
  176. package/src/hooks/useActiveRoute.js +3 -3
  177. package/src/hooks/useActiveRoutes.js +4 -4
  178. package/src/hooks/useHierarchies.js +112 -0
  179. package/src/hooks/useLocales.js +1 -1
  180. package/src/hooks/useMessages.js +1 -1
  181. package/src/hooks/usePath.js +4 -4
  182. package/src/hooks/useUserFilters.js +1 -1
  183. package/src/i18n/components/EditableCell.js +1 -1
  184. package/src/i18n/components/I18nRoutes.js +11 -16
  185. package/src/i18n/components/LangProvider.js +56 -101
  186. package/src/i18n/components/LangProviderWrapper.js +26 -33
  187. package/src/i18n/components/Languages.js +8 -7
  188. package/src/i18n/components/MessageForm.js +9 -23
  189. package/src/i18n/components/Messages.js +5 -4
  190. package/src/i18n/components/MessagesTable.js +0 -1
  191. package/src/i18n/components/NewMessage.js +5 -4
  192. package/src/i18n/components/__tests__/EditableCell.spec.js +18 -20
  193. package/src/i18n/components/__tests__/I18nRoutes.spec.js +39 -5
  194. package/src/i18n/components/__tests__/MessageForm.spec.js +0 -1
  195. package/src/i18n/components/__tests__/Messages.spec.js +9 -21
  196. package/src/i18n/components/__tests__/NewMessage.spec.js +0 -1
  197. package/src/i18n/components/__tests__/__snapshots__/I18nRoutes.spec.js.snap +25 -1
  198. package/src/i18n/components/__tests__/__snapshots__/MessageForm.spec.js.snap +1 -0
  199. package/src/i18n/components/__tests__/__snapshots__/Messages.spec.js.snap +5 -13
  200. package/src/i18n/components/__tests__/__snapshots__/NewMessage.spec.js.snap +2 -0
  201. package/src/reducers/__tests__/comments.spec.js +9 -6
  202. package/src/reducers/__tests__/commentsResource.spec.js +5 -2
  203. package/src/reducers/__tests__/coreMessage.spec.js +1 -1
  204. package/src/reducers/__tests__/dashboardDomains.spec.js +5 -5
  205. package/src/reducers/__tests__/systems.spec.js +42 -0
  206. package/src/reducers/__tests__/systemsLoading.spec.js +22 -0
  207. package/src/reducers/index.js +5 -1
  208. package/src/reducers/systems.js +19 -0
  209. package/src/reducers/systemsLoading.js +14 -0
  210. package/src/router/Loader.js +10 -0
  211. package/src/router/ProtectedRoute.js +11 -0
  212. package/src/router/Unauthorized.js +16 -0
  213. package/src/router/__tests__/ProtectedRoute.spec.js +49 -0
  214. package/src/router/__tests__/Unauthorized.spec.js +15 -0
  215. package/src/router/__tests__/__snapshots__/ProtectedRoute.spec.js.snap +44 -0
  216. package/src/router/__tests__/__snapshots__/Unauthorized.spec.js.snap +26 -0
  217. package/src/router/index.js +5 -0
  218. package/src/routes.js +7 -7
  219. package/src/routesTree.js +93 -0
  220. package/src/routines.js +8 -0
  221. package/src/sagas/__tests__/addComment.spec.js +3 -5
  222. package/src/sagas/__tests__/fetchComments.spec.js +1 -1
  223. package/src/sagas/__tests__/fetchSystems.spec.js +69 -0
  224. package/src/sagas/fetchSystems.js +25 -0
  225. package/src/sagas/index.js +3 -0
  226. package/src/search/FilterDropdown.js +0 -1
  227. package/src/search/FilterItem.js +0 -1
  228. package/src/search/FilterMultilevelDropdown.js +1 -1
  229. package/src/search/FilterQueryDropdown.js +38 -42
  230. package/src/search/HierarchyFilterDropdown.js +3 -4
  231. package/src/search/ModalSaveFilter.js +1 -1
  232. package/src/search/Pagination.js +0 -1
  233. package/src/search/SearchContext.js +9 -11
  234. package/src/search/SearchDateFilter.js +0 -1
  235. package/src/search/SearchFilters.js +1 -2
  236. package/src/search/SearchSelectedFilters.js +4 -4
  237. package/src/search/SearchWidget.js +0 -4
  238. package/src/search/UserFilter.js +0 -2
  239. package/src/search/UserFilters.js +4 -3
  240. package/src/search/__tests__/FilterDropdown.spec.js +54 -51
  241. package/src/search/__tests__/FilterItem.spec.js +20 -15
  242. package/src/search/__tests__/FilterQueryDropdown.spec.js +106 -84
  243. package/src/search/__tests__/ModalSaveFilter.spec.js +4 -5
  244. package/src/search/__tests__/SearchContext.spec.js +3 -4
  245. package/src/search/__tests__/SearchWidget.spec.js +0 -1
  246. package/src/selectors/__tests__/getConceptSubscope.spec.js +37 -0
  247. package/src/selectors/__tests__/getDashboardConfig.spec.js +9 -9
  248. package/src/selectors/__tests__/getMessage.spec.js +1 -1
  249. package/src/selectors/__tests__/getSidemenuGlossarySubscopes.spec.js +17 -0
  250. package/src/selectors/__tests__/makeActiveFiltersSelector.spec.js +2 -2
  251. package/src/selectors/__tests__/makeSearchQuerySelector.spec.js +1 -1
  252. package/src/selectors/__tests__/makeTagOptionsSelector.spec.js +6 -6
  253. package/src/selectors/getConceptSubscope.js +19 -0
  254. package/src/selectors/getMessage.js +2 -2
  255. package/src/selectors/getRecipients.js +34 -0
  256. package/src/selectors/getSidemenuGlossarySubscopes.js +8 -0
  257. package/src/selectors/index.js +5 -0
  258. package/src/selectors/makeActiveFiltersSelector.js +2 -6
  259. package/src/selectors/makeSearchQuerySelector.js +4 -11
  260. package/src/selectors/makeTagOptionsSelector.js +4 -8
  261. package/src/selectors/subscopedTemplates.js +16 -0
  262. package/src/selectors/taxonomy.js +170 -0
  263. package/src/services/__tests__/columnDecorator.spec.js +1 -1
  264. package/src/services/__tests__/dateFilterFormatter.spec.js +2 -2
  265. package/src/services/__tests__/fieldType.spec.js +2 -2
  266. package/src/services/__tests__/filters.spec.js +1 -1
  267. package/src/services/__tests__/message.spec.js +2 -2
  268. package/src/services/__tests__/operators.spec.js +5 -5
  269. package/src/services/__tests__/sort.spec.js +8 -8
  270. package/src/services/__tests__/storage.spec.js +17 -0
  271. package/src/services/arrays.js +16 -14
  272. package/src/services/columnDecoratorComponent.js +2 -2
  273. package/src/services/columnDecorators.js +0 -1
  274. package/src/services/fieldType.js +8 -8
  275. package/src/services/filters.js +5 -5
  276. package/src/services/message.js +1 -4
  277. package/src/services/operators.js +1 -1
@@ -1,21 +1,17 @@
1
1
  import _ from "lodash/fp";
2
- import {
3
- createSelector,
4
- createSelectorCreator,
5
- defaultMemoize
6
- } from "reselect";
2
+ import { createSelector, createSelectorCreator, lruMemoize } from "reselect";
7
3
 
8
4
  const tagsToOptions = _.map(({ id: value, value: { label, type } }) => ({
9
5
  value,
10
- text: _.defaultTo(type)(label)
6
+ text: _.defaultTo(type)(label),
11
7
  }));
12
8
 
13
- export const makeTagOptionsSelector = targetType => {
9
+ export const makeTagOptionsSelector = (targetType) => {
14
10
  const getTagOptions = createSelector(
15
11
  _.prop("relationTags"),
16
12
  _.flow(_.filter(_.pathEq("value.target_type", targetType)), tagsToOptions)
17
13
  );
18
- return createSelectorCreator(defaultMemoize, _.isEqual)(
14
+ return createSelectorCreator(lruMemoize, _.isEqual)(
19
15
  getTagOptions,
20
16
  _.identity
21
17
  );
@@ -0,0 +1,16 @@
1
+ import _ from "lodash/fp";
2
+ import { createSelector } from "reselect";
3
+
4
+ export const getSubscopes = (allTemplates, mainScope) => {
5
+ return _.flow(
6
+ _.filter({ scope: mainScope }),
7
+ _.map("subscope"),
8
+ _.uniq,
9
+ _.filter((el) => el !== null)
10
+ )(allTemplates);
11
+ };
12
+
13
+ export const makeGetSubscopes = (mainScope) =>
14
+ createSelector(_.prop("allTemplates"), (allTemplates) =>
15
+ getSubscopes(allTemplates, mainScope)
16
+ );
@@ -0,0 +1,170 @@
1
+ import _ from "lodash/fp";
2
+ import { createSelector } from "reselect";
3
+ import { FormattedMessage } from "react-intl";
4
+ import { accentInsensitivePathOrder } from "@truedat/core/services/sort";
5
+
6
+ const getDomain = ({ domain }) => domain;
7
+ const getDomains = ({ domains }) => domains;
8
+ const getDomainsFilter = ({ domainsFilter }) => domainsFilter;
9
+
10
+ const isChildOf =
11
+ ({ id }) =>
12
+ ({ parent_id }) =>
13
+ parent_id === id;
14
+ const isParentOf =
15
+ ({ parent_id }) =>
16
+ ({ id }) =>
17
+ parent_id === id;
18
+
19
+ const hasNoParentIn = (domains) => (domain) =>
20
+ !_.some(isParentOf(domain))(domains);
21
+
22
+ /**
23
+ * Creates a selector which returns the child domains of the currently selected domain.
24
+ * If no domain is currently selected, it returns the domains for which no parent is found.
25
+ */
26
+ const getChildOrRootDomains = createSelector(
27
+ [getDomain, getDomains],
28
+ (domain, domains) => {
29
+ return _.isEmpty(domain)
30
+ ? _.filter(hasNoParentIn(domains))(domains)
31
+ : _.filter(isChildOf(domain))(domains);
32
+ }
33
+ );
34
+
35
+ const findParentsIn = (domains) => (child) =>
36
+ _.filter(isParentOf(child))(domains);
37
+ const findChildrenIn = (domains) => (parent) =>
38
+ _.filter(isChildOf(parent))(domains);
39
+
40
+ const findDescendents = (parents) => (domains) => {
41
+ const children = _.flatMap(findChildrenIn(domains))(parents);
42
+ return _.isEmpty(children)
43
+ ? children
44
+ : _.concat(children, findDescendents(children)(domains));
45
+ };
46
+
47
+ /**
48
+ * A selector to compute the descendents of the currently selected domain.
49
+ * If no domain is currently selected, all domains are returned.
50
+ */
51
+ const getDescendents = createSelector(
52
+ [getDomain, getDomains],
53
+ (domain, domains) =>
54
+ _.isEmpty(domain) ? domains : findDescendents([domain])(domains)
55
+ );
56
+
57
+ const toSearchable = _.flow(_.deburr, _.toLower, _.trim);
58
+
59
+ const isValidFilter = (filter) => !_.isEmpty(toSearchable(filter));
60
+
61
+ const matchesFilter = (filter) =>
62
+ _.flow(
63
+ _.at(["name", "description"]),
64
+ _.map(toSearchable),
65
+ _.some(_.includes(toSearchable(filter)))
66
+ );
67
+
68
+ /**
69
+ * A selector to compute the domains whose name or description matches a search string.
70
+ * If a domain is currently selected, the scope of the search will be limited to descendents
71
+ * of the currently selected domain. The search is case-insensitive and accent-insensitive.
72
+ */
73
+ const getFilteredDomains = createSelector(
74
+ [getDescendents, getDomainsFilter],
75
+ (descendents, domainsFilter) =>
76
+ isValidFilter(domainsFilter)
77
+ ? _.filter(matchesFilter(domainsFilter))(descendents)
78
+ : []
79
+ );
80
+
81
+ const _getVisibleDomains = createSelector(
82
+ [getDomainsFilter, getFilteredDomains, getChildOrRootDomains],
83
+ (filter, filteredDomains, childOrRootDomains) =>
84
+ _.isEmpty(filter) ? childOrRootDomains : filteredDomains
85
+ );
86
+
87
+ /**
88
+ * A selector to compute the currently visible domains. If a filter is present, the selector
89
+ * returns descendent domains matching the filter within the scope of the currently selected
90
+ * domain (or within the scope of all domains if no domain is currently selected).
91
+ * If no filter is present, the selector returns domains without parents.
92
+ * Enriches domains with child count.
93
+ */
94
+ const getVisibleDomains = createSelector(
95
+ [_getVisibleDomains, getDomains],
96
+ (visibleDomains, domains) =>
97
+ visibleDomains
98
+ .map((d) => ({
99
+ ...d,
100
+ children: _.filter(isChildOf(d))(domains),
101
+ }))
102
+ .map(({ children, ...d }) => ({ childCount: children.length, ...d }))
103
+ );
104
+
105
+ const findAncestorsIn = (domains) => (children) => {
106
+ const parents = _.flatMap(findParentsIn(domains))(children);
107
+ return _.isEmpty(parents)
108
+ ? parents
109
+ : _.concat(findAncestorsIn(domains)(parents), parents);
110
+ };
111
+
112
+ /**
113
+ * A selector to obtain the parents of the currently selected domain.
114
+ */
115
+ const getAncestorDomains = createSelector(
116
+ [getDomains, getDomain],
117
+ (domains, domain) =>
118
+ _.isEmpty(domain) ? [] : findAncestorsIn(domains)([domain])
119
+ );
120
+
121
+ const reduceTaxonomy = (domains) => (domainsInLevel, level) => {
122
+ if (domains)
123
+ return _.reduce((acc, domain) => {
124
+ const children = _.sortBy(["name"])(findChildrenIn(domains)(domain));
125
+ return [
126
+ ...acc,
127
+ {
128
+ ...domain,
129
+ ancestors: findAncestorsIn(domains)([domain]),
130
+ descendents: _.sortBy(["name"])(findDescendents([domain])(domains)),
131
+ children,
132
+ level,
133
+ },
134
+ ...reduceTaxonomy(domains)(children, level + 1),
135
+ ];
136
+ }, [])(domainsInLevel);
137
+ return [];
138
+ };
139
+
140
+ const getDomainSelectorOptions = createSelector([getDomains], (domains) => {
141
+ const roots = _.flow(
142
+ _.filter(hasNoParentIn(domains)),
143
+ _.sortBy(accentInsensitivePathOrder("name"))
144
+ )(domains);
145
+ const emptyDomain = _.contains("")(domains)
146
+ ? [
147
+ {
148
+ external_id: null,
149
+ id: 0,
150
+ name: <FormattedMessage id={`filter.empty`} />,
151
+ parent_id: null,
152
+ ancestors: [],
153
+ descendents: [],
154
+ children: [],
155
+ level: 0,
156
+ },
157
+ ]
158
+ : [];
159
+
160
+ return _.concat(emptyDomain, reduceTaxonomy(domains)(roots, 0));
161
+ });
162
+
163
+ export {
164
+ getChildOrRootDomains,
165
+ getDescendents,
166
+ getDomainSelectorOptions,
167
+ getFilteredDomains,
168
+ getVisibleDomains,
169
+ getAncestorDomains,
170
+ };
@@ -29,7 +29,7 @@ describe("services: columnDecorator", () => {
29
29
  it("should apply a decorator to a selected field", () => {
30
30
  const column = {
31
31
  fieldDecorator: _.upperCase,
32
- fieldSelector: _.path("foo.bar")
32
+ fieldSelector: _.path("foo.bar"),
33
33
  };
34
34
  const obj = { foo: { bar: "baz" } };
35
35
  expect(columnDecorator(column)(obj)).toEqual("BAZ");
@@ -41,7 +41,7 @@ describe("dateFilterFormatter", () => {
41
41
  const filter = dff(foo);
42
42
 
43
43
  expect(
44
- filter == { updated_at: { gte: "2024-04-17", lt: "2024-05-05||+1d" } }
44
+ filter == { updated_at: { gte: "2024-04-17", lt: "2024-05-05||+1d" } },
45
45
  );
46
46
  });
47
47
 
@@ -61,7 +61,7 @@ describe("dateFilterFormatter", () => {
61
61
  start_date: { gte: "2024-04-17" },
62
62
  end_date: { lt: "2024-05-05" },
63
63
  },
64
- }
64
+ },
65
65
  );
66
66
  });
67
67
 
@@ -6,8 +6,8 @@ describe("services: getFieldType", () => {
6
6
  "should return data_type_class if it has value %s",
7
7
  (data_type_class) =>
8
8
  expect(getFieldType({ metadata: { data_type_class } })).toBe(
9
- data_type_class
10
- )
9
+ data_type_class,
10
+ ),
11
11
  );
12
12
 
13
13
  test.each([
@@ -61,7 +61,7 @@ describe("services: filters", () => {
61
61
  defaultFilters,
62
62
  linkable,
63
63
  pageSize: size,
64
- })
64
+ }),
65
65
  ).toEqual({
66
66
  must: { ...must, ...defaultFilters },
67
67
  only_linkable: true,
@@ -9,13 +9,13 @@ describe("services: message", () => {
9
9
  describe("toErrorList", () => {
10
10
  it("should transform an object with array values to a list of strings prepended by the keys", () => {
11
11
  expect(
12
- toErrorList("foo")({ name: ["unique", "missing"], bar: ["baz"] })
12
+ toErrorList("foo")({ name: ["unique", "missing"], bar: ["baz"] }),
13
13
  ).toEqual(
14
14
  expect.arrayContaining([
15
15
  { name: "foo.name.unique" },
16
16
  { name: "foo.name.missing" },
17
17
  { name: "foo.bar.baz" },
18
- ])
18
+ ]),
19
19
  );
20
20
  });
21
21
  });
@@ -10,7 +10,7 @@ describe("services: operators toItem should transform to existing operator/modif
10
10
  name: "name",
11
11
  returnType: "boolean",
12
12
  args: [{ type: "xyz" }],
13
- })
13
+ }),
14
14
  ).toEqual({ id, category: "xyz", name: "name", returnType: "boolean" });
15
15
  });
16
16
 
@@ -23,7 +23,7 @@ describe("services: operators toItem should transform to existing operator/modif
23
23
  scope: "scope",
24
24
  returnType: "boolean",
25
25
  args: [{ type: "any" }],
26
- })
26
+ }),
27
27
  ).toEqual({
28
28
  id,
29
29
  category: "any",
@@ -45,7 +45,7 @@ describe("services: operators toItem should transform to existing operator/modif
45
45
  { name: "start", type: "number" },
46
46
  { name: "end", type: "number" },
47
47
  ],
48
- })
48
+ }),
49
49
  ).toEqual({
50
50
  id,
51
51
  category: "cat",
@@ -77,7 +77,7 @@ describe("services: operators toItem should transform to existing operator/modif
77
77
  values: ["D-0", "D-1", "M-0", "M-1", "M-2", "Y-0", "Y-1"],
78
78
  },
79
79
  ],
80
- })
80
+ }),
81
81
  ).toEqual({
82
82
  id,
83
83
  category: "date",
@@ -99,7 +99,7 @@ describe("services: operators toItem should transform to existing operator/modif
99
99
  group: "references",
100
100
  returnType: "boolean",
101
101
  args: [{ type: "any" }, { type: "ref" }],
102
- })
102
+ }),
103
103
  ).toEqual({
104
104
  id,
105
105
  category: "any",
@@ -3,7 +3,7 @@ import {
3
3
  i18nOrder,
4
4
  lowerDeburr,
5
5
  lowerDeburrPath,
6
- sortColumn
6
+ sortColumn,
7
7
  } from "../sort";
8
8
 
9
9
  describe("services: sort", () => {
@@ -12,7 +12,7 @@ describe("services: sort", () => {
12
12
  const formatMessage = ({ id }) => id;
13
13
  const prefix = "PREFIX";
14
14
  expect(i18nOrder(formatMessage, prefix)("ÇÖPùLÂÉ")).toEqual(
15
- "prefix.copulae"
15
+ "prefix.copulae",
16
16
  );
17
17
  });
18
18
  });
@@ -26,7 +26,7 @@ describe("services: sort", () => {
26
26
  describe("lowerDeburrPath", () => {
27
27
  it("should extract a path, remove accents and convert to lower case", () => {
28
28
  expect(lowerDeburrPath("foo.bar")({ foo: { bar: "ÇÖPùLÂÉ" } })).toEqual(
29
- "copulae"
29
+ "copulae",
30
30
  );
31
31
  });
32
32
  });
@@ -34,10 +34,10 @@ describe("services: sort", () => {
34
34
  describe("getSortInfo", () => {
35
35
  it("should return a column and semantic ui direction map with the first element of an array of sorted columns", () => {
36
36
  expect(
37
- getSortInfo([{ "name.raw": "desc" }, { "description.raw": "asc" }])
37
+ getSortInfo([{ "name.raw": "desc" }, { "description.raw": "asc" }]),
38
38
  ).toMatchObject({
39
39
  column: "name.raw",
40
- direction: "descending"
40
+ direction: "descending",
41
41
  });
42
42
  });
43
43
  });
@@ -60,7 +60,7 @@ describe("services: sort", () => {
60
60
  setDirection,
61
61
  setColumn,
62
62
  currentDirection,
63
- currentSortedColumn
63
+ currentSortedColumn,
64
64
  );
65
65
  expect(sort.mock.calls.length).toBe(1);
66
66
  expect(sort.mock.calls[0][0]).toMatchObject([{ "name.raw": "desc" }]);
@@ -85,11 +85,11 @@ describe("services: sort", () => {
85
85
  setDirection,
86
86
  setColumn,
87
87
  currentDirection,
88
- currentSortedColumn
88
+ currentSortedColumn,
89
89
  );
90
90
  expect(sort.mock.calls.length).toBe(1);
91
91
  expect(sort.mock.calls[0][0]).toMatchObject([
92
- { "description.raw": "asc" }
92
+ { "description.raw": "asc" },
93
93
  ]);
94
94
  expect(setDirection.mock.calls.length).toBe(1);
95
95
  expect(setDirection.mock.calls[0][0]).toEqual("ascending");
@@ -1,5 +1,22 @@
1
1
  import { clearToken, readToken, saveToken } from "../storage";
2
2
 
3
+ // Mock localStorage
4
+ beforeEach(() => {
5
+ // Setup localStorage mock
6
+ const localStorageMock = {
7
+ getItem: jest.fn(),
8
+ setItem: jest.fn(),
9
+ removeItem: jest.fn(),
10
+ clear: jest.fn(),
11
+ };
12
+
13
+ // Replace the global localStorage with our mock
14
+ Object.defineProperty(window, "localStorage", {
15
+ value: localStorageMock,
16
+ writable: true,
17
+ });
18
+ });
19
+
3
20
  describe("readToken", () => {
4
21
  it("should read the token from local storage", () => {
5
22
  readToken();
@@ -1,25 +1,27 @@
1
- export const dropAt = (i, n = 1) => array =>
2
- i >= 0 && i < array.length
3
- ? [...array.slice(0, i), ...array.slice(i + n)]
4
- : array;
1
+ export const dropAt =
2
+ (i, n = 1) =>
3
+ (array) =>
4
+ i >= 0 && i < array.length
5
+ ? [...array.slice(0, i), ...array.slice(i + n)]
6
+ : array;
5
7
 
6
- export const replaceAt = (i, value) => array =>
8
+ export const replaceAt = (i, value) => (array) =>
7
9
  i >= 0 && i < array.length
8
10
  ? [...array.slice(0, i), value, ...array.slice(i + 1)]
9
11
  : array;
10
12
 
11
- export const swap = (i1, i2) => array => {
13
+ export const swap = (i1, i2) => (array) => {
12
14
  const j1 = i1 < i2 ? i1 : i2;
13
15
  const j2 = i1 > i2 ? i1 : i2;
14
16
  return j1 == j2
15
17
  ? array
16
18
  : j1 >= 0 && j2 < array.length
17
- ? [
18
- ...array.slice(0, j1),
19
- array[j2],
20
- ...array.slice(j1 + 1, j2),
21
- array[j1],
22
- ...array.slice(j2 + 1)
23
- ]
24
- : array;
19
+ ? [
20
+ ...array.slice(0, j1),
21
+ array[j2],
22
+ ...array.slice(j1 + 1, j2),
23
+ array[j1],
24
+ ...array.slice(j2 + 1),
25
+ ]
26
+ : array;
25
27
  };
@@ -1,5 +1,5 @@
1
1
  import _ from "lodash/fp";
2
- import React from "react";
2
+ import { createElement } from "react";
3
3
 
4
4
  export const columnDecoratorComponent = (column) => (obj) => {
5
5
  const { fieldSelector, fieldDecorator, name } = column || {};
@@ -14,7 +14,7 @@ export const columnDecoratorComponent = (column) => (obj) => {
14
14
  * https://stackoverflow.com/a/57456179
15
15
  */
16
16
  return _.isFunction(fieldDecorator)
17
- ? React.createElement(fieldDecorator, field)
17
+ ? createElement(fieldDecorator, field)
18
18
  : field;
19
19
  };
20
20
 
@@ -1,5 +1,4 @@
1
1
  import _ from "lodash/fp";
2
- import React from "react";
3
2
  import PropTypes from "prop-types";
4
3
  import { FormattedMessage } from "react-intl";
5
4
  import Moment from "react-moment";
@@ -15,11 +15,11 @@ export const getFieldType = ({ metadata, type }) =>
15
15
  type === "reference_dataset_field"
16
16
  ? "string"
17
17
  : _.includes(metadata?.data_type_class)([
18
- "boolean",
19
- "date",
20
- "number",
21
- "string",
22
- "timestamp",
23
- ])
24
- ? metadata?.data_type_class
25
- : guessType(type);
18
+ "boolean",
19
+ "date",
20
+ "number",
21
+ "string",
22
+ "timestamp",
23
+ ])
24
+ ? metadata?.data_type_class
25
+ : guessType(type);
@@ -1,5 +1,5 @@
1
1
  import _ from "lodash/fp";
2
- import { getDomainSelectorOptions } from "@truedat/bg/taxonomy/selectors";
2
+ import { getDomainSelectorOptions } from "@truedat/core/selectors/taxonomy";
3
3
 
4
4
  const intersectionOrDefault = (defaults, overrides) => {
5
5
  const v = _.intersection(defaults, overrides);
@@ -12,8 +12,8 @@ const filterCustomizer = (defaults, overrides, key) =>
12
12
  key === "taxonomy" && isNonEmptyArray(overrides)
13
13
  ? overrides
14
14
  : isNonEmptyArray(defaults) && isNonEmptyArray(overrides)
15
- ? intersectionOrDefault(defaults, overrides)
16
- : undefined;
15
+ ? intersectionOrDefault(defaults, overrides)
16
+ : undefined;
17
17
 
18
18
  export const mergeFilters = _.mergeAllWith(filterCustomizer);
19
19
 
@@ -34,8 +34,8 @@ export const formatFilterValues = ({ values, type }) =>
34
34
  type === "domain"
35
35
  ? getDomainSelectorOptions({ domains: values })
36
36
  : _.any(isEmbedded)(values)
37
- ? _.map(({ id, name }) => ({ value: id, text: name }))(values)
38
- : values;
37
+ ? _.map(({ id, name }) => ({ value: id, text: name }))(values)
38
+ : values;
39
39
 
40
40
  export const toFilterValues = (filterValues) =>
41
41
  _.map((v) => (_.isObject(v) ? v.id || v.value : v))(filterValues);
@@ -32,10 +32,7 @@ export const defaultMessage = (state, type, payload) => {
32
32
 
33
33
  const changesetErrorTranslation = (error) =>
34
34
  // eslint-disable-next-line prettier/prettier
35
- _.flow(
36
- _.toPairs,
37
- _.head,
38
- ([field, errorList]) =>
35
+ _.flow(_.toPairs, _.head, ([field, errorList]) =>
39
36
  errorList.length === 1
40
37
  ? `${field}.${errorList[0]}`
41
38
  : /* This is horrible, showing the raw errorList makes it untranslatable,
@@ -4,7 +4,7 @@ const transformType = (type) =>
4
4
  ({
5
5
  ref: "field",
6
6
  reference_dataset_field: "reference_dataset_field",
7
- }[type]);
7
+ })[type];
8
8
 
9
9
  export const toItem = ({
10
10
  name,