diff --git a/packages/react-table/src/docs/demos/Table.md b/packages/react-table/src/docs/demos/Table.md
index aa3afbf8413..59893dcf8b3 100644
--- a/packages/react-table/src/docs/demos/Table.md
+++ b/packages/react-table/src/docs/demos/Table.md
@@ -317,648 +317,7 @@ class BulkSelectTableDemo extends React.Component {
### Column management
-```js
-import React from 'react';
-import {
- Button,
- DataList,
- DataListCheck,
- DataListItem,
- DataListItemRow,
- DataListCell,
- DataListItemCells,
- Toolbar,
- ToolbarContent,
- ToolbarItem,
- Modal,
- OverflowMenu,
- OverflowMenuGroup,
- OverflowMenuItem,
- OptionsMenu,
- OptionsMenuToggle,
- Pagination,
- PaginationVariant,
- Text,
- TextContent,
- Select,
- SelectVariant
-} from '@patternfly/react-core';
-import { Table, TableHeader, TableBody } from '@patternfly/react-table';
-import CodeIcon from '@patternfly/react-icons/dist/esm/icons/code-icon';
-import CodeBranchIcon from '@patternfly/react-icons/dist/esm/icons/code-branch-icon';
-import CubeIcon from '@patternfly/react-icons/dist/esm/icons/cube-icon';
-import FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon';
-import SortAmountDownIcon from '@patternfly/react-icons/dist/esm/icons/sort-amount-down-icon';
-
-class ColumnManagementAction extends React.Component {
- constructor(props) {
- super(props);
- this.actions = [
- {
- title: Link
- },
- {
- title: 'Action'
- },
- {
- isSeparator: true
- },
- {
- title: Separated link
- }
- ];
- this.defaultColumns = ['Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last commit', ''];
- this.defaultRows = [
- {
- cells: [
- {
- title: (
-
- Node 1
- siemur/test-space
-
- ),
- props: { column: 'Repositories' }
- },
- {
- title: (
-
- 10
-
- ),
- props: { column: 'Branches' }
- },
- {
- title: (
-
- 25
-
- ),
- props: { column: 'Pull requests' }
- },
- {
- title: (
-
- 5
-
- ),
- props: { column: 'Workspaces' }
- },
- {
- title: '2 days ago',
- props: { column: 'Last commit' }
- },
- {
- title: (
-
- Action link
-
- ),
- props: { column: '' }
- }
- ]
- },
- {
- cells: [
- {
- title: (
-
- Node 2
- siemur/test-space
-
- ),
- props: { column: 'Repositories' }
- },
- {
- title: (
-
- 8
-
- ),
- props: { column: 'Branches' }
- },
- {
- title: (
-
- 30
-
- ),
- props: { column: 'Pull requests' }
- },
- {
- title: (
-
- 2
-
- ),
- props: { column: 'Workspaces' }
- },
- {
- title: '2 days ago',
- props: { column: 'Last commit' }
- },
- {
- title: (
-
- Action link
-
- ),
- props: { column: '' }
- }
- ]
- },
- {
- cells: [
- {
- title: (
-
- Node 3
- siemur/test-space
-
- ),
- props: { column: 'Repositories' }
- },
- {
- title: (
-
- 12
-
- ),
- props: { column: 'Branches' }
- },
- {
- title: (
-
- 48
-
- ),
- props: { column: 'Pull requests' }
- },
- {
- title: (
-
- 13
-
- ),
- props: { column: 'Workspaces' }
- },
- {
- title: '30 days ago',
- props: { column: 'Last commit' }
- },
- {
- title: (
-
- Action link
-
- ),
- props: { column: '' }
- }
- ]
- },
- {
- cells: [
- {
- title: (
-
- Node 4
- siemur/test-space
-
- ),
- props: { column: 'Repositories' }
- },
- {
- title: (
-
- 3
-
- ),
- props: { column: 'Branches' }
- },
- {
- title: (
-
- 8
-
- ),
- props: { column: 'Pull requests' }
- },
- {
- title: (
-
- 20
-
- ),
- props: { column: 'Workspaces' }
- },
- {
- title: '8 days ago',
- props: { column: 'Last commit' }
- },
- {
- title: (
-
- Action link
-
- ),
- props: { column: '' }
- }
- ]
- },
- {
- cells: [
- {
- title: (
-
- Node 5
- siemur/test-space
-
- ),
- props: { column: 'Repositories' }
- },
- {
- title: (
-
- 34
-
- ),
- props: { column: 'Branches' }
- },
- {
- title: (
-
- 21
-
- ),
- props: { column: 'Pull requests' }
- },
- {
- title: (
-
- 26
-
- ),
- props: { column: 'Workspaces' }
- },
- {
- title: '2 days ago',
- props: { column: 'Last commit' }
- },
- {
- title: (
-
- Action link
-
- ),
- props: { column: '' }
- }
- ]
- }
- ];
- this.state = {
- filters: [],
- filteredColumns: [],
- filteredRows: [],
- columns: this.defaultColumns,
- rows: this.defaultRows,
- canSelectAll: true,
- isModalOpen: false,
- check1: true,
- check2: true,
- check3: true,
- check4: true,
- check5: true
- };
- this.onSelect = this.onSelect.bind(this);
- this.toggleSelect = this.toggleSelect.bind(this);
- this.renderModal = this.renderModal.bind(this);
- this.matchCheckboxNameToColumn = name => {
- switch (name) {
- case 'check1':
- return 'Repositories';
- case 'check2':
- return 'Branches';
- case 'check3':
- return 'Pull requests';
- case 'check4':
- return 'Workspaces';
- case 'check5':
- return 'Last commit';
- }
- };
- this.filterData = (checked, name) => {
- const { rows, columns, filters } = this.state;
- if (checked) {
- const updatedFilters = filters.filter(item => item !== name);
- const filteredColumns = this.defaultColumns.filter(column => !updatedFilters.includes(column));
- const filteredRows = this.defaultRows.map(({ ...row }) => {
- row.cells = row.cells.filter(cell => !updatedFilters.includes(cell.props.column));
- return row;
- });
- this.setState({
- filters: updatedFilters,
- filteredColumns: filteredColumns,
- filteredRows: filteredRows
- });
- } else {
- let updatedFilters = filters;
- updatedFilters.push(name);
- const filteredColumns = columns.filter(column => !filters.includes(column));
- const filteredRows = rows.map(({ ...row }) => {
- row.cells = row.cells.filter(cell => !filters.includes(cell.props.column));
- return row;
- });
- this.setState({
- filters: updatedFilters,
- filteredColumns: filteredColumns,
- filteredRows: filteredRows
- });
- }
- };
- this.unfilterAllData = () => {
- this.setState({
- filters: [],
- filteredColumns: this.defaultColumns,
- filteredRows: this.defaultRows
- });
- };
- this.handleChange = (checked, event) => {
- const target = event.target;
- const value = target.type === 'checkbox' ? target.checked : target.value;
- this.filterData(checked, this.matchCheckboxNameToColumn(target.name));
- this.setState({
- [target.name]: value
- });
- };
- this.handleModalToggle = () => {
- this.setState(({ isModalOpen }) => ({
- isModalOpen: !isModalOpen
- }));
- };
- this.onSave = () => {
- this.setState(({ filteredColumns, filteredRows, isModalOpen }) => ({
- columns: filteredColumns,
- rows: filteredRows,
- isModalOpen: !isModalOpen
- }));
- };
- this.selectAllColumns = () => {
- this.unfilterAllData();
- this.setState({
- check1: true,
- check2: true,
- check3: true,
- check4: true,
- check5: true
- });
- };
- }
-
- onSelect(event, isSelected, rowId) {
- let rows;
- if (rowId === -1) {
- rows = this.state.rows.map(oneRow => {
- oneRow.selected = isSelected;
- return oneRow;
- });
- } else {
- rows = [...this.state.rows];
- rows[rowId] = { ...rows[rowId], selected: isSelected };
- }
- this.setState({
- rows
- });
- }
-
- toggleSelect(checked) {
- this.setState({
- canSelectAll: checked
- });
- }
-
- renderModal() {
- const { isModalOpen } = this.state;
- return (
-
- Selected categories will be displayed in the table.
-
-
- }
- onClose={this.handleModalToggle}
- actions={[
- ,
-
- ]}
- >
-
-
- );
- }
-
- render() {
- const { canSelectAll, columns, rows } = this.state;
-
- const toolbarItems = (
-
-
- Choose one
-
-
-
-
-
-
-
- }
- aria-label="Sort by"
- hideCaret
- />
- }
- />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
-
- return (
-
-
- {toolbarItems}
-
- }
- aria-label="This is a table with checkboxes"
- id="page-layout-table-column-management-action-table"
- onSelect={this.onSelect}
- cells={columns}
- rows={rows}
- actions={this.actions}
- canSelectAll={canSelectAll}
- >
-
-
-
-
- {this.renderModal()}
-
- );
- }
-}
+```js isFullscreen file="./table-demos/ColumnManagement.jsx"
```
### Column management with draggable
diff --git a/packages/react-table/src/docs/demos/table-demos/ColumnManagement.jsx b/packages/react-table/src/docs/demos/table-demos/ColumnManagement.jsx
new file mode 100644
index 00000000000..8a883f8c32a
--- /dev/null
+++ b/packages/react-table/src/docs/demos/table-demos/ColumnManagement.jsx
@@ -0,0 +1,486 @@
+import * as React from 'react';
+import {
+ Button,
+ DataList,
+ DataListCheck,
+ DataListItem,
+ DataListItemRow,
+ DataListCell,
+ DataListItemCells,
+ Label,
+ Toolbar,
+ ToolbarContent,
+ ToolbarItem,
+ Modal,
+ OverflowMenu,
+ OverflowMenuGroup,
+ OverflowMenuItem,
+ OptionsMenu,
+ OptionsMenuToggle,
+ Pagination,
+ PaginationVariant,
+ Text,
+ TextContent,
+ Select,
+ SelectVariant
+} from '@patternfly/react-core';
+import FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon';
+import SortAmountDownIcon from '@patternfly/react-icons/dist/esm/icons/sort-amount-down-icon';
+import { rows, columns } from '../../examples/Data.jsx';
+import DashboardWrapper from '@patternfly/react-core/src/demos/examples/DashboardWrapper.js';
+import { capitalize } from '@patternfly/react-table/src/components/Table/utils/utils';
+
+export const ColumnManagementAction = () => {
+ const defaultColumns = columns;
+ const defaultRows = rows;
+
+ const [filters, setFilters] = React.useState([]);
+ const [filteredColumns, setFilteredColumns] = React.useState([]);
+ const [filteredRows, setFilteredRows] = React.useState([]);
+ const [managedColumns, setManagedColumns] = React.useState(defaultColumns);
+ const [managedRows, setManagedRows] = React.useState(defaultRows);
+ const [isModalOpen, setIsModalOpen] = React.useState(false);
+ const [checkedState, setCheckedState] = React.useState(Array(columns.length).fill(true));
+ const [page, setPage] = React.useState(1);
+ const [perPage, setPerPage] = React.useState(10);
+ const [paginatedRows, setPaginatedRows] = React.useState(rows);
+
+ const matchCheckboxNameToColumn = name => {
+ switch (name) {
+ case 'check1':
+ return 'Servers';
+ case 'check2':
+ return 'Threads';
+ case 'check3':
+ return 'Applications';
+ case 'check4':
+ return 'Workspaces';
+ case 'check5':
+ return 'Status';
+ case 'check6':
+ return 'Location';
+ case 'check7':
+ return 'Last Modified';
+ case 'check8':
+ return 'URL';
+ }
+ };
+ const matchSelectedColumnNameToAttr = name => {
+ switch (name) {
+ case 'Servers':
+ return 'name';
+ case 'Threads':
+ return 'threads';
+ case 'Applications':
+ return 'applications';
+ case 'Workspaces':
+ return 'workspaces';
+ case 'Status':
+ return 'status';
+ case 'Location':
+ return 'location';
+ case 'Last Modified':
+ return 'lastModified';
+ case 'URL':
+ return 'url';
+ }
+ };
+
+ // Pagination logic
+ const handleSetPage = (_evt, newPage) => {
+ setPage(newPage);
+ };
+
+ const handlePerPageSelect = (_evt, newPerPage) => {
+ setPerPage(newPerPage);
+ };
+
+ const renderPagination = (variant, isCompact) => (
+
+ );
+
+ React.useEffect(() => {
+ setPaginatedRows(managedRows.slice((page - 1) * perPage, page * perPage - 1));
+ }, [managedRows, page, perPage]);
+
+ // Removes attribute from each node object in Data.jsx
+ const removePropFromObject = (object, keys) =>
+ keys.reduce((obj, prop) => {
+ const { [prop]: _, ...keep } = obj;
+ return keep;
+ }, object);
+
+ // Filters columns out of table that are not selected in the column management modal
+ const filterData = (checked, name) => {
+ const selectedColumn = matchSelectedColumnNameToAttr(name);
+
+ const filteredRows = [];
+ if (checked) {
+ const updatedFilters = filters.filter(item => item !== selectedColumn);
+
+ // Only show the names of columns that were selected in the modal
+ const filteredColumns = defaultColumns.filter(
+ column => !updatedFilters.includes(matchSelectedColumnNameToAttr(column))
+ );
+
+ // Remove the attributes (i.e. "columns") that were not selected
+ defaultRows.forEach(item => filteredRows.push(removePropFromObject(item, updatedFilters)));
+
+ setFilters(updatedFilters);
+ setFilteredColumns(filteredColumns);
+ setFilteredRows(filteredRows);
+ } else {
+ let updatedFilters = filters;
+ updatedFilters.push(selectedColumn);
+
+ // Only show the names of columns that were selected in the modal
+ const filteredColumns = managedColumns.filter(column => !filters.includes(matchSelectedColumnNameToAttr(column)));
+
+ // Remove the attributes (i.e. "columns") that were not selected
+ managedRows.forEach(item => filteredRows.push(removePropFromObject(item, updatedFilters)));
+
+ setFilters(updatedFilters);
+ setFilteredColumns(filteredColumns);
+ setFilteredRows(filteredRows);
+ }
+ };
+ const unfilterAllData = () => {
+ setFilters([]);
+ setFilteredColumns(defaultColumns);
+ setFilteredRows(defaultRows);
+ };
+
+ const handleChange = (checked, event) => {
+ const target = event.target;
+ const value = target.type === 'checkbox' ? target.checked : target.value;
+
+ // Remove any columns from the table that aren't checked
+ filterData(checked, matchCheckboxNameToColumn(target.name));
+ const checkedIndex = columns.findIndex(element => element === matchCheckboxNameToColumn(target.name));
+
+ const updatedCheckedState = [...checkedState];
+ updatedCheckedState[checkedIndex] = value;
+ setCheckedState(updatedCheckedState);
+ };
+
+ const handleModalToggle = () => {
+ setIsModalOpen(!isModalOpen);
+ };
+
+ const onSave = () => {
+ setManagedColumns(filteredColumns);
+ setManagedRows(filteredRows);
+ setPaginatedRows(filteredRows);
+ setIsModalOpen(!isModalOpen);
+ };
+
+ const selectAllColumns = () => {
+ unfilterAllData();
+ setCheckedState(Array(columns.length).fill(true));
+ };
+
+ const renderModal = () => {
+ return (
+
+ Selected categories will be displayed in the table.
+
+
+ }
+ onClose={handleModalToggle}
+ actions={[
+ ,
+
+ ]}
+ >
+
+
+ );
+ };
+
+ const renderLabel = labelText => {
+ switch (labelText) {
+ case 'Running':
+ return ;
+ case 'Stopped':
+ return ;
+ case 'Needs Maintenance':
+ return ;
+ case 'Down':
+ return ;
+ }
+ };
+
+ const toolbarItems = (
+
+
+
+ Choose one
+
+
+
+
+
+
+
+ }
+ aria-label="Sort by"
+ hideCaret
+ />
+ }
+ />
+
+
+
+
+
+
+
+
+
+
+
+ {renderPagination()}
+
+
+
+ );
+
+ return (
+
+
+
+
+ {toolbarItems}
+
+
+
+ {managedColumns.map((column, columnIndex) => (
+ | {column} |
+ ))}
+
+
+
+ {paginatedRows.map((row, rowIndex) => (
+
+ <>
+ {Object.entries(row).map(([key, value]) =>
+ key === 'status' ? (
+ |
+ {renderLabel(value)}
+ |
+ ) : key === 'url' ? (
+
+
+ {row.url}
+
+ |
+ ) : (
+
+ {value}
+ |
+ )
+ )}
+ >
+
+ ))}
+
+
+ {renderPagination()}
+ {renderModal()}
+
+
+
+
+ );
+};