@databiosphere/findable-ui 29.0.2 → 30.0.0

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 (205) hide show
  1. package/.release-please-manifest.json +1 -1
  2. package/CHANGELOG.md +22 -0
  3. package/lib/common/categories/config/types.d.ts +28 -0
  4. package/lib/common/categories/config/utils.d.ts +31 -0
  5. package/lib/common/categories/config/utils.js +29 -0
  6. package/lib/common/categories/models/range/typeGuards.d.ts +14 -0
  7. package/lib/common/categories/models/range/typeGuards.js +18 -0
  8. package/lib/common/categories/models/range/types.d.ts +15 -0
  9. package/lib/common/categories/models/range/types.js +1 -0
  10. package/lib/common/categories/models/range/utils.d.ts +23 -0
  11. package/lib/common/categories/models/range/utils.js +41 -0
  12. package/lib/common/categories/models/select/utils.d.ts +8 -0
  13. package/lib/common/categories/models/select/utils.js +16 -0
  14. package/lib/common/categories/models/types.d.ts +6 -0
  15. package/lib/common/categories/models/types.js +1 -0
  16. package/lib/common/categories/views/common/types.d.ts +10 -0
  17. package/lib/common/categories/views/common/types.js +1 -0
  18. package/lib/common/categories/views/range/typeGuards.d.ts +8 -0
  19. package/lib/common/categories/views/range/typeGuards.js +8 -0
  20. package/lib/common/categories/views/range/types.d.ts +19 -0
  21. package/lib/common/categories/views/range/types.js +1 -0
  22. package/lib/common/categories/views/range/utils.d.ts +12 -0
  23. package/lib/common/categories/views/range/utils.js +24 -0
  24. package/lib/common/categories/views/select/typeGuards.d.ts +8 -0
  25. package/lib/common/categories/views/select/typeGuards.js +8 -0
  26. package/lib/common/categories/views/select/types.d.ts +7 -0
  27. package/lib/common/categories/views/select/types.js +1 -0
  28. package/lib/common/categories/views/types.d.ts +13 -0
  29. package/lib/common/categories/views/types.js +8 -0
  30. package/lib/common/entities.d.ts +5 -2
  31. package/lib/components/DataDictionary/components/Table/components/BasicCell/basicCell.d.ts +3 -2
  32. package/lib/components/DataDictionary/components/Table/components/BasicCell/basicCell.js +6 -2
  33. package/lib/components/DataDictionary/components/Table/components/BasicCell/utils.d.ts +9 -0
  34. package/lib/components/DataDictionary/components/Table/components/BasicCell/utils.js +12 -0
  35. package/lib/components/DataDictionary/dataDictionary.styles.js +2 -3
  36. package/lib/components/Filter/components/Filter/filter.d.ts +2 -2
  37. package/lib/components/Filter/components/Filter/filter.js +11 -3
  38. package/lib/components/Filter/components/Filter/stories/args.d.ts +5 -0
  39. package/lib/components/Filter/components/Filter/stories/args.js +19 -0
  40. package/lib/components/Filter/components/Filter/stories/filter.stories.d.ts +8 -0
  41. package/lib/components/Filter/components/Filter/stories/filter.stories.js +21 -0
  42. package/lib/components/Filter/components/FilterMenu/filterMenu.js +2 -2
  43. package/lib/components/Filter/components/FilterMenu/filterMenu.styles.d.ts +1 -1
  44. package/lib/components/Filter/components/FilterMenu/filterMenu.styles.js +1 -1
  45. package/lib/components/Filter/components/FilterRange/constants.d.ts +0 -2
  46. package/lib/components/Filter/components/FilterRange/constants.js +0 -5
  47. package/lib/components/Filter/components/FilterRange/filterRange.d.ts +1 -1
  48. package/lib/components/Filter/components/FilterRange/filterRange.js +50 -21
  49. package/lib/components/Filter/components/FilterRange/filterRange.styles.js +58 -10
  50. package/lib/components/Filter/components/FilterRange/hooks/UseFilterRange/constants.d.ts +5 -0
  51. package/lib/components/Filter/components/FilterRange/hooks/UseFilterRange/constants.js +5 -0
  52. package/lib/components/Filter/components/FilterRange/hooks/UseFilterRange/hook.d.ts +2 -2
  53. package/lib/components/Filter/components/FilterRange/hooks/UseFilterRange/hook.js +32 -7
  54. package/lib/components/Filter/components/FilterRange/hooks/UseFilterRange/schema.d.ts +6 -0
  55. package/lib/components/Filter/components/FilterRange/hooks/UseFilterRange/schema.js +50 -0
  56. package/lib/components/Filter/components/FilterRange/hooks/UseFilterRange/types.d.ts +26 -3
  57. package/lib/components/Filter/components/FilterRange/hooks/UseFilterRange/types.js +6 -1
  58. package/lib/components/Filter/components/FilterRange/hooks/UseFilterRange/utils.d.ts +15 -0
  59. package/lib/components/Filter/components/FilterRange/hooks/UseFilterRange/utils.js +25 -0
  60. package/lib/components/Filter/components/FilterRange/stories/args.d.ts +3 -0
  61. package/lib/components/Filter/components/FilterRange/stories/args.js +13 -0
  62. package/lib/components/Filter/components/FilterRange/stories/filterRange.stories.js +2 -2
  63. package/lib/components/Filter/components/FilterRange/types.d.ts +10 -6
  64. package/lib/components/Filter/components/FilterRange/types.js +1 -6
  65. package/lib/components/Filter/components/FilterRange/utils.d.ts +8 -0
  66. package/lib/components/Filter/components/FilterRange/utils.js +15 -0
  67. package/lib/components/Filter/components/FilterTag/stories/args.d.ts +5 -0
  68. package/lib/components/Filter/components/FilterTag/stories/args.js +17 -0
  69. package/lib/components/Filter/components/FilterTag/stories/filterTag.stories.d.ts +8 -0
  70. package/lib/components/Filter/components/FilterTag/stories/filterTag.stories.js +21 -0
  71. package/lib/components/Filter/components/FilterTag/utils.d.ts +10 -0
  72. package/lib/components/Filter/components/FilterTag/utils.js +40 -0
  73. package/lib/components/Filter/components/Filters/filters.d.ts +2 -2
  74. package/lib/components/Filter/components/Filters/filters.js +15 -8
  75. package/lib/components/Filter/components/Filters/stories/args.d.ts +3 -0
  76. package/lib/components/Filter/components/Filters/stories/args.js +15 -0
  77. package/lib/components/Filter/components/Filters/stories/constants.d.ts +22 -0
  78. package/lib/components/Filter/components/Filters/stories/constants.js +134 -0
  79. package/lib/components/Filter/components/Filters/stories/filters.stories.d.ts +6 -0
  80. package/lib/components/Filter/components/Filters/stories/filters.stories.js +15 -0
  81. package/lib/components/Filter/components/SearchAllFilters/components/VariableSizeList/VariableSizeList.d.ts +1 -1
  82. package/lib/components/Filter/components/SearchAllFilters/components/VariableSizeList/VariableSizeList.js +5 -5
  83. package/lib/components/Filter/components/SearchAllFilters/components/VariableSizeListItem/variableSizeListItem.js +2 -1
  84. package/lib/components/Filter/components/SearchAllFilters/searchAllFilters.d.ts +3 -2
  85. package/lib/components/Filter/components/SearchAllFilters/searchAllFilters.js +6 -4
  86. package/lib/components/Filter/components/VariableSizeListItem/variableSizeListItem.js +2 -1
  87. package/lib/components/Index/components/EntitiesView/components/ChartView/utils.js +2 -0
  88. package/lib/components/Index/table/hook.js +4 -0
  89. package/lib/components/Table/columnDef/accessorFn/typeGuards.d.ts +9 -0
  90. package/lib/components/Table/columnDef/accessorFn/typeGuards.js +10 -0
  91. package/lib/components/Table/common/utils.d.ts +2 -2
  92. package/lib/components/Table/common/utils.js +28 -13
  93. package/lib/components/Table/components/TableCell/components/ChipCell/chipCell.d.ts +3 -0
  94. package/lib/components/Table/components/TableCell/components/ChipCell/chipCell.js +8 -0
  95. package/lib/components/Table/components/TableCell/components/LinkCell/linkCell.d.ts +4 -0
  96. package/lib/components/Table/components/TableCell/components/LinkCell/linkCell.js +21 -0
  97. package/lib/components/Table/components/TableCell/components/LinkCell/stories/args.d.ts +6 -0
  98. package/lib/components/Table/components/TableCell/components/LinkCell/stories/args.js +27 -0
  99. package/lib/components/Table/components/TableCell/components/LinkCell/stories/linkCell.stories.d.ts +9 -0
  100. package/lib/components/Table/components/TableCell/components/LinkCell/stories/linkCell.stories.js +18 -0
  101. package/lib/components/Table/components/TableCell/components/LinkCell/stories/types.d.ts +3 -0
  102. package/lib/components/Table/components/TableCell/components/LinkCell/stories/types.js +1 -0
  103. package/lib/components/Table/components/TableCell/components/LinkCell/utils.d.ts +22 -0
  104. package/lib/components/Table/components/TableCell/components/LinkCell/utils.js +45 -0
  105. package/lib/components/Table/featureOptions/facetedColumn/getFacetedMinMaxValues.d.ts +8 -0
  106. package/lib/components/Table/featureOptions/facetedColumn/getFacetedMinMaxValues.js +46 -0
  107. package/lib/components/common/Link/typeGuards.d.ts +13 -0
  108. package/lib/components/common/Link/typeGuards.js +21 -0
  109. package/lib/config/entities.d.ts +2 -11
  110. package/lib/hooks/useCategoryFilter.d.ts +8 -13
  111. package/lib/hooks/useCategoryFilter.js +31 -28
  112. package/lib/providers/exploreState/entities.d.ts +5 -3
  113. package/lib/providers/exploreState/payloads/entities.d.ts +6 -2
  114. package/lib/providers/exploreState.d.ts +3 -2
  115. package/lib/providers/exploreState.js +1 -1
  116. package/lib/tests/utils.d.ts +24 -0
  117. package/lib/tests/utils.js +34 -0
  118. package/lib/theme/common/components.js +19 -1
  119. package/lib/views/ExploreView/exploreView.js +10 -8
  120. package/package.json +2 -1
  121. package/src/common/categories/config/types.ts +42 -0
  122. package/src/common/categories/config/utils.ts +47 -0
  123. package/src/common/categories/models/range/typeGuards.ts +24 -0
  124. package/src/common/categories/models/range/types.ts +17 -0
  125. package/src/common/categories/models/range/utils.ts +51 -0
  126. package/src/common/categories/models/select/utils.ts +23 -0
  127. package/src/common/categories/models/types.ts +7 -0
  128. package/src/common/categories/views/common/types.ts +11 -0
  129. package/src/common/categories/views/range/typeGuards.ts +13 -0
  130. package/src/common/categories/views/range/types.ts +21 -0
  131. package/src/common/categories/views/range/utils.ts +35 -0
  132. package/src/common/categories/views/select/typeGuards.ts +13 -0
  133. package/src/common/categories/views/select/types.ts +8 -0
  134. package/src/common/categories/views/types.ts +15 -0
  135. package/src/common/entities.ts +10 -5
  136. package/src/components/DataDictionary/components/Table/components/BasicCell/basicCell.tsx +12 -4
  137. package/src/components/DataDictionary/components/Table/components/BasicCell/utils.ts +13 -0
  138. package/src/components/DataDictionary/dataDictionary.styles.ts +2 -3
  139. package/src/components/Filter/components/Filter/filter.tsx +38 -13
  140. package/src/components/Filter/components/Filter/stories/args.ts +24 -0
  141. package/src/components/Filter/components/Filter/stories/filter.stories.tsx +32 -0
  142. package/src/components/Filter/components/FilterMenu/filterMenu.styles.ts +1 -1
  143. package/src/components/Filter/components/FilterMenu/filterMenu.tsx +7 -3
  144. package/src/components/Filter/components/FilterRange/constants.ts +0 -7
  145. package/src/components/Filter/components/FilterRange/filterRange.styles.ts +58 -14
  146. package/src/components/Filter/components/FilterRange/filterRange.tsx +112 -40
  147. package/src/components/Filter/components/FilterRange/hooks/UseFilterRange/constants.ts +5 -0
  148. package/src/components/Filter/components/FilterRange/hooks/UseFilterRange/hook.ts +51 -10
  149. package/src/components/Filter/components/FilterRange/hooks/UseFilterRange/schema.ts +60 -0
  150. package/src/components/Filter/components/FilterRange/hooks/UseFilterRange/types.ts +34 -3
  151. package/src/components/Filter/components/FilterRange/hooks/UseFilterRange/utils.ts +32 -0
  152. package/src/components/Filter/components/FilterRange/stories/args.ts +16 -0
  153. package/src/components/Filter/components/FilterRange/stories/filterRange.stories.tsx +2 -2
  154. package/src/components/Filter/components/FilterRange/types.ts +12 -6
  155. package/src/components/Filter/components/FilterRange/utils.ts +16 -0
  156. package/src/components/Filter/components/FilterTag/stories/args.ts +22 -0
  157. package/src/components/Filter/components/FilterTag/stories/filterTag.stories.tsx +32 -0
  158. package/src/components/Filter/components/FilterTag/utils.ts +57 -0
  159. package/src/components/Filter/components/Filters/filters.tsx +21 -12
  160. package/src/components/Filter/components/Filters/stories/args.ts +24 -0
  161. package/src/components/Filter/components/Filters/stories/constants.ts +151 -0
  162. package/src/components/Filter/components/Filters/stories/filters.stories.tsx +24 -0
  163. package/src/components/Filter/components/SearchAllFilters/components/VariableSizeList/VariableSizeList.tsx +32 -29
  164. package/src/components/Filter/components/SearchAllFilters/components/VariableSizeListItem/variableSizeListItem.tsx +9 -1
  165. package/src/components/Filter/components/SearchAllFilters/searchAllFilters.tsx +12 -6
  166. package/src/components/Filter/components/VariableSizeListItem/variableSizeListItem.tsx +2 -1
  167. package/src/components/Index/components/EntitiesView/components/ChartView/utils.ts +2 -0
  168. package/src/components/Index/table/hook.ts +4 -0
  169. package/src/components/Table/columnDef/accessorFn/typeGuards.ts +15 -0
  170. package/src/components/Table/common/utils.ts +37 -16
  171. package/src/components/Table/components/TableCell/components/ChipCell/chipCell.tsx +14 -0
  172. package/src/components/Table/components/TableCell/components/LinkCell/linkCell.tsx +64 -0
  173. package/src/components/Table/components/TableCell/components/LinkCell/stories/args.ts +35 -0
  174. package/src/components/Table/components/TableCell/components/LinkCell/stories/linkCell.stories.tsx +32 -0
  175. package/src/components/Table/components/TableCell/components/LinkCell/stories/types.ts +4 -0
  176. package/src/components/Table/components/TableCell/components/LinkCell/utils.ts +59 -0
  177. package/src/components/Table/featureOptions/facetedColumn/getFacetedMinMaxValues.ts +64 -0
  178. package/src/components/common/Link/typeGuards.ts +35 -0
  179. package/src/config/entities.ts +1 -14
  180. package/src/hooks/useCategoryFilter.ts +56 -53
  181. package/src/providers/exploreState/entities.ts +3 -3
  182. package/src/providers/exploreState/initializer/utils.ts +1 -1
  183. package/src/providers/exploreState/payloads/entities.ts +5 -2
  184. package/src/providers/exploreState.tsx +5 -3
  185. package/src/tests/utils.ts +44 -0
  186. package/src/theme/common/components.ts +19 -1
  187. package/src/views/ExploreView/exploreView.tsx +17 -22
  188. package/tests/filter.test.tsx +100 -0
  189. package/tests/filterRange.test.tsx +331 -46
  190. package/tests/filters.test.tsx +61 -0
  191. package/tests/getFacetedMinMaxValues.test.ts +166 -0
  192. package/tests/linkCell.test.tsx +89 -0
  193. package/lib/components/DataDictionary/components/Table/components/BasicCell/types.d.ts +0 -3
  194. package/lib/components/Filter/components/Filter/filter.stories.d.ts +0 -25
  195. package/lib/components/Filter/components/Filter/filter.stories.js +0 -42
  196. package/lib/components/Filter/components/FilterTag/filterTag.stories.d.ts +0 -16
  197. package/lib/components/Filter/components/FilterTag/filterTag.stories.js +0 -17
  198. package/lib/components/Filter/components/Filters/filters.stories.d.ts +0 -6
  199. package/lib/components/Filter/components/Filters/filters.stories.js +0 -91
  200. package/src/components/DataDictionary/components/Table/components/BasicCell/types.ts +0 -7
  201. package/src/components/Filter/components/Filter/filter.stories.tsx +0 -52
  202. package/src/components/Filter/components/FilterTag/filterTag.stories.tsx +0 -23
  203. package/src/components/Filter/components/Filters/filters.stories.tsx +0 -101
  204. package/tests/filterRangeMock.test.tsx +0 -38
  205. /package/lib/{components/DataDictionary/components/Table/components/BasicCell → common/categories/config}/types.js +0 -0
@@ -3,11 +3,12 @@ import {
3
3
  GroupingState,
4
4
  RowSelectionState,
5
5
  } from "@tanstack/react-table";
6
+ import { Category } from "../../../common/categories/models/types";
7
+ import { VIEW_KIND } from "../../../common/categories/views/types";
6
8
  import {
7
9
  CategoryKey,
8
10
  CategoryValueKey,
9
11
  PaginationDirectionType,
10
- SelectCategory,
11
12
  SelectedFilter,
12
13
  } from "../../../common/entities";
13
14
  import { RowPreviewState } from "../../../components/Table/features/RowPreview/entities";
@@ -21,6 +22,7 @@ export interface ApplySavedFilterPayload {
21
22
  categoryKey: CategoryKey;
22
23
  selected: boolean;
23
24
  selectedValue: CategoryValueKey;
25
+ viewKind?: VIEW_KIND; // viewKind is included here because this payload shares a dispatch with UpdateFilter.
24
26
  }
25
27
 
26
28
  /**
@@ -43,7 +45,7 @@ export interface ProcessExploreResponsePayload {
43
45
  listItems: ListItems;
44
46
  loading: boolean;
45
47
  paginationResponse: PaginationResponse;
46
- selectCategories?: SelectCategory[];
48
+ selectCategories?: Category[];
47
49
  }
48
50
 
49
51
  /**
@@ -74,6 +76,7 @@ export interface UpdateFilterPayload {
74
76
  categoryKey: CategoryKey;
75
77
  selected: boolean;
76
78
  selectedValue: CategoryValueKey;
79
+ viewKind?: VIEW_KIND;
77
80
  }
78
81
 
79
82
  /**
@@ -9,7 +9,8 @@ import React, {
9
9
  useState,
10
10
  } from "react";
11
11
  import { AzulSearchIndex } from "../apis/azul/common/entities";
12
- import { SelectCategoryView, SelectedFilter } from "../common/entities";
12
+ import { CategoryView } from "../common/categories/views/types";
13
+ import { SelectedFilter } from "../common/entities";
13
14
  import { RowPreviewState } from "../components/Table/features/RowPreview/entities";
14
15
  import { CategoryGroup, SiteConfig } from "../config/entities";
15
16
  import { useToken } from "../hooks/authentication/token/useToken";
@@ -78,7 +79,7 @@ export interface ExploreContext {
78
79
  export type ExploreState = {
79
80
  catalogState: CatalogState;
80
81
  categoryGroups?: CategoryGroup[];
81
- categoryViews: SelectCategoryView[];
82
+ categoryViews: CategoryView[];
82
83
  entityPageState: EntityPageStateMapper;
83
84
  entityStateByCategoryGroupConfigKey: EntityStateByCategoryGroupConfigKey;
84
85
  featureFlagState: FeatureFlagState;
@@ -638,7 +639,8 @@ function exploreReducer(
638
639
  state.filterState,
639
640
  payload.categoryKey,
640
641
  payload.selectedValue,
641
- payload.selected
642
+ payload.selected,
643
+ payload.viewKind
642
644
  );
643
645
  const rowPreview = closeRowPreview(state.rowPreview);
644
646
  const rowSelection: RowSelectionState = {};
@@ -0,0 +1,44 @@
1
+ import { screen } from "@testing-library/react";
2
+ import { escapeRegExp } from "../common/utils";
3
+
4
+ /**
5
+ * Retrieves a button by its name.
6
+ * @param name - The name of the button.
7
+ * @returns The button element.
8
+ */
9
+ export function getButton<T extends HTMLElement = HTMLElement>(
10
+ name: string | RegExp
11
+ ): T {
12
+ return screen.getByRole("button", { name });
13
+ }
14
+
15
+ /**
16
+ * Retrieves an input element by its label text.
17
+ * @param text - The label text of the input element.
18
+ * @returns The input element.
19
+ */
20
+ export function getLabelText<T extends HTMLElement = HTMLElement>(
21
+ text: string
22
+ ): T {
23
+ return screen.getByLabelText(text);
24
+ }
25
+
26
+ /**
27
+ * Returns regex that matches the start of the given text.
28
+ * @param text - Text to match.
29
+ * @returns RegExp.
30
+ */
31
+ export function getStartsWithRegex(text: string): RegExp {
32
+ return new RegExp(`^${escapeRegExp(text)}`);
33
+ }
34
+
35
+ /**
36
+ * Retrieves an element by its text content.
37
+ * @param text - The text content of the element.
38
+ * @returns The element.
39
+ */
40
+ export function getText<T extends HTMLElement = HTMLElement>(
41
+ text: string | RegExp
42
+ ): T {
43
+ return screen.getByText(text);
44
+ }
@@ -410,6 +410,14 @@ export const MuiChip = (theme: Theme): Components["MuiChip"] => {
410
410
  },
411
411
  label: {
412
412
  ...theme.typography[TEXT_BODY_SMALL_400],
413
+ variants: [
414
+ {
415
+ props: { variant: "status" },
416
+ style: {
417
+ ...theme.typography[TEXT_BODY_SMALL_500],
418
+ },
419
+ },
420
+ ],
413
421
  },
414
422
  },
415
423
  variants: [
@@ -489,13 +497,18 @@ export const MuiChip = (theme: Theme): Components["MuiChip"] => {
489
497
  {
490
498
  props: { variant: "status" },
491
499
  style: {
492
- ...theme.typography[TEXT_BODY_SMALL_500],
493
500
  boxShadow: `0 0 0 2px ${PALETTE.COMMON_WHITE}`,
494
501
  height: 20,
495
502
  maxWidth: "fit-content",
496
503
  minWidth: 0,
497
504
  },
498
505
  },
506
+ {
507
+ props: { color: "default", variant: "status" },
508
+ style: {
509
+ color: PALETTE.INK_LIGHT,
510
+ },
511
+ },
499
512
  ],
500
513
  };
501
514
  };
@@ -902,6 +915,11 @@ export const MuiLink: Components["MuiLink"] = {
902
915
  textDecorationSkipInk: "none",
903
916
  textUnderlinePosition: "from-font",
904
917
  },
918
+ underlineNone: {
919
+ "&:hover": {
920
+ textDecoration: "none",
921
+ },
922
+ },
905
923
  },
906
924
  };
907
925
 
@@ -5,11 +5,8 @@ import {
5
5
  } from "../../apis/azul/common/entities";
6
6
  import { track } from "../../common/analytics/analytics";
7
7
  import { EVENT_NAME, EVENT_PARAM } from "../../common/analytics/entities";
8
- import {
9
- CategoryKey,
10
- CategoryValueKey,
11
- SelectCategoryView,
12
- } from "../../common/entities";
8
+ import { CategoryView, VIEW_KIND } from "../../common/categories/views/types";
9
+ import { CategoryKey, CategoryValueKey } from "../../common/entities";
13
10
  import { ComponentCreator } from "../../components/ComponentCreator/ComponentCreator";
14
11
  import { ClearAllFilters } from "../../components/Filter/components/ClearAllFilters/clearAllFilters";
15
12
  import {
@@ -76,6 +73,7 @@ export const ExploreView = (props: ExploreViewProps): JSX.Element => {
76
73
  * @param selectedCategoryValue - The value to set or clear.
77
74
  * @param selected - Indication of whether the selected value is being set or cleared.
78
75
  * @param categorySection - Name of group the category is in.
76
+ * @param viewKind - View kind.
79
77
  * @param searchTerm - Search term used to find the value.
80
78
  */
81
79
  const onFilterChange = (
@@ -84,6 +82,7 @@ export const ExploreView = (props: ExploreViewProps): JSX.Element => {
84
82
  selectedCategoryValue: CategoryValueKey,
85
83
  selected: boolean,
86
84
  categorySection?: string,
85
+ viewKind?: VIEW_KIND,
87
86
  searchTerm?: string
88
87
  ): void => {
89
88
  const dispatchType =
@@ -96,6 +95,7 @@ export const ExploreView = (props: ExploreViewProps): JSX.Element => {
96
95
  categoryKey,
97
96
  selected,
98
97
  selectedValue: selectedCategoryValue,
98
+ viewKind,
99
99
  },
100
100
  type: dispatchType,
101
101
  });
@@ -188,33 +188,28 @@ export const ExploreView = (props: ExploreViewProps): JSX.Element => {
188
188
 
189
189
  /**
190
190
  * Builds the category views into category views grouped by the given category group configuration.
191
- * @param selectCategoryViews - View models of categories to display.
191
+ * @param categoryViews - View models of categories to display.
192
192
  * @param categoryGroups - Category groups.
193
193
  * @returns category filters.
194
194
  */
195
195
  function buildCategoryFilters(
196
- selectCategoryViews: SelectCategoryView[],
196
+ categoryViews: CategoryView[],
197
197
  categoryGroups?: CategoryGroup[]
198
198
  ): CategoryFilter[] {
199
199
  if (!categoryGroups) {
200
- return [{ categoryViews: selectCategoryViews }];
200
+ return [{ categoryViews }];
201
201
  }
202
202
  return categoryGroups.reduce((accGroups, { categoryConfigs, label }) => {
203
203
  // Grab the category views for the configured grouped categories.
204
- const categoryViews = categoryConfigs.reduce(
205
- (accViews, { key: categoryKey }) => {
206
- const categoryView = selectCategoryViews.find(
207
- ({ key }) => key === categoryKey
208
- );
209
- if (categoryView) {
210
- accViews.push(categoryView);
211
- }
212
- return accViews;
213
- },
214
- [] as SelectCategoryView[]
215
- );
216
- if (categoryViews.length > 0) {
217
- accGroups.push({ categoryViews, label });
204
+ const views = categoryConfigs.reduce((accViews, { key: categoryKey }) => {
205
+ const categoryView = categoryViews.find(({ key }) => key === categoryKey);
206
+ if (categoryView) {
207
+ accViews.push(categoryView);
208
+ }
209
+ return accViews;
210
+ }, [] as CategoryView[]);
211
+ if (views.length > 0) {
212
+ accGroups.push({ categoryViews: views, label });
218
213
  }
219
214
  return accGroups;
220
215
  }, [] as CategoryFilter[]);
@@ -0,0 +1,100 @@
1
+ import { jest } from "@jest/globals";
2
+ import { composeStories } from "@storybook/react";
3
+ import { render, screen, waitFor, within } from "@testing-library/react";
4
+ import { userEvent } from "@testing-library/user-event";
5
+ import React from "react";
6
+ import { VIEW_KIND } from "../src/common/categories/views/types";
7
+ import * as stories from "../src/components/Filter/components/Filter/stories/filter.stories";
8
+ import { TEST_IDS } from "../src/tests/testIds";
9
+ import { getButton } from "../src/tests/utils";
10
+
11
+ const { RangeCategory } = composeStories(stories);
12
+
13
+ const TEST_VALUES = {
14
+ ON_FILTER_BY_RANGE: RangeCategory.args.onFilter,
15
+ RANGE_CATEGORY: RangeCategory.args.categoryView,
16
+ RANGE_CATEGORY_KEY: RangeCategory.args.categoryView?.key,
17
+ };
18
+
19
+ /**
20
+ * Tests for the Filter component.
21
+ * TODO(cc) add tests:
22
+ * - selected values (rending of tags) for select and range categories
23
+ * - disabled state
24
+ * - select category view
25
+ */
26
+
27
+ describe("Filter", () => {
28
+ describe("RANGE Category", () => {
29
+ let buttonEl: HTMLButtonElement;
30
+
31
+ beforeEach(() => {
32
+ jest.clearAllMocks();
33
+ render(<RangeCategory />);
34
+ const expectedLabel = TEST_VALUES.RANGE_CATEGORY?.label;
35
+ buttonEl = screen.getByRole("button", { name: expectedLabel });
36
+ });
37
+
38
+ it("renders filter label", () => {
39
+ expect(buttonEl).toBeDefined();
40
+ });
41
+
42
+ it("opens popover when filter button is clicked", async () => {
43
+ await openPopover(buttonEl);
44
+ });
45
+
46
+ it("calls onFilter with correct values", async () => {
47
+ await openPopover(buttonEl);
48
+ const popoverEl = getPopoverEl();
49
+ const inputEl = within(popoverEl).getByLabelText("Min");
50
+ await userEvent.type(inputEl, "100");
51
+ await userEvent.click(getButton("Filter"));
52
+ await waitFor(() => {
53
+ expect(TEST_VALUES.ON_FILTER_BY_RANGE).toHaveBeenCalledTimes(1);
54
+ expect(TEST_VALUES.ON_FILTER_BY_RANGE).toHaveBeenCalledWith(
55
+ TEST_VALUES.RANGE_CATEGORY_KEY,
56
+ [100, null],
57
+ true,
58
+ undefined,
59
+ VIEW_KIND.RANGE
60
+ );
61
+ });
62
+ });
63
+
64
+ it("closes popover with keyboard escape", async () => {
65
+ await openPopover(buttonEl);
66
+ await closePopover();
67
+ });
68
+ });
69
+ });
70
+
71
+ /**
72
+ * Retrieves the popover element.
73
+ * @returns The popover element.
74
+ */
75
+ function getPopoverEl(): HTMLElement {
76
+ return screen.getByTestId(TEST_IDS.FILTER_POPOVER);
77
+ }
78
+
79
+ /**
80
+ * Closes the popover with keyboard escape.
81
+ * @returns A promise that resolves when the popover is closed.
82
+ */
83
+ async function closePopover(): Promise<void> {
84
+ await userEvent.keyboard("{Escape}");
85
+ await waitFor(() => {
86
+ expect(screen.queryByTestId(TEST_IDS.FILTER_POPOVER)).toBeNull();
87
+ });
88
+ }
89
+
90
+ /**
91
+ * Opens the popover by clicking the button.
92
+ * @param buttonEl - The button element to click.
93
+ * @returns A promise that resolves when the popover is opened.
94
+ */
95
+ async function openPopover(buttonEl: HTMLButtonElement): Promise<void> {
96
+ await userEvent.click(buttonEl);
97
+ await waitFor(() => {
98
+ expect(screen.getByTestId(TEST_IDS.FILTER_POPOVER)).toBeDefined();
99
+ });
100
+ }