From c9dd302266db290934d5c8565fcc705f18d4280e Mon Sep 17 00:00:00 2001 From: Katie McFaul Date: Wed, 27 Nov 2024 10:59:39 -0500 Subject: [PATCH 1/2] feat(Table,misc): rewrite column management demo, remove old dnd examples --- .../DataList/examples/DataListDraggable.tsx | 108 --- .../examples/DualListSelectorDragDrop.tsx | 177 ---- packages/react-table/src/demos/Table.md | 6 +- .../demos/examples/TableColumnManagement.tsx | 416 ++++----- .../TableColumnManagementWithDraggable.tsx | 860 +++++++----------- 5 files changed, 523 insertions(+), 1044 deletions(-) delete mode 100644 packages/react-core/src/components/DataList/examples/DataListDraggable.tsx delete mode 100644 packages/react-core/src/components/DualListSelector/examples/DualListSelectorDragDrop.tsx diff --git a/packages/react-core/src/components/DataList/examples/DataListDraggable.tsx b/packages/react-core/src/components/DataList/examples/DataListDraggable.tsx deleted file mode 100644 index 1a1940e2b88..00000000000 --- a/packages/react-core/src/components/DataList/examples/DataListDraggable.tsx +++ /dev/null @@ -1,108 +0,0 @@ -import React from 'react'; -import { - DataList, - DataListItem, - DataListCell, - DataListItemRow, - DataListCheck, - DataListControl, - DataListDragButton, - DataListItemCells, - getUniqueId -} from '@patternfly/react-core'; -import { DragDrop, Draggable, Droppable } from '@patternfly/react-core/deprecated'; - -interface ItemType { - id: string; - content: string; -} - -const getItems = (count: number) => - Array.from({ length: count }, (_, idx) => idx).map((idx) => ({ - id: `draggable-item-${idx}`, - content: `item ${idx} `.repeat(idx === 4 ? 20 : 1) - })); - -const reorder = (list: ItemType[], startIndex: number, endIndex: number) => { - const result = list; - const [removed] = result.splice(startIndex, 1); - result.splice(endIndex, 0, removed); - return result; -}; - -export const DataListDraggable: React.FunctionComponent = () => { - const [items, setItems] = React.useState(getItems(10)); - const [liveText, setLiveText] = React.useState(''); - - function onDrag(source) { - setLiveText(`Started dragging ${items[source.index].content}`); - // Return true to allow drag - return true; - } - - function onDragMove(source, dest) { - const newText = dest ? `Move ${items[source.index].content} to ${items[dest.index].content}` : 'Invalid drop zone'; - if (newText !== liveText) { - setLiveText(newText); - } - } - - function onDrop(source, dest) { - if (dest) { - const newItems = reorder(items, source.index, dest.index); - setItems(newItems); - - setLiveText('Dragging finished.'); - return true; // Signal that this is a valid drop and not to animate the item returning home. - } else { - setLiveText('Dragging cancelled. List unchanged.'); - } - } - - const uniqueId = getUniqueId(); - - return ( - - - - {items.map(({ id, content }) => ( - - - - - - - - - {content} - - ]} - /> - - - - ))} - - -
- {liveText} -
-
- Press space or enter to begin dragging, and use the arrow keys to navigate up or down. Press enter to confirm - the drag, or any other key to cancel the drag operation. -
-
- ); -}; diff --git a/packages/react-core/src/components/DualListSelector/examples/DualListSelectorDragDrop.tsx b/packages/react-core/src/components/DualListSelector/examples/DualListSelectorDragDrop.tsx deleted file mode 100644 index 54b12fb317d..00000000000 --- a/packages/react-core/src/components/DualListSelector/examples/DualListSelectorDragDrop.tsx +++ /dev/null @@ -1,177 +0,0 @@ -import React from 'react'; -import { - DualListSelector, - DualListSelectorPane, - DualListSelectorList, - DualListSelectorListItem, - DualListSelectorControlsWrapper, - DualListSelectorControl -} from '@patternfly/react-core'; -import { DragDrop, Draggable, Droppable, DraggableItemPosition } from '@patternfly/react-core/deprecated'; -import AngleDoubleLeftIcon from '@patternfly/react-icons/dist/esm/icons/angle-double-left-icon'; -import AngleLeftIcon from '@patternfly/react-icons/dist/esm/icons/angle-left-icon'; -import AngleDoubleRightIcon from '@patternfly/react-icons/dist/esm/icons/angle-double-right-icon'; -import AngleRightIcon from '@patternfly/react-icons/dist/esm/icons/angle-right-icon'; - -export const DualListSelectorComposableDragDrop: React.FunctionComponent = () => { - const [ignoreNextOptionSelect, setIgnoreNextOptionSelect] = React.useState(false); - const [availableOptions, setAvailableOptions] = React.useState([ - { text: 'Apple', selected: false, isVisible: true }, - { text: 'Banana', selected: false, isVisible: true }, - { text: 'Pineapple', selected: false, isVisible: true } - ]); - const [chosenOptions, setChosenOptions] = React.useState([ - { text: 'Orange', selected: false, isVisible: true }, - { text: 'Grape', selected: false, isVisible: true }, - { text: 'Peach', selected: false, isVisible: true }, - { text: 'Strawberry', selected: false, isVisible: true } - ]); - - const moveSelected = (fromAvailable: boolean) => { - const sourceOptions = fromAvailable ? availableOptions : chosenOptions; - const destinationOptions = fromAvailable ? chosenOptions : availableOptions; - for (let i = 0; i < sourceOptions.length; i++) { - const option = sourceOptions[i]; - if (option.selected && option.isVisible) { - sourceOptions.splice(i, 1); - destinationOptions.push(option); - option.selected = false; - i--; - } - } - if (fromAvailable) { - setAvailableOptions([...sourceOptions]); - setChosenOptions([...destinationOptions]); - } else { - setChosenOptions([...sourceOptions]); - setAvailableOptions([...destinationOptions]); - } - }; - - const moveAll = (fromAvailable: boolean) => { - if (fromAvailable) { - setChosenOptions([...availableOptions.filter((option) => option.isVisible), ...chosenOptions]); - setAvailableOptions([...availableOptions.filter((option) => !option.isVisible)]); - } else { - setAvailableOptions([...chosenOptions.filter((option) => option.isVisible), ...availableOptions]); - setChosenOptions([...chosenOptions.filter((option) => !option.isVisible)]); - } - }; - - const onOptionSelect = ( - event: React.MouseEvent | React.ChangeEvent | React.KeyboardEvent, - index: number, - isChosen: boolean - ) => { - if (ignoreNextOptionSelect) { - setIgnoreNextOptionSelect(false); - return; - } - if (isChosen) { - const newChosen = [...chosenOptions]; - newChosen[index].selected = !chosenOptions[index].selected; - setChosenOptions(newChosen); - } else { - const newAvailable = [...availableOptions]; - newAvailable[index].selected = !availableOptions[index].selected; - setAvailableOptions(newAvailable); - } - }; - - const onDrop = (source: DraggableItemPosition, dest: DraggableItemPosition | undefined) => { - if (dest) { - const newList = [...chosenOptions]; - const [removed] = newList.splice(source.index, 1); - newList.splice(dest.index, 0, removed); - setChosenOptions(newList); - return true; - } - return false; - }; - - return ( - - option.selected && option.isVisible).length} of ${ - availableOptions.filter((option) => option.isVisible).length - } options selected`} - > - - {availableOptions.map((option, index) => - option.isVisible ? ( - onOptionSelect(e, index, false)} - > - {option.text} - - ) : null - )} - - - - option.selected)} - onClick={() => moveSelected(true)} - aria-label="Add selected" - icon={} - /> - moveAll(true)} - aria-label="Add all" - icon={} - /> - moveAll(false)} - aria-label="Remove all" - icon={} - /> - moveSelected(false)} - isDisabled={!chosenOptions.some((option) => option.selected)} - aria-label="Remove selected" - icon={} - /> - - { - setIgnoreNextOptionSelect(true); - return true; - }} - onDrop={onDrop} - > - option.selected && option.isVisible).length} of ${ - chosenOptions.filter((option) => option.isVisible).length - } options selected`} - isChosen - > - - - {chosenOptions.map((option, index) => - option.isVisible ? ( - - onOptionSelect(e, index, true)} - isDraggable - > - {option.text} - - - ) : null - )} - - - - - - ); -}; diff --git a/packages/react-table/src/demos/Table.md b/packages/react-table/src/demos/Table.md index 2ba18a2a546..98512a99c1a 100644 --- a/packages/react-table/src/demos/Table.md +++ b/packages/react-table/src/demos/Table.md @@ -40,8 +40,12 @@ NavItem, NavList, PageSidebar, PageSidebarBody, +Modal, +ModalHeader, +ModalBody, +ModalFooter, } from '@patternfly/react-core'; -import { Table as TableDeprecated, TableHeader, TableBody } from '@patternfly/react-table/deprecated'; +import { DragDropSort } from '@patternfly/react-drag-drop'; import CheckIcon from '@patternfly/react-icons/dist/esm/icons/check-icon'; import CloneIcon from '@patternfly/react-icons/dist/esm/icons/clone-icon'; import CodeIcon from '@patternfly/react-icons/dist/esm/icons/code-icon'; diff --git a/packages/react-table/src/demos/examples/TableColumnManagement.tsx b/packages/react-table/src/demos/examples/TableColumnManagement.tsx index 69d194a2837..00a25e8a27f 100644 --- a/packages/react-table/src/demos/examples/TableColumnManagement.tsx +++ b/packages/react-table/src/demos/examples/TableColumnManagement.tsx @@ -2,7 +2,6 @@ import React from 'react'; import { Button, - Card, Content, DataList, DataListCheck, @@ -16,6 +15,9 @@ import { ToolbarItem, MenuToggle, Modal, + ModalHeader, + ModalBody, + ModalFooter, OverflowMenu, OverflowMenuGroup, OverflowMenuItem, @@ -207,173 +209,181 @@ export const TableColumnManagement: React.FunctionComponent = () => { const renderModal = () => ( -

Selected categories will be displayed in the table.

- - - } onClose={handleModalToggle} - actions={[ + aria-labelledby="basic-modal-title" + aria-describedby="modal-box-body-basic" + > + +

Selected categories will be displayed in the table.

+ + + } + /> + + + + + + + + + ]} + /> + + + + + + + + + ]} + /> + + + + + + + + + ]} + /> + + + + + + + + + ]} + /> + + + + + + + + + ]} + /> + + + + + + + + + ]} + /> + + + + + + + + + ]} + /> + + + + + + + + + ]} + /> + + + + + , + + , - ]} - > - - - - - - - - ]} - /> - - - - - - - - - ]} - /> - - - - - - - - - ]} - /> - - - - - - - - - ]} - /> - - - - - - - - - ]} - /> - - - - - - - - - ]} - /> - - - - - - - - - ]} - /> - - - - - - - - - ]} - /> - - - +
); @@ -399,7 +409,7 @@ export const TableColumnManagement: React.FunctionComponent = () => { Choose one - + }>Name @@ -433,50 +443,48 @@ export const TableColumnManagement: React.FunctionComponent = () => { - - {toolbarItems} - - - - {managedColumns.map((column, columnIndex) => ( - - ))} - - - - {paginatedRows.map((row, rowIndex) => ( - - <> - {Object.entries(row).map(([key, value]) => - // eslint-disable-next-line no-nested-ternary - key === 'status' ? ( - // eslint-disable-next-line react/jsx-key - - ) : key === 'url' ? ( - - ) : ( - - ) - )} - - + {toolbarItems} +
{column}
- {renderLabel(value as string)} - - - {row.url} - - - {value as string} -
+ + + {managedColumns.map((column, columnIndex) => ( + ))} - -
{column}
- {renderPagination('bottom', false)} - {renderModal()} -
+ + + + {paginatedRows.map((row, rowIndex) => ( + + <> + {Object.entries(row).map(([key, value], idx) => + // eslint-disable-next-line no-nested-ternary + key === 'status' ? ( + + {renderLabel(value as string)} + + ) : key === 'url' ? ( + + + {row.url} + + + ) : ( + + {value as string} + + ) + )} + + + ))} + + + {renderPagination('bottom', false)} + {renderModal()}
diff --git a/packages/react-table/src/demos/examples/TableColumnManagementWithDraggable.tsx b/packages/react-table/src/demos/examples/TableColumnManagementWithDraggable.tsx index 9b0e3cbc492..43eab7d6cf6 100644 --- a/packages/react-table/src/demos/examples/TableColumnManagementWithDraggable.tsx +++ b/packages/react-table/src/demos/examples/TableColumnManagementWithDraggable.tsx @@ -1,635 +1,387 @@ import React from 'react'; + import { Button, Content, DataList, DataListCheck, - DataListControl, - DataListDragButton, - DataListItem, - DataListItemRow, DataListCell, DataListItemCells, + DataListControl, + Label, Toolbar, ToolbarContent, ToolbarItem, + MenuToggle, Modal, + ModalHeader, + ModalBody, + ModalFooter, OverflowMenu, OverflowMenuGroup, OverflowMenuItem, - MenuToggle + PageSection, + Pagination, + PaginationVariant } from '@patternfly/react-core'; -import { Table as TableDeprecated, TableHeader, TableBody } from '@patternfly/react-table/deprecated'; -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 { Table, TableText, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table'; +import { DragDropSort } from '@patternfly/react-drag-drop'; 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 { DashboardWrapper } from '@patternfly/react-table/dist/esm/demos/DashboardWrapper'; +import { capitalize } from '@patternfly/react-table/src/components/Table/utils/utils'; +import { rows, columns, SampleDataRow } from '@patternfly/react-table/dist/esm/demos/sampleData'; -interface RowType { - cells: ( - | { - title: React.JSX.Element; - props: { - column: string; - }; - } - | { - title: string; - props: { - column: string; - }; - } - )[]; -} - -export const TableColumnManagementWithDraggable: React.FunctionComponent = () => { - const actions = [ - { - title: Link - }, - { - title: 'Action' - }, - { - isSeparator: true - }, - { - title: Separated link - } - ]; - const defaultColumns: string[] = ['Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last commit', '']; - const 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: '' } - } - ] - } - ]; +export const TableColumnManagement: React.FunctionComponent = () => { + const defaultColumns = columns; + const defaultRows = rows; const [filters, setFilters] = React.useState([]); const [filteredColumns, setFilteredColumns] = React.useState([]); - const [columns, setColumns] = React.useState(defaultColumns); - const [rows, setRows] = React.useState(defaultRows); + const [filteredRows, setFilteredRows] = React.useState([]); + const [managedColumns, setManagedColumns] = React.useState(defaultColumns); + const [managedRows, setManagedRows] = React.useState(defaultRows); const [isModalOpen, setIsModalOpen] = React.useState(false); - const [check1, setCheck1] = React.useState(true); - const [check2, setCheck2] = React.useState(true); - const [check3, setCheck3] = React.useState(true); - const [check4, setCheck4] = React.useState(true); - const [check5, setCheck5] = React.useState(true); + const [page, setPage] = React.useState(1); + const [perPage, setPerPage] = React.useState(10); + const [paginatedRows, setPaginatedRows] = React.useState(rows); - const matchCheckboxNameToColumn = (name: string) => { + const [columnData, setColumnData] = React.useState(defaultColumns.map((col) => ({ name: col, checked: true }))); + const [initialColData, setInitialColData] = React.useState(columnData); + + const matchSelectedColumnNameToAttr = (name: string): string => { switch (name) { - case 'check1': - return 'Repositories'; - case 'check2': - return 'Branches'; - case 'check3': - return 'Pull requests'; - case 'check4': - return 'Workspaces'; - case 'check5': - return 'Last commit'; + 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'; default: return ''; } }; + // Pagination logic + const handleSetPage = ( + _evt: MouseEvent | React.MouseEvent | React.KeyboardEvent, + newPage: number + ) => { + setPage(newPage); + }; + + const handlePerPageSelect = ( + _evt: MouseEvent | React.MouseEvent | React.KeyboardEvent, + newPerPage: number + ) => { + setPerPage(newPerPage); + }; + + const renderPagination = (variant: 'top' | 'bottom' | PaginationVariant, isCompact: boolean) => ( + + ); + + 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: any, keys: string[]): any => + keys.reduce((obj, prop) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { [prop]: _, ...keep } = obj; + return keep; + }, object); + + // Filters columns out of table that are not selected in the column management modal const filterData = (checked: boolean, name: string) => { + const selectedColumn = matchSelectedColumnNameToAttr(name); + + const filteredRows: SampleDataRow[] = []; if (checked) { - const updatedFilters = filters.filter((item) => item !== name); - const updatedFilteredColumns = defaultColumns.filter((column) => !updatedFilters.includes(column)); + 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(updatedFilteredColumns); + setFilteredColumns(filteredColumns); + setFilteredRows(filteredRows); } else { const updatedFilters = filters; - updatedFilters.push(name); - const updatedFilteredColumns = columns.filter((column) => !filters.includes(column)); + 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(updatedFilteredColumns); + setFilteredColumns(filteredColumns); + setFilteredRows(filteredRows); } }; + const unfilterAllData = () => { setFilters([]); setFilteredColumns(defaultColumns); + setFilteredRows(defaultRows); }; - const handleChange = (event: React.FormEvent, checked: boolean) => { - const target = event.currentTarget; - const name = target.name; - const value = target.type === 'checkbox' ? checked : !!target.value; - filterData(checked, matchCheckboxNameToColumn(target.name)); - switch (name) { - case 'check1': - setCheck1(value); - break; - case 'check2': - setCheck2(value); - break; - case 'check3': - setCheck3(value); - break; - case 'check4': - setCheck4(value); - break; - case 'check5': - setCheck5(value); - break; - } - }; - const handleModalToggle = (_event: KeyboardEvent | React.MouseEvent) => { + const handleModalToggle = (_event: React.MouseEvent | KeyboardEvent) => { setIsModalOpen(!isModalOpen); + setInitialColData(columnData); }; + const onSave = () => { - // concat empty string at the end for actions column - const filteredOrderedColumns: string[] = columns - .filter((col) => filteredColumns.length === 0 || filteredColumns.indexOf(col as string) > -1) - .concat(['']); - const orderedRows: RowType[] = []; - defaultRows.forEach((row) => { - const updatedCells = row.cells - .filter((cell) => filteredOrderedColumns.indexOf(cell.props.column) > -1) - .sort((cellA, cellB) => { - const indexA = filteredOrderedColumns.indexOf(cellA.props.column); - const indexB = filteredOrderedColumns.indexOf(cellB.props.column); - if (indexA < indexB) { - return -1; - } - if (indexA > indexB) { - return 1; - } - // a must be equal to b - return 0; - }); - orderedRows.push({ - cells: updatedCells + const orderedFilteredColumns: string[] = []; + columnData.map((col) => { + if (filteredColumns.find((filteredCol) => filteredCol === col.name)) { + orderedFilteredColumns.push(col.name); + } + }); + + const orderedFilteredRows = filteredRows.map((row) => { + let orderedRow; + columnData.map((col) => { + if (filteredColumns.find((filteredCol) => filteredCol === col.name)) { + const rowField = matchSelectedColumnNameToAttr(col.name); + orderedRow = { ...orderedRow, [rowField]: row[rowField] }; + } }); + return orderedRow; }); - setColumns(filteredOrderedColumns as string[]); - setRows(orderedRows); + + setManagedColumns(orderedFilteredColumns); + setManagedRows(orderedFilteredRows); + setPaginatedRows(filteredRows); setIsModalOpen(!isModalOpen); }; const selectAllColumns = () => { unfilterAllData(); - setCheck1(true); - setCheck2(true); - setCheck3(true); - setCheck4(true); - setCheck5(true); + setColumnData(columnData.map((col) => ({ name: col.name, checked: true }))); }; const renderModal = () => ( -

Selected categories will be displayed in the table.

- - - } onClose={handleModalToggle} - actions={[ + aria-labelledby="basic-modal-title" + aria-describedby="modal-box-body-basic" + > + +

Selected categories will be displayed in the table.

+ + + } + /> + + ({ + id: colData.name, + content: ( + <> + + , _checked: boolean) => { + let newColumnData: { name: string; checked: boolean }[] = []; + + columnData.map((colData) => { + if (event.currentTarget.name === `check-${colData.name}`) { + newColumnData = [...newColumnData, { name: colData.name, checked: !colData.checked }]; + filterData(!colData.checked, colData.name); + } else { + newColumnData = [...newColumnData, colData]; + } + }); + + setColumnData(newColumnData); + }} + /> + + + + + ]} + /> + + ), + data: colData + }))} + onDrop={(_, newItems) => { + setColumnData(newItems.map((item) => (item as any).data)); + }} + variant="DataList" + overlayProps={{ isCompact: true }} + > + + + + , - + , + - ]} - > - - - - - - - - - - - ]} - /> - - - - - - - - - - - - ]} - /> - - - - - - - - - - - - ]} - /> - - - - - - - - - - - - ]} - /> - - - - - - - - - - - - ]} - /> - - - +
); + const renderLabel = (labelText: string): JSX.Element => { + switch (labelText) { + case 'Running': + return ; + case 'Stopped': + return ; + case 'Needs maintenance': + return ; + case 'Down': + return ; + default: + return <>; + } + }; + const toolbarItems = ( - - - - - - }>Name - - - - + + + + + - + }>Name - + - - - - + + + + + + + + +
+
+ {renderPagination('top', false)} +
+ ); return ( - - {toolbarItems} - - } - aria-label="Column Management with Draggable Table" - cells={columns} - rows={rows} - actions={actions} - > - - - - {renderModal()} + + + {toolbarItems} + + + + {managedColumns.map((column, columnIndex) => ( + + ))} + + + + {paginatedRows.map((row, rowIndex) => ( + + <> + {Object.entries(row).map(([key, value], idx) => + // eslint-disable-next-line no-nested-ternary + key === 'status' ? ( + + ) : key === 'url' ? ( + + ) : ( + + ) + )} + + + ))} + +
{column}
+ {renderLabel(value as string)} + + + {row.url} + + + {value as string} +
+ {renderPagination('bottom', false)} + {renderModal()} +
+
); }; From 547121b8fccfd6e1d69a8d9c6eb2628aee291bee Mon Sep 17 00:00:00 2001 From: Katie McFaul Date: Mon, 16 Dec 2024 11:18:35 -0500 Subject: [PATCH 2/2] fix basic table column management --- .../src/demos/examples/TableColumnManagement.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/react-table/src/demos/examples/TableColumnManagement.tsx b/packages/react-table/src/demos/examples/TableColumnManagement.tsx index 00a25e8a27f..334d54262a4 100644 --- a/packages/react-table/src/demos/examples/TableColumnManagement.tsx +++ b/packages/react-table/src/demos/examples/TableColumnManagement.tsx @@ -233,7 +233,7 @@ export const TableColumnManagement: React.FunctionComponent = () => { { { { { { { {