@databiosphere/findable-ui 33.0.0 → 34.1.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 (213) hide show
  1. package/.release-please-manifest.json +1 -1
  2. package/CHANGELOG.md +18 -0
  3. package/jest.config.js +4 -0
  4. package/lib/common/entities.d.ts +3 -1
  5. package/lib/components/DataDictionary/components/Entities/entities.d.ts +1 -1
  6. package/lib/components/DataDictionary/components/Entities/entities.js +3 -2
  7. package/lib/components/DataDictionary/components/Entities/types.d.ts +3 -4
  8. package/lib/components/DataDictionary/components/Entity/entity.d.ts +1 -1
  9. package/lib/components/DataDictionary/components/Entity/entity.js +12 -6
  10. package/lib/components/DataDictionary/components/Entity/entity.styles.js +7 -1
  11. package/lib/components/DataDictionary/components/Entity/types.d.ts +4 -4
  12. package/lib/components/DataDictionary/components/Entity/utils.d.ts +9 -0
  13. package/lib/components/DataDictionary/components/Entity/utils.js +18 -0
  14. package/lib/components/DataDictionary/components/Filters/components/ColumnFilters/columnFilters.d.ts +4 -0
  15. package/lib/components/DataDictionary/components/Filters/components/ColumnFilters/columnFilters.js +9 -0
  16. package/lib/components/DataDictionary/components/Filters/components/ColumnFilters/types.d.ts +5 -0
  17. package/lib/components/DataDictionary/components/Filters/components/ColumnFilters/types.js +1 -0
  18. package/lib/components/DataDictionary/components/Filters/filters.d.ts +4 -0
  19. package/lib/components/DataDictionary/components/Filters/filters.js +7 -0
  20. package/lib/components/DataDictionary/components/Filters/filters.styles.d.ts +7 -0
  21. package/lib/components/DataDictionary/components/Filters/filters.styles.js +13 -0
  22. package/lib/components/DataDictionary/components/Filters/stories/constants.d.ts +4 -0
  23. package/lib/components/DataDictionary/components/Filters/stories/constants.js +25 -0
  24. package/lib/components/DataDictionary/components/Filters/stories/filters.stories.d.ts +6 -0
  25. package/lib/components/DataDictionary/components/Filters/stories/filters.stories.js +31 -0
  26. package/lib/components/DataDictionary/components/Filters/stories/hook.d.ts +5 -0
  27. package/lib/components/DataDictionary/components/Filters/stories/hook.js +5 -0
  28. package/lib/components/DataDictionary/components/Filters/stories/types.d.ts +4 -0
  29. package/lib/components/DataDictionary/components/Filters/stories/types.js +1 -0
  30. package/lib/components/DataDictionary/components/Filters/types.d.ts +5 -0
  31. package/lib/components/DataDictionary/components/Filters/types.js +1 -0
  32. package/lib/components/DataDictionary/components/Layout/components/EntitiesLayout/entitiesLayout.styles.js +3 -1
  33. package/lib/components/DataDictionary/components/Layout/components/FiltersLayout/filtersLayout.d.ts +2 -0
  34. package/lib/components/DataDictionary/components/Layout/components/FiltersLayout/filtersLayout.js +5 -0
  35. package/lib/components/DataDictionary/components/Layout/components/FiltersLayout/filtersLayout.styles.d.ts +5 -0
  36. package/lib/components/DataDictionary/components/Layout/components/FiltersLayout/filtersLayout.styles.js +24 -0
  37. package/lib/components/DataDictionary/components/Layout/components/FiltersLayout/types.d.ts +5 -0
  38. package/lib/components/DataDictionary/components/Layout/components/FiltersLayout/types.js +1 -0
  39. package/lib/components/DataDictionary/components/Layout/components/OutlineLayout/outlineLayout.styles.js +1 -1
  40. package/lib/components/DataDictionary/components/Layout/components/TitleLayout/titleLayout.styles.js +1 -0
  41. package/lib/components/DataDictionary/components/Layout/constants.d.ts +4 -0
  42. package/lib/components/DataDictionary/components/Layout/constants.js +4 -0
  43. package/lib/components/DataDictionary/components/Outline/utils.d.ts +5 -5
  44. package/lib/components/DataDictionary/components/Outline/utils.js +23 -6
  45. package/lib/components/DataDictionary/components/Table/hook.d.ts +3 -3
  46. package/lib/components/DataDictionary/components/Table/hook.js +11 -3
  47. package/lib/components/DataDictionary/components/Table/options/columnFilters/constants.d.ts +2 -0
  48. package/lib/components/DataDictionary/components/Table/options/columnFilters/constants.js +8 -0
  49. package/lib/components/DataDictionary/components/Table/options/columnFilters/hook.d.ts +6 -0
  50. package/lib/components/DataDictionary/components/Table/options/columnFilters/hook.js +14 -0
  51. package/lib/components/DataDictionary/components/Table/options/expanded/constants.d.ts +2 -0
  52. package/lib/components/DataDictionary/components/Table/options/expanded/constants.js +5 -0
  53. package/lib/components/DataDictionary/components/Table/options/faceted/constants.d.ts +2 -0
  54. package/lib/components/DataDictionary/components/Table/options/faceted/constants.js +6 -0
  55. package/lib/components/DataDictionary/components/Table/options/grouping/constants.d.ts +2 -0
  56. package/lib/components/DataDictionary/components/Table/options/grouping/constants.js +5 -0
  57. package/lib/components/DataDictionary/components/Table/options/hook.d.ts +1 -1
  58. package/lib/components/DataDictionary/components/Table/options/hook.js +17 -0
  59. package/lib/components/DataDictionary/components/Table/options/visibility/constants.d.ts +2 -0
  60. package/lib/components/DataDictionary/components/Table/options/visibility/constants.js +3 -0
  61. package/lib/components/DataDictionary/components/Table/table.d.ts +1 -1
  62. package/lib/components/DataDictionary/components/Table/table.js +2 -2
  63. package/lib/components/DataDictionary/components/Table/types.d.ts +4 -1
  64. package/lib/components/DataDictionary/components/Table/utils.d.ts +18 -0
  65. package/lib/components/DataDictionary/components/Table/utils.js +27 -0
  66. package/lib/components/DataDictionary/dataDictionary.d.ts +1 -1
  67. package/lib/components/DataDictionary/dataDictionary.js +8 -6
  68. package/lib/components/DataDictionary/hooks/UseDataDictionary/hook.js +16 -5
  69. package/lib/components/DataDictionary/hooks/UseDataDictionary/types.d.ts +5 -4
  70. package/lib/components/DataDictionary/types.d.ts +1 -0
  71. package/lib/components/Detail/components/Table/components/TableBody/tableBody.d.ts +8 -2
  72. package/lib/components/Detail/components/Table/components/TableBody/tableBody.js +2 -2
  73. package/lib/components/Detail/components/Table/components/TableRows/components/CollapsableRows/collapsableRows.d.ts +8 -2
  74. package/lib/components/Detail/components/Table/components/TableRows/components/CollapsableRows/collapsableRows.js +2 -2
  75. package/lib/components/Detail/components/Table/components/TableRows/tableRows.d.ts +8 -2
  76. package/lib/components/Detail/components/Table/components/TableRows/tableRows.js +2 -2
  77. package/lib/components/Filter/components/FilterLabel/filterLabel.styles.d.ts +1 -1
  78. package/lib/components/Filter/components/FilterList/filterList.styles.d.ts +2 -0
  79. package/lib/components/Filter/components/FilterList/filterList.styles.js +28 -15
  80. package/lib/components/Filter/components/SearchAllFiltersSearch/searchAllFiltersSearch.styles.d.ts +1 -1
  81. package/lib/components/Layout/components/Header/components/Content/components/Actions/components/Authentication/components/Button/button.styles.d.ts +1 -1
  82. package/lib/components/Layout/components/Header/components/Content/components/Actions/components/Search/components/Button/button.styles.d.ts +1 -1
  83. package/lib/components/Layout/components/Outline/components/ContentsTab/contentsTab.styles.d.ts +1 -1
  84. package/lib/components/Layout/components/Outline/outline.styles.d.ts +1 -1
  85. package/lib/components/Login/components/Button/button.styles.d.ts +1 -1
  86. package/lib/components/Table/common/utils.d.ts +6 -0
  87. package/lib/components/Table/common/utils.js +14 -0
  88. package/lib/components/Table/components/TableFeatures/ColumnFilter/columnFilter.d.ts +7 -0
  89. package/lib/components/Table/components/TableFeatures/ColumnFilter/columnFilter.js +33 -0
  90. package/lib/components/Table/components/TableFeatures/ColumnFilter/columnFilter.styles.d.ts +3 -0
  91. package/lib/components/Table/components/TableFeatures/ColumnFilter/columnFilter.styles.js +19 -0
  92. package/lib/components/Table/components/TableFeatures/ColumnFilter/constants.d.ts +2 -0
  93. package/lib/components/Table/components/TableFeatures/ColumnFilter/constants.js +14 -0
  94. package/lib/components/Table/components/TableFeatures/ColumnFilter/types.d.ts +7 -0
  95. package/lib/components/Table/components/TableFeatures/ColumnFilter/types.js +1 -0
  96. package/lib/components/Table/components/TableFeatures/ColumnFilter/utils.d.ts +6 -0
  97. package/lib/components/Table/components/TableFeatures/ColumnFilter/utils.js +23 -0
  98. package/lib/components/Table/featureOptions/facetedColumn/utils.d.ts +6 -0
  99. package/lib/components/Table/featureOptions/facetedColumn/utils.js +9 -0
  100. package/lib/components/common/ButtonGroup/constants.d.ts +2 -0
  101. package/lib/components/common/ButtonGroup/constants.js +11 -0
  102. package/lib/components/common/Tabs/tabs.styles.d.ts +1 -1
  103. package/lib/mocks/@storybook/addon-actions.d.ts +9 -0
  104. package/lib/mocks/@storybook/addon-actions.js +9 -0
  105. package/lib/providers/exploreState/entities.d.ts +1 -1
  106. package/lib/providers/exploreState.js +10 -10
  107. package/lib/providers/exploreStateSync/hooks/UseMetaCommands/handlers.d.ts +10 -0
  108. package/lib/providers/exploreStateSync/hooks/UseMetaCommands/handlers.js +18 -0
  109. package/lib/providers/exploreStateSync/hooks/UseMetaCommands/hook.d.ts +1 -0
  110. package/lib/providers/exploreStateSync/hooks/UseMetaCommands/hook.js +33 -0
  111. package/lib/providers/exploreStateSync/hooks/UseMetaCommands/types.d.ts +11 -0
  112. package/lib/providers/exploreStateSync/hooks/UseMetaCommands/types.js +5 -0
  113. package/lib/providers/exploreStateSync/hooks/UseMetaCommands/utils.d.ts +34 -0
  114. package/lib/providers/exploreStateSync/hooks/UseMetaCommands/utils.js +59 -0
  115. package/lib/providers/exploreStateSync/provider.d.ts +19 -0
  116. package/lib/providers/exploreStateSync/provider.js +22 -0
  117. package/lib/styles/common/mui/buttonGroup.d.ts +13 -0
  118. package/lib/styles/common/mui/buttonGroup.js +34 -0
  119. package/lib/styles/common/mui/typography.js +2 -0
  120. package/lib/tests/mui/constants.d.ts +1 -0
  121. package/lib/tests/mui/constants.js +1 -0
  122. package/lib/tests/utils.d.ts +6 -0
  123. package/lib/tests/utils.js +8 -0
  124. package/lib/theme/common/components.d.ts +0 -6
  125. package/lib/theme/common/components.js +17 -31
  126. package/lib/theme/components/index.d.ts +1 -0
  127. package/lib/theme/components/index.js +1 -0
  128. package/lib/theme/components/muiButtonGroup.d.ts +2 -0
  129. package/lib/theme/components/muiButtonGroup.js +76 -0
  130. package/lib/theme/theme.js +1 -1
  131. package/lib/views/ExploreView/exploreView.js +2 -1
  132. package/package.json +1 -1
  133. package/src/common/entities.ts +3 -1
  134. package/src/components/DataDictionary/components/Entities/entities.tsx +5 -9
  135. package/src/components/DataDictionary/components/Entities/types.ts +3 -4
  136. package/src/components/DataDictionary/components/Entity/entity.styles.ts +9 -1
  137. package/src/components/DataDictionary/components/Entity/entity.tsx +18 -8
  138. package/src/components/DataDictionary/components/Entity/types.ts +4 -4
  139. package/src/components/DataDictionary/components/Entity/utils.ts +25 -0
  140. package/src/components/DataDictionary/components/Filters/components/ColumnFilters/columnFilters.tsx +21 -0
  141. package/src/components/DataDictionary/components/Filters/components/ColumnFilters/types.ts +6 -0
  142. package/src/components/DataDictionary/components/Filters/filters.styles.ts +14 -0
  143. package/src/components/DataDictionary/components/Filters/filters.tsx +16 -0
  144. package/src/components/DataDictionary/components/Filters/stories/constants.ts +31 -0
  145. package/src/components/DataDictionary/components/Filters/stories/filters.stories.tsx +42 -0
  146. package/src/components/DataDictionary/components/Filters/stories/hook.ts +9 -0
  147. package/src/components/DataDictionary/components/Filters/stories/types.ts +3 -0
  148. package/src/components/DataDictionary/components/Filters/types.ts +6 -0
  149. package/src/components/DataDictionary/components/Layout/components/EntitiesLayout/entitiesLayout.styles.ts +4 -1
  150. package/src/components/DataDictionary/components/Layout/components/FiltersLayout/filtersLayout.styles.ts +27 -0
  151. package/src/components/DataDictionary/components/Layout/components/FiltersLayout/filtersLayout.tsx +10 -0
  152. package/src/components/DataDictionary/components/Layout/components/FiltersLayout/types.ts +6 -0
  153. package/src/components/DataDictionary/components/Layout/components/OutlineLayout/outlineLayout.styles.ts +1 -1
  154. package/src/components/DataDictionary/components/Layout/components/TitleLayout/titleLayout.styles.ts +1 -0
  155. package/src/components/DataDictionary/components/Layout/constants.ts +4 -0
  156. package/src/components/DataDictionary/components/Outline/utils.ts +35 -13
  157. package/src/components/DataDictionary/components/Table/hook.ts +17 -5
  158. package/src/components/DataDictionary/components/Table/options/columnFilters/constants.ts +16 -0
  159. package/src/components/DataDictionary/components/Table/options/columnFilters/hook.ts +32 -0
  160. package/src/components/DataDictionary/components/Table/options/expanded/constants.ts +13 -0
  161. package/src/components/DataDictionary/components/Table/options/faceted/constants.ts +14 -0
  162. package/src/components/DataDictionary/components/Table/options/grouping/constants.ts +9 -0
  163. package/src/components/DataDictionary/components/Table/options/hook.ts +26 -3
  164. package/src/components/DataDictionary/components/Table/options/visibility/constants.ts +5 -0
  165. package/src/components/DataDictionary/components/Table/table.tsx +2 -0
  166. package/src/components/DataDictionary/components/Table/types.ts +8 -1
  167. package/src/components/DataDictionary/components/Table/utils.ts +40 -0
  168. package/src/components/DataDictionary/dataDictionary.tsx +9 -5
  169. package/src/components/DataDictionary/hooks/UseDataDictionary/hook.ts +19 -5
  170. package/src/components/DataDictionary/hooks/UseDataDictionary/types.ts +5 -4
  171. package/src/components/DataDictionary/types.ts +1 -0
  172. package/src/components/Detail/components/Table/components/TableBody/tableBody.tsx +14 -3
  173. package/src/components/Detail/components/Table/components/TableRows/components/CollapsableRows/collapsableRows.tsx +9 -2
  174. package/src/components/Detail/components/Table/components/TableRows/tableRows.tsx +9 -2
  175. package/src/components/Filter/components/FilterList/filterList.styles.ts +34 -15
  176. package/src/components/Table/common/utils.ts +16 -0
  177. package/src/components/Table/components/TableFeatures/ColumnFilter/columnFilter.styles.ts +23 -0
  178. package/src/components/Table/components/TableFeatures/ColumnFilter/columnFilter.tsx +98 -0
  179. package/src/components/Table/components/TableFeatures/ColumnFilter/constants.ts +16 -0
  180. package/src/components/Table/components/TableFeatures/ColumnFilter/types.ts +10 -0
  181. package/src/components/Table/components/TableFeatures/ColumnFilter/utils.ts +27 -0
  182. package/src/components/Table/featureOptions/facetedColumn/utils.ts +14 -0
  183. package/src/components/common/ButtonGroup/constants.ts +13 -0
  184. package/src/mocks/@storybook/addon-actions.ts +10 -0
  185. package/src/providers/exploreState/entities.ts +1 -1
  186. package/src/providers/exploreState.tsx +10 -11
  187. package/src/providers/exploreStateSync/hooks/UseMetaCommands/handlers.ts +25 -0
  188. package/src/providers/exploreStateSync/hooks/UseMetaCommands/hook.ts +38 -0
  189. package/src/providers/exploreStateSync/hooks/UseMetaCommands/types.ts +13 -0
  190. package/src/providers/exploreStateSync/hooks/UseMetaCommands/utils.ts +69 -0
  191. package/src/providers/exploreStateSync/provider.tsx +29 -0
  192. package/src/styles/common/mui/buttonGroup.ts +46 -0
  193. package/src/styles/common/mui/typography.ts +2 -0
  194. package/src/tests/mui/constants.ts +1 -0
  195. package/src/tests/utils.ts +9 -0
  196. package/src/theme/common/components.ts +17 -32
  197. package/src/theme/components/index.ts +1 -0
  198. package/src/theme/components/muiButtonGroup.ts +79 -0
  199. package/src/theme/theme.ts +1 -1
  200. package/src/views/ExploreView/exploreView.tsx +3 -2
  201. package/tests/dataDictionaryColumnFilters.test.tsx +101 -0
  202. package/lib/providers/exploreState/hooks/UseMetaCommands/actions.d.ts +0 -13
  203. package/lib/providers/exploreState/hooks/UseMetaCommands/actions.js +0 -24
  204. package/lib/providers/exploreState/hooks/UseMetaCommands/types.d.ts +0 -4
  205. package/lib/providers/exploreState/hooks/UseMetaCommands/types.js +0 -5
  206. package/lib/providers/exploreState/hooks/UseMetaCommands/useMetaCommands.d.ts +0 -2
  207. package/lib/providers/exploreState/hooks/UseMetaCommands/useMetaCommands.js +0 -21
  208. package/lib/providers/exploreState/hooks/UseMetaCommands/utils.d.ts +0 -9
  209. package/lib/providers/exploreState/hooks/UseMetaCommands/utils.js +0 -25
  210. package/src/providers/exploreState/hooks/UseMetaCommands/actions.ts +0 -29
  211. package/src/providers/exploreState/hooks/UseMetaCommands/types.ts +0 -4
  212. package/src/providers/exploreState/hooks/UseMetaCommands/useMetaCommands.ts +0 -27
  213. package/src/providers/exploreState/hooks/UseMetaCommands/utils.ts +0 -33
@@ -0,0 +1,76 @@
1
+ import { COLOR_MIXES } from "../../styles/common/constants/colorMixes";
2
+ import { PALETTE } from "../../styles/common/constants/palette";
3
+ import { BUTTON_GROUP_PROPS } from "../../styles/common/mui/buttonGroup";
4
+ const SELECTORS = {
5
+ GROUPED: `.${BUTTON_GROUP_PROPS.CLASSES.GROUPED}`,
6
+ };
7
+ export const MuiButtonGroup = {
8
+ defaultProps: {
9
+ disableElevation: true,
10
+ disableRipple: true,
11
+ },
12
+ styleOverrides: {
13
+ root: {
14
+ variants: [
15
+ /* PRIMARY CONTAINED */
16
+ {
17
+ props: {
18
+ color: BUTTON_GROUP_PROPS.COLOR.PRIMARY,
19
+ variant: BUTTON_GROUP_PROPS.VARIANT.CONTAINED,
20
+ },
21
+ style: {
22
+ [SELECTORS.GROUPED]: {
23
+ borderColor: PALETTE.PRIMARY_DARK,
24
+ boxShadow: `0 1px 0 0 ${PALETTE.PRIMARY_DARK}`,
25
+ minWidth: 0,
26
+ // eslint-disable-next-line sort-keys -- disabling key order for readability
27
+ "&:hover": {
28
+ boxShadow: `0 1px 0 0 ${PALETTE.PRIMARY_DARK}`,
29
+ },
30
+ // eslint-disable-next-line sort-keys -- disabling key order for readability
31
+ "&:active": {
32
+ boxShadow: "none",
33
+ },
34
+ },
35
+ },
36
+ },
37
+ /* SECONDARY OUTLINED */
38
+ {
39
+ props: {
40
+ color: BUTTON_GROUP_PROPS.COLOR.SECONDARY,
41
+ variant: BUTTON_GROUP_PROPS.VARIANT.OUTLINED,
42
+ },
43
+ style: {
44
+ [SELECTORS.GROUPED]: {
45
+ backgroundColor: PALETTE.COMMON_WHITE,
46
+ boxShadow: `inset 0 0 0 1px ${PALETTE.SMOKE_DARK}, 0 1px 0 0 ${COLOR_MIXES.COMMON_BLACK_08}`,
47
+ color: PALETTE.INK_MAIN,
48
+ minWidth: 0,
49
+ // eslint-disable-next-line sort-keys -- disabling key order for readability
50
+ "&:hover": {
51
+ backgroundColor: PALETTE.SMOKE_LIGHTEST,
52
+ boxShadow: `inset 0 0 0 1px ${PALETTE.SMOKE_DARK}, 0 1px 0 0 ${COLOR_MIXES.COMMON_BLACK_08}`,
53
+ },
54
+ // eslint-disable-next-line sort-keys -- disabling key order for readability
55
+ "&:active": {
56
+ backgroundColor: PALETTE.SMOKE_LIGHTEST,
57
+ boxShadow: `inset 0 0 0 1px ${PALETTE.SMOKE_DARK}`,
58
+ },
59
+ },
60
+ },
61
+ },
62
+ /* SMALL */
63
+ {
64
+ props: {
65
+ size: BUTTON_GROUP_PROPS.SIZE.SMALL,
66
+ },
67
+ style: {
68
+ [SELECTORS.GROUPED]: {
69
+ padding: "6px 8px",
70
+ },
71
+ },
72
+ },
73
+ ],
74
+ },
75
+ },
76
+ };
@@ -69,7 +69,7 @@ export function createAppTheme(customOptions = {}) {
69
69
  MuiBreadcrumbs: C.MuiBreadcrumbs(theme),
70
70
  MuiButton: C.MuiButton(theme),
71
71
  MuiButtonBase: C.MuiButtonBase(theme),
72
- MuiButtonGroup: C.MuiButtonGroup(theme),
72
+ MuiButtonGroup: M.MuiButtonGroup,
73
73
  MuiCard: C.MuiCard,
74
74
  MuiCheckbox: C.MuiCheckbox(theme),
75
75
  MuiChip: C.MuiChip(theme),
@@ -18,6 +18,7 @@ import { useExploreState } from "../../hooks/useExploreState";
18
18
  import { useSummary } from "../../hooks/useSummary";
19
19
  import { ExploreActionKind } from "../../providers/exploreState";
20
20
  import { SELECT_CATEGORY_KEY } from "../../providers/exploreState/constants";
21
+ import { ExploreStateSyncProvider } from "../../providers/exploreStateSync/provider";
21
22
  import { TEST_IDS } from "../../tests/testIds";
22
23
  import { DESKTOP_SM } from "../../theme/common/breakpoints";
23
24
  export const ExploreView = (props) => {
@@ -98,7 +99,7 @@ export const ExploreView = (props) => {
98
99
  });
99
100
  }
100
101
  }, [entityListType, exploreDispatch]);
101
- return (React.createElement(React.Fragment, null,
102
+ return (React.createElement(ExploreStateSyncProvider, null,
102
103
  categoryViews && !!categoryViews.length && (React.createElement(Sidebar, { drawerOpen: isDrawerOpen, onDrawerClose: onCloseDrawer },
103
104
  React.createElement(SidebarTools, { "data-testid": TEST_IDS.FILTER_CONTROLS },
104
105
  React.createElement(SidebarLabel, { label: "Filters" }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@databiosphere/findable-ui",
3
- "version": "33.0.0",
3
+ "version": "34.1.0",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
@@ -1,4 +1,4 @@
1
- import { ColumnDef, RowData } from "@tanstack/react-table";
1
+ import { ColumnDef, RowData, TableOptions } from "@tanstack/react-table";
2
2
 
3
3
  /**
4
4
  * Model of a value of a metadata class.
@@ -6,6 +6,7 @@ import { ColumnDef, RowData } from "@tanstack/react-table";
6
6
  export interface Attribute {
7
7
  // Prefix to fragment mapping, e.g. cxg: "batch_condition", or, general tags e.g. tier: "Tier 1" and bionetwork: ["gut"]
8
8
  annotations?: Record<string, string | string[] | undefined>; // 'undefined' allows for mix of keys across attributes e.g. tier, or tier and cxg, or cxg
9
+ classKey?: string; // Programmatic class name or key (e.g. cell, sample) the attribute belongs to.
9
10
  description: string;
10
11
  example?: string; // Free text example of attribute
11
12
  multivalued: boolean; // True if attribute can have multiple values
@@ -73,6 +74,7 @@ export interface DataDictionary<T extends RowData = Attribute> {
73
74
  export interface DataDictionaryConfig<T extends RowData = Attribute> {
74
75
  columnDefs: ColumnDef<T, T[keyof T]>[];
75
76
  dataDictionary: DataDictionary<T>;
77
+ tableOptions?: Omit<TableOptions<T>, "columns" | "data" | "getCoreRowModel">;
76
78
  }
77
79
 
78
80
  /**
@@ -7,19 +7,15 @@ import { GRID_PROPS } from "./constants";
7
7
  import { ClassesProps } from "./types";
8
8
 
9
9
  export const Entities = <T extends RowData = Attribute>({
10
- classes,
11
- columnDefs,
12
10
  spacing,
11
+ table,
13
12
  }: ClassesProps<T>): JSX.Element => {
13
+ const { getGroupedRowModel } = table;
14
14
  return (
15
15
  <Grid {...GRID_PROPS}>
16
- {classes.map((cls) => (
17
- <Entity
18
- key={cls.name}
19
- class={cls}
20
- columnDefs={columnDefs}
21
- spacing={spacing}
22
- />
16
+ {/* Render grouped rows where each "group" is a class e.g. "donor" */}
17
+ {getGroupedRowModel().rows.map((row) => (
18
+ <Entity key={row.id} row={row} spacing={spacing} table={table} />
23
19
  ))}
24
20
  </Grid>
25
21
  );
@@ -1,9 +1,8 @@
1
- import { ColumnDef, RowData } from "@tanstack/react-table";
2
- import { Attribute, Class } from "../../../../common/entities";
1
+ import { RowData, Table } from "@tanstack/react-table";
2
+ import { Attribute } from "../../../../common/entities";
3
3
  import { LayoutSpacing } from "../../hooks/UseLayoutSpacing/types";
4
4
 
5
5
  export interface ClassesProps<T extends RowData = Attribute> {
6
- classes: Class<T>[];
7
- columnDefs: ColumnDef<T, T[keyof T]>[];
8
6
  spacing?: LayoutSpacing;
7
+ table: Table<T>;
9
8
  }
@@ -2,9 +2,17 @@ import styled from "@emotion/styled";
2
2
  import { Typography } from "@mui/material";
3
3
  import { LayoutSpacing } from "../../hooks/UseLayoutSpacing/types";
4
4
  import { ENTITIES_ROW_GAP } from "../Entities/constants";
5
+ import { LAYOUT_SPACING } from "../Layout/constants";
6
+
7
+ const TOP =
8
+ ENTITIES_ROW_GAP +
9
+ LAYOUT_SPACING.TITLE_HEIGHT +
10
+ LAYOUT_SPACING.FILTERS_HEIGHT +
11
+ LAYOUT_SPACING.FILTERS_PADDING_TOP +
12
+ LAYOUT_SPACING.CONTENT_PADDING_TOP;
5
13
 
6
14
  export const StyledTypography = styled(Typography)<Partial<LayoutSpacing>>`
7
- scroll-margin-top: ${({ top = 0 }) => top + ENTITIES_ROW_GAP}px;
15
+ scroll-margin-top: ${({ top = 0 }) => top + TOP}px;
8
16
 
9
17
  &:hover a {
10
18
  opacity: 1;
@@ -4,28 +4,37 @@ import React from "react";
4
4
  import { Attribute } from "../../../../common/entities";
5
5
  import { TYPOGRAPHY_PROPS } from "../../../../styles/common/mui/typography";
6
6
  import { AnchorLink } from "../../../common/AnchorLink/anchorLink";
7
- import { useTable } from "../Table/hook";
8
7
  import { Table } from "../Table/table";
9
8
  import { GRID_PROPS } from "./constants";
10
9
  import { StyledTypography } from "./entity.styles";
11
10
  import { EntityProps } from "./types";
11
+ import { getClassMeta } from "./utils";
12
12
 
13
13
  export const Entity = <T extends RowData = Attribute>({
14
- class: cls,
15
- columnDefs,
14
+ row,
16
15
  spacing,
17
- }: EntityProps<T>): JSX.Element => {
18
- const table = useTable<T>(cls.attributes, columnDefs);
16
+ table,
17
+ }: EntityProps<T>): JSX.Element | null => {
18
+ // Get class key from row.
19
+ const classKey = row.getValue<string>("classKey");
20
+
21
+ // Get class metadata from table options.
22
+ const cls = getClassMeta<T>(classKey, table);
23
+
24
+ // Class not found in table meta - return null.
25
+ if (!cls) return null;
26
+
19
27
  return (
20
28
  <Grid {...GRID_PROPS} rowGap={4}>
29
+ {/* Class title and description */}
21
30
  <Grid {...GRID_PROPS} rowGap={1}>
22
31
  <StyledTypography
23
32
  component="h3"
24
- id={cls.name}
33
+ id={classKey}
25
34
  variant={TYPOGRAPHY_PROPS.VARIANT.TEXT_HEADING_SMALL}
26
35
  {...spacing}
27
36
  >
28
- {cls.title} <AnchorLink anchorLink={cls.name} />
37
+ {cls.title} <AnchorLink anchorLink={classKey} />
29
38
  </StyledTypography>
30
39
  <Typography
31
40
  color={TYPOGRAPHY_PROPS.COLOR.INK_LIGHT}
@@ -35,7 +44,8 @@ export const Entity = <T extends RowData = Attribute>({
35
44
  {cls.description}
36
45
  </Typography>
37
46
  </Grid>
38
- <Table table={table} />
47
+ {/* Class attributes table */}
48
+ <Table row={row} table={table} />
39
49
  </Grid>
40
50
  );
41
51
  };
@@ -1,9 +1,9 @@
1
- import { ColumnDef, RowData } from "@tanstack/react-table";
2
- import { Attribute, Class } from "../../../../common/entities";
1
+ import { Row, RowData, Table } from "@tanstack/react-table";
2
+ import { Attribute } from "../../../../common/entities";
3
3
  import { LayoutSpacing } from "../../hooks/UseLayoutSpacing/types";
4
4
 
5
5
  export interface EntityProps<T extends RowData = Attribute> {
6
- class: Class<T>;
7
- columnDefs: ColumnDef<T, T[keyof T]>[];
6
+ row: Row<T>;
8
7
  spacing?: LayoutSpacing;
8
+ table: Table<T>;
9
9
  }
@@ -0,0 +1,25 @@
1
+ import { RowData, Table } from "@tanstack/react-table";
2
+ import { Attribute, Class } from "../../../../common/entities";
3
+ import { ClassMeta } from "../Table/types";
4
+
5
+ /**
6
+ * Retrieves class metadata from the table options meta.
7
+ * @param classKey - Class key.
8
+ * @param table - Table instance.
9
+ * @returns Class metadata or undefined.
10
+ */
11
+ export function getClassMeta<T extends RowData = Attribute>(
12
+ classKey: string | undefined,
13
+ table: Table<T>
14
+ ): Pick<Class<T>, "description" | "title"> | undefined {
15
+ if (!classKey) return;
16
+
17
+ // Grab the table meta and return if not defined.
18
+ const meta = table.options.meta;
19
+ if (!meta) return;
20
+
21
+ // Return class metadata if defined.
22
+ if ("classMeta" in meta) {
23
+ return (meta.classMeta as ClassMeta)?.[classKey];
24
+ }
25
+ }
@@ -0,0 +1,21 @@
1
+ import { ButtonGroup } from "@mui/material";
2
+ import { RowData } from "@tanstack/react-table";
3
+ import React from "react";
4
+ import { Attribute } from "../../../../../../common/entities";
5
+ import { BUTTON_GROUP_PROPS } from "../../../../../common/ButtonGroup/constants";
6
+ import { ColumnFilter } from "../../../../../Table/components/TableFeatures/ColumnFilter/columnFilter";
7
+ import { ColumnFiltersProps } from "./types";
8
+
9
+ export const ColumnFilters = <T extends RowData = Attribute>({
10
+ table,
11
+ }: ColumnFiltersProps<T>): JSX.Element => {
12
+ const columns = table.getAllColumns();
13
+ const columnFilters = columns.filter((column) => column.getCanFilter());
14
+ return (
15
+ <ButtonGroup {...BUTTON_GROUP_PROPS.SECONDARY_OUTLINED}>
16
+ {columnFilters.map((column) => (
17
+ <ColumnFilter key={column.id} column={column} />
18
+ ))}
19
+ </ButtonGroup>
20
+ );
21
+ };
@@ -0,0 +1,6 @@
1
+ import { RowData, Table } from "@tanstack/react-table";
2
+ import { Attribute } from "../../../../../../common/entities";
3
+
4
+ export interface ColumnFiltersProps<T extends RowData = Attribute> {
5
+ table: Table<T>;
6
+ }
@@ -0,0 +1,14 @@
1
+ import styled from "@emotion/styled";
2
+ import { Grid } from "@mui/material";
3
+ import { BUTTON_GROUP_PROPS } from "../../../../styles/common/mui/buttonGroup";
4
+
5
+ export const StyledGrid = styled(Grid)`
6
+ align-items: center;
7
+ display: grid;
8
+ gap: 16px;
9
+ grid-template-columns: 1fr auto;
10
+
11
+ .${BUTTON_GROUP_PROPS.CLASSES.ROOT} {
12
+ grid-column: 2;
13
+ }
14
+ `;
@@ -0,0 +1,16 @@
1
+ import { RowData } from "@tanstack/react-table";
2
+ import React from "react";
3
+ import { Attribute } from "../../../../common/entities";
4
+ import { ColumnFilters } from "./components/ColumnFilters/columnFilters";
5
+ import { StyledGrid } from "./filters.styles";
6
+ import { FiltersProps } from "./types";
7
+
8
+ export const Filters = <T extends RowData = Attribute>({
9
+ table,
10
+ }: FiltersProps<T>): JSX.Element => {
11
+ return (
12
+ <StyledGrid>
13
+ <ColumnFilters table={table} />
14
+ </StyledGrid>
15
+ );
16
+ };
@@ -0,0 +1,31 @@
1
+ import { PartialColumn } from "./types";
2
+
3
+ export const BIONETWORK: PartialColumn = {
4
+ columnDef: { header: "BioNetwork" },
5
+ getCanFilter: () => true,
6
+ getFacetedUniqueValues: () =>
7
+ new Map([
8
+ ["Nervous System", 3],
9
+ ["Brain", 2],
10
+ ["Lung", 1],
11
+ ]),
12
+ id: "bioNetwork",
13
+ };
14
+
15
+ export const EXAMPLE: PartialColumn = {
16
+ columnDef: { header: "Example" },
17
+ getCanFilter: () => false,
18
+ getFacetedUniqueValues: () => new Map([["EFO:0008563", 1]]),
19
+ id: "example",
20
+ };
21
+
22
+ export const REQUIRED: PartialColumn = {
23
+ columnDef: { header: "Required" },
24
+ getCanFilter: () => true,
25
+ getFacetedUniqueValues: () =>
26
+ new Map([
27
+ ["Required", 16],
28
+ ["Not Required", 30],
29
+ ]),
30
+ id: "required",
31
+ };
@@ -0,0 +1,42 @@
1
+ import { action } from "@storybook/addon-actions";
2
+ import { Meta, StoryObj } from "@storybook/react";
3
+ import { functionalUpdate, Table } from "@tanstack/react-table";
4
+ import React from "react";
5
+ import { Filters } from "../filters";
6
+ import { BIONETWORK, EXAMPLE, REQUIRED } from "./constants";
7
+ import { useFilterStore } from "./hook";
8
+ import { PartialColumn } from "./types";
9
+
10
+ const meta: Meta<typeof Filters> = {
11
+ component: Filters,
12
+ };
13
+
14
+ export default meta;
15
+
16
+ type Story = StoryObj<typeof meta>;
17
+
18
+ const DefaultStory = (): JSX.Element => {
19
+ const { filterStore, setFilterStore } = useFilterStore();
20
+
21
+ const makeColumn = (column: PartialColumn): PartialColumn => ({
22
+ ...column,
23
+ getFilterValue: () => filterStore[column.id],
24
+ getIsFiltered: () => !!filterStore[column.id],
25
+ setFilterValue: (updaterOrValue: unknown): unknown => {
26
+ const next = functionalUpdate(updaterOrValue, filterStore[column.id]);
27
+ setFilterStore({ ...filterStore, [column.id]: next });
28
+ action("setFilterValue")(next);
29
+ return next;
30
+ },
31
+ });
32
+
33
+ const table = {
34
+ getAllColumns: () => [REQUIRED, BIONETWORK, EXAMPLE].map(makeColumn),
35
+ } as Table<unknown>;
36
+
37
+ return <Filters table={table} />;
38
+ };
39
+
40
+ export const Default: Story = {
41
+ render: () => <DefaultStory />,
42
+ };
@@ -0,0 +1,9 @@
1
+ import { Dispatch, SetStateAction, useState } from "react";
2
+
3
+ export function useFilterStore(): {
4
+ filterStore: Record<string, unknown>;
5
+ setFilterStore: Dispatch<SetStateAction<Record<string, unknown>>>;
6
+ } {
7
+ const [filterStore, setFilterStore] = useState<Record<string, unknown>>({});
8
+ return { filterStore, setFilterStore };
9
+ }
@@ -0,0 +1,3 @@
1
+ import { Column } from "@tanstack/react-table";
2
+
3
+ export type PartialColumn = Partial<Column<unknown>> & { id: string };
@@ -0,0 +1,6 @@
1
+ import { RowData, Table } from "@tanstack/react-table";
2
+ import { Attribute } from "../../../../common/entities";
3
+
4
+ export interface FiltersProps<T extends RowData = Attribute> {
5
+ table: Table<T>;
6
+ }
@@ -5,13 +5,16 @@ import { LAYOUT_SPACING } from "../../constants";
5
5
 
6
6
  const PB = LAYOUT_SPACING.CONTENT_PADDING_BOTTOM; /* bottom padding */
7
7
  const PT = LAYOUT_SPACING.CONTENT_PADDING_TOP; /* top padding */
8
+ const FILTERS_HEIGHT =
9
+ LAYOUT_SPACING.FILTERS_HEIGHT +
10
+ LAYOUT_SPACING.FILTERS_PADDING_TOP; /* filters height */
8
11
  const TITLE_HEIGHT = LAYOUT_SPACING.TITLE_HEIGHT; /* title height */
9
12
 
10
13
  export const Layout = styled("div")<LayoutSpacing>`
11
14
  grid-column: 2;
12
15
  grid-row: 1;
13
16
  padding-bottom: ${PB}px;
14
- padding-top: ${({ top }) => top + TITLE_HEIGHT + PT}px;
17
+ padding-top: ${({ top }) => top + TITLE_HEIGHT + FILTERS_HEIGHT + PT}px;
15
18
  z-index: 1; /* not required, but helpful in that the entities are always on top */
16
19
 
17
20
  ${mediaTabletDown} {
@@ -0,0 +1,27 @@
1
+ import styled from "@emotion/styled";
2
+ import { PALETTE } from "../../../../../../styles/common/constants/palette";
3
+ import { mediaTabletDown } from "../../../../../../styles/common/mixins/breakpoints";
4
+ import { LayoutSpacing } from "../../../../hooks/UseLayoutSpacing/types";
5
+ import { LAYOUT_SPACING } from "../../constants";
6
+
7
+ const PB = LAYOUT_SPACING.FILTERS_PADDING_BOTTOM; /* bottom padding */
8
+ const PT = LAYOUT_SPACING.FILTERS_PADDING_TOP; /* top padding */
9
+ const TITLE_HEIGHT = LAYOUT_SPACING.TITLE_HEIGHT; /* title height */
10
+
11
+ export const Layout = styled("div")<LayoutSpacing>`
12
+ align-self: flex-start;
13
+ background-color: ${PALETTE.BACKGROUND_DEFAULT};
14
+ grid-column: 2;
15
+ grid-row: 1;
16
+ margin-bottom: ${PB}px;
17
+ padding-top: ${({ top }) => top + TITLE_HEIGHT + PT}px;
18
+ position: sticky;
19
+ top: 0;
20
+ z-index: 2; /* required, filters should be on top of entities */
21
+
22
+ ${mediaTabletDown} {
23
+ grid-column: 1;
24
+ grid-row: auto;
25
+ padding-top: ${PT}px;
26
+ }
27
+ `;
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import { Layout } from "./filtersLayout.styles";
3
+ import { FiltersLayoutProps } from "./types";
4
+
5
+ export const FiltersLayout = ({
6
+ children,
7
+ ...props
8
+ }: FiltersLayoutProps): JSX.Element => {
9
+ return <Layout {...props}>{children}</Layout>;
10
+ };
@@ -0,0 +1,6 @@
1
+ import { ReactNode } from "react";
2
+ import { LayoutSpacing } from "../../../../hooks/UseLayoutSpacing/types";
3
+
4
+ export interface FiltersLayoutProps extends LayoutSpacing {
5
+ children: ReactNode;
6
+ }
@@ -4,7 +4,7 @@ import { LayoutSpacing } from "../../../../hooks/UseLayoutSpacing/types";
4
4
  import { LAYOUT_SPACING } from "../../constants";
5
5
 
6
6
  const PB = LAYOUT_SPACING.CONTENT_PADDING_BOTTOM; /* bottom padding */
7
- const PT = LAYOUT_SPACING.CONTENT_PADDING_TOP; /* top padding */
7
+ const PT = LAYOUT_SPACING.OUTLINE_PADDING_TOP; /* top padding */
8
8
  const TITLE_HEIGHT = LAYOUT_SPACING.TITLE_HEIGHT; /* title height */
9
9
 
10
10
  export const Layout = styled("div")<LayoutSpacing>`
@@ -9,6 +9,7 @@ export const Layout = styled("div")<LayoutSpacing>`
9
9
  padding-top: ${({ top }) => top}px; /* header height */
10
10
  position: sticky;
11
11
  top: 0;
12
+ z-index: 4;
12
13
 
13
14
  ${mediaTabletDown} {
14
15
  grid-column: 1;
@@ -1,5 +1,9 @@
1
1
  export const LAYOUT_SPACING = {
2
2
  CONTENT_PADDING_BOTTOM: 24,
3
3
  CONTENT_PADDING_TOP: 16,
4
+ FILTERS_HEIGHT: 40,
5
+ FILTERS_PADDING_BOTTOM: 16,
6
+ FILTERS_PADDING_TOP: 16,
7
+ OUTLINE_PADDING_TOP: 16,
4
8
  TITLE_HEIGHT: 74,
5
9
  };
@@ -1,21 +1,43 @@
1
- import { RowData } from "@tanstack/react-table";
2
- import { Attribute, Class } from "../../../../common/entities";
1
+ import { RowData, Table } from "@tanstack/react-table";
2
+ import { Attribute } from "../../../../common/entities";
3
3
  import { OutlineItem } from "../../../Layout/components/Outline/types";
4
+ import { ClassMeta } from "../Table/types";
4
5
 
5
6
  /**
6
- * Returns outline items from classes.
7
- * @param classes - Class entities.
7
+ * Returns outline items from class metadata.
8
+ * @param table - Table instance.
8
9
  * @returns Outline items.
9
10
  */
10
11
  export function buildClassesOutline<T extends RowData = Attribute>(
11
- classes: Class<T>[]
12
+ table: Table<T>
12
13
  ): OutlineItem[] {
13
- return classes.map(({ name, title }) => {
14
- return {
15
- depth: 2,
16
- disabled: false,
17
- hash: name,
18
- value: title,
19
- };
20
- });
14
+ const meta = table.options.meta;
15
+ if (!meta) return [];
16
+ if (!("classMeta" in meta)) return [];
17
+ return Object.entries(meta.classMeta as ClassMeta).map(
18
+ ([classKey, { title }]) => {
19
+ return {
20
+ depth: 2,
21
+ disabled: !hasGroupedRow(table, classKey),
22
+ hash: classKey,
23
+ value: title,
24
+ };
25
+ }
26
+ );
27
+ }
28
+
29
+ /**
30
+ * Returns true if a grouped row exists for a class key.
31
+ * @param table - Table instance.
32
+ * @param classKey - Class key.
33
+ * @returns True if a grouped row exists, false otherwise.
34
+ */
35
+ function hasGroupedRow<T extends RowData = Attribute>(
36
+ table: Table<T>,
37
+ classKey: string
38
+ ): boolean {
39
+ const groupRow = table
40
+ .getGroupedRowModel()
41
+ .rows.find((row) => row.getValue("classKey") === classKey);
42
+ return !!groupRow;
21
43
  }
@@ -2,22 +2,34 @@ import {
2
2
  ColumnDef,
3
3
  RowData,
4
4
  Table,
5
+ TableOptions,
5
6
  useReactTable,
6
7
  } from "@tanstack/react-table";
7
- import { Attribute } from "../../../../common/entities";
8
+ import { useMemo } from "react";
9
+ import { Attribute, Class } from "../../../../common/entities";
8
10
  import { useTableOptions } from "./options/hook";
11
+ import { buildClassMeta, buildTableData } from "./utils";
9
12
 
10
13
  export const useTable = <T extends RowData = Attribute>(
11
- data: T[],
12
- columnDefs: ColumnDef<T, T[keyof T]>[]
14
+ classes: Class<T>[],
15
+ columnDefs: ColumnDef<T, T[keyof T]>[],
16
+ tableOptions?: Omit<TableOptions<T>, "columns" | "data" | "getCoreRowModel">
13
17
  ): Table<T> => {
14
- // Table options.
15
- const tableOptions = useTableOptions<T>();
18
+ // Build table data.
19
+ const data = useMemo(() => buildTableData(classes), [classes]);
20
+
21
+ // Default table options.
22
+ const defaultTableOptions = useTableOptions<T>();
23
+
24
+ // Build class meta.
25
+ const classMeta = useMemo(() => buildClassMeta(classes), [classes]);
16
26
 
17
27
  // Table instance.
18
28
  return useReactTable<T>({
29
+ ...defaultTableOptions,
19
30
  ...tableOptions,
20
31
  columns: columnDefs,
21
32
  data,
33
+ meta: { classMeta },
22
34
  });
23
35
  };