import { Fragment, useEffect, useState } from 'react'; import { Button, Content, DataList, DataListCheck, DataListCell, DataListItemCells, DataListControl, Label, Toolbar, ToolbarContent, ToolbarItem, MenuToggle, Modal, ModalHeader, ModalBody, ModalFooter, OverflowMenu, OverflowMenuGroup, OverflowMenuItem, PageSection, Pagination, PaginationVariant } from '@patternfly/react-core'; 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 RhMicronsSortDownLargeToSmallIcon from '@patternfly/react-icons/dist/esm/icons/rh-microns-sort-down-large-to-small-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'; export const TableColumnManagement: React.FunctionComponent = () => { const defaultColumns = columns; const defaultRows = rows; const [filters, setFilters] = useState([]); const [filteredColumns, setFilteredColumns] = useState(defaultColumns); const [filteredRows, setFilteredRows] = useState(defaultRows); const [managedColumns, setManagedColumns] = useState(defaultColumns); const [managedRows, setManagedRows] = useState(defaultRows); const [isModalOpen, setIsModalOpen] = useState(false); const [page, setPage] = useState(1); const [perPage, setPerPage] = useState(10); const [paginatedRows, setPaginatedRows] = useState(rows); const [columnData, setColumnData] = useState(defaultColumns.map((col) => ({ name: col, checked: true }))); const [initialColData, setInitialColData] = useState(columnData); const matchSelectedColumnNameToAttr = (name: string): string => { 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'; 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) => ( ); 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 !== 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 { const 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 handleModalToggle = (_event: React.MouseEvent | KeyboardEvent) => { setIsModalOpen(!isModalOpen); setInitialColData(columnData); }; const onSave = () => { 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; }); setManagedColumns(orderedFilteredColumns); setManagedRows(orderedFilteredRows); setPaginatedRows(filteredRows); setIsModalOpen(!isModalOpen); }; const selectAllColumns = () => { unfilterAllData(); setColumnData(columnData.map((col) => ({ name: col.name, checked: true }))); }; const renderModal = () => (

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): React.JSX.Element => { switch (labelText) { case 'Running': return ; case 'Stopped': return ; case 'Needs maintenance': return ; case 'Down': return ; default: return <>; } }; const toolbarItems = ( }>Name {renderPagination('top', false)} ); return ( {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()}
); };