@databiosphere/findable-ui 2.2.0 → 3.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 (127) hide show
  1. package/lib/components/Detail/components/DetailViewTable/detailViewTable.js +1 -1
  2. package/lib/components/Filter/components/FilterLabel/filterLabel.styles.d.ts +1 -1
  3. package/lib/components/Index/index.d.ts +2 -1
  4. package/lib/components/Index/index.js +2 -2
  5. package/lib/components/Layout/components/Header/components/Content/components/Actions/components/Authentication/components/AuthenticationMenu/authenticationMenu.styles.d.ts +3 -3
  6. package/lib/components/Layout/components/Header/components/Content/components/Actions/components/Authentication/components/RequestAuthentication/requestAuthentication.styles.d.ts +1 -1
  7. package/lib/components/Layout/components/Header/components/Content/components/Actions/components/Search/components/SearchBar/searchBar.styles.d.ts +1 -1
  8. package/lib/components/Layout/components/Header/components/Content/components/Actions/components/Search/components/SearchButton/searchButton.styles.d.ts +1 -1
  9. package/lib/components/Layout/components/Outline/components/ContentsTab/contentsTab.styles.d.ts +1 -1
  10. package/lib/components/Layout/components/Outline/outline.styles.d.ts +1 -1
  11. package/lib/components/Table/common/utils.d.ts +6 -0
  12. package/lib/components/Table/common/utils.js +12 -1
  13. package/lib/components/Table/components/CheckboxMenu/checkboxMenu.js +2 -2
  14. package/lib/components/Table/components/CheckboxMenu/checkboxMenu.styles.d.ts +1 -1
  15. package/lib/components/Table/components/CheckboxMenu/checkboxMenu.styles.js +3 -3
  16. package/lib/components/Table/components/TableCell/common/utils.d.ts +8 -0
  17. package/lib/components/Table/components/TableCell/common/utils.js +15 -0
  18. package/lib/components/Table/components/TableCell/components/RowSelectionCell/rowSelectionCell.d.ts +6 -0
  19. package/lib/components/Table/components/TableCell/components/RowSelectionCell/rowSelectionCell.js +15 -0
  20. package/lib/components/Table/components/TableHead/components/HeadSelectionCell/headSelectionCell.d.ts +6 -0
  21. package/lib/components/Table/components/TableHead/components/HeadSelectionCell/headSelectionCell.js +16 -0
  22. package/lib/components/Table/components/TableHead/tableHead.js +2 -2
  23. package/lib/components/Table/components/TableRows/tableRows.js +2 -3
  24. package/lib/components/Table/components/TableToolbar/components/RowSelection/components/DropdownMenu/dropdownMenu.d.ts +10 -0
  25. package/lib/components/Table/components/TableToolbar/components/RowSelection/components/DropdownMenu/dropdownMenu.js +37 -0
  26. package/lib/components/Table/components/TableToolbar/components/RowSelection/components/DropdownMenu/dropdownMenu.styles.d.ts +3 -0
  27. package/lib/components/Table/components/TableToolbar/components/RowSelection/components/DropdownMenu/dropdownMenu.styles.js +13 -0
  28. package/lib/components/Table/components/TableToolbar/components/RowSelection/rowSelection.d.ts +9 -0
  29. package/lib/components/Table/components/TableToolbar/components/RowSelection/rowSelection.js +19 -0
  30. package/lib/components/Table/components/TableToolbar/components/RowSelection/rowSelection.styles.d.ts +5 -0
  31. package/lib/components/Table/components/TableToolbar/components/RowSelection/rowSelection.styles.js +13 -0
  32. package/lib/components/Table/components/TableToolbar/tableToolbar.js +5 -5
  33. package/lib/components/Table/components/TableToolbar/tableToolbar.styles.d.ts +1 -5
  34. package/lib/components/Table/components/TableToolbar/tableToolbar.styles.js +10 -7
  35. package/lib/components/Table/table.d.ts +5 -2
  36. package/lib/components/Table/table.js +13 -2
  37. package/lib/components/TableCreator/common/constants.d.ts +6 -0
  38. package/lib/components/TableCreator/common/constants.js +22 -0
  39. package/lib/components/TableCreator/common/entities.d.ts +5 -0
  40. package/lib/components/TableCreator/common/entities.js +2 -0
  41. package/lib/components/TableCreator/common/utils.d.ts +8 -0
  42. package/lib/components/TableCreator/common/utils.js +24 -0
  43. package/lib/components/TableCreator/tableCreator.d.ts +3 -1
  44. package/lib/components/TableCreator/tableCreator.js +19 -34
  45. package/lib/components/common/Alert/components/AlertText/alertText.styles.d.ts +5 -0
  46. package/lib/components/common/Alert/components/AlertText/alertText.styles.js +25 -0
  47. package/lib/components/common/Button/components/DropdownButton/dropdownButton.d.ts +4 -2
  48. package/lib/components/common/Button/components/DropdownButton/dropdownButton.js +2 -2
  49. package/lib/components/common/Button/components/DropdownButton/dropdownButton.styles.d.ts +5 -1
  50. package/lib/components/common/Button/components/DropdownButton/dropdownButton.styles.js +24 -1
  51. package/lib/components/common/CustomIcon/components/IndeterminateIcon/indeterminateIcon.d.ts +6 -0
  52. package/lib/components/common/CustomIcon/components/IndeterminateIcon/indeterminateIcon.js +29 -0
  53. package/lib/components/common/Dialog/dialog.d.ts +7 -0
  54. package/lib/components/common/Dialog/dialog.js +24 -0
  55. package/lib/components/common/DropdownMenu/common/constants.d.ts +2 -0
  56. package/lib/components/common/DropdownMenu/common/constants.js +8 -0
  57. package/lib/components/common/DropdownMenu/common/entities.d.ts +10 -0
  58. package/lib/components/common/DropdownMenu/common/entities.js +2 -0
  59. package/lib/components/common/DropdownMenu/components/MenuItem/menuItem.d.ts +7 -0
  60. package/lib/components/common/DropdownMenu/components/MenuItem/menuItem.js +25 -0
  61. package/lib/components/common/DropdownMenu/dropdownMenu.d.ts +9 -0
  62. package/lib/components/common/DropdownMenu/dropdownMenu.js +49 -0
  63. package/lib/components/common/DropdownMenu/dropdownMenu.styles.d.ts +3 -0
  64. package/lib/components/common/DropdownMenu/dropdownMenu.styles.js +13 -0
  65. package/lib/components/common/IconButton/iconButton.d.ts +4 -3
  66. package/lib/components/common/IconButton/iconButton.js +4 -4
  67. package/lib/components/common/IconButton/iconButton.styles.d.ts +34 -0
  68. package/lib/components/common/IconButton/iconButton.styles.js +27 -1
  69. package/lib/components/common/Tabs/tabs.styles.d.ts +1 -1
  70. package/lib/config/entities.d.ts +4 -1
  71. package/lib/hooks/useCategoryFilter.d.ts +7 -1
  72. package/lib/hooks/useCategoryFilter.js +25 -6
  73. package/lib/providers/exploreState/entities.d.ts +6 -2
  74. package/lib/providers/exploreState/initializer/utils.js +20 -7
  75. package/lib/providers/exploreState/payloads/entities.d.ts +24 -6
  76. package/lib/providers/exploreState/utils.d.ts +24 -2
  77. package/lib/providers/exploreState/utils.js +52 -3
  78. package/lib/providers/exploreState.d.ts +29 -5
  79. package/lib/providers/exploreState.js +28 -7
  80. package/lib/theme/common/components.js +4 -0
  81. package/lib/views/ExploreView/exploreView.d.ts +3 -1
  82. package/lib/views/ExploreView/exploreView.js +3 -3
  83. package/package.json +1 -1
  84. package/src/components/Detail/components/DetailViewTable/detailViewTable.tsx +2 -2
  85. package/src/components/Index/index.tsx +3 -1
  86. package/src/components/Table/common/utils.ts +17 -0
  87. package/src/components/Table/components/CheckboxMenu/checkboxMenu.styles.ts +3 -3
  88. package/src/components/Table/components/CheckboxMenu/checkboxMenu.tsx +4 -2
  89. package/src/components/Table/components/TableCell/common/utils.ts +16 -0
  90. package/src/components/Table/components/TableCell/components/RowSelectionCell/rowSelectionCell.tsx +24 -0
  91. package/src/components/Table/components/TableHead/components/HeadSelectionCell/headSelectionCell.tsx +31 -0
  92. package/src/components/Table/components/TableHead/tableHead.tsx +18 -7
  93. package/src/components/Table/components/TableRows/tableRows.tsx +10 -8
  94. package/src/components/Table/components/TableToolbar/components/RowSelection/components/DropdownMenu/dropdownMenu.styles.ts +8 -0
  95. package/src/components/Table/components/TableToolbar/components/RowSelection/components/DropdownMenu/dropdownMenu.tsx +50 -0
  96. package/src/components/Table/components/TableToolbar/components/RowSelection/rowSelection.styles.ts +8 -0
  97. package/src/components/Table/components/TableToolbar/components/RowSelection/rowSelection.tsx +30 -0
  98. package/src/components/Table/components/TableToolbar/tableToolbar.styles.ts +10 -7
  99. package/src/components/Table/components/TableToolbar/tableToolbar.tsx +11 -8
  100. package/src/components/Table/table.tsx +18 -1
  101. package/src/components/TableCreator/common/constants.ts +26 -0
  102. package/src/components/TableCreator/common/entities.ts +6 -0
  103. package/src/components/TableCreator/common/utils.ts +33 -0
  104. package/src/components/TableCreator/tableCreator.tsx +38 -17
  105. package/src/components/common/Alert/components/AlertText/alertText.styles.ts +20 -0
  106. package/src/components/common/Button/components/DropdownButton/dropdownButton.styles.ts +15 -1
  107. package/src/components/common/Button/components/DropdownButton/dropdownButton.tsx +10 -2
  108. package/src/components/common/CustomIcon/components/IndeterminateIcon/indeterminateIcon.tsx +23 -0
  109. package/src/components/common/Dialog/dialog.tsx +21 -0
  110. package/src/components/common/DropdownMenu/common/constants.ts +7 -0
  111. package/src/components/common/DropdownMenu/common/entities.ts +11 -0
  112. package/src/components/common/DropdownMenu/components/MenuItem/menuItem.tsx +24 -0
  113. package/src/components/common/DropdownMenu/dropdownMenu.styles.ts +8 -0
  114. package/src/components/common/DropdownMenu/dropdownMenu.tsx +48 -0
  115. package/src/components/common/IconButton/iconButton.styles.ts +18 -0
  116. package/src/components/common/IconButton/iconButton.tsx +10 -11
  117. package/src/config/entities.ts +6 -0
  118. package/src/hooks/useCategoryFilter.ts +31 -7
  119. package/src/providers/exploreState/entities.ts +8 -2
  120. package/src/providers/exploreState/initializer/utils.ts +21 -1
  121. package/src/providers/exploreState/payloads/entities.ts +32 -7
  122. package/src/providers/exploreState/utils.ts +81 -1
  123. package/src/providers/exploreState.tsx +88 -11
  124. package/src/theme/common/components.ts +4 -0
  125. package/src/views/ExploreView/exploreView.tsx +6 -2
  126. package/types/data-explorer-ui.d.ts +10 -0
  127. package/src/components/Table/components/EntityViewToggle/entityViewToggle.tsx +0 -36
@@ -96,6 +96,7 @@ var ExploreActionKind;
96
96
  ExploreActionKind["ApplySavedFilter"] = "APPLY_SAVED_FILTER";
97
97
  ExploreActionKind["ClearFilters"] = "CLEAR_FILTERS";
98
98
  ExploreActionKind["PaginateTable"] = "PAGINATE_TABLE";
99
+ ExploreActionKind["PatchExploreResponse"] = "PATCH_EXPLORE_RESPONSE";
99
100
  ExploreActionKind["ProcessExploreResponse"] = "PROCESS_EXPLORE_RESPONSE";
100
101
  ExploreActionKind["ProcessRelatedResponse"] = "PROCESS_RELATED_RESPONSE";
101
102
  ExploreActionKind["ResetExploreResponse"] = "RESET_EXPLORE_RESPONSE";
@@ -103,7 +104,9 @@ var ExploreActionKind;
103
104
  ExploreActionKind["SelectEntityType"] = "SELECT_ENTITY_TYPE";
104
105
  ExploreActionKind["ToggleEntityView"] = "TOGGLE_ENTITY_VIEW";
105
106
  ExploreActionKind["UpdateColumnVisibility"] = "UPDATE_COLUMN_VISIBILITY";
107
+ ExploreActionKind["UpdateEntityViewAccess"] = "UPDATE_ENTITY_VIEW_ACCESS";
106
108
  ExploreActionKind["UpdateFilter"] = "UPDATE_FILTER";
109
+ ExploreActionKind["UpdateRowSelection"] = "UPDATE_ROW_SELECTION";
107
110
  ExploreActionKind["UpdateSorting"] = "UPDATE_SORTING";
108
111
  })(ExploreActionKind = exports.ExploreActionKind || (exports.ExploreActionKind = {}));
109
112
  /**
@@ -159,6 +162,12 @@ function exploreReducer(state, action, exploreContext) {
159
162
  }
160
163
  return Object.assign(Object.assign({}, state), { paginationState: nextPaginationState });
161
164
  }
165
+ /**
166
+ * Patch explore response
167
+ */
168
+ case ExploreActionKind.PatchExploreResponse: {
169
+ return Object.assign(Object.assign({}, state), { entityPageState: (0, utils_2.updateEntityPageState)(state.tabValue, state.entityPageState, { rowSelection: {} }), listItems: (0, utils_2.patchEntityListItems)(state.listItems, payload.updatedListItems, payload.listItemKey) });
170
+ }
162
171
  /**
163
172
  * Process explore response
164
173
  **/
@@ -209,6 +218,18 @@ function exploreReducer(state, action, exploreContext) {
209
218
  case ExploreActionKind.ToggleEntityView: {
210
219
  return Object.assign(Object.assign({}, state), { isRelatedView: payload === ENTITY_VIEW.RELATED, listView: payload });
211
220
  }
221
+ /**
222
+ * Update column visibility
223
+ **/
224
+ case ExploreActionKind.UpdateColumnVisibility: {
225
+ return Object.assign(Object.assign({}, state), { entityPageState: (0, utils_2.updateEntityPageState)(state.tabValue, state.entityPageState, { columnsVisibility: payload }) });
226
+ }
227
+ /**
228
+ * Update entity view access
229
+ **/
230
+ case ExploreActionKind.UpdateEntityViewAccess: {
231
+ return Object.assign(Object.assign({}, state), { entityPageState: (0, utils_2.updateSelectColumnVisibility)(state, payload.canEdit) });
232
+ }
212
233
  /**
213
234
  * Update filter
214
235
  **/
@@ -219,7 +240,13 @@ function exploreReducer(state, action, exploreContext) {
219
240
  filterState,
220
241
  savedFilterState,
221
242
  });
222
- return Object.assign(Object.assign({}, state), { filterCount: (0, utils_2.getFilterCount)(filterState), filterState, paginationState: (0, utils_2.resetPage)(state.paginationState) });
243
+ return Object.assign(Object.assign({}, state), { entityPageState: (0, utils_2.resetRowSelection)(state), filterCount: (0, utils_2.getFilterCount)(filterState), filterState, paginationState: (0, utils_2.resetPage)(state.paginationState) });
244
+ }
245
+ /**
246
+ * Update row selection
247
+ */
248
+ case ExploreActionKind.UpdateRowSelection: {
249
+ return Object.assign(Object.assign({}, state), { entityPageState: (0, utils_2.updateEntityPageState)(state.tabValue, state.entityPageState, { rowSelection: payload }) });
223
250
  }
224
251
  /**
225
252
  * Update sorting
@@ -227,12 +254,6 @@ function exploreReducer(state, action, exploreContext) {
227
254
  case ExploreActionKind.UpdateSorting: {
228
255
  return Object.assign(Object.assign({}, state), { entityPageState: (0, utils_2.updateEntityPageState)(state.tabValue, state.entityPageState, { sorting: payload }), paginationState: (0, utils_2.resetPage)(state.paginationState) });
229
256
  }
230
- /**
231
- * Update column visibility
232
- **/
233
- case ExploreActionKind.UpdateColumnVisibility: {
234
- return Object.assign(Object.assign({}, state), { entityPageState: (0, utils_2.updateEntityPageState)(state.tabValue, state.entityPageState, { columnsVisibility: payload }) });
235
- }
236
257
  default:
237
258
  return state;
238
259
  }
@@ -1198,6 +1198,10 @@ const MuiTableCell = (theme) => {
1198
1198
  styleOverrides: {
1199
1199
  body: Object.assign({}, theme.typography[typography_1.TEXT_BODY_400]),
1200
1200
  head: Object.assign(Object.assign({}, theme.typography[typography_1.TEXT_BODY_SMALL_500]), { padding: "20px" }),
1201
+ paddingCheckbox: {
1202
+ paddingRight: 0,
1203
+ width: "unset",
1204
+ },
1201
1205
  root: {
1202
1206
  padding: "18px 20px",
1203
1207
  },
@@ -1,4 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  import { AzulEntitiesStaticResponse } from "../../apis/azul/common/entities";
3
- export declare type ExploreViewProps = AzulEntitiesStaticResponse;
3
+ export interface ExploreViewProps extends AzulEntitiesStaticResponse {
4
+ className?: string;
5
+ }
4
6
  export declare const ExploreView: (props: ExploreViewProps) => JSX.Element;
@@ -157,7 +157,7 @@ const ExploreView = (props) => {
157
157
  react_1.default.createElement(clearAllFilters_1.ClearAllFilters, null),
158
158
  react_1.default.createElement(searchAllFilters_1.SearchAllFilters, { categoryViews: categoryViews, drawerOpen: isDrawerOpen, onFilter: onFilterChange.bind(null, true) })),
159
159
  react_1.default.createElement(filters_1.Filters, { categoryFilters: categoryFilters, closeAncestor: onCloseDrawer, disabled: isRelatedView, onFilter: onFilterChange.bind(null, false), trackFilterOpened: trackingConfig === null || trackingConfig === void 0 ? void 0 : trackingConfig.trackFilterOpened }))),
160
- react_1.default.createElement(index_1.Index, { List: renderList(exploreState, entityConfig, entityListType), ListHero: renderComponent(listHero), SideBarButton: tabletDown ? (react_1.default.createElement(sidebarButton_1.SidebarButton, { count: filterCount, label: "Filter", onClick: onOpenDrawer })) : undefined, SubTitleHero: renderComponent(subTitleHero), Summaries: renderSummary(summaryConfig, summaryResponse), Tabs: react_1.default.createElement(tabs_1.Tabs, { onTabChange: onTabChange, tabs: tabs, value: tabValue }), title: explorerTitle })));
160
+ react_1.default.createElement(index_1.Index, { className: props.className, List: renderList(exploreState, entityConfig, entityListType), ListHero: renderComponent(listHero), SideBarButton: tabletDown ? (react_1.default.createElement(sidebarButton_1.SidebarButton, { count: filterCount, label: "Filter", onClick: onOpenDrawer })) : undefined, SubTitleHero: renderComponent(subTitleHero), Summaries: renderSummary(summaryConfig, summaryResponse), Tabs: react_1.default.createElement(tabs_1.Tabs, { onTabChange: onTabChange, tabs: tabs, value: tabValue }), title: explorerTitle })));
161
161
  };
162
162
  exports.ExploreView = ExploreView;
163
163
  /**
@@ -206,7 +206,7 @@ function renderComponent(componentsConfig, response) {
206
206
  */
207
207
  function renderList(exploreState, entityConfig, entityListType) {
208
208
  const { isRelatedView, listItems, loading, paginationState, relatedListItems, tabValue, } = exploreState;
209
- const { list, listView } = entityConfig;
209
+ const { getId: getRowId, list, listView } = entityConfig;
210
210
  const { columns: columnsConfig, defaultSort } = list;
211
211
  if (!exploreState || !tabValue) {
212
212
  return react_1.default.createElement(react_1.default.Fragment, null); //TODO: return the loading UI component
@@ -216,7 +216,7 @@ function renderList(exploreState, entityConfig, entityListType) {
216
216
  // loads with the previous tabs data on the first render after switching tabs. (or similar)
217
217
  return react_1.default.createElement(react_1.default.Fragment, null);
218
218
  }
219
- return (react_1.default.createElement(tableCreator_1.TableCreator, { columns: columnsConfig, defaultSort: defaultSort, items: isRelatedView && relatedListItems ? relatedListItems : listItems !== null && listItems !== void 0 ? listItems : [], listView: listView, loading: loading, pages: paginationState.pages, pageSize: paginationState.pageSize, pagination: undefined, total: paginationState.rows }));
219
+ return (react_1.default.createElement(tableCreator_1.TableCreator, { columns: columnsConfig, defaultSort: defaultSort, getRowId: getRowId, items: isRelatedView && relatedListItems ? relatedListItems : listItems !== null && listItems !== void 0 ? listItems : [], listView: listView, loading: loading, pages: paginationState.pages, pageSize: paginationState.pageSize, pagination: undefined, total: paginationState.rows }));
220
220
  }
221
221
  /**
222
222
  * Renders Summaries component when all the following requirements are fulfilled:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@databiosphere/findable-ui",
3
- "version": "2.2.0",
3
+ "version": "3.1.0",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "jest",
@@ -7,7 +7,7 @@ import {
7
7
  RoundedPaper,
8
8
  } from "../../../common/Paper/paper.styles";
9
9
  import { NoResults } from "../../../NoResults/noResults";
10
- import { TableToolbar } from "../../../Table/components/TableToolbar/tableToolbar.styles";
10
+ import { Toolbar } from "../../../Table/components/TableToolbar/tableToolbar.styles";
11
11
  import { Table } from "../Table/table";
12
12
 
13
13
  interface DetailViewTableProps<T extends object> {
@@ -32,7 +32,7 @@ export const DetailViewTable = <T extends object>({
32
32
  return items.length > 0 ? (
33
33
  <Paper className={className}>
34
34
  <GridPaper>
35
- {tools && <TableToolbar>{tools}</TableToolbar>}
35
+ {tools && <Toolbar variant="table">{tools}</Toolbar>}
36
36
  <Table
37
37
  columns={columns}
38
38
  gridTemplateColumns={gridTemplateColumns}
@@ -5,6 +5,7 @@ import { Hero } from "./components/Hero/hero";
5
5
  import { Index as IndexLayout } from "./index.styles";
6
6
 
7
7
  export interface IndexProps {
8
+ className?: string;
8
9
  List?: ReactNode;
9
10
  ListHero?: ReactNode | ReactNode[];
10
11
  SideBarButton?: ReactNode;
@@ -15,6 +16,7 @@ export interface IndexProps {
15
16
  }
16
17
 
17
18
  export const Index = ({
19
+ className,
18
20
  List,
19
21
  ListHero,
20
22
  SideBarButton,
@@ -26,7 +28,7 @@ export const Index = ({
26
28
  const { layoutState } = useLayoutState();
27
29
  const { headerHeight } = layoutState;
28
30
  return (
29
- <IndexLayout marginTop={headerHeight}>
31
+ <IndexLayout className={className} marginTop={headerHeight}>
30
32
  <Hero SideBarButton={SideBarButton} Summaries={Summaries} title={title} />
31
33
  {SubTitleHero}
32
34
  {Tabs}
@@ -334,6 +334,23 @@ function getVisibleRowsTableData<T>(rows: Row<T>[]): TableData[][] {
334
334
  );
335
335
  }
336
336
 
337
+ /**
338
+ * Returns true if any or all table rows are selected.
339
+ * @param table - Table.
340
+ * @returns true if a row is selected.
341
+ */
342
+ export function isAnyRowSelected<T>(table: Table<T>): boolean {
343
+ const {
344
+ getIsAllPageRowsSelected,
345
+ getIsSomePageRowsSelected,
346
+ options: { enableRowSelection },
347
+ } = table;
348
+ return Boolean(
349
+ enableRowSelection &&
350
+ (getIsSomePageRowsSelected() || getIsAllPageRowsSelected())
351
+ );
352
+ }
353
+
337
354
  /**
338
355
  * Returns true if client-side filtering is enabled.
339
356
  * @param exploreMode - Explore mode.
@@ -1,9 +1,9 @@
1
1
  import styled from "@emotion/styled";
2
- import { Menu } from "@mui/material";
2
+ import { Menu as MMenu } from "@mui/material";
3
3
 
4
- export const CheckboxMenu = styled(Menu)`
4
+ export const Menu = styled(MMenu)`
5
5
  .MuiPaper-menu {
6
- margin: 8px 0;
6
+ margin: 4px 0;
7
7
  }
8
8
 
9
9
  // List item button
@@ -9,7 +9,7 @@ import { ButtonTextPrimary } from "../../../common/Button/components/ButtonTextP
9
9
  import { DropdownButton } from "../../../common/Button/components/DropdownButton/dropdownButton";
10
10
  import { CheckedIcon } from "../../../common/CustomIcon/components/CheckedIcon/checkedIcon";
11
11
  import { UncheckedIcon } from "../../../common/CustomIcon/components/UncheckedIcon/uncheckedIcon";
12
- import { CheckboxMenu as Menu } from "./checkboxMenu.styles";
12
+ import { Menu } from "./checkboxMenu.styles";
13
13
 
14
14
  type MenuListItemOnChangeFn = (event: unknown) => void; // see React Table VisibilityColumn "getToggleVisibilityHandler".
15
15
  type onResetFn = () => void; // see React Table VisibilityInstance "resetColumnVisibility".
@@ -46,7 +46,9 @@ export const CheckboxMenu = ({
46
46
 
47
47
  return (
48
48
  <>
49
- <DropdownButton onClick={onOpenMenu}>{buttonLabel}</DropdownButton>
49
+ <DropdownButton onClick={onOpenMenu} open={open}>
50
+ {buttonLabel}
51
+ </DropdownButton>
50
52
  <Menu
51
53
  anchorEl={anchorEl}
52
54
  anchorOrigin={{ horizontal: "right", vertical: "bottom" }}
@@ -0,0 +1,16 @@
1
+ import { TableCellProps as MTableCellProps } from "@mui/material/TableCell/TableCell";
2
+ import { CoreCell, CoreHeader } from "@tanstack/table-core";
3
+ import { ACCESSOR_KEYS } from "../../../../TableCreator/common/constants";
4
+
5
+ /**
6
+ * Returns table cell padding based on the cell ID.
7
+ * @param id - Cell ID.
8
+ * @returns table cell padding.
9
+ */
10
+ export function getTableCellPadding<T extends object, TValue>(
11
+ id: CoreHeader<T, TValue>["id"] | CoreCell<T, TValue>["id"]
12
+ ): MTableCellProps["padding"] {
13
+ if (id === ACCESSOR_KEYS.SELECT) {
14
+ return "checkbox";
15
+ }
16
+ }
@@ -0,0 +1,24 @@
1
+ import { Checkbox as MCheckbox } from "@mui/material";
2
+ import { Row } from "@tanstack/react-table";
3
+ import { RowData } from "@tanstack/table-core";
4
+ import React from "react";
5
+ import { CheckedIcon } from "../../../../../common/CustomIcon/components/CheckedIcon/checkedIcon";
6
+ import { UncheckedIcon } from "../../../../../common/CustomIcon/components/UncheckedIcon/uncheckedIcon";
7
+
8
+ export interface RowSelectionCellProps<T> {
9
+ row: Row<T>;
10
+ }
11
+
12
+ export const RowSelectionCell = <T extends RowData>({
13
+ row,
14
+ }: RowSelectionCellProps<T>): JSX.Element => {
15
+ const { getIsSelected, getToggleSelectedHandler } = row;
16
+ return (
17
+ <MCheckbox
18
+ checked={getIsSelected()}
19
+ checkedIcon={<CheckedIcon />}
20
+ icon={<UncheckedIcon />}
21
+ onChange={getToggleSelectedHandler()}
22
+ />
23
+ );
24
+ };
@@ -0,0 +1,31 @@
1
+ import { Checkbox } from "@mui/material";
2
+ import { Table } from "@tanstack/react-table";
3
+ import { RowData } from "@tanstack/table-core";
4
+ import React from "react";
5
+ import { CheckedIcon } from "../../../../../common/CustomIcon/components/CheckedIcon/checkedIcon";
6
+ import { IndeterminateIcon } from "../../../../../common/CustomIcon/components/IndeterminateIcon/indeterminateIcon";
7
+ import { UncheckedIcon } from "../../../../../common/CustomIcon/components/UncheckedIcon/uncheckedIcon";
8
+
9
+ export interface HeadSelectionCellProps<T> {
10
+ tableInstance: Table<T>;
11
+ }
12
+
13
+ export const HeadSelectionCell = <T extends RowData>({
14
+ tableInstance,
15
+ }: HeadSelectionCellProps<T>): JSX.Element => {
16
+ const {
17
+ getIsAllPageRowsSelected,
18
+ getIsSomePageRowsSelected,
19
+ getToggleAllRowsSelectedHandler,
20
+ } = tableInstance;
21
+ return (
22
+ <Checkbox
23
+ checked={getIsAllPageRowsSelected()}
24
+ checkedIcon={<CheckedIcon />}
25
+ icon={<UncheckedIcon />}
26
+ indeterminate={getIsSomePageRowsSelected()}
27
+ indeterminateIcon={<IndeterminateIcon />}
28
+ onChange={getToggleAllRowsSelectedHandler()}
29
+ />
30
+ );
31
+ };
@@ -1,5 +1,5 @@
1
1
  import {
2
- TableCell,
2
+ TableCell as MTableCell,
3
3
  TableHead as MTableHead,
4
4
  TableRow,
5
5
  TableSortLabel,
@@ -8,6 +8,7 @@ import { flexRender, Table } from "@tanstack/react-table";
8
8
  import React, { Fragment } from "react";
9
9
  import { ROW_DIRECTION } from "../../common/entities";
10
10
  import { getTableSortLabelProps } from "../../common/utils";
11
+ import { getTableCellPadding } from "../TableCell/common/utils";
11
12
 
12
13
  export interface TableHeadProps<T> {
13
14
  rowDirection: ROW_DIRECTION;
@@ -25,14 +26,24 @@ export const TableHead = <T extends object>({
25
26
  <MTableHead key={headerGroup.id}>
26
27
  <TableRow>
27
28
  {headerGroup.headers.map((header) => (
28
- <TableCell key={header.id}>
29
- <TableSortLabel {...getTableSortLabelProps(header.column)}>
30
- {flexRender(
29
+ <MTableCell
30
+ key={header.id}
31
+ padding={getTableCellPadding(header.id)}
32
+ >
33
+ {header.column.getCanSort() ? (
34
+ <TableSortLabel {...getTableSortLabelProps(header.column)}>
35
+ {flexRender(
36
+ header.column.columnDef.header,
37
+ header.getContext()
38
+ )}
39
+ </TableSortLabel>
40
+ ) : (
41
+ flexRender(
31
42
  header.column.columnDef.header,
32
43
  header.getContext()
33
- )}
34
- </TableSortLabel>
35
- </TableCell>
44
+ )
45
+ )}
46
+ </MTableCell>
36
47
  ))}
37
48
  </TableRow>
38
49
  </MTableHead>
@@ -1,7 +1,8 @@
1
- import { TableCell, TableRow as MTableRow } from "@mui/material";
1
+ import { TableCell as MTableCell, TableRow as MTableRow } from "@mui/material";
2
2
  import { flexRender, Row, Table } from "@tanstack/react-table";
3
3
  import { Virtualizer } from "@tanstack/react-virtual";
4
4
  import React, { Fragment } from "react";
5
+ import { getTableCellPadding } from "../TableCell/common/utils";
5
6
 
6
7
  export interface TableRowsProps<T> {
7
8
  tableInstance: Table<T>;
@@ -25,13 +26,14 @@ export const TableRows = <T extends object>({
25
26
  data-index={virtualRow.index}
26
27
  ref={virtualizer.measureElement}
27
28
  >
28
- {row.getVisibleCells().map((cell) => {
29
- return (
30
- <TableCell key={cell.id}>
31
- {flexRender(cell.column.columnDef.cell, cell.getContext())}
32
- </TableCell>
33
- );
34
- })}
29
+ {row.getVisibleCells().map((cell) => (
30
+ <MTableCell
31
+ key={cell.id}
32
+ padding={getTableCellPadding(cell.column.id)}
33
+ >
34
+ {flexRender(cell.column.columnDef.cell, cell.getContext())}
35
+ </MTableCell>
36
+ ))}
35
37
  </MTableRow>
36
38
  );
37
39
  })}
@@ -0,0 +1,8 @@
1
+ import styled from "@emotion/styled";
2
+ import { DropdownMenu as DXDropdownMenu } from "../../../../../../../common/DropdownMenu/dropdownMenu";
3
+
4
+ export const DropdownMenu = styled(DXDropdownMenu)`
5
+ .MuiPaper-menu {
6
+ min-width: 288px;
7
+ }
8
+ `;
@@ -0,0 +1,50 @@
1
+ import { MenuProps as MMenuProps } from "@mui/material";
2
+ import React from "react";
3
+ import { DropdownButton as DXDropdownButton } from "../../../../../../../common/Button/components/DropdownButton/dropdownButton";
4
+ import {
5
+ DropdownMenuButtonProps,
6
+ DropdownMenuItemProps,
7
+ } from "../../../../../../../common/DropdownMenu/common/entities";
8
+ import { DropdownMenuProps as DXDropdownMenuProps } from "../../../../../../../common/DropdownMenu/dropdownMenu";
9
+ import { DropdownMenu as RowSelectionDropdownMenu } from "./dropdownMenu.styles";
10
+
11
+ const DEFAULT_MENU_PROPS: Partial<MMenuProps> = {
12
+ anchorOrigin: { horizontal: "left", vertical: "bottom" },
13
+ transformOrigin: { horizontal: "left", vertical: "top" },
14
+ };
15
+
16
+ export interface DropdownMenuProps {
17
+ Button?: DXDropdownMenuProps["Button"];
18
+ buttonLabel?: string;
19
+ children: ({ closeMenu }: DropdownMenuItemProps) => JSX.Element[];
20
+ className?: string;
21
+ }
22
+
23
+ export const DropdownMenu = ({
24
+ Button = (props: DropdownMenuButtonProps): JSX.Element =>
25
+ renderButton({ children: buttonLabel, ...props }),
26
+ buttonLabel = "Edit",
27
+ children,
28
+ className,
29
+ ...props /* Spread props to allow for Mui Menu specific prop overrides e.g. "anchorOrigin". */
30
+ }: DropdownMenuProps): JSX.Element => {
31
+ return (
32
+ <RowSelectionDropdownMenu
33
+ {...DEFAULT_MENU_PROPS}
34
+ className={className}
35
+ Button={Button}
36
+ {...props}
37
+ >
38
+ {({ closeMenu }): JSX.Element[] => children({ closeMenu })}
39
+ </RowSelectionDropdownMenu>
40
+ );
41
+ };
42
+
43
+ /**
44
+ * Return the dropdown button.
45
+ * @param props - Button props e.g. "onClick".
46
+ * @returns button element.
47
+ */
48
+ function renderButton(props: DropdownMenuButtonProps): JSX.Element {
49
+ return <DXDropdownButton {...props} />;
50
+ }
@@ -0,0 +1,8 @@
1
+ import styled from "@emotion/styled";
2
+
3
+ export const RowSelection = styled.div`
4
+ align-items: center;
5
+ display: flex;
6
+ gap: 16px;
7
+ justify-content: flex-start;
8
+ `;
@@ -0,0 +1,30 @@
1
+ import { Typography } from "@mui/material";
2
+ import { Row } from "@tanstack/react-table";
3
+ import React from "react";
4
+ import { ComponentsConfig } from "../../../../../../config/entities";
5
+ import { TEXT_BODY_400 } from "../../../../../../theme/common/typography";
6
+ import { ComponentCreator } from "../../../../../ComponentCreator/ComponentCreator";
7
+ import { RowSelection as RowSelectionActions } from "./rowSelection.styles";
8
+
9
+ export interface RowSelectionProps<T> {
10
+ className?: string;
11
+ rows: Row<T>[];
12
+ rowSelectionView?: ComponentsConfig;
13
+ }
14
+
15
+ export const RowSelection = <T extends object>({
16
+ className,
17
+ rows,
18
+ rowSelectionView,
19
+ }: RowSelectionProps<T>): JSX.Element | null => {
20
+ return (
21
+ <RowSelectionActions className={className}>
22
+ <Typography variant={TEXT_BODY_400}>
23
+ {rows.length} items selected:
24
+ </Typography>
25
+ {rowSelectionView ? (
26
+ <ComponentCreator components={rowSelectionView} response={rows} />
27
+ ) : null}
28
+ </RowSelectionActions>
29
+ );
30
+ };
@@ -1,14 +1,17 @@
1
1
  import styled from "@emotion/styled";
2
+ import { Toolbar as MToolbar } from "@mui/material";
2
3
  import { white } from "../../../../styles/common/mixins/colors";
3
4
  import { Grid } from "../../../common/Grid/grid";
4
5
 
5
- export const TableToolbar = styled.div`
6
- align-items: center;
7
- background-color: ${white};
8
- display: flex;
9
- justify-content: space-between;
10
- padding: 20px;
11
- `;
6
+ export const Toolbar = styled(MToolbar)`
7
+ &.MuiToolbar-table {
8
+ align-items: center;
9
+ background-color: ${white};
10
+ display: flex;
11
+ justify-content: space-between;
12
+ padding: 20px;
13
+ }
14
+ ` as typeof MToolbar;
12
15
 
13
16
  export const ToolbarActions = styled(Grid)`
14
17
  gap: 8px;
@@ -3,12 +3,12 @@ import React, { Fragment } from "react";
3
3
  import { ListViewConfig } from "../../../../config/entities";
4
4
  import { useExploreState } from "../../../../hooks/useExploreState";
5
5
  import { ROW_DIRECTION } from "../../common/entities";
6
- import { getEditColumnOptions } from "../../common/utils";
6
+ import { getEditColumnOptions, isAnyRowSelected } from "../../common/utils";
7
7
  import { CheckboxMenu } from "../CheckboxMenu/checkboxMenu";
8
8
  import { DownloadEntityResults } from "../DownloadEntityResults/downloadEntityResults";
9
- import { EntityViewToggle } from "../EntityViewToggle/entityViewToggle";
10
9
  import { PaginationSummary } from "../PaginationSummary/paginationSummary";
11
- import { TableToolbar as Toolbar, ToolbarActions } from "./tableToolbar.styles";
10
+ import { RowSelection } from "./components/RowSelection/rowSelection";
11
+ import { Toolbar, ToolbarActions } from "./tableToolbar.styles";
12
12
 
13
13
  export interface TableToolbarProps<T> {
14
14
  listView?: ListViewConfig;
@@ -22,9 +22,9 @@ export const TableToolbar = <T extends object>({
22
22
  tableInstance,
23
23
  }: TableToolbarProps<T>): JSX.Element => {
24
24
  const { exploreState } = useExploreState();
25
- const { paginationState, relatedListItems } = exploreState;
25
+ const { paginationState } = exploreState;
26
26
  const { currentPage, pages, pageSize, rows } = paginationState;
27
- const { resetColumnVisibility } = tableInstance;
27
+ const { getSelectedRowModel, resetColumnVisibility } = tableInstance;
28
28
  const { enableDownload } = listView || {};
29
29
  const isLastPage = currentPage === pages;
30
30
  const editColumnOptions = getEditColumnOptions(tableInstance);
@@ -42,9 +42,12 @@ export const TableToolbar = <T extends object>({
42
42
  return (
43
43
  <Fragment>
44
44
  {showToolbar && (
45
- <Toolbar>
46
- {relatedListItems ? (
47
- <EntityViewToggle />
45
+ <Toolbar variant="table">
46
+ {isAnyRowSelected(tableInstance) ? (
47
+ <RowSelection
48
+ rows={getSelectedRowModel().rows}
49
+ rowSelectionView={listView?.rowSelectionView}
50
+ />
48
51
  ) : (
49
52
  <PaginationSummary
50
53
  firstResult={(currentPage - 1) * pageSize + 1}
@@ -8,11 +8,13 @@ import {
8
8
  getPaginationRowModel,
9
9
  getSortedRowModel,
10
10
  InitialTableState,
11
+ RowSelectionState,
11
12
  TableState,
12
13
  Updater,
13
14
  useReactTable,
14
15
  VisibilityState,
15
16
  } from "@tanstack/react-table";
17
+ import { CoreOptions } from "@tanstack/table-core";
16
18
  import React, { useEffect } from "react";
17
19
  import { track } from "../../common/analytics/analytics";
18
20
  import {
@@ -51,6 +53,7 @@ import { GridTable } from "./table.styles";
51
53
  export interface TableProps<T extends object> {
52
54
  columns: ColumnDef<T>[];
53
55
  count?: number;
56
+ getRowId?: CoreOptions<T>["getRowId"];
54
57
  initialState: InitialTableState;
55
58
  items: T[];
56
59
  listView?: ListViewConfig;
@@ -67,6 +70,7 @@ export interface TableProps<T extends object> {
67
70
  * Uncontrolled table will take advantage of React Table's state and will be used for static loads.
68
71
  * @param tableProps - Set of props required for displaying the table.
69
72
  * @param tableProps.columns - Set of columns to display.
73
+ * @param tableProps.getRowId - Function to customize the row ID.
70
74
  * @param tableProps.initialState - Initial table state.
71
75
  * @param tableProps.items - Row data to display.
72
76
  * @param tableProps.listView - List view configuration.
@@ -75,6 +79,7 @@ export interface TableProps<T extends object> {
75
79
  */
76
80
  export const TableComponent = <T extends object>({
77
81
  columns,
82
+ getRowId,
78
83
  initialState,
79
84
  items,
80
85
  listView,
@@ -93,7 +98,8 @@ TableProps<T>): JSX.Element => {
93
98
  paginationState,
94
99
  tabValue,
95
100
  } = exploreState;
96
- const { columnsVisibility, sorting } = entityPageState[tabValue];
101
+ const { columnsVisibility, enableRowSelection, rowSelection, sorting } =
102
+ entityPageState[tabValue];
97
103
  const { currentPage, pages, pageSize } = paginationState;
98
104
  const { disablePagination = false } = listView || {};
99
105
  const clientFiltering = isClientFilteringEnabled(exploreMode);
@@ -126,12 +132,20 @@ TableProps<T>): JSX.Element => {
126
132
  });
127
133
  };
128
134
 
135
+ const onRowSelectionChange = (updater: Updater<RowSelectionState>): void => {
136
+ exploreDispatch({
137
+ payload: typeof updater === "function" ? updater(rowSelection) : updater,
138
+ type: ExploreActionKind.UpdateRowSelection,
139
+ });
140
+ };
141
+
129
142
  const state: Partial<TableState> = {
130
143
  columnVisibility: columnsVisibility,
131
144
  pagination: {
132
145
  pageIndex: 0,
133
146
  pageSize: disablePagination ? Number.MAX_SAFE_INTEGER : pageSize,
134
147
  },
148
+ rowSelection,
135
149
  sorting,
136
150
  };
137
151
  const tableInstance = useReactTable({
@@ -140,6 +154,7 @@ TableProps<T>): JSX.Element => {
140
154
  enableColumnFilters: true, // client-side filtering.
141
155
  enableFilters: true, // client-side filtering.
142
156
  enableMultiSort: false,
157
+ enableRowSelection,
143
158
  enableSorting: true, // client-side filtering.
144
159
  enableSortingRemoval: false, // client-side filtering.
145
160
  getCoreRowModel: getCoreRowModel(),
@@ -149,11 +164,13 @@ TableProps<T>): JSX.Element => {
149
164
  : undefined,
150
165
  getFilteredRowModel: clientFiltering ? getFilteredRowModel() : undefined,
151
166
  getPaginationRowModel: getPaginationRowModel(),
167
+ getRowId,
152
168
  getSortedRowModel: clientFiltering ? getSortedRowModel() : undefined,
153
169
  initialState,
154
170
  manualPagination: clientFiltering,
155
171
  manualSorting: !clientFiltering,
156
172
  onColumnVisibilityChange,
173
+ onRowSelectionChange,
157
174
  onSortingChange,
158
175
  pageCount: total,
159
176
  state,