Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(table): add multi-sort columns to table #2336

Merged
merged 34 commits into from
Jun 16, 2021
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
a7da975
chore(table): split Table/StatefulTable stories into folders
kevinsperrine May 12, 2021
b658da7
Merge branch 'next' into 1376-table-multi-sort
kevinsperrine May 14, 2021
c0d345a
feat(table): added multi-sort column capabilities to table
kevinsperrine May 17, 2021
de6a883
feat(table): update snapshots for multi-sort table columns
kevinsperrine May 17, 2021
9a90ff8
chore(table): added docs for multi-sort features
kevinsperrine May 17, 2021
5ed565b
Merge branch 'next' into 1376-table-multi-sort
kevinsperrine May 17, 2021
8475d25
Merge branch 'next' into 1376-table-multi-sort
kevinsperrine May 18, 2021
317d3da
chore(repo): update snapshots
kevinsperrine May 18, 2021
1687719
chore(table): cleanup table stories
kevinsperrine May 18, 2021
cb4f4d5
chore(storybook): update names of ListBuilder/MenuButton stories
kevinsperrine May 18, 2021
db1cc9f
fix(table-head): use i18n for multi-sort overflow menu name
kevinsperrine May 18, 2021
8475e5b
feat(table): add i18n for overflow menu, remove console.logs
kevinsperrine May 18, 2021
42f56d1
fix(table): maintain backwards compat. on custom sort
kevinsperrine May 19, 2021
dad4d39
Merge branch 'next' into 1376-table-multi-sort
kevinsperrine May 20, 2021
f4b086b
fix(table): i18n fixes, better testing, and rtl for multi-sort columns
kevinsperrine May 21, 2021
77cc164
Merge branch 'next' into 1376-table-multi-sort
kevinsperrine May 21, 2021
a0d4eeb
Merge branch 'next' into 1376-table-multi-sort
kevinsperrine May 21, 2021
8e54989
Merge branch 'next' into 1376-table-multi-sort
kevinsperrine May 24, 2021
22ce9ab
Merge branch 'next' into 1376-table-multi-sort
kevinsperrine May 24, 2021
8d31766
Merge branch 'next' into 1376-table-multi-sort
kevinsperrine May 24, 2021
91c78ed
fix(table): switch sort to A tag to prevent button-in-button warning
kevinsperrine May 24, 2021
eb05264
Merge branch 'next' into 1376-table-multi-sort
kevinsperrine May 25, 2021
9eb700f
fix(table): fix button in button when multi-sort is used
kevinsperrine Jun 1, 2021
f24a8fa
fix(table): use A tag when hasOverflow, too
kevinsperrine Jun 1, 2021
abdcbd9
Merge branch 'next' into 1376-table-multi-sort
kevinsperrine Jun 1, 2021
6bf9eaf
Merge branch 'next' into 1376-table-multi-sort
kevinsperrine Jun 1, 2021
715b1cb
Merge branch 'next' into 1376-table-multi-sort
kevinsperrine Jun 7, 2021
4321d82
Merge branch '1376-table-multi-sort' of github.com:carbon-design-syst…
kevinsperrine Jun 7, 2021
e9bfde5
Merge branch 'next' into 1376-table-multi-sort
kevinsperrine Jun 10, 2021
bf12ebb
feat(table): multi-sort clearing, better modal ux, change sort direction
kevinsperrine Jun 11, 2021
83bb4a8
Merge branch 'next' into 1376-table-multi-sort
kevinsperrine Jun 11, 2021
a6333c4
feat(table): limit multi-sort to number of sortable columns
kevinsperrine Jun 11, 2021
f6518d2
fix(table): multi-sort modal rtl spacing
kevinsperrine Jun 11, 2021
e383c54
Merge branch 'next' into 1376-table-multi-sort
kevinsperrine Jun 16, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
"react-visibility-sensor": "^5.0.2",
"scroll-into-view-if-needed": "^2.2.26",
"styled-components": "^4.1.3",
"thenby": "^1.3.4",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really need a new 28k library to just sort data?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's only 28K unpacked. It's a 2K module, and yeah, it simplifies the experience significantly when sorting in various directions and orders.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would be very conservative about adding new libraries. I'm not saying, don't, but you should verify that this library is "blessed". ie, it in the IBM open source list of approved libraries (you can check the wicked system). When you add a new library, it has to get legal approval eventually. That is why I question importing a library to do a sorting, when that seems pretty trivial.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

our OM is looking into what is happening with our code scans we are supposed to have for teams to use. We will hopefully have an answer soon on when we can expect them.

"use-deep-compare-effect": "^1.2.0",
"use-lang-direction": "^0.1.11",
"use-resize-observer": "^6.1.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ const commonOptions = {
values: comboHealthData,
};

/*
/*
FYI: the underlying Carbon Charts controls have been mocked.
Check __mocks__/@carbon/charts-react/ for details
*/
Expand Down
24,361 changes: 24,360 additions & 1 deletion packages/react/src/components/MapCard/storyFiles/data.json

Large diffs are not rendered by default.

137 changes: 97 additions & 40 deletions packages/react/src/components/Table/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- [Sorting](#sorting)
- [Programmatic sorting](#programmatic-sorting)
- [Custom sorting](#custom-sorting)
- [Multi-sorting](#multi-sorting)
- [Expansion](#expansion)
- [Programmatic expansion](#programmatic-expansion)
- [Selection](#selection)
Expand Down Expand Up @@ -287,6 +288,45 @@ const columns = [
];
```

### Multi-sorting

By passing `options.hasMultiSort` you can enable multi-sort columns functionality. If you want to set the sorted column order,
you can pass an array of sort objects to the `view.table.sort`, and interact with this data via the callbacks on `actions.table`. See example below.

```jsx
<Table
id="table"
columns={columns}
data={data}
actions={{
table: {
onAddMultiSortColumn: (index) => {},
onRemoveMultiSortColumn: (index) => {},
/* example onSaveMultiSortColumns param structure: ([{columnId: 'select', direction: 'ASC'}, {columnId: 'string', direction: 'ASC'}]) => {} */
onSaveMultiSortColumns: (multiSortedColumns) => {},
onCancelMultiSortColumns: () => {},
},
}}
options={{
hasMultiSort: true,
}}
view={{
table: {
sort: [
{
columnId: 'select',
direction: 'ASC',
},
{
columnId: 'string',
direction: 'ASC',
},
],
},
}}
/>
```

## Expansion

The `Table` components supports row-level expansion by passing options.hasRowExpansion=true and passing the row content via the view.table.expandedRows prop.
Expand Down Expand Up @@ -808,6 +848,7 @@ the following props:
| | | | \_ always - Wrap if needed for all table column configurations |
| | | | \_ never - Tables with dynamic columns widths grow larger and tables with fixed or resizable columns truncate. |
| | | | \_ alwaysTruncate - Always truncate if needed for all table column configurations |
| hasMultiSort | bool | | If true, the sortable columns in the table will be able to be sorted by multiple dimensions |

### View Prop

Expand Down Expand Up @@ -853,7 +894,7 @@ the following props:
| table.isSelectAllSelected | bool | | If true, the select all option is checked |
| table.isSelectAllIndeterminate | bool | | |
| table.selectedIds | string[] | | An array of row ids that are currently selected |
| table.sort | object | | an object in the form of {columnId: string; direction: 'NONE' or 'ASC' or 'DESC' } |
| table.sort | object, array | | an object or array of objects in the form of {columnId: string; direction: 'NONE' or 'ASC' or 'DESC' } |
| table.sort.columnId | string | | the id of the column to sort |
| table.sort.direction | 'NONE', 'ASC', or 'DESC' | | |
| table.ordering | object[] | | an array of objects representing the order and visibility of the columns |
Expand Down Expand Up @@ -914,50 +955,66 @@ the following props:
| table.onColumnSelectionConfig | func | | |
| table.onColumnResize | func | | |
| table.onOverflowItemClicked | func | | |
| table.onSaveMultiSortColumns | func | | |
| table.onCancelMultiSortColumns | func | | |
| table.onAddMultiSortColumn | func | | |
| table.onRemoveMultiSortColumn | func | | |
| table.onTableErrorStateAction | func | | callback action relavent on error state. This can be used with `error` message. When `view.table.errorState` property is used then this callback function has no effect. |
| onUserViewModified | func | | callback for actions relevant for view management |

### i18n Prop

| Name | Type | Default | Description |
| :------------------------ | :----- | :------ | :----------------------------------------------------- |
| pageBackwardAria | string | | pagination |
| pageForwardAria | string | |
| pageNumberAria | string | |
| itemsPerPage | string | |
| itemsRange | func | | (min, max) => `${min}-${max} items` |
| currentPage | func | | (page) => `page ${page}` |
| itemsRangeWithTotal | func | | (min, max, total) => `${min}-${max} of ${total} items` |
| pageRange | func | | (current, total) => `${current} of ${total} pages` |
| overflowMenuAria | string | |
| clickToExpandAria | string | |
| clickToCollapseAria | string | |
| selectAllAria | string | |
| selectRowAria | string | |
| searchLabel | string | | toolbar |
| searchPlaceholder | string | |
| clearAllFilters | string | |
| columnSelectionButtonAria | string | |
| columnSelectionConfig | string | |
| filterButtonAria | string | |
| editButtonAria | string | |
| clearFilterAria | string | |
| filterAria | string | |
| downloadIconDescription | string | |
| openMenuAria | string | |
| closeMenuAria | string | |
| clearSelectionAria | string | |
| batchCancel | string | |
| itemsSelected | string | |
| itemSelected | string | |
| inProgressText | string | | I18N label for in progress |
| actionFailedText | string | | I18N label for action failed |
| learnMoreText | string | | I18N label for learn more |
| dismissText | string | | I18N label for dismiss |
| filterNone | string | | |
| filterAscending | string | | |
| filterDescending | string | | |
| rowCountInHeader | func | | |
| Name | Type | Default | Description |
| :------------------------------- | :----- | :----------------------- | :----------------------------------------------------- |
| pageBackwardAria | string | | pagination |
| pageForwardAria | string | |
| pageNumberAria | string | |
| itemsPerPage | string | |
| itemsRange | func | | (min, max) => `${min}-${max} items` |
| currentPage | func | | (page) => `page ${page}` |
| itemsRangeWithTotal | func | | (min, max, total) => `${min}-${max} of ${total} items` |
| pageRange | func | | (current, total) => `${current} of ${total} pages` |
| overflowMenuAria | string | |
| clickToExpandAria | string | |
| clickToCollapseAria | string | |
| selectAllAria | string | |
| selectRowAria | string | |
| searchLabel | string | | toolbar |
| searchPlaceholder | string | |
| clearAllFilters | string | |
| columnSelectionButtonAria | string | |
| columnSelectionConfig | string | |
| filterButtonAria | string | |
| editButtonAria | string | |
| clearFilterAria | string | |
| filterAria | string | |
| downloadIconDescription | string | |
| openMenuAria | string | |
| closeMenuAria | string | |
| clearSelectionAria | string | |
| batchCancel | string | |
| itemsSelected | string | |
| itemSelected | string | |
| inProgressText | string | | I18N label for in progress |
| actionFailedText | string | | I18N label for action failed |
| learnMoreText | string | | I18N label for learn more |
| dismissText | string | | I18N label for dismiss |
| filterNone | string | | |
| filterAscending | string | | |
| filterDescending | string | | |
| rowCountInHeader | func | | |
| multiSortModalTitle | string | 'Select columns to sort' | |
| multiSortModalPrimaryLabel | string | 'Sort' | |
| multiSortModalSecondaryLabel | string | 'Cancel' | |
| multiSortSelectColumnLabel | string | 'Select a column' | |
| multiSortSelectColumnSortByTitle | string | 'Sort by' | |
| multiSortSelectColumnThenByTitle | string | 'Then by' | |
| multiSortDirectionLabel | string | 'Select a direction' | |
| multiSortDirectionTitle | string | 'Sort order' | |
| multiSortAddColumn | string | 'Add column' | |
| multiSortRemoveColumn | string | 'Remove column' | |
| multiSortAscending | string | 'Ascending' | |
| multiSortDescending | string | 'Descending' | |

## Source Code

Expand Down
28 changes: 28 additions & 0 deletions packages/react/src/components/Table/StatefulTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ import {
tableAdvancedFiltersApply,
tableAdvancedFiltersCancel,
tableAdvancedFiltersCreate,
tableMultiSortToggleModal,
tableSaveMultiSortColumns,
tableCancelMultiSortColumns,
tableAddMultiSortColumn,
tableRemoveMultiSortColumn,
} from './tableActionCreators';
import Table, { defaultProps } from './Table';

Expand Down Expand Up @@ -144,6 +149,10 @@ const StatefulTable = ({ data: initialData, expandedData, ...other }) => {
onChangeOrdering,
onColumnResize,
onOverflowItemClicked,
onSaveMultiSortColumns,
onCancelMultiSortColumns,
onAddMultiSortColumn,
onRemoveMultiSortColumn,
} = table || {};

const getRowAction = (data, actionId, rowId) => {
Expand Down Expand Up @@ -293,8 +302,27 @@ const StatefulTable = ({ data: initialData, expandedData, ...other }) => {
callbackParent(onColumnResize, resizedColumns);
},
onOverflowItemClicked: (id) => {
if (id === 'multi-sort') {
dispatch(tableMultiSortToggleModal());
}
callbackParent(onOverflowItemClicked, id);
},
onSaveMultiSortColumns: (sortColumns) => {
dispatch(tableSaveMultiSortColumns(sortColumns));
callbackParent(onSaveMultiSortColumns, sortColumns);
},
onCancelMultiSortColumns: () => {
dispatch(tableCancelMultiSortColumns());
callbackParent(onCancelMultiSortColumns);
},
onAddMultiSortColumn: (index) => {
dispatch(tableAddMultiSortColumn(index));
callbackParent(onAddMultiSortColumn, index);
},
onRemoveMultiSortColumn: (index) => {
dispatch(tableRemoveMultiSortColumn(index));
callbackParent(onRemoveMultiSortColumn, index);
},
},
onUserViewModified: (viewConfiguration) => {
callbackParent(onUserViewModified, viewConfiguration);
Expand Down
Loading