From 7e4fd9327c7ef248c311329b8d62b791504f2293 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Pet=C5=99=C3=ADk?= Date: Wed, 13 Sep 2023 12:20:45 +0200 Subject: [PATCH 01/15] chore(table) convert to TS chore(DashboardWrapper) convert to TS chore(Table) convert demos to TS delete superfluous dashboard components declare as ts files remove duplicate ids fix import errors, WIP build errors sync toolbar demo with main --- .../examples/TableStickyColumnsAndHeader.tsx | 10 +- .../react-table/src/{docs => }/demos/Table.md | 189 +------ .../examples/BulkSelect.tsx} | 68 ++- .../src/demos/examples/ColumnManagement.tsx | 486 ++++++++++++++++++ .../examples/Compact.tsx} | 38 +- .../examples/CompoundExpansion.tsx} | 35 +- .../src/demos/examples/EmptyStateDefault.tsx | 60 +++ .../src/demos/examples/EmptyStateError.tsx | 53 ++ .../src/demos/examples/EmptyStateLoading.tsx | 43 ++ .../examples/ExpandCollapseAll.tsx} | 25 +- .../examples/SortableResponsive.tsx} | 54 +- .../examples/StaticBottomPagination.tsx} | 17 +- .../examples/StickyFirstColumn.tsx} | 29 +- .../examples/StickyHeader.tsx} | 2 +- packages/react-table/src/demos/index.ts | 1 + .../sampleData.js => demos/sampleData.tsx} | 15 +- .../demos/table-demos/ColumnManagement.jsx | 471 ----------------- packages/react-table/src/index.ts | 1 + packages/react-table/tsconfig.json | 5 +- 19 files changed, 848 insertions(+), 754 deletions(-) rename packages/react-table/src/{docs => }/demos/Table.md (88%) rename packages/react-table/src/{docs/demos/table-demos/BulkSelect.jsx => demos/examples/BulkSelect.tsx} (68%) create mode 100644 packages/react-table/src/demos/examples/ColumnManagement.tsx rename packages/react-table/src/{docs/demos/table-demos/Compact.jsx => demos/examples/Compact.tsx} (82%) rename packages/react-table/src/{docs/demos/table-demos/CompoundExpansion.jsx => demos/examples/CompoundExpansion.tsx} (90%) create mode 100644 packages/react-table/src/demos/examples/EmptyStateDefault.tsx create mode 100644 packages/react-table/src/demos/examples/EmptyStateError.tsx create mode 100644 packages/react-table/src/demos/examples/EmptyStateLoading.tsx rename packages/react-table/src/{docs/demos/table-demos/ExpandCollapseAll.jsx => demos/examples/ExpandCollapseAll.tsx} (92%) rename packages/react-table/src/{docs/demos/table-demos/SortableResponsive.jsx => demos/examples/SortableResponsive.tsx} (90%) rename packages/react-table/src/{docs/demos/table-demos/StaticBottomPagination.jsx => demos/examples/StaticBottomPagination.tsx} (88%) rename packages/react-table/src/{docs/demos/table-demos/StickyFirstColumn.jsx => demos/examples/StickyFirstColumn.tsx} (92%) rename packages/react-table/src/{docs/demos/table-demos/StickyHeader.jsx => demos/examples/StickyHeader.tsx} (96%) create mode 100644 packages/react-table/src/demos/index.ts rename packages/react-table/src/{docs/demos/table-demos/sampleData.js => demos/sampleData.tsx} (98%) delete mode 100644 packages/react-table/src/docs/demos/table-demos/ColumnManagement.jsx diff --git a/packages/react-table/src/components/Table/examples/TableStickyColumnsAndHeader.tsx b/packages/react-table/src/components/Table/examples/TableStickyColumnsAndHeader.tsx index 68d39559119..eb2b42bdbdb 100644 --- a/packages/react-table/src/components/Table/examples/TableStickyColumnsAndHeader.tsx +++ b/packages/react-table/src/components/Table/examples/TableStickyColumnsAndHeader.tsx @@ -53,10 +53,10 @@ export const TableStickyColumnsAndHeader: React.FunctionComponent = () => { // Index of the currently sorted column // Note: if you intend to make columns reorderable, you may instead want to use a non-numeric key // as the identifier of the sorted column. See the "Compound expandable" example. - const [activeSortIndex, setActiveSortIndex] = React.useState(null); + const [activeSortIndex, setActiveSortIndex] = React.useState(null); // Sort direction of the currently sorted column - const [activeSortDirection, setActiveSortDirection] = React.useState<'asc' | 'desc' | null>(null); + const [activeSortDirection, setActiveSortDirection] = React.useState<'asc' | 'desc' | null | undefined>(null); // Since OnSort specifies sorted columns by index, we need sortable values for our object by column index. // This example is trivial since our data objects just contain strings, but if the data was more complex @@ -69,7 +69,7 @@ export const TableStickyColumnsAndHeader: React.FunctionComponent = () => { // Note that we perform the sort as part of the component's render logic and not in onSort. // We shouldn't store the list of data in state because we don't want to have to sync that with props. let sortedFacts = facts; - if (activeSortIndex !== null) { + if (activeSortIndex) { sortedFacts = facts.sort((a, b) => { const aValue = getSortableRowValues(a)[activeSortIndex]; const bValue = getSortableRowValues(b)[activeSortIndex]; @@ -86,8 +86,8 @@ export const TableStickyColumnsAndHeader: React.FunctionComponent = () => { const getSortParams = (columnIndex: number): ThProps['sort'] => ({ sortBy: { - index: activeSortIndex, - direction: activeSortDirection + index: activeSortIndex as number, + direction: activeSortDirection as any }, onSort: (_event, index, direction) => { setActiveSortIndex(index); diff --git a/packages/react-table/src/docs/demos/Table.md b/packages/react-table/src/demos/Table.md similarity index 88% rename from packages/react-table/src/docs/demos/Table.md rename to packages/react-table/src/demos/Table.md index 6aebb44de5b..f3f5f2457f3 100644 --- a/packages/react-table/src/docs/demos/Table.md +++ b/packages/react-table/src/demos/Table.md @@ -25,7 +25,6 @@ TextContent, Text, Divider } from '@patternfly/react-core'; import { Table as TableDeprecated, TableHeader, TableBody } from '@patternfly/react-table/deprecated'; - 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'; @@ -49,37 +48,36 @@ import BarsIcon from '@patternfly/react-icons/dist/esm/icons/bars-icon'; import AttentionBellIcon from '@patternfly/react-icons/dist/esm/icons/attention-bell-icon'; import BlueprintIcon from '@patternfly/react-icons/dist/esm/icons/blueprint-icon'; import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon'; -import { rows, columns } from '@patternfly/react-table/src/docs/demos/table-demos/sampleData'; +import { rows, columns } from './sampleData'; ## Demos ### Bulk select -```js isFullscreen file="./table-demos/BulkSelect.jsx" - +```js isFullscreen file="./examples/BulkSelect.tsx" ``` ### Expand/collapse all -```js isFullscreen file="./table-demos/ExpandCollapseAll.jsx" +```js isFullscreen file="./examples/ExpandCollapseAll.tsx" ``` ### Compact -```js isFullscreen file="./table-demos/Compact.jsx" +```js isFullscreen file="./examples/Compact.tsx" ``` ### Compound expansion -```js isFullscreen file="./table-demos/CompoundExpansion.jsx" +```js isFullscreen file="./examples/CompoundExpansion.tsx" ``` ### Column management -```js isFullscreen file="./table-demos/ColumnManagement.jsx" +```js isFullscreen file="./examples/ColumnManagement.tsx" ``` @@ -855,7 +853,7 @@ import { import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon'; import FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon'; import { Table, TableText, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table'; -import { rows, columns } from '@patternfly/react-table/src/docs/demos/table-demos/sampleData'; +import { rows, columns } from './sampleData'; class FilterTableDemo extends React.Component { constructor(props) { @@ -1297,7 +1295,7 @@ class FilterTableDemo extends React.Component { ### Sortable - responsive -```js isFullscreen file="./table-demos/SortableResponsive.jsx" +```js isFullscreen file="./examples/SortableResponsive.tsx" ``` @@ -1420,19 +1418,19 @@ class ComplexPaginationTableDemo extends React.Component { ### Static bottom pagination on mobile -```js isFullscreen file="table-demos/StaticBottomPagination.jsx" +```ts isFullscreen file="./examples/StaticBottomPagination.tsx" ``` ### Sticky header -```js isFullscreen file="./table-demos/StickyHeader.jsx" +```js isFullscreen file="./examples/StickyHeader.tsx" ``` ### Sticky first column -```js isFullscreen file="./table-demos/StickyFirstColumn.jsx" +```js isFullscreen file="./examples/StickyFirstColumn.tsx" ``` @@ -1440,7 +1438,7 @@ class ComplexPaginationTableDemo extends React.Component { A toolbar may be added above a sticky table either inside or outside the `OuterScrollContainer`. -```ts isFullscreen file="../../components/Table/examples/TableStickyColumnsAndHeader.tsx" +```js isFullscreen file="../components/Table/examples/TableStickyColumnsAndHeader.tsx" ``` @@ -1450,172 +1448,15 @@ These examples demonstrate the use of an [Empty State component](/components/emp ### Empty -```js isFullscreen -import React from 'react'; -import { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table'; -import { - Bullseye, - Button, - Card, - EmptyState, - EmptyStateVariant, - EmptyStateIcon, - EmptyStateBody, - EmptyStateHeader, - EmptyStateFooter, - EmptyStateActions, - PageSection -} from '@patternfly/react-core'; -import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon'; -import { DashboardWrapper } from '@patternfly/react-core/src/demos/DashboardWrapper'; - -export const TableEmptyState: React.FunctionComponent = () => ( - - - - - - - - - - - - - - - - - - -
RepositoriesBranchesPull requestsWorkspacesLast commit
- - - } - titleText="No results found" - headingLevel="h2" - /> - - No results match this filter criteria. Clear all filters and try again. - - - - - - - - -
-
-
-
-); +```js isFullscreen file="./examples/EmptyStateDefault.tsx" ``` ### Loading -```js isFullscreen -import React from 'react'; -import { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table'; -import { - Bullseye, - Card, - EmptyState, - EmptyStateIcon, - EmptyStateBody, - EmptyStateHeader, - PageSection, - Spinner -} from '@patternfly/react-core'; -import { DashboardWrapper } from '@patternfly/react-core/src/demos/DashboardWrapper'; - -export const LoadingStateDemo: React.FunctionComponent = () => ( - - - - - - - - - - - - - - - - - - -
RepositoriesBranchesPull requestsWorkspacesLast commit
- - - } /> - - -
-
-
-
-); +```js isFullscreen file="./examples/EmptyStateLoading.tsx" ``` ### Error -```js isFullscreen -import React from 'react'; -import { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table'; -import { - Bullseye, - Card, - EmptyState, - EmptyStateVariant, - EmptyStateIcon, - EmptyStateBody, - EmptyStateHeader, - PageSection -} from '@patternfly/react-core'; -import ExclamationCircleIcon from '@patternfly/react-icons/dist/esm/icons/exclamation-circle-icon'; -import globalDangerColor200 from '@patternfly/react-tokens/dist/esm/global_danger_color_200'; -import { DashboardWrapper } from '@patternfly/react-core/src/demos/DashboardWrapper'; - -export const ErrorStateDemo: React.FunctionComponent = () => ( - - - - - - - - - - - - - - - - - - -
RepositoriesBranchesPull requestsWorkspacesLast commit
- - - } - headingLevel="h2" - /> - - There was an error retrieving data. Check your connection and reload the page. - - - -
-
-
-
-); +```js isFullscreen file="./examples/EmptyStateError.tsx" ``` diff --git a/packages/react-table/src/docs/demos/table-demos/BulkSelect.jsx b/packages/react-table/src/demos/examples/BulkSelect.tsx similarity index 68% rename from packages/react-table/src/docs/demos/table-demos/BulkSelect.jsx rename to packages/react-table/src/demos/examples/BulkSelect.tsx index 7625126924e..55585336c94 100644 --- a/packages/react-table/src/docs/demos/table-demos/BulkSelect.jsx +++ b/packages/react-table/src/demos/examples/BulkSelect.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState } from 'react'; import { Dropdown, @@ -6,44 +6,62 @@ import { DropdownItem, MenuToggle, MenuToggleCheckbox, + MenuToggleElement, PageSection, Pagination, Toolbar, ToolbarContent, ToolbarGroup, - ToolbarItem + ToolbarItem, + PaginationVariant } from '@patternfly/react-core'; -import { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table'; +import { Table, Thead, Tr, Th, Tbody, Td, rows, columns, SampleDataRow } from '@patternfly/react-table'; import { DashboardWrapper } from '@patternfly/react-core/src/demos/DashboardWrapper'; -import { rows, columns } from '@patternfly/react-table/src/docs/demos/table-demos/sampleData'; -export const BulkSelectTableDemo = () => { - const [isBulkSelectDropdownOpen, setIsBulkSelectDropdownOpen] = React.useState(false); - const [bulkSelection, setBulkSelection] = React.useState(''); - const [page, setPage] = React.useState(1); - const [perPage, setPerPage] = React.useState(10); - const [paginatedRows, setPaginatedRows] = React.useState(rows.slice(0, 10)); - const [selectedRows, setSelectedRows] = React.useState([]); - const handleSetPage = (_evt, newPage, _perPage, startIdx, endIdx) => { +export const BulkSelectTableDemo: React.FunctionComponent = () => { + const [isBulkSelectDropdownOpen, setIsBulkSelectDropdownOpen] = useState(false); + const [bulkSelection, setBulkSelection] = useState(''); + const [page, setPage] = useState(1); + const [perPage, setPerPage] = useState(10); + const [paginatedRows, setPaginatedRows] = useState(rows.slice(0, 10)); + const [selectedRows, setSelectedRows] = useState([]); + + const handleSetPage = ( + _evt: MouseEvent | React.MouseEvent | React.KeyboardEvent, + newPage: number, + _perPage: number, + startIdx: number, + endIdx: number + ) => { setPaginatedRows(rows.slice(startIdx, endIdx)); setPage(newPage); }; - const handlePerPageSelect = (_evt, newPerPage, newPage, startIdx, endIdx) => { + + const handlePerPageSelect = ( + _evt: MouseEvent | React.MouseEvent | React.KeyboardEvent, + newPerPage: number, + newPage: number, + startIdx: number, + endIdx: number + ) => { setPaginatedRows(rows.slice(startIdx, endIdx)); setPage(newPage); setPerPage(newPerPage); }; - const setRowSelected = (row, isSelecting = true) => + const setRowSelected = (row: SampleDataRow, isSelecting: boolean) => setSelectedRows((prevSelected) => { const otherSelectedRows = prevSelected.filter((r) => r !== row.name); return isSelecting ? [...otherSelectedRows, row.name] : otherSelectedRows; }); - const selectAllRows = (isSelecting = true) => setSelectedRows(isSelecting ? rows.map((r) => r.name) : []); - const selectPageRows = (isSelecting = true) => setSelectedRows(isSelecting ? paginatedRows.map((r) => r.name) : []); - const isRowSelected = (row) => selectedRows.includes(row.name); - const buildPagination = (variant, isCompact) => ( + const selectAllRows = (isSelecting: boolean) => setSelectedRows(isSelecting ? rows.map((r) => r.name) : []); + + const selectPageRows = (isSelecting: boolean) => setSelectedRows(isSelecting ? paginatedRows.map((r) => r.name) : []); + + const isRowSelected = (row: any) => selectedRows.includes(row.name); + + const buildPagination = (variant: 'bottom' | 'top' | PaginationVariant, isCompact: boolean) => ( { Select all ({rows.length} items) ); + return ( { + onSelect={(_ev: React.MouseEvent, value: string | number) => { if (value === 'all') { selectAllRows(bulkSelection !== 'all'); } else if (value === 'page') { @@ -86,8 +105,8 @@ export const BulkSelectTableDemo = () => { setBulkSelection(value); }} isOpen={isBulkSelectDropdownOpen} - onOpenChange={(isOpen) => setIsBulkSelectDropdownOpen(isOpen)} - toggle={(toggleRef) => ( + onOpenChange={(isOpen: boolean) => setIsBulkSelectDropdownOpen(isOpen)} + toggle={(toggleRef: React.Ref) => ( { {buildBulkSelectDropdown()} - {buildPagination('top')} + {buildPagination('top', false)} ); @@ -147,7 +166,8 @@ export const BulkSelectTableDemo = () => { setRowSelected(row, isSelecting), + onSelect: (_event: React.FormEvent, isSelecting: boolean) => + setRowSelected(row, isSelecting), isSelected: isRowSelected(row) }} /> @@ -159,7 +179,7 @@ export const BulkSelectTableDemo = () => { ))} - {buildPagination('bottom')} + {buildPagination('bottom', true)} ); diff --git a/packages/react-table/src/demos/examples/ColumnManagement.tsx b/packages/react-table/src/demos/examples/ColumnManagement.tsx new file mode 100644 index 00000000000..3d23a282951 --- /dev/null +++ b/packages/react-table/src/demos/examples/ColumnManagement.tsx @@ -0,0 +1,486 @@ +import React, { useState, useEffect } from 'react'; + +import { + Button, + Card, + DataList, + DataListCheck, + DataListItem, + DataListItemRow, + DataListCell, + DataListItemCells, + Label, + Toolbar, + ToolbarContent, + ToolbarItem, + MenuToggle, + Modal, + OverflowMenu, + OverflowMenuGroup, + OverflowMenuItem, + PageSection, + Pagination, + PaginationVariant, + Text, + TextContent, + TextVariants +} from '@patternfly/react-core'; +import { Table, TableText, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table'; +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-core/src/demos/DashboardWrapper'; +import { capitalize } from '@patternfly/react-table/src/components/Table/utils/utils'; +import { rows, columns } from '@patternfly/react-table/src/demos/examples/Table/sampleData'; + +export const ColumnManagementAction: React.FC = () => { + const defaultColumns = columns; + const defaultRows = rows; + + const [filters, setFilters] = useState([]); + const [filteredColumns, setFilteredColumns] = useState([]); + const [filteredRows, setFilteredRows] = useState([]); + const [managedColumns, setManagedColumns] = useState(defaultColumns); + const [managedRows, setManagedRows] = useState(defaultRows); + const [isModalOpen, setIsModalOpen] = useState(false); + const [checkedState, setCheckedState] = useState(Array(columns.length).fill(true)); + const [page, setPage] = useState(1); + const [perPage, setPerPage] = useState(10); + const [paginatedRows, setPaginatedRows] = useState(rows); + + const matchCheckboxNameToColumn = (name: string): string => { + 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'; + default: + return ''; + } + }; + + 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: string = matchSelectedColumnNameToAttr(name); + + const filteredRows: any[] = []; + if (checked) { + const updatedFilters: string[] = filters.filter((item) => item !== selectedColumn); + + // Only show the names of columns that were selected in the modal + const filteredColumns: string[] = 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: string[] = [...filters]; + updatedFilters.push(selectedColumn); + + // Only show the names of columns that were selected in the modal + const filteredColumns: string[] = 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 = (event: React.FormEvent, checked: boolean) => { + const target = event.currentTarget; + 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: number = columns.findIndex((element) => element === matchCheckboxNameToColumn(target.name)); + + const updatedCheckedState: boolean[] = [...checkedState]; + updatedCheckedState[checkedIndex] = value as boolean; + setCheckedState(updatedCheckedState); + }; + + const handleModalToggle = (_event: React.MouseEvent | KeyboardEvent) => { + setIsModalOpen(!isModalOpen); + }; + + const onSave = () => { + setManagedColumns(filteredColumns); + setManagedRows(filteredRows); + setPaginatedRows(filteredRows); + setIsModalOpen(!isModalOpen); + }; + + const selectAllColumns = () => { + unfilterAllData(); + setCheckedState(Array(columns.length).fill(true)); + }; + + const renderModal = () => ( + + Selected categories will be displayed in the table. + + + } + onClose={handleModalToggle} + actions={[ + , + + ]} + > + + + + + + + + ]} + /> + + + + + + + + + ]} + /> + + + + + + + + + ]} + /> + + + + + + + + + ]} + /> + + + + + + + + + ]} + /> + + + + + + + + + ]} + /> + + + + + + + + + ]} + /> + + + + + + + + + ]} + /> + + + + + ); + + 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 + + + + + + + + + + + + + + + + + {renderPagination(PaginationVariant.top)} + + + + ); + + return ( + + + + + {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' ? ( + + ) : ( + + ) + )} + + + ))} + +
{column}
+ {renderLabel(value as string)} + + + {row.url} + + + {value} +
+ {renderPagination(PaginationVariant.bottom)} + {renderModal()} +
+
+
+
+ ); +}; diff --git a/packages/react-table/src/docs/demos/table-demos/Compact.jsx b/packages/react-table/src/demos/examples/Compact.tsx similarity index 82% rename from packages/react-table/src/docs/demos/table-demos/Compact.jsx rename to packages/react-table/src/demos/examples/Compact.tsx index 381fb629729..db841a6dad4 100644 --- a/packages/react-table/src/docs/demos/table-demos/Compact.jsx +++ b/packages/react-table/src/demos/examples/Compact.tsx @@ -1,9 +1,7 @@ -import React from 'react'; - +import React, { useState } from 'react'; import { Button, Card, - Label, MenuToggle, MenuToggleElement, Pagination, @@ -13,29 +11,33 @@ import { Toolbar, ToolbarContent, ToolbarGroup, - ToolbarItem + ToolbarItem, + Label, + PaginationVariant } from '@patternfly/react-core'; import { Table, TableText, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table'; import FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon'; +import { rows, columns } from '@patternfly/react-table/src/demos/examples/Table/sampleData'; import { DashboardWrapper } from '@patternfly/react-core/src/demos/DashboardWrapper'; -import { rows, columns } from '@patternfly/react-table/src/docs/demos/table-demos/sampleData'; -export const CompactTable = () => { - const [isSelectOpen, setIsSelectOpen] = React.useState(false); - const [page, setPage] = React.useState(1); - const [perPage, setPerPage] = React.useState(10); - const [paginatedRows, setPaginatedRows] = React.useState(rows.slice(0, 10)); - const handleSetPage = (_evt, newPage, perPage, startIdx, endIdx) => { +export const CompactTable: React.FC = () => { + const [isSelectOpen, setIsSelectOpen] = useState(false); + const [page, setPage] = useState(1); + const [perPage, setPerPage] = useState(10); + const [paginatedRows, setPaginatedRows] = useState(rows.slice(0, 10)); + + const handleSetPage = (_evt: any, newPage: number, startIdx: number, endIdx: number) => { setPaginatedRows(rows.slice(startIdx, endIdx)); setPage(newPage); }; - handlePerPageSelect = (_evt, newPerPage, newPage, startIdx, endIdx) => { + + const handlePerPageSelect = (_evt: any, newPerPage: number, newPage: number, startIdx: number, endIdx: number) => { setPaginatedRows(rows.slice(startIdx, endIdx)); setPage(newPage); setPerPage(newPerPage); }; - const renderPagination = (variant, isCompact) => ( + const renderPagination = (variant: string, isCompact: boolean) => ( { perPage={perPage} onSetPage={handleSetPage} onPerPageSelect={handlePerPageSelect} - variant={variant} + variant={variant as PaginationVariant} titles={{ paginationAriaLabel: `${variant} pagination` }} @@ -63,7 +65,7 @@ export const CompactTable = () => {
)} isOpen={isSelectOpen} - onOpenChange={(isOpen) => setIsSelectOpen(isOpen)} + onOpenChange={(isOpen: boolean) => setIsSelectOpen(isOpen)} onSelect={() => setIsSelectOpen(!isSelectOpen)} > {[ @@ -92,7 +94,7 @@ export const CompactTable = () => { ); - const renderLabel = (labelText) => { + const renderLabel = (labelText: string) => { switch (labelText) { case 'Running': return ; @@ -102,8 +104,11 @@ export const CompactTable = () => { return ; case 'Down': return ; + default: + return <>; } }; + return ( @@ -146,7 +151,6 @@ export const CompactTable = () => { ))} - {renderPagination('bottom', false)} diff --git a/packages/react-table/src/docs/demos/table-demos/CompoundExpansion.jsx b/packages/react-table/src/demos/examples/CompoundExpansion.tsx similarity index 90% rename from packages/react-table/src/docs/demos/table-demos/CompoundExpansion.jsx rename to packages/react-table/src/demos/examples/CompoundExpansion.tsx index c66ac7e2509..ceb01006995 100644 --- a/packages/react-table/src/docs/demos/table-demos/CompoundExpansion.jsx +++ b/packages/react-table/src/demos/examples/CompoundExpansion.tsx @@ -14,7 +14,8 @@ import { Pagination, PageSection, Select, - SelectOption + SelectOption, + PaginationVariant } from '@patternfly/react-core'; import CodeBranchIcon from '@patternfly/react-icons/dist/esm/icons/code-branch-icon'; import CodeIcon from '@patternfly/react-icons/dist/esm/icons/code-icon'; @@ -23,7 +24,7 @@ import { DashboardWrapper } from '@patternfly/react-core/src/demos/DashboardWrap import FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon'; import spacing from '@patternfly/react-styles/css/utilities/Spacing/spacing'; -export const CompoundExpandable = () => { +export const CompoundExpandable: React.FC = () => { // In real usage, this data would come from some external source like an API via props. const [isSelectOpen, setIsSelectOpen] = React.useState(false); @@ -55,7 +56,7 @@ export const CompoundExpandable = () => { {items.map((item) => ( - + {item.description} {item.date} {item.status} @@ -69,7 +70,7 @@ export const CompoundExpandable = () => { ); }; - const renderPagination = (variant, isCompact) => ( + const renderPagination = (variant: 'top' | 'bottom' | PaginationVariant, isCompact: boolean) => ( { )} isOpen={isSelectOpen} - onOpenChange={(isOpen) => setIsSelectOpen(isOpen)} + onOpenChange={(isOpen: boolean) => setIsSelectOpen(isOpen)} onSelect={() => setIsSelectOpen(!isSelectOpen)} > {[ @@ -137,7 +138,19 @@ export const CompoundExpandable = () => { } ]; - const repositories = [ + interface Repo { + name: string; + branches: number; + prs: number; + workspaces: number; + lastCommit: string; + } + + interface IDictionary { + [Key: string]: T; + } + + const repositories: Repo[] = [ { name: 'siemur/test-space', branches: 10, @@ -148,7 +161,7 @@ export const CompoundExpandable = () => { { name: 'siemur/test-space-2', branches: 3, prs: 4, workspaces: 4, lastCommit: '20 minutes' } ]; - const columnNames = { + const columnNames: IDictionary = { name: 'Repositories', branches: 'Branches', prs: 'Pull requests', @@ -159,11 +172,11 @@ export const CompoundExpandable = () => { // In this example, expanded cells are tracked by the repo and property names from each row. This could be any pair of unique identifiers. // This is to prevent state from being based on row and column order index in case we later add sorting and rearranging columns. // Note that this behavior is very similar to selection state. - const [expandedCells, setExpandedCells] = React.useState({ + const [expandedCells, setExpandedCells] = React.useState>({ 'siemur/test-space': 'branches' // Default to the first cell of the first row being expanded }); - const setCellExpanded = (repo, columnKey, isExpanding = true) => { - const newExpandedCells = { ...expandedCells }; + const setCellExpanded = (repo: Repo, columnKey: string, isExpanding = true) => { + const newExpandedCells: IDictionary = { ...expandedCells }; if (isExpanding) { newExpandedCells[repo.name] = columnKey; } else { @@ -171,7 +184,7 @@ export const CompoundExpandable = () => { } setExpandedCells(newExpandedCells); }; - const compoundExpandParams = (repo, columnKey, rowIndex, columnIndex) => ({ + const compoundExpandParams = (repo: Repo, columnKey: string, rowIndex: number, columnIndex: number) => ({ isExpanded: expandedCells[repo.name] === columnKey, onToggle: () => setCellExpanded(repo, columnKey, expandedCells[repo.name] !== columnKey), expandId: 'compound-expandable-demo', diff --git a/packages/react-table/src/demos/examples/EmptyStateDefault.tsx b/packages/react-table/src/demos/examples/EmptyStateDefault.tsx new file mode 100644 index 00000000000..92254c68bfa --- /dev/null +++ b/packages/react-table/src/demos/examples/EmptyStateDefault.tsx @@ -0,0 +1,60 @@ +import React from 'react'; +import { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table'; +import { + Bullseye, + Button, + Card, + EmptyState, + EmptyStateVariant, + EmptyStateIcon, + EmptyStateBody, + EmptyStateHeader, + EmptyStateFooter, + EmptyStateActions, + PageSection +} from '@patternfly/react-core'; +import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon'; +import { DashboardWrapper } from '@patternfly/react-core/src/demos/DashboardWrapper'; + +export const EmptyStateDefaultDemo: React.FunctionComponent = () => ( + + + + + + + + + + + + + + + + + + +
RepositoriesBranchesPull requestsWorkspacesLast commit
+ + + } + titleText="No results found" + headingLevel="h2" + /> + + No results match this filter criteria. Clear all filters and try again. + + + + + + + + +
+
+
+
+); diff --git a/packages/react-table/src/demos/examples/EmptyStateError.tsx b/packages/react-table/src/demos/examples/EmptyStateError.tsx new file mode 100644 index 00000000000..355d5ac9d9b --- /dev/null +++ b/packages/react-table/src/demos/examples/EmptyStateError.tsx @@ -0,0 +1,53 @@ +import React from 'react'; +import { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table'; +import { + Bullseye, + Card, + EmptyState, + EmptyStateVariant, + EmptyStateIcon, + EmptyStateBody, + EmptyStateHeader, + PageSection +} from '@patternfly/react-core'; +import ExclamationCircleIcon from '@patternfly/react-icons/dist/esm/icons/exclamation-circle-icon'; +import globalDangerColor200 from '@patternfly/react-tokens/dist/esm/global_danger_color_200'; +import { DashboardWrapper } from '@patternfly/react-core/src/demos/DashboardWrapper'; + +export const ErrorStateDemo: React.FunctionComponent = () => ( + + + + + + + + + + + + + + + + + + +
RepositoriesBranchesPull requestsWorkspacesLast commit
+ + + } + headingLevel="h2" + /> + + There was an error retrieving data. Check your connection and reload the page. + + + +
+
+
+
+); diff --git a/packages/react-table/src/demos/examples/EmptyStateLoading.tsx b/packages/react-table/src/demos/examples/EmptyStateLoading.tsx new file mode 100644 index 00000000000..834b0354371 --- /dev/null +++ b/packages/react-table/src/demos/examples/EmptyStateLoading.tsx @@ -0,0 +1,43 @@ +import React from 'react'; +import { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table'; +import { + Bullseye, + Card, + EmptyState, + EmptyStateIcon, + EmptyStateHeader, + PageSection, + Spinner +} from '@patternfly/react-core'; +import { DashboardWrapper } from '@patternfly/react-core/src/demos/DashboardWrapper'; + +export const EmptyStateLoadingDemo: React.FunctionComponent = () => ( + + + + + + + + + + + + + + + + + + +
RepositoriesBranchesPull requestsWorkspacesLast commit
+ + + } /> + + +
+
+
+
+); diff --git a/packages/react-table/src/docs/demos/table-demos/ExpandCollapseAll.jsx b/packages/react-table/src/demos/examples/ExpandCollapseAll.tsx similarity index 92% rename from packages/react-table/src/docs/demos/table-demos/ExpandCollapseAll.jsx rename to packages/react-table/src/demos/examples/ExpandCollapseAll.tsx index f7d6d5f18fb..b4207b648ec 100644 --- a/packages/react-table/src/docs/demos/table-demos/ExpandCollapseAll.jsx +++ b/packages/react-table/src/demos/examples/ExpandCollapseAll.tsx @@ -1,11 +1,20 @@ -import React from 'react'; +import React, { ReactNode } from 'react'; import { Card, Label, PageSection, TextVariants, Text, TextContent } from '@patternfly/react-core'; import { Table, Thead, Tbody, Tr, Th, Td, ExpandableRowContent } from '@patternfly/react-table'; import { DashboardWrapper } from '@patternfly/react-core/src/demos/DashboardWrapper'; const expandableColumns = ['Servers', 'Threads', 'Applications', 'Workspaces', 'Status']; -const serverData = [ +interface Server { + name: string; + threads: number; + applications: number; + workspaces: number; + status: { title: ReactNode }; + details: ReactNode; +} + +const serverData: Server[] = [ { name: 'US-Node 1', threads: 18, @@ -110,7 +119,7 @@ const serverData = [ const initialExpandedServerNames = ['US-Node 2']; // Default to expanded -const ExpandCollapseAllTableDemo = () => { +export const ExpandCollapseAllTableDemo: React.FC = () => { const [areAllExpanded, setAreAllExpanded] = React.useState(false); const [collapseAllAriaLabel, setCollapseAllAriaLabel] = React.useState('Expand all'); const [expandedServerNames, setExpandedServerNames] = React.useState(initialExpandedServerNames); @@ -121,20 +130,18 @@ const ExpandCollapseAllTableDemo = () => { setCollapseAllAriaLabel(allExpanded ? 'Collapse all' : 'Expand all'); }, [expandedServerNames]); - const setServerExpanded = (server, isExpanding) => { + const setServerExpanded = (server: Server, isExpanding: boolean) => { const otherExpandedServerNames = expandedServerNames.filter((r) => r !== server.name); setExpandedServerNames(isExpanding ? [...otherExpandedServerNames, server.name] : otherExpandedServerNames); }; - const isServerExpanded = (server) => { - return expandedServerNames.includes(server.name); - }; + const isServerExpanded = (server: Server) => expandedServerNames.includes(server.name); // We want to be able to reference the original data object based on row index. But because an expanded // row takes up two row indexes, servers[rowIndex] will not be accurate like it would in a normal table. // One solution to this is to create an array of data objects indexed by the displayed row index. - const onCollapseAll = (_event, _rowIndex, isOpen) => { + const onCollapseAll = (_event: any, _rowIndex: number, isOpen: boolean) => { setExpandedServerNames(isOpen ? [...serverData.map((server) => server.name)] : []); }; @@ -154,7 +161,7 @@ const ExpandCollapseAllTableDemo = () => { diff --git a/packages/react-table/src/docs/demos/table-demos/SortableResponsive.jsx b/packages/react-table/src/demos/examples/SortableResponsive.tsx similarity index 90% rename from packages/react-table/src/docs/demos/table-demos/SortableResponsive.jsx rename to packages/react-table/src/demos/examples/SortableResponsive.tsx index bc7978746af..4b4338e3dd8 100644 --- a/packages/react-table/src/docs/demos/table-demos/SortableResponsive.jsx +++ b/packages/react-table/src/demos/examples/SortableResponsive.tsx @@ -7,19 +7,10 @@ import { DropdownList, Flex, FlexItem, - Label, MenuToggle, MenuToggleElement, - OverflowMenu, - OverflowMenuContent, - OverflowMenuControl, - OverflowMenuDropdownItem, - OverflowMenuGroup, - OverflowMenuItem, PageSection, - PageSectionVariants, Pagination, - Select, SelectOption, SelectList, SelectGroup, @@ -28,7 +19,17 @@ import { Toolbar, ToolbarContent, ToolbarGroup, - ToolbarItem + ToolbarItem, + OverflowMenuDropdownItem, + PaginationVariant, + Label, + Select, + OverflowMenu, + OverflowMenuContent, + OverflowMenuControl, + OverflowMenuGroup, + OverflowMenuItem, + PageSectionVariants } from '@patternfly/react-core'; import { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table'; import CloneIcon from '@patternfly/react-icons/dist/esm/icons/clone-icon'; @@ -40,13 +41,15 @@ import SortAmountDownIcon from '@patternfly/react-icons/dist/esm/icons/sort-amou import CubeIcon from '@patternfly/react-icons/dist/esm/icons/cube-icon'; import { DashboardWrapper } from '@patternfly/react-core/src/demos/DashboardWrapper'; import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon'; -import { rows, columns } from '@patternfly/react-table/src/docs/demos/table-demos/sampleData'; +import { rows, columns, SampleDataRow } from '@patternfly/react-table/src/demos/examples/Table/sampleData'; -export const ComposableTableSortable = () => { +type Direction = 'asc' | 'desc' | 'none'; + +export const ComposableTableSortable: React.FC = () => { const [isKebabDropdownOpen, setIsKebabDropdownOpen] = React.useState(false); - const sortRows = (r, sortIndex, sortDirection) => { - return [...r].sort((a, b) => { + const sortRows = (rows: SampleDataRow[], sortIndex: number, sortDirection: Direction) => + [...rows].sort((a, b) => { let returnValue = 0; if (sortIndex === 0 || sortIndex === 7) { returnValue = 1; @@ -62,7 +65,6 @@ export const ComposableTableSortable = () => { } return returnValue; }); - }; const [sortedData, setSortedData] = React.useState([...sortRows(rows, 0, 'asc')]); const [sortedRows, setSortedRows] = React.useState([...sortedData]); @@ -72,11 +74,11 @@ export const ComposableTableSortable = () => { // index of the currently active column const [activeSortIndex, setActiveSortIndex] = React.useState(0); // sort direction of the currently active column - const [activeSortDirection, setActiveSortDirection] = React.useState('asc'); + const [activeSortDirection, setActiveSortDirection] = React.useState('asc'); // sort dropdown expansion const [isSortDropdownOpen, setIsSortDropdownOpen] = React.useState(false); - const onSort = (event, index, direction) => { + const onSort = (_event: any, index: number, direction: Direction) => { setActiveSortIndex(index); setActiveSortDirection(direction); @@ -89,15 +91,15 @@ export const ComposableTableSortable = () => { setSortedRows(sortedData.slice((page - 1) * perPage, page * perPage - 1)); }, [sortedData, page, perPage]); - const handleSetPage = (_evt, newPage) => { + const handleSetPage = (_evt: any, newPage: number) => { setPage(newPage); }; - const handlePerPageSelect = (_evt, newPerPage) => { + const handlePerPageSelect = (_evt: any, newPerPage: number) => { setPerPage(newPerPage); }; - const renderPagination = (variant) => ( + const renderPagination = (variant: 'top' | 'bottom' | PaginationVariant) => ( { /> ); - const renderLabel = (labelText) => { + const renderLabel = (labelText: string) => { switch (labelText) { case 'Running': return ; @@ -138,12 +140,12 @@ export const ComposableTableSortable = () => { ) => ( - } - style={ - { - width: '100%', - verticalAlign: 'text-bottom' - } as React.CSSProperties - } - > - {currentCategory} - - )} - isOpen={isCategoryDropdownOpen} - > - {categoryMenuItems} - - - ); - } - - buildFilterDropdown() { - const { currentCategory, isFilterDropdownOpen, inputValue, filters } = this.state; - - const locationMenuItems = [ - Raleigh, - San Francisco, - Boston, - Atlanta, - ]; - - const statusMenuItems = [ - - Running - , - - Stopped - , - - Down - , - - Degraded - , - - Needs maintenance - - ]; - - return ( - - - - - - this.onInputChange(value)} - value={inputValue} - onClear={() => { - this.onInputChange(''); - }} - onSearch={this.onNameInput} - /> - - - - - - ); - } - - renderToolbar() { - return ( - - - } breakpoint="xl"> - - {this.buildCategoryDropdown()} - {this.buildFilterDropdown()} - - - - - ); - } - - render() { - const { loading, filters, rows } = this.state; - - const filteredRows = - filters.name.length > 0 || filters.location.length > 0 || filters.status.length > 0 - ? rows.filter((row) => { - return ( - (filters.name.length === 0 || - filters.name.some((name) => row.name.toLowerCase().includes(name.toLowerCase()))) && - (filters.location.length === 0 || filters.location.includes(row.location)) && - (filters.status.length === 0 || filters.status.includes(row.status)) - ); - }) - : rows; - - let tableRows = filteredRows; - if (!loading && filteredRows.length === 0) { - tableRows = [ - { - heightAuto: true, - cells: [ - { - props: { colSpan: 8 }, - title: ( - - - } - /> - - No results match this filter criteria. Remove all filters or clear all filters to show results. - - - - - - - - - ) - } - ] - } - ]; - } else if (loading) { - tableRows = [ - { - heightAuto: true, - cells: [ - { - props: { colSpan: 8 }, - title: ( - - Please wait while loading data - - ) - } - ] - } - ]; - } - - const renderLabel = labelText => { - switch (labelText) { - case 'Running': - return ; - case 'Stopped': - return ; - case 'Needs maintenance': - return ; - case 'Down': - return ; - } - }; - - return ( - - {this.renderToolbar()} - - - - - - - - - - - - - - - {filteredRows.slice(0, 10).map((row, rowIndex) => ( - - <> - - - - - - - - - - - ))} - -
{columns[0]}{columns[1]}{columns[2]}{columns[3]}{columns[4]}{columns[5]}{columns[6]} - {columns[7]} -
{row.name}{row.threads}{row.applications}{row.workspaces}{renderLabel(row.status)}{row.location}{row.lastModified} - - {row.url} - -
-
- ); - } -} +```js isFullscreen file="./examples/Filterable.tsx" ``` ### Sortable - responsive @@ -1312,110 +110,7 @@ To demonstrate this, navigate to the last page of data below using the `>>` navi - The default behavior would show the last page of results, which would only contain the last two rows (rows 11 - 12). - The `isLastFullPageShown` prop navigates you back to the previous page which does contain a full page of 5 rows (rows 6 - 10). -```js isFullscreen -import React from 'react'; -import { Pagination } from '@patternfly/react-core'; -import { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table'; - -class ComplexPaginationTableDemo extends React.Component { - constructor(props) { - super(props); - (this.columns = { - firstColumn: 'First column', - secondColumn: 'Second column', - thirdColumn: 'Third column' - }), - (this.defaultRows = [ - { firstColumn: 'Row 1 column 1', secondColumn: 'Row 1 column 2', thirdColumn: 'Row 1 column 3' }, - { firstColumn: 'Row 2 column 1', secondColumn: 'Row 2 column 2', thirdColumn: 'Row 2 column 3' }, - { firstColumn: 'Row 3 column 1', secondColumn: 'Row 3 column 2', thirdColumn: 'Row 3 column 3' }, - { firstColumn: 'Row 4 column 1', secondColumn: 'Row 4 column 2', thirdColumn: 'Row 4 column 3' }, - { firstColumn: 'Row 5 column 1', secondColumn: 'Row 5 column 2', thirdColumn: 'Row 5 column 3' }, - { firstColumn: 'Row 6 column 1', secondColumn: 'Row 6 column 2', thirdColumn: 'Row 6 column 3' }, - { firstColumn: 'Row 7 column 1', secondColumn: 'Row 7 column 2', thirdColumn: 'Row 7 column 3' }, - { firstColumn: 'Row 8 column 1', secondColumn: 'Row 8 column 2', thirdColumn: 'Row 8 column 3' }, - { firstColumn: 'Row 9 column 1', secondColumn: 'Row 9 column 2', thirdColumn: 'Row 9 column 3' }, - { firstColumn: 'Row 10 column 1', secondColumn: 'Row 10 column 2', thirdColumn: 'Row 10 column 3' }, - { firstColumn: 'Row 11 column 1', secondColumn: 'Row 11 column 2', thirdColumn: 'Row 11 column 3' }, - { firstColumn: 'Row 12 column 1', secondColumn: 'Row 12 column 2', thirdColumn: 'Row 12 column 3' } - ]); - this.defaultPerPage = 10; - this.state = { - perPage: this.defaultPerPage, - page: 1, - rows: this.defaultRows.slice(0, this.defaultPerPage) - }; - this.handleSetPage = this.handleSetPage.bind(this); - this.handlePerPageSelect = this.handlePerPageSelect.bind(this); - } - - handleSetPage(_evt, newPage, perPage, startIdx, endIdx) { - this.setState({ - page: newPage, - rows: this.defaultRows.slice(startIdx, endIdx) - }); - } - - handlePerPageSelect(_evt, newPerPage, newPage, startIdx, endIdx) { - this.setState({ - perPage: newPerPage, - page: newPage, - rows: this.defaultRows.slice(startIdx, endIdx) - }); - } - - renderPagination(variant = 'top') { - const { page, perPage } = this.state; - return ( - - ); - } - - render() { - return ( - - {this.renderPagination()} - - - - - - - - - - {this.state.rows.map((row, rowIndex) => ( - - <> - - - - - - ))} - -
{this.columns.firstColumn}{this.columns.secondColumn}{this.columns.thirdColumn}
{row.firstColumn}{row.secondColumn}{row.thirdColumn}
-
- ); - } -} +```js isFullscreen file="./examples/AutomaticPagination.tsx" ``` ### Static bottom pagination on mobile diff --git a/packages/react-table/src/demos/examples/AutomaticPagination.tsx b/packages/react-table/src/demos/examples/AutomaticPagination.tsx new file mode 100644 index 00000000000..1053bbc24b2 --- /dev/null +++ b/packages/react-table/src/demos/examples/AutomaticPagination.tsx @@ -0,0 +1,89 @@ +import React from 'react'; +import { Pagination } from '@patternfly/react-core'; +import { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table'; + +export const AutomaticPaginationTableDemo: React.FunctionComponent = () => { + const columns = { + firstColumn: 'First column', + secondColumn: 'Second column', + thirdColumn: 'Third column' + }; + + const defaultRows = [ + { firstColumn: 'Row 1 column 1', secondColumn: 'Row 1 column 2', thirdColumn: 'Row 1 column 3' }, + { firstColumn: 'Row 2 column 1', secondColumn: 'Row 2 column 2', thirdColumn: 'Row 2 column 3' }, + { firstColumn: 'Row 3 column 1', secondColumn: 'Row 3 column 2', thirdColumn: 'Row 3 column 3' }, + { firstColumn: 'Row 4 column 1', secondColumn: 'Row 4 column 2', thirdColumn: 'Row 4 column 3' }, + { firstColumn: 'Row 5 column 1', secondColumn: 'Row 5 column 2', thirdColumn: 'Row 5 column 3' }, + { firstColumn: 'Row 6 column 1', secondColumn: 'Row 6 column 2', thirdColumn: 'Row 6 column 3' }, + { firstColumn: 'Row 7 column 1', secondColumn: 'Row 7 column 2', thirdColumn: 'Row 7 column 3' }, + { firstColumn: 'Row 8 column 1', secondColumn: 'Row 8 column 2', thirdColumn: 'Row 8 column 3' }, + { firstColumn: 'Row 9 column 1', secondColumn: 'Row 9 column 2', thirdColumn: 'Row 9 column 3' }, + { firstColumn: 'Row 10 column 1', secondColumn: 'Row 10 column 2', thirdColumn: 'Row 10 column 3' }, + { firstColumn: 'Row 11 column 1', secondColumn: 'Row 11 column 2', thirdColumn: 'Row 11 column 3' }, + { firstColumn: 'Row 12 column 1', secondColumn: 'Row 12 column 2', thirdColumn: 'Row 12 column 3' } + ]; + const defaultPerPage = 10; + + const [perPage, setPerPage] = React.useState(defaultPerPage); + const [page, setPage] = React.useState(1); + const [rows, setRows] = React.useState(defaultRows.slice(0, defaultPerPage)); + + const handleSetPage = (_evt, newPage, perPage, startIdx, endIdx) => { + setPage(newPage); + setRows(defaultRows.slice(startIdx, endIdx)); + }; + + const handlePerPageSelect = (_evt, newPerPage, newPage, startIdx, endIdx) => { + setPerPage(newPerPage); + setPage(newPage); + setRows(defaultRows.slice(startIdx, endIdx)); + }; + + const renderPagination = (variant = 'top') => ( + + ); + + return ( + + {renderPagination()} + + + + + + + + + + {rows.map((row, rowIndex) => ( + + <> + + + + + + ))} + +
{columns.firstColumn}{columns.secondColumn}{columns.thirdColumn}
{row.firstColumn}{row.secondColumn}{row.thirdColumn}
+
+ ); +}; diff --git a/packages/react-table/src/demos/examples/ColumnManagementWithDraggable.tsx b/packages/react-table/src/demos/examples/ColumnManagementWithDraggable.tsx new file mode 100644 index 00000000000..43a1a6fcc53 --- /dev/null +++ b/packages/react-table/src/demos/examples/ColumnManagementWithDraggable.tsx @@ -0,0 +1,738 @@ +import React from 'react'; +import { + Button, + DataList, + DataListCheck, + DataListControl, + DataListDragButton, + DataListItem, + DataListItemRow, + DataListCell, + DataListItemCells, + DragDrop, + Draggable, + Droppable, + Toolbar, + ToolbarContent, + ToolbarItem, + Modal, + OverflowMenu, + OverflowMenuGroup, + OverflowMenuItem, + Pagination, + PaginationVariant, + Text, + TextContent, + TextVariants, + MenuToggle +} 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 FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon'; +import SortAmountDownIcon from '@patternfly/react-icons/dist/esm/icons/sort-amount-down-icon'; + +interface RowType { + cells: ( + | { + title: React.JSX.Element; + props: { + column: string; + }; + } + | { + title: string; + props: { + column: string; + }; + } + )[]; +} + +export const ColumnManagementAction: 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: '' } + } + ] + } + ]; + + const [filters, setFilters] = React.useState([]); + const [filteredColumns, setFilteredColumns] = React.useState([]); + const [columns, setColumns] = React.useState(defaultColumns); + const [rows, setRows] = 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 [liveText, setLiveText] = React.useState(''); + const id = ''; + const canSelectAll = true; + + const reorder = (list: string[], startIndex: number, endIndex: number) => { + const result = list; + const [removed] = result.splice(startIndex, 1); + result.splice(endIndex, 0, removed); + return result; + }; + + const 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'; + } + }; + + const filterData = (checked, name) => { + if (checked) { + const updatedFilters = filters.filter((item) => item !== name); + const updatedFilteredColumns = defaultColumns.filter((column) => !updatedFilters.includes(column)); + setFilters(updatedFilters); + setFilteredColumns(updatedFilteredColumns); + } else { + const updatedFilters = filters; + updatedFilters.push(name); + const updatedFilteredColumns = columns.filter((column) => !filters.includes(column)); + setFilters(updatedFilters); + setFilteredColumns(updatedFilteredColumns); + } + }; + const unfilterAllData = () => { + setFilters([]); + setFilteredColumns(defaultColumns); + }; + const handleChange = (event, checked) => { + const target = event.target; + const value = target.type === 'checkbox' ? target.checked : target.value; + filterData(checked, matchCheckboxNameToColumn(target.name)); + switch (target.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) => { + setIsModalOpen(!isModalOpen); + }; + const onSave = () => { + // const orderedColumns: string[] = itemOrder.map((item) => matchDataListNameToColumn(item)); + // 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 + }); + }); + setColumns(filteredOrderedColumns as string[]); + setRows(orderedRows); + setIsModalOpen(!isModalOpen); + }; + + const selectAllColumns = () => { + unfilterAllData(); + setCheck1(true); + setCheck2(true); + setCheck3(true); + setCheck4(true); + setCheck5(true); + }; + + const onSelect = (event, isSelected, rowId) => { + let updatedRows; + if (rowId === -1) { + updatedRows = updatedRows.map((oneRow) => { + oneRow.selected = isSelected; + return oneRow; + }); + } else { + updatedRows = [...updatedRows]; + updatedRows[rowId] = { ...rows[rowId], selected: isSelected }; + } + setRows(updatedRows); + }; + + const onDrag = (source) => { + setLiveText(`Started dragging ${columns[source.index]}`); + // Return true to allow drag + return true; + }; + + const onDragMove = (source, dest) => { + const newText = dest ? `Move ${columns[source.index]} to ${columns[dest.index]}` : 'Invalid drop zone'; + if (newText !== liveText) { + setLiveText(newText); + } + }; + + const onDrop = (source, dest) => { + if (dest) { + const newItems = reorder(columns, source.index, dest.index); + setColumns(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 renderModal = () => ( + + Selected categories will be displayed in the table. + + + } + onClose={handleModalToggle} + actions={[ + , + + ]} + > + + + + + + + + + + + + Repositories + + ]} + /> + + + + + + + + + + + + Branches + + ]} + /> + + + + + + + + + + + + Pull requests + + ]} + /> + + + + + + + + + + + + Workspaces + + ]} + /> + + + + + + + + + + + + Last commit + + ]} + /> + + + + + +
+ {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. +
+
+
+ ); + + const toolbarItems = ( + + + + + + + + Name + + + + + + + + + + + + + + + + + + + + + + ); + + return ( + + + {toolbarItems} + + } + aria-label="This is a table with checkboxes" + onSelect={onSelect} + cells={columns} + rows={rows} + actions={actions} + canSelectAll={canSelectAll} + > + + + + + {renderModal()} +
+ ); +}; diff --git a/packages/react-table/src/demos/examples/Filterable.tsx b/packages/react-table/src/demos/examples/Filterable.tsx new file mode 100644 index 00000000000..9a6f878ce96 --- /dev/null +++ b/packages/react-table/src/demos/examples/Filterable.tsx @@ -0,0 +1,394 @@ +import React from 'react'; +import { + Badge, + Button, + Bullseye, + EmptyState, + EmptyStateActions, + EmptyStateBody, + EmptyStateIcon, + EmptyStateHeader, + EmptyStateFooter, + Label, + MenuToggle, + MenuToggleElement, + Toolbar, + ToolbarItem, + ToolbarContent, + ToolbarFilter, + ToolbarToggleGroup, + ToolbarGroup, + Select, + SelectOption, + SearchInput, + ToolbarChipGroup +} from '@patternfly/react-core'; +import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon'; +import FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon'; +import { Table, TableText, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table'; +import { rows, columns } from '@patternfly/react-table/dist/esm/demos/sampleData'; + +export const FilterTableDemo: React.FunctionComponent = () => { + const [filters, setFilters] = React.useState>({ location: [], name: [], status: [] }); + const [currentCategory, setCurrentCategory] = React.useState('Status'); + const [isFilterDropdownOpen, setIsFilterDropdownOpen] = React.useState(false); + const [isCategoryDropdownOpen, setIsCategoryDropdownOpen] = React.useState(false); + const [inputValue, setInputValue] = React.useState(''); + + const rowData = rows.slice(0, 10); + + const onDelete = (type: string | ToolbarChipGroup, id: string) => { + if (type === 'Location') { + setFilters({ + ...filters, + location: filters.location.filter((fil: string) => fil !== id) + }); + } else if (type === 'Name') { + setFilters({ + ...filters, + name: filters.name.filter((fil: string) => fil !== id) + }); + } else if (type === 'Status') { + setFilters({ + ...filters, + status: filters.status.filter((fil: string) => fil !== id) + }); + } else { + setFilters({ location: [], name: [], status: [] }); + } + }; + + const onCategoryToggle = () => { + setIsCategoryDropdownOpen(!isCategoryDropdownOpen); + }; + + const onCategorySelect = (event) => { + setCurrentCategory(event.target.innerText); + setIsCategoryDropdownOpen(false); + }; + + const onFilterToggle = () => { + setIsFilterDropdownOpen(!isFilterDropdownOpen); + }; + + const onFilterSelect = () => { + setIsFilterDropdownOpen(!isFilterDropdownOpen); + }; + + const onInputChange = (newValue) => { + setInputValue(newValue); + }; + + const onStatusSelect = (event, selection) => { + const checked = event.target.checked; + setFilters({ + ...filters, + status: checked ? [...filters.status, selection] : filters.status.filter((value) => value !== selection) + }); + setIsFilterDropdownOpen(false); + }; + + const onNameInput = (event) => { + if (event.key && event.key !== 'Enter') { + return; + } + + const prevFilters = filters.name; + setFilters({ ...filters, name: prevFilters.includes(inputValue) ? prevFilters : [...prevFilters, inputValue] }); + }; + + const onLocationSelect = (event, selection) => { + setFilters({ ...filters, location: [selection] }); + + setIsFilterDropdownOpen(false); + onFilterSelect(); + }; + + const buildCategoryDropdown = () => { + const categoryMenuItems = [ + + Location + , + + Name + , + + Status + + ]; + + return ( + + + + ); + }; + + const buildFilterDropdown = () => { + const locationMenuItems = [ + + Raleigh + , + + San Francisco + , + + Boston + , + + Atlanta + + ]; + + const statusMenuItems = [ + + Running + , + + Stopped + , + + Down + , + + Degraded + , + + Needs maintenance + + ]; + + return ( + + onDelete(category, chip as string)} + categoryName="Location" + showToolbarItem={currentCategory === 'Location'} + > + + + onDelete(category, chip as string)} + categoryName="Name" + showToolbarItem={currentCategory === 'Name'} + > + onInputChange(value)} + value={inputValue} + onClear={() => { + onInputChange(''); + }} + onSearch={onNameInput} + /> + + onDelete(category, chip as string)} + categoryName="Status" + showToolbarItem={currentCategory === 'Status'} + > + + + + ); + }; + + const renderToolbar = () => ( + setFilters({ location: [], name: [], status: [] })} + collapseListedFiltersBreakpoint="xl" + > + + } breakpoint="xl"> + + {buildCategoryDropdown()} + {buildFilterDropdown()} + + + + + ); + + const filteredRows = + filters.name.length > 0 || filters.location.length > 0 || filters.status.length > 0 + ? rowData.filter( + (row) => + (filters.name.length === 0 || + filters.name.some((name) => row.name.toLowerCase().includes(name.toLowerCase()))) && + (filters.location.length === 0 || filters.location.includes(row.location)) && + (filters.status.length === 0 || filters.status.includes(row.status)) + ) + : rowData; + + const emptyState = ( + + } + /> + No results match the filter criteria. Clear all filters and try again. + + + + + + + ); + + const renderLabel = (labelText) => { + switch (labelText) { + case 'Running': + return ; + case 'Stopped': + return ; + case 'Needs maintenance': + return ; + case 'Down': + return ; + } + }; + + return ( + + {renderToolbar()} + + + + + + + + + + + + + + + {filteredRows.slice(0, 10).map((row, rowIndex) => ( + + <> + + + + + + + + + + + ))} + {filteredRows.length === 0 && ( + + + + )} + +
{columns[0]}{columns[1]}{columns[2]}{columns[3]}{columns[4]}{columns[5]}{columns[6]} + {columns[7]} +
{row.name}{row.threads}{row.applications}{row.workspaces}{renderLabel(row.status)}{row.location}{row.lastModified} + + {row.url} + +
+ {emptyState} +
+
+ ); +}; diff --git a/packages/react-table/src/demos/sampleData.tsx b/packages/react-table/src/demos/sampleData.tsx index 215c27f4095..bf3902f3169 100644 --- a/packages/react-table/src/demos/sampleData.tsx +++ b/packages/react-table/src/demos/sampleData.tsx @@ -28,7 +28,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Raleigh', 'Boston', 'Atlanta', 'San Francisco'][getRandomInteger(0, 3)], lastModified: '2 hours ago', url: 'http://www.redhat.com/en/office-locations/US-node1' @@ -38,7 +38,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Raleigh', 'Boston', 'Atlanta', 'San Francisco'][getRandomInteger(0, 3)], lastModified: '5 hours ago', url: 'http://www.redhat.com/en/office-locations/US-node2' @@ -48,7 +48,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Raleigh', 'Boston', 'Atlanta', 'San Francisco'][getRandomInteger(0, 3)], lastModified: '20 minutes ago', url: 'http://www.redhat.com/en/office-locations/US-node3' @@ -58,7 +58,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Raleigh', 'Boston', 'Atlanta', 'San Francisco'][getRandomInteger(0, 3)], lastModified: '10 minutes ago', url: 'http://www.redhat.com/en/office-locations/US-node4' @@ -68,7 +68,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Raleigh', 'Boston', 'Atlanta', 'San Francisco'][getRandomInteger(0, 3)], lastModified: '15 minutes ago', url: 'http://www.redhat.com/en/office-locations/US-node5' @@ -78,7 +78,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Raleigh', 'Boston', 'Atlanta', 'San Francisco'][getRandomInteger(0, 3)], lastModified: '4 hours ago', url: 'http://www.redhat.com/en/office-locations/US-node6' @@ -88,7 +88,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Raleigh', 'Boston', 'Atlanta', 'San Francisco'][getRandomInteger(0, 3)], lastModified: '10 minutes ago', url: 'http://www.redhat.com/en/office-locations/US-node7' @@ -98,7 +98,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Raleigh', 'Boston', 'Atlanta', 'San Francisco'][getRandomInteger(0, 3)], lastModified: '8 hours ago', url: 'http://www.redhat.com/en/office-locations/US-node8' @@ -108,7 +108,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Raleigh', 'Boston', 'Atlanta', 'San Francisco'][getRandomInteger(0, 3)], lastModified: '1 hour ago', url: 'http://www.redhat.com/en/office-locations/US-node9' @@ -118,7 +118,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Raleigh', 'Boston', 'Atlanta', 'San Francisco'][getRandomInteger(0, 3)], lastModified: '2 hours ago', url: 'http://www.redhat.com/en/office-locations/US-node10' @@ -128,7 +128,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Raleigh', 'Boston', 'Atlanta', 'San Francisco'][getRandomInteger(0, 3)], lastModified: '55 minutes ago', url: 'http://www.redhat.com/en/office-locations/US-node11' @@ -138,7 +138,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Raleigh', 'Boston', 'Atlanta', 'San Francisco'][getRandomInteger(0, 3)], lastModified: '1 hour ago', url: 'http://www.redhat.com/en/office-locations/US-node12' @@ -148,7 +148,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Raleigh', 'Boston', 'Atlanta', 'San Francisco'][getRandomInteger(0, 3)], lastModified: '20 minutes ago', url: 'http://www.redhat.com/en/office-locations/US-node13' @@ -158,7 +158,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Raleigh', 'Boston', 'Atlanta', 'San Francisco'][getRandomInteger(0, 3)], lastModified: '4 hours ago', url: 'http://www.redhat.com/en/office-locations/US-node14' @@ -168,7 +168,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Raleigh', 'Boston', 'Atlanta', 'San Francisco'][getRandomInteger(0, 3)], lastModified: '10 minutes ago', url: 'http://www.redhat.com/en/office-locations/US-node15' @@ -178,7 +178,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Raleigh', 'Boston', 'Atlanta', 'San Francisco'][getRandomInteger(0, 3)], lastModified: '5 minutes ago', url: 'http://www.redhat.com/en/office-locations/US-node16' @@ -188,7 +188,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Raleigh', 'Boston', 'Atlanta', 'San Francisco'][getRandomInteger(0, 3)], lastModified: '5 hours ago', url: 'http://www.redhat.com/en/office-locations/US-node17' @@ -198,7 +198,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Raleigh', 'Boston', 'Atlanta', 'San Francisco'][getRandomInteger(0, 3)], lastModified: '10 minutes ago', url: 'http://www.redhat.com/en/office-locations/US-node18' @@ -208,7 +208,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Raleigh', 'Boston', 'Atlanta', 'San Francisco'][getRandomInteger(0, 3)], lastModified: '30 minutes ago', url: 'http://www.redhat.com/en/office-locations/US-node19' @@ -218,7 +218,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Raleigh', 'Boston', 'Atlanta', 'San Francisco'][getRandomInteger(0, 3)], lastModified: '3 hours ago', url: 'http://www.redhat.com/en/office-locations/US-node20' @@ -228,7 +228,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Raleigh', 'Boston', 'Atlanta', 'San Francisco'][getRandomInteger(0, 3)], lastModified: '15 minutes ago', url: 'http://www.redhat.com/en/office-locations/US-node21' @@ -238,7 +238,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Raleigh', 'Boston', 'Atlanta', 'San Francisco'][getRandomInteger(0, 3)], lastModified: '2 hours ago', url: 'http://www.redhat.com/en/office-locations/US-node22' @@ -248,7 +248,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Raleigh', 'Boston', 'Atlanta', 'San Francisco'][getRandomInteger(0, 3)], lastModified: '2 hours ago', url: 'http://www.redhat.com/en/office-locations/US-node23' @@ -258,7 +258,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Raleigh', 'Boston', 'Atlanta', 'San Francisco'][getRandomInteger(0, 3)], lastModified: '40 minutes ago', url: 'http://www.redhat.com/en/office-locations/US-node24' @@ -268,7 +268,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Raleigh', 'Boston', 'Atlanta', 'San Francisco'][getRandomInteger(0, 3)], lastModified: '1 hour ago', url: 'http://www.redhat.com/en/office-locations/US-node25' @@ -278,7 +278,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Raleigh', 'Boston', 'Atlanta', 'San Francisco'][getRandomInteger(0, 3)], lastModified: '2 hours ago', url: 'http://www.redhat.com/en/office-locations/US-node26' @@ -288,7 +288,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '7 hours ago', url: 'http://www.redhat.com/en/office-locations/CZ-node1' @@ -298,7 +298,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '50 minutes ago', url: 'http://www.redhat.com/en/office-locations/CZ-node2' @@ -308,7 +308,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '10 minutes ago', url: 'http://www.redhat.com/en/office-locations/CZ-node3' @@ -318,7 +318,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '3 hours ago', url: 'http://www.redhat.com/en/office-locations/CZ-node4' @@ -328,7 +328,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '2 hours ago', url: 'http://www.redhat.com/en/office-locations/CZ-node5' @@ -338,7 +338,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '2 hours ago', url: 'http://www.redhat.com/en/office-locations/CZ-node6' @@ -348,7 +348,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '25 minutes ago', url: 'http://www.redhat.com/en/office-locations/CZ-node7' @@ -358,7 +358,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '1 hour ago', url: 'http://www.redhat.com/en/office-locations/CZ-node8' @@ -368,7 +368,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '15 minutes ago', url: 'http://www.redhat.com/en/office-locations/CZ-node9' @@ -378,7 +378,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '3 hours ago', url: 'http://www.redhat.com/en/office-locations/CZ-node10' @@ -388,7 +388,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '30 minutes ago', url: 'http://www.redhat.com/en/office-locations/CZ-node11' @@ -398,7 +398,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '5 minutes ago', url: 'http://www.redhat.com/en/office-locations/CZ-node12' @@ -408,7 +408,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '45 minutes ago', url: 'http://www.redhat.com/en/office-locations/CZ-node13' @@ -418,7 +418,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '2 hours ago', url: 'http://www.redhat.com/en/office-locations/CZ-node14' @@ -428,7 +428,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '10 minutes ago', url: 'http://www.redhat.com/en/office-locations/CZ-node15' @@ -438,7 +438,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '20 minutes ago', url: 'http://www.redhat.com/en/office-locations/CZ-Remote-node1' @@ -448,7 +448,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '15 minutes ago', url: 'http://www.redhat.com/en/office-locations/CZ-Remote-node2' @@ -458,7 +458,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '2 hours ago', url: 'http://www.redhat.com/en/office-locations/CZ-Remote-node3' @@ -468,7 +468,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '1 hour ago', url: 'http://www.redhat.com/en/office-locations/CZ-Remote-node4' @@ -478,7 +478,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '30 minutes ago', url: 'http://www.redhat.com/en/office-locations/CZ-Remote-node5' @@ -488,7 +488,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '2 hours ago', url: 'http://www.redhat.com/en/office-locations/CZ-Remote-node6' @@ -498,7 +498,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '45 minutes ago', url: 'http://www.redhat.com/en/office-locations/CZ-remote-node7' @@ -508,7 +508,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '6 hours ago', url: 'http://www.redhat.com/en/office-locations/CZ-remote-node8' @@ -518,7 +518,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '50 minutes ago', url: 'http://www.redhat.com/en/office-locations/CZ-remote-node9' @@ -528,7 +528,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '3 hours ago', url: 'http://www.redhat.com/en/office-locations/CZ-remote-node10' @@ -538,7 +538,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '2 hours ago', url: 'http://www.redhat.com/en/office-locations/CZ-remote-node11' @@ -548,7 +548,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '20 minutes ago', url: 'http://www.redhat.com/en/office-locations/CZ-remote-node12' @@ -558,7 +558,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '5 hours ago', url: 'http://www.redhat.com/en/office-locations/CZ-remote-node13' @@ -568,7 +568,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '30 minutes ago', url: 'http://www.redhat.com/en/office-locations/CZ-remote-node14' @@ -578,7 +578,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '1 hour ago', url: 'http://www.redhat.com/en/office-locations/CZ-remote-node15' @@ -588,7 +588,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '1 hour ago', url: 'http://www.redhat.com/en/office-locations/CZ-remote-node16' @@ -598,7 +598,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '25 minutes ago', url: 'http://www.redhat.com/en/office-locations/CZ-remote-node17' @@ -608,7 +608,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: ['Brno', 'Prague'][getRandomInteger(0, 1)], lastModified: '20 minutes ago', url: 'http://www.redhat.com/en/office-locations/CZ-remote-node18' @@ -618,7 +618,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: 'Bangalore', lastModified: '25 minutes ago', url: 'http://www.redhat.com/en/office-locations/Bangalore-node1' @@ -628,7 +628,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: 'Bangalore', lastModified: '2 hours ago', url: 'http://www.redhat.com/en/office-locations/Bangalore-node2' @@ -638,7 +638,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: 'Bangalore', lastModified: '10 minutes ago', url: 'http://www.redhat.com/en/office-locations/Bangalore-node3' @@ -648,7 +648,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: 'Bangalore', lastModified: '50 minutes ago', url: 'http://www.redhat.com/en/office-locations/Bangalore-node4' @@ -658,7 +658,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: 'Bangalore', lastModified: '3 hours ago', url: 'http://www.redhat.com/en/office-locations/Bangalore-node5' @@ -668,7 +668,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: 'Bangalore', lastModified: '2 hours ago', url: 'http://www.redhat.com/en/office-locations/Bangalore-node6' @@ -678,7 +678,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: 'Bangalore', lastModified: '5 hours ago', url: 'http://www.redhat.com/en/office-locations/Bangalore-node7' @@ -688,7 +688,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: 'Bangalore', lastModified: '30 minutes ago', url: 'http://www.redhat.com/en/office-locations/Bangalore-node8' @@ -698,7 +698,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: 'Bangalore', lastModified: '20 minutes ago', url: 'http://www.redhat.com/en/office-locations/Bangalore-node9' @@ -708,7 +708,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: 'Bangalore', lastModified: '1 hour ago', url: 'http://www.redhat.com/en/office-locations/Bangalore-node10' @@ -718,7 +718,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: 'Bangalore', lastModified: '40 minutes ago', url: 'http://www.redhat.com/en/office-locations/Bangalore-node11' @@ -728,7 +728,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: 'Bangalore', lastModified: '1 hour ago', url: 'http://www.redhat.com/en/office-locations/Bangalore-node12' @@ -738,7 +738,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: 'Bangalore', lastModified: '20 minutes ago', url: 'http://www.redhat.com/en/office-locations/Bangalore-node13' @@ -748,7 +748,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: 'Bangalore', lastModified: '4 hours ago', url: 'http://www.redhat.com/en/office-locations/Bangalore-node14' @@ -758,7 +758,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: 'Bangalore', lastModified: '2 hours ago', url: 'http://www.redhat.com/en/office-locations/Bangalore-node15' @@ -768,7 +768,7 @@ export const rows: SampleDataRow[] = [ threads: getRandomInteger(1, 20), applications: getRandomInteger(1, 50), workspaces: getRandomInteger(1, 30), - status: ['Stopped', 'Running', 'Down', 'Needs Maintenance'][getRandomInteger(0, 3)], + status: ['Stopped', 'Running', 'Down', 'Needs maintenance'][getRandomInteger(0, 3)], location: 'Bangalore', lastModified: '3 hours ago', url: 'http://www.redhat.com/en/office-locations/Bangalore-node16' From 1cf4855829d542253ca67c186c144de9eb9ddcce Mon Sep 17 00:00:00 2001 From: Jenny <32821331+jenny-s51@users.noreply.github.com> Date: Wed, 25 Oct 2023 12:15:48 -0400 Subject: [PATCH 07/15] revert col management with draggable to previous dnd implementation --- .../ColumnManagementWithDraggable.tsx | 341 ++++++++---------- 1 file changed, 141 insertions(+), 200 deletions(-) diff --git a/packages/react-table/src/demos/examples/ColumnManagementWithDraggable.tsx b/packages/react-table/src/demos/examples/ColumnManagementWithDraggable.tsx index 43a1a6fcc53..676991a96ce 100644 --- a/packages/react-table/src/demos/examples/ColumnManagementWithDraggable.tsx +++ b/packages/react-table/src/demos/examples/ColumnManagementWithDraggable.tsx @@ -9,9 +9,6 @@ import { DataListItemRow, DataListCell, DataListItemCells, - DragDrop, - Draggable, - Droppable, Toolbar, ToolbarContent, ToolbarItem, @@ -324,17 +321,8 @@ export const ColumnManagementAction: React.FunctionComponent = () => { const [check3, setCheck3] = React.useState(true); const [check4, setCheck4] = React.useState(true); const [check5, setCheck5] = React.useState(true); - const [liveText, setLiveText] = React.useState(''); - const id = ''; const canSelectAll = true; - const reorder = (list: string[], startIndex: number, endIndex: number) => { - const result = list; - const [removed] = result.splice(startIndex, 1); - result.splice(endIndex, 0, removed); - return result; - }; - const matchCheckboxNameToColumn = (name) => { switch (name) { case 'check1': @@ -434,41 +422,15 @@ export const ColumnManagementAction: React.FunctionComponent = () => { }; const onSelect = (event, isSelected, rowId) => { - let updatedRows; + let rows; if (rowId === -1) { - updatedRows = updatedRows.map((oneRow) => { + rows = rows.map((oneRow) => { oneRow.selected = isSelected; return oneRow; }); } else { - updatedRows = [...updatedRows]; - updatedRows[rowId] = { ...rows[rowId], selected: isSelected }; - } - setRows(updatedRows); - }; - - const onDrag = (source) => { - setLiveText(`Started dragging ${columns[source.index]}`); - // Return true to allow drag - return true; - }; - - const onDragMove = (source, dest) => { - const newText = dest ? `Move ${columns[source.index]} to ${columns[dest.index]}` : 'Invalid drop zone'; - if (newText !== liveText) { - setLiveText(newText); - } - }; - - const onDrop = (source, dest) => { - if (dest) { - const newItems = reorder(columns, source.index, dest.index); - setColumns(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.'); + rows = [...rows]; + rows[rowId] = { ...rows[rowId], selected: isSelected }; } }; @@ -495,164 +457,143 @@ export const ColumnManagementAction: React.FunctionComponent = () => { ]} > - - - - - - - - - - - - Repositories - - ]} - /> - - - - - - - - - - - - Branches - - ]} - /> - - - - - - - - - - - - Pull requests - - ]} - /> - - - - - - - - - - - - Workspaces - - ]} - /> - - - - - - - - - - - - Last commit - - ]} - /> - - - - - -
- {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. -
-
+ + + + + + + + + + + ]} + /> + + + + + + + + + + + + ]} + /> + + + + + + + + + + + + ]} + /> + + + + + + + + + + + + ]} + /> + + + + + + + + + + + + ]} + /> + + + ); From b868b8b70d5a4bd54fc02a7d4168c524c614d3a6 Mon Sep 17 00:00:00 2001 From: Jenny <32821331+jenny-s51@users.noreply.github.com> Date: Wed, 25 Oct 2023 16:14:27 -0400 Subject: [PATCH 08/15] align file names with demo names, cleanup types, fix TS errors in demo files --- .../examples/TableStickyColumnsAndHeader.tsx | 13 +++++----- ...ation.tsx => TableAutomaticPagination.tsx} | 4 +-- .../{BulkSelect.tsx => TableBulkSelect.tsx} | 26 +++++-------------- ...nagement.tsx => TableColumnManagement.tsx} | 16 ++++++------ ...=> TableColumnManagementWithDraggable.tsx} | 2 +- .../{Compact.tsx => TableCompact.tsx} | 6 ++--- ...pansion.tsx => TableCompoundExpansion.tsx} | 2 +- ...Default.tsx => TableEmptyStateDefault.tsx} | 2 +- ...tateError.tsx => TableEmptyStateError.tsx} | 2 +- ...Loading.tsx => TableEmptyStateLoading.tsx} | 2 +- ...apseAll.tsx => TableExpandCollapseAll.tsx} | 2 +- .../{Filterable.tsx => TableFilterable.tsx} | 2 +- ...onsive.tsx => TableSortableResponsive.tsx} | 12 ++++----- ...on.tsx => TableStaticBottomPagination.tsx} | 6 ++--- ...tColumn.tsx => TableStickyFirstColumn.tsx} | 10 +++---- ...StickyHeader.tsx => TableStickyHeader.tsx} | 2 +- 16 files changed, 48 insertions(+), 61 deletions(-) rename packages/react-table/src/demos/examples/{AutomaticPagination.tsx => TableAutomaticPagination.tsx} (95%) rename packages/react-table/src/demos/examples/{BulkSelect.tsx => TableBulkSelect.tsx} (89%) rename packages/react-table/src/demos/examples/{ColumnManagement.tsx => TableColumnManagement.tsx} (96%) rename packages/react-table/src/demos/examples/{ColumnManagementWithDraggable.tsx => TableColumnManagementWithDraggable.tsx} (99%) rename packages/react-table/src/demos/examples/{Compact.tsx => TableCompact.tsx} (95%) rename packages/react-table/src/demos/examples/{CompoundExpansion.tsx => TableCompoundExpansion.tsx} (99%) rename packages/react-table/src/demos/examples/{EmptyStateDefault.tsx => TableEmptyStateDefault.tsx} (96%) rename packages/react-table/src/demos/examples/{EmptyStateError.tsx => TableEmptyStateError.tsx} (96%) rename packages/react-table/src/demos/examples/{EmptyStateLoading.tsx => TableEmptyStateLoading.tsx} (94%) rename packages/react-table/src/demos/examples/{ExpandCollapseAll.tsx => TableExpandCollapseAll.tsx} (99%) rename packages/react-table/src/demos/examples/{Filterable.tsx => TableFilterable.tsx} (99%) rename packages/react-table/src/demos/examples/{SortableResponsive.tsx => TableSortableResponsive.tsx} (97%) rename packages/react-table/src/demos/examples/{StaticBottomPagination.tsx => TableStaticBottomPagination.tsx} (94%) rename packages/react-table/src/demos/examples/{StickyFirstColumn.tsx => TableStickyFirstColumn.tsx} (96%) rename packages/react-table/src/demos/examples/{StickyHeader.tsx => TableStickyHeader.tsx} (97%) diff --git a/packages/react-table/src/components/Table/examples/TableStickyColumnsAndHeader.tsx b/packages/react-table/src/components/Table/examples/TableStickyColumnsAndHeader.tsx index eb2b42bdbdb..876e0142790 100644 --- a/packages/react-table/src/components/Table/examples/TableStickyColumnsAndHeader.tsx +++ b/packages/react-table/src/components/Table/examples/TableStickyColumnsAndHeader.tsx @@ -8,7 +8,8 @@ import { Td, InnerScrollContainer, OuterScrollContainer, - ThProps + ThProps, + ISortBy } from '@patternfly/react-table'; import BlueprintIcon from '@patternfly/react-icons/dist/esm/icons/blueprint-icon'; @@ -53,10 +54,10 @@ export const TableStickyColumnsAndHeader: React.FunctionComponent = () => { // Index of the currently sorted column // Note: if you intend to make columns reorderable, you may instead want to use a non-numeric key // as the identifier of the sorted column. See the "Compound expandable" example. - const [activeSortIndex, setActiveSortIndex] = React.useState(null); + const [activeSortIndex, setActiveSortIndex] = React.useState(-1); // Sort direction of the currently sorted column - const [activeSortDirection, setActiveSortDirection] = React.useState<'asc' | 'desc' | null | undefined>(null); + const [activeSortDirection, setActiveSortDirection] = React.useState(); // Since OnSort specifies sorted columns by index, we need sortable values for our object by column index. // This example is trivial since our data objects just contain strings, but if the data was more complex @@ -69,7 +70,7 @@ export const TableStickyColumnsAndHeader: React.FunctionComponent = () => { // Note that we perform the sort as part of the component's render logic and not in onSort. // We shouldn't store the list of data in state because we don't want to have to sync that with props. let sortedFacts = facts; - if (activeSortIndex) { + if (activeSortIndex > -1) { sortedFacts = facts.sort((a, b) => { const aValue = getSortableRowValues(a)[activeSortIndex]; const bValue = getSortableRowValues(b)[activeSortIndex]; @@ -86,8 +87,8 @@ export const TableStickyColumnsAndHeader: React.FunctionComponent = () => { const getSortParams = (columnIndex: number): ThProps['sort'] => ({ sortBy: { - index: activeSortIndex as number, - direction: activeSortDirection as any + index: activeSortIndex, + direction: activeSortDirection }, onSort: (_event, index, direction) => { setActiveSortIndex(index); diff --git a/packages/react-table/src/demos/examples/AutomaticPagination.tsx b/packages/react-table/src/demos/examples/TableAutomaticPagination.tsx similarity index 95% rename from packages/react-table/src/demos/examples/AutomaticPagination.tsx rename to packages/react-table/src/demos/examples/TableAutomaticPagination.tsx index 1053bbc24b2..3aa11c7d19a 100644 --- a/packages/react-table/src/demos/examples/AutomaticPagination.tsx +++ b/packages/react-table/src/demos/examples/TableAutomaticPagination.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { Pagination } from '@patternfly/react-core'; import { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table'; -export const AutomaticPaginationTableDemo: React.FunctionComponent = () => { +export const TableAutomaticPagination: React.FunctionComponent = () => { const columns = { firstColumn: 'First column', secondColumn: 'Second column', @@ -29,7 +29,7 @@ export const AutomaticPaginationTableDemo: React.FunctionComponent = () => { const [page, setPage] = React.useState(1); const [rows, setRows] = React.useState(defaultRows.slice(0, defaultPerPage)); - const handleSetPage = (_evt, newPage, perPage, startIdx, endIdx) => { + const handleSetPage = (_evt, newPage, _perPage, startIdx, endIdx) => { setPage(newPage); setRows(defaultRows.slice(startIdx, endIdx)); }; diff --git a/packages/react-table/src/demos/examples/BulkSelect.tsx b/packages/react-table/src/demos/examples/TableBulkSelect.tsx similarity index 89% rename from packages/react-table/src/demos/examples/BulkSelect.tsx rename to packages/react-table/src/demos/examples/TableBulkSelect.tsx index c68acfe0e88..312d07c1cf1 100644 --- a/packages/react-table/src/demos/examples/BulkSelect.tsx +++ b/packages/react-table/src/demos/examples/TableBulkSelect.tsx @@ -19,32 +19,20 @@ import { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table'; import { rows, columns, SampleDataRow } from '@patternfly/react-table/dist/esm/demos/sampleData'; import { DashboardWrapper } from '@patternfly/react-core/dist/esm/demos/DashboardWrapper'; -export const BulkSelectTableDemo: React.FunctionComponent = () => { +export const TableBulkSelect: React.FunctionComponent = () => { const [isBulkSelectDropdownOpen, setIsBulkSelectDropdownOpen] = React.useState(false); - const [bulkSelection, setBulkSelection] = React.useState(''); + const [bulkSelection, setBulkSelection] = React.useState(''); const [page, setPage] = React.useState(1); const [perPage, setPerPage] = React.useState(10); const [paginatedRows, setPaginatedRows] = React.useState(rows.slice(0, 10)); const [selectedRows, setSelectedRows] = React.useState([]); - const handleSetPage = ( - _evt: MouseEvent | React.MouseEvent | React.KeyboardEvent, - newPage: number, - _perPage: number, - startIdx: number, - endIdx: number - ) => { - setPaginatedRows(rows.slice(startIdx, endIdx)); + const handleSetPage = (_evt, newPage, _perPage, startIdx, endIdx) => { + setPaginatedRows(rows?.slice(startIdx, endIdx)); setPage(newPage); }; - const handlePerPageSelect = ( - _evt: MouseEvent | React.MouseEvent | React.KeyboardEvent, - newPerPage: number, - newPage: number, - startIdx: number, - endIdx: number - ) => { + const handlePerPageSelect = (_evt, newPerPage, newPage, startIdx, endIdx) => { setPaginatedRows(rows.slice(startIdx, endIdx)); setPage(newPage); setPerPage(newPerPage); @@ -95,7 +83,7 @@ export const BulkSelectTableDemo: React.FunctionComponent = () => { return ( , value: string | number) => { + onSelect={(_event, value) => { if (value === 'all') { selectAllRows(bulkSelection !== 'all'); } else if (value === 'page') { @@ -103,7 +91,7 @@ export const BulkSelectTableDemo: React.FunctionComponent = () => { } else { setSelectedRows([]); } - setBulkSelection(value); + setBulkSelection(value as string); }} isOpen={isBulkSelectDropdownOpen} onOpenChange={(isOpen: boolean) => setIsBulkSelectDropdownOpen(isOpen)} diff --git a/packages/react-table/src/demos/examples/ColumnManagement.tsx b/packages/react-table/src/demos/examples/TableColumnManagement.tsx similarity index 96% rename from packages/react-table/src/demos/examples/ColumnManagement.tsx rename to packages/react-table/src/demos/examples/TableColumnManagement.tsx index 94f57b2b360..2fe489d5805 100644 --- a/packages/react-table/src/demos/examples/ColumnManagement.tsx +++ b/packages/react-table/src/demos/examples/TableColumnManagement.tsx @@ -30,17 +30,17 @@ 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-core/dist/esm/demos/DashboardWrapper'; import { capitalize } from '@patternfly/react-table/src/components/Table/utils/utils'; -import { rows, columns } from '@patternfly/react-table/dist/esm/demos/sampleData'; +import { rows, columns, SampleDataRow } from '@patternfly/react-table/dist/esm/demos/sampleData'; -export const ColumnManagementAction: React.FC = () => { +export const TableColumnManagement: React.FunctionComponent = () => { const defaultColumns = columns; const defaultRows = rows; const [filters, setFilters] = React.useState([]); const [filteredColumns, setFilteredColumns] = React.useState([]); - const [filteredRows, setFilteredRows] = React.useState([]); + const [filteredRows, setFilteredRows] = React.useState([]); const [managedColumns, setManagedColumns] = React.useState(defaultColumns); - const [managedRows, setManagedRows] = React.useState(defaultRows); + 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); @@ -108,7 +108,7 @@ export const ColumnManagementAction: React.FC = () => { setPerPage(newPerPage); }; - const renderPagination = (variant: 'top' | 'bottom' | PaginationVariant, isCompact: boolean) => ( + const renderPagination = (variant: 'top' | 'bottom' | PaginationVariant, isCompact?: boolean) => ( { - {renderPagination(PaginationVariant.top)} + {renderPagination('top')} @@ -467,7 +467,7 @@ export const ColumnManagementAction: React.FC = () => { width={key === 'name' ? 15 : 10} dataLabel={key === 'lastModified' ? 'Last modified' : capitalize(key)} > - {value} + {value as string} ) )} @@ -476,7 +476,7 @@ export const ColumnManagementAction: React.FC = () => { ))} - {renderPagination(PaginationVariant.bottom)} + {renderPagination('bottom')} {renderModal()} diff --git a/packages/react-table/src/demos/examples/ColumnManagementWithDraggable.tsx b/packages/react-table/src/demos/examples/TableColumnManagementWithDraggable.tsx similarity index 99% rename from packages/react-table/src/demos/examples/ColumnManagementWithDraggable.tsx rename to packages/react-table/src/demos/examples/TableColumnManagementWithDraggable.tsx index 676991a96ce..840420452d3 100644 --- a/packages/react-table/src/demos/examples/ColumnManagementWithDraggable.tsx +++ b/packages/react-table/src/demos/examples/TableColumnManagementWithDraggable.tsx @@ -47,7 +47,7 @@ interface RowType { )[]; } -export const ColumnManagementAction: React.FunctionComponent = () => { +export const TableColumnManagementWithDraggable: React.FunctionComponent = () => { const actions = [ { title: Link diff --git a/packages/react-table/src/demos/examples/Compact.tsx b/packages/react-table/src/demos/examples/TableCompact.tsx similarity index 95% rename from packages/react-table/src/demos/examples/Compact.tsx rename to packages/react-table/src/demos/examples/TableCompact.tsx index 4643055a470..639dcfc26e5 100644 --- a/packages/react-table/src/demos/examples/Compact.tsx +++ b/packages/react-table/src/demos/examples/TableCompact.tsx @@ -20,18 +20,18 @@ import FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon'; import { rows, columns } from '@patternfly/react-table/dist/esm/demos/sampleData'; import { DashboardWrapper } from '@patternfly/react-core/dist/esm/demos/DashboardWrapper'; -export const CompactTable: React.FC = () => { +export const TableCompact: React.FunctionComponent = () => { const [isSelectOpen, setIsSelectOpen] = React.useState(false); const [page, setPage] = React.useState(1); const [perPage, setPerPage] = React.useState(10); const [paginatedRows, setPaginatedRows] = React.useState(rows.slice(0, 10)); - const handleSetPage = (_evt: any, newPage: number, startIdx: number, endIdx: number) => { + const handleSetPage = (_evt, newPage, _perPage, startIdx, endIdx) => { setPaginatedRows(rows.slice(startIdx, endIdx)); setPage(newPage); }; - const handlePerPageSelect = (_evt: any, newPerPage: number, newPage: number, startIdx: number, endIdx: number) => { + const handlePerPageSelect = (_evt, newPerPage, newPage, startIdx, endIdx) => { setPaginatedRows(rows.slice(startIdx, endIdx)); setPage(newPage); setPerPage(newPerPage); diff --git a/packages/react-table/src/demos/examples/CompoundExpansion.tsx b/packages/react-table/src/demos/examples/TableCompoundExpansion.tsx similarity index 99% rename from packages/react-table/src/demos/examples/CompoundExpansion.tsx rename to packages/react-table/src/demos/examples/TableCompoundExpansion.tsx index a2afd21ef7a..7554acad0ab 100644 --- a/packages/react-table/src/demos/examples/CompoundExpansion.tsx +++ b/packages/react-table/src/demos/examples/TableCompoundExpansion.tsx @@ -24,7 +24,7 @@ import { DashboardWrapper } from '@patternfly/react-core/dist/esm/demos/Dashboar import FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon'; import spacing from '@patternfly/react-styles/css/utilities/Spacing/spacing'; -export const CompoundExpandable: React.FC = () => { +export const TableCompoundExpansion: React.FunctionComponent = () => { // In real usage, this data would come from some external source like an API via props. const [isSelectOpen, setIsSelectOpen] = React.useState(false); diff --git a/packages/react-table/src/demos/examples/EmptyStateDefault.tsx b/packages/react-table/src/demos/examples/TableEmptyStateDefault.tsx similarity index 96% rename from packages/react-table/src/demos/examples/EmptyStateDefault.tsx rename to packages/react-table/src/demos/examples/TableEmptyStateDefault.tsx index 83b42b31aeb..ab9febef731 100644 --- a/packages/react-table/src/demos/examples/EmptyStateDefault.tsx +++ b/packages/react-table/src/demos/examples/TableEmptyStateDefault.tsx @@ -16,7 +16,7 @@ import { import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon'; import { DashboardWrapper } from '@patternfly/react-core/dist/esm/demos/DashboardWrapper'; -export const EmptyStateDefaultDemo: React.FunctionComponent = () => ( +export const TableEmptyStateDefault: React.FunctionComponent = () => ( diff --git a/packages/react-table/src/demos/examples/EmptyStateError.tsx b/packages/react-table/src/demos/examples/TableEmptyStateError.tsx similarity index 96% rename from packages/react-table/src/demos/examples/EmptyStateError.tsx rename to packages/react-table/src/demos/examples/TableEmptyStateError.tsx index 0bcfab5e5d2..c291b619f2b 100644 --- a/packages/react-table/src/demos/examples/EmptyStateError.tsx +++ b/packages/react-table/src/demos/examples/TableEmptyStateError.tsx @@ -14,7 +14,7 @@ import ExclamationCircleIcon from '@patternfly/react-icons/dist/esm/icons/exclam import globalDangerColor200 from '@patternfly/react-tokens/dist/esm/global_danger_color_200'; import { DashboardWrapper } from '@patternfly/react-core/dist/esm/demos/DashboardWrapper'; -export const ErrorStateDemo: React.FunctionComponent = () => ( +export const TableEmptyStateError: React.FunctionComponent = () => ( diff --git a/packages/react-table/src/demos/examples/EmptyStateLoading.tsx b/packages/react-table/src/demos/examples/TableEmptyStateLoading.tsx similarity index 94% rename from packages/react-table/src/demos/examples/EmptyStateLoading.tsx rename to packages/react-table/src/demos/examples/TableEmptyStateLoading.tsx index f1b9eddf81b..229a6a327fc 100644 --- a/packages/react-table/src/demos/examples/EmptyStateLoading.tsx +++ b/packages/react-table/src/demos/examples/TableEmptyStateLoading.tsx @@ -11,7 +11,7 @@ import { } from '@patternfly/react-core'; import { DashboardWrapper } from '@patternfly/react-core/dist/esm/demos/DashboardWrapper'; -export const EmptyStateLoadingDemo: React.FunctionComponent = () => ( +export const TableEmptyStateLoading: React.FunctionComponent = () => ( diff --git a/packages/react-table/src/demos/examples/ExpandCollapseAll.tsx b/packages/react-table/src/demos/examples/TableExpandCollapseAll.tsx similarity index 99% rename from packages/react-table/src/demos/examples/ExpandCollapseAll.tsx rename to packages/react-table/src/demos/examples/TableExpandCollapseAll.tsx index 239a873cb54..f8e903be6c8 100644 --- a/packages/react-table/src/demos/examples/ExpandCollapseAll.tsx +++ b/packages/react-table/src/demos/examples/TableExpandCollapseAll.tsx @@ -119,7 +119,7 @@ const serverData: Server[] = [ const initialExpandedServerNames = ['US-Node 2']; // Default to expanded -export const ExpandCollapseAllTableDemo: React.FC = () => { +export const TableExpandCollapseAll: React.FunctionComponent = () => { const [areAllExpanded, setAreAllExpanded] = React.useState(false); const [collapseAllAriaLabel, setCollapseAllAriaLabel] = React.useState('Expand all'); const [expandedServerNames, setExpandedServerNames] = React.useState(initialExpandedServerNames); diff --git a/packages/react-table/src/demos/examples/Filterable.tsx b/packages/react-table/src/demos/examples/TableFilterable.tsx similarity index 99% rename from packages/react-table/src/demos/examples/Filterable.tsx rename to packages/react-table/src/demos/examples/TableFilterable.tsx index 9a6f878ce96..639978b351a 100644 --- a/packages/react-table/src/demos/examples/Filterable.tsx +++ b/packages/react-table/src/demos/examples/TableFilterable.tsx @@ -28,7 +28,7 @@ import FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon'; import { Table, TableText, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table'; import { rows, columns } from '@patternfly/react-table/dist/esm/demos/sampleData'; -export const FilterTableDemo: React.FunctionComponent = () => { +export const TableFilterable: React.FunctionComponent = () => { const [filters, setFilters] = React.useState>({ location: [], name: [], status: [] }); const [currentCategory, setCurrentCategory] = React.useState('Status'); const [isFilterDropdownOpen, setIsFilterDropdownOpen] = React.useState(false); diff --git a/packages/react-table/src/demos/examples/SortableResponsive.tsx b/packages/react-table/src/demos/examples/TableSortableResponsive.tsx similarity index 97% rename from packages/react-table/src/demos/examples/SortableResponsive.tsx rename to packages/react-table/src/demos/examples/TableSortableResponsive.tsx index 1c641cc29fd..00f6bc604a9 100644 --- a/packages/react-table/src/demos/examples/SortableResponsive.tsx +++ b/packages/react-table/src/demos/examples/TableSortableResponsive.tsx @@ -43,9 +43,9 @@ import { DashboardWrapper } from '@patternfly/react-core/dist/esm/demos/Dashboar import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon'; import { rows, columns, SampleDataRow } from '@patternfly/react-table/dist/esm/demos/sampleData'; -type Direction = 'asc' | 'desc' | 'none'; +type Direction = 'asc' | 'desc' | undefined; -export const ComposableTableSortable: React.FC = () => { +export const TableSortableResponsive: React.FunctionComponent = () => { const [isKebabDropdownOpen, setIsKebabDropdownOpen] = React.useState(false); const sortRows = (rows: SampleDataRow[], sortIndex: number, sortDirection: Direction) => @@ -99,9 +99,9 @@ export const ComposableTableSortable: React.FC = () => { setPerPage(newPerPage); }; - const renderPagination = (variant: 'top' | 'bottom' | PaginationVariant) => ( + const renderPagination = (variant: 'top' | 'bottom' | PaginationVariant, isCompact: boolean) => ( { isOpen={isSortDropdownOpen} selected={[activeSortDirection, activeSortIndex]} onOpenChange={(isOpen: boolean) => setIsSortDropdownOpen(isOpen)} - onSelect={(event: React.MouseEvent, value: string | number) => { + onSelect={(event, value) => { if (value === 'asc' || value === 'desc') { onSort(event, activeSortIndex, value); } else { - onSort(event, value as number, activeSortDirection !== 'none' ? activeSortDirection : 'asc'); + onSort(event, value as number, activeSortDirection ?? 'asc'); } }} toggle={(toggleRef: React.Ref) => ( diff --git a/packages/react-table/src/demos/examples/StaticBottomPagination.tsx b/packages/react-table/src/demos/examples/TableStaticBottomPagination.tsx similarity index 94% rename from packages/react-table/src/demos/examples/StaticBottomPagination.tsx rename to packages/react-table/src/demos/examples/TableStaticBottomPagination.tsx index 8d8226d0ac0..8bd1e93ce2e 100644 --- a/packages/react-table/src/demos/examples/StaticBottomPagination.tsx +++ b/packages/react-table/src/demos/examples/TableStaticBottomPagination.tsx @@ -21,16 +21,16 @@ import FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon'; import { DashboardWrapper } from '@patternfly/react-core/dist/esm/demos/DashboardWrapper'; import { rows, columns } from '@patternfly/react-table/dist/esm/demos/sampleData'; -export const StaticBottomPagination: React.FC = () => { +export const TableStaticBottomPagination: React.FunctionComponent = () => { const [isSelectOpen, setIsSelectOpen] = React.useState(false); const [page, setPage] = React.useState(1); const [perPage, setPerPage] = React.useState(10); const [paginatedRows, setPaginatedRows] = React.useState(rows.slice(0, 10)); - const handleSetPage = (_evt: any, newPage: number, perPage: number, startIdx: number, endIdx: number) => { + const handleSetPage = (_evt, newPage, _perPage, startIdx, endIdx) => { setPaginatedRows(rows.slice(startIdx, endIdx)); setPage(newPage); }; - const handlePerPageSelect = (_evt: any, newPerPage: number, newPage: number, startIdx: number, endIdx: number) => { + const handlePerPageSelect = (_evt, newPerPage, newPage, startIdx, endIdx) => { setPaginatedRows(rows.slice(startIdx, endIdx)); setPage(newPage); setPerPage(newPerPage); diff --git a/packages/react-table/src/demos/examples/StickyFirstColumn.tsx b/packages/react-table/src/demos/examples/TableStickyFirstColumn.tsx similarity index 96% rename from packages/react-table/src/demos/examples/StickyFirstColumn.tsx rename to packages/react-table/src/demos/examples/TableStickyFirstColumn.tsx index 2a45b566c17..62a51bb876f 100644 --- a/packages/react-table/src/demos/examples/StickyFirstColumn.tsx +++ b/packages/react-table/src/demos/examples/TableStickyFirstColumn.tsx @@ -22,9 +22,7 @@ interface Fact { detail14: string; } -type Direction = 'asc' | 'desc' | 'none'; - -export const StickyFirstColumn = () => { +export const TableStickyFirstColumn = () => { const facts = Array.from( { length: 9 @@ -66,8 +64,8 @@ export const StickyFirstColumn = () => { header15: 'Header 15', header16: 'Header 16' }; - const [activeSortIndex, setActiveSortIndex] = React.useState(null); - const [activeSortDirection, setActiveSortDirection] = React.useState(null); + const [activeSortIndex, setActiveSortIndex] = React.useState(-1); + const [activeSortDirection, setActiveSortDirection] = React.useState(); const getSortableRowValues = (fact: Fact) => { const { name, @@ -126,7 +124,7 @@ export const StickyFirstColumn = () => { index: activeSortIndex, direction: activeSortDirection }, - onSort: (_event: any, index: number, direction: Direction) => { + onSort: (_event, index, direction) => { setActiveSortIndex(index); setActiveSortDirection(direction); }, diff --git a/packages/react-table/src/demos/examples/StickyHeader.tsx b/packages/react-table/src/demos/examples/TableStickyHeader.tsx similarity index 97% rename from packages/react-table/src/demos/examples/StickyHeader.tsx rename to packages/react-table/src/demos/examples/TableStickyHeader.tsx index 4ab5cfdabad..5816310a8dd 100644 --- a/packages/react-table/src/demos/examples/StickyHeader.tsx +++ b/packages/react-table/src/demos/examples/TableStickyHeader.tsx @@ -5,7 +5,7 @@ import { Table, Thead, Tr, Th, Tbody, Td, TableText } from '@patternfly/react-ta import { DashboardWrapper } from '@patternfly/react-core/dist/esm/demos/DashboardWrapper'; import { rows, columns } from '@patternfly/react-table/dist/esm/demos/sampleData'; -export const StickyHeader: React.FunctionComponent = () => { +export const TableStickyHeader: React.FunctionComponent = () => { const renderLabel = (labelText: string) => { switch (labelText) { case 'Running': From f8b54d015b5db4e351a1a6f1cb6a3a4712c76221 Mon Sep 17 00:00:00 2001 From: Jenny <32821331+jenny-s51@users.noreply.github.com> Date: Thu, 26 Oct 2023 08:50:43 -0400 Subject: [PATCH 09/15] update fileNames in table.md --- packages/react-table/src/demos/Table.md | 30 ++++++++++++------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/react-table/src/demos/Table.md b/packages/react-table/src/demos/Table.md index cc3e69923c5..2376f807504 100644 --- a/packages/react-table/src/demos/Table.md +++ b/packages/react-table/src/demos/Table.md @@ -56,46 +56,46 @@ import spacing from '@patternfly/react-styles/css/utilities/Spacing/spacing'; ### Bulk select -```js isFullscreen file="./examples/BulkSelect.tsx" +```js isFullscreen file="./examples/TableBulkSelect.tsx" ``` ### Expand/collapse all -```js isFullscreen file="./examples/ExpandCollapseAll.tsx" +```js isFullscreen file="./examples/TableExpandCollapseAll.tsx" ``` ### Compact -```js isFullscreen file="./examples/Compact.tsx" +```js isFullscreen file="./examples/TableCompact.tsx" ``` ### Compound expansion -```js isFullscreen file="./examples/CompoundExpansion.tsx" +```js isFullscreen file="./examples/TableCompoundExpansion.tsx" ``` ### Column management -```js isFullscreen file="./examples/ColumnManagement.tsx" +```js isFullscreen file="./examples/TableColumnManagement.tsx" ``` ### Column management with draggable -```js isFullscreen file="./examples/ColumnManagementWithDraggable.tsx" +```js isFullscreen file="./examples/TableColumnManagementWithDraggable.tsx" ``` ### Filterable -```js isFullscreen file="./examples/Filterable.tsx" +```js isFullscreen file="./examples/TableFilterable.tsx" ``` ### Sortable - responsive -```js isFullscreen file="./examples/SortableResponsive.tsx" +```js isFullscreen file="./examples/TableSortableResponsive.tsx" ``` @@ -110,24 +110,24 @@ To demonstrate this, navigate to the last page of data below using the `>>` navi - The default behavior would show the last page of results, which would only contain the last two rows (rows 11 - 12). - The `isLastFullPageShown` prop navigates you back to the previous page which does contain a full page of 5 rows (rows 6 - 10). -```js isFullscreen file="./examples/AutomaticPagination.tsx" +```js isFullscreen file="./examples/TableAutomaticPagination.tsx" ``` ### Static bottom pagination on mobile -```ts isFullscreen file="./examples/StaticBottomPagination.tsx" +```ts isFullscreen file="./examples/TableStaticBottomPagination.tsx" ``` ### Sticky header -```js isFullscreen file="./examples/StickyHeader.tsx" +```js isFullscreen file="./examples/TableStickyHeader.tsx" ``` ### Sticky first column -```js isFullscreen file="./examples/StickyFirstColumn.tsx" +```js isFullscreen file="./examples/TableStickyFirstColumn.tsx" ``` @@ -145,15 +145,15 @@ These examples demonstrate the use of an [Empty State component](/components/emp ### Empty -```js isFullscreen file="./examples/EmptyStateDefault.tsx" +```js isFullscreen file="./examples/TableEmptyStateDefault.tsx" ``` ### Loading -```js isFullscreen file="./examples/EmptyStateLoading.tsx" +```js isFullscreen file="./examples/TableEmptyStateLoading.tsx" ``` ### Error -```js isFullscreen file="./examples/EmptyStateError.tsx" +```js isFullscreen file="./examples/TableEmptyStateError.tsx" ``` From 3886ee7ea9f637755d43ac62796d0e88c23de85f Mon Sep 17 00:00:00 2001 From: Jenny <32821331+jenny-s51@users.noreply.github.com> Date: Fri, 3 Nov 2023 15:59:23 -0400 Subject: [PATCH 10/15] PR feedback from Eric --- .../examples/TableAutomaticPagination.tsx | 16 ++++++++++-- .../src/demos/examples/TableBulkSelect.tsx | 26 ++++++++++++++----- .../demos/examples/TableColumnManagement.tsx | 14 +++++----- .../TableColumnManagementWithDraggable.tsx | 19 ++++++++------ .../src/demos/examples/TableCompact.tsx | 16 ++++++++++-- .../src/demos/examples/TableFilterable.tsx | 10 +++---- .../examples/TableSortableResponsive.tsx | 6 ++--- .../examples/TableStaticBottomPagination.tsx | 16 ++++++++++-- .../demos/examples/TableStickyFirstColumn.tsx | 9 ++++--- 9 files changed, 93 insertions(+), 39 deletions(-) diff --git a/packages/react-table/src/demos/examples/TableAutomaticPagination.tsx b/packages/react-table/src/demos/examples/TableAutomaticPagination.tsx index 3aa11c7d19a..ab17c272bf1 100644 --- a/packages/react-table/src/demos/examples/TableAutomaticPagination.tsx +++ b/packages/react-table/src/demos/examples/TableAutomaticPagination.tsx @@ -29,12 +29,24 @@ export const TableAutomaticPagination: React.FunctionComponent = () => { const [page, setPage] = React.useState(1); const [rows, setRows] = React.useState(defaultRows.slice(0, defaultPerPage)); - const handleSetPage = (_evt, newPage, _perPage, startIdx, endIdx) => { + const handleSetPage = ( + _evt: React.MouseEvent | React.KeyboardEvent | MouseEvent, + newPage: number, + _perPage: number, + startIdx: number, + endIdx: number + ) => { setPage(newPage); setRows(defaultRows.slice(startIdx, endIdx)); }; - const handlePerPageSelect = (_evt, newPerPage, newPage, startIdx, endIdx) => { + const handlePerPageSelect = ( + _evt: React.MouseEvent | React.KeyboardEvent | MouseEvent, + newPerPage: number, + newPage: number, + startIdx: number, + endIdx: number + ) => { setPerPage(newPerPage); setPage(newPage); setRows(defaultRows.slice(startIdx, endIdx)); diff --git a/packages/react-table/src/demos/examples/TableBulkSelect.tsx b/packages/react-table/src/demos/examples/TableBulkSelect.tsx index 312d07c1cf1..fd680a3e36d 100644 --- a/packages/react-table/src/demos/examples/TableBulkSelect.tsx +++ b/packages/react-table/src/demos/examples/TableBulkSelect.tsx @@ -20,19 +20,31 @@ import { rows, columns, SampleDataRow } from '@patternfly/react-table/dist/esm/d import { DashboardWrapper } from '@patternfly/react-core/dist/esm/demos/DashboardWrapper'; export const TableBulkSelect: React.FunctionComponent = () => { - const [isBulkSelectDropdownOpen, setIsBulkSelectDropdownOpen] = React.useState(false); - const [bulkSelection, setBulkSelection] = React.useState(''); - const [page, setPage] = React.useState(1); - const [perPage, setPerPage] = React.useState(10); + const [isBulkSelectDropdownOpen, setIsBulkSelectDropdownOpen] = React.useState(false); + const [bulkSelection, setBulkSelection] = React.useState(''); + const [page, setPage] = React.useState(1); + const [perPage, setPerPage] = React.useState(10); const [paginatedRows, setPaginatedRows] = React.useState(rows.slice(0, 10)); const [selectedRows, setSelectedRows] = React.useState([]); - const handleSetPage = (_evt, newPage, _perPage, startIdx, endIdx) => { + const handleSetPage = ( + _evt: React.MouseEvent | React.KeyboardEvent | MouseEvent, + newPage: number, + _perPage: number, + startIdx: number, + endIdx: number + ) => { setPaginatedRows(rows?.slice(startIdx, endIdx)); setPage(newPage); }; - const handlePerPageSelect = (_evt, newPerPage, newPage, startIdx, endIdx) => { + const handlePerPageSelect = ( + _evt: React.MouseEvent | React.KeyboardEvent | MouseEvent, + newPerPage: number, + newPage: number, + startIdx: number, + endIdx: number + ) => { setPaginatedRows(rows.slice(startIdx, endIdx)); setPage(newPage); setPerPage(newPerPage); @@ -83,7 +95,7 @@ export const TableBulkSelect: React.FunctionComponent = () => { return ( { + onSelect={(_event: React.MouseEvent, value: string) => { if (value === 'all') { selectAllRows(bulkSelection !== 'all'); } else if (value === 'page') { diff --git a/packages/react-table/src/demos/examples/TableColumnManagement.tsx b/packages/react-table/src/demos/examples/TableColumnManagement.tsx index 2fe489d5805..6d129e5c36d 100644 --- a/packages/react-table/src/demos/examples/TableColumnManagement.tsx +++ b/packages/react-table/src/demos/examples/TableColumnManagement.tsx @@ -41,10 +41,10 @@ export const TableColumnManagement: React.FunctionComponent = () => { const [filteredRows, setFilteredRows] = React.useState([]); const [managedColumns, setManagedColumns] = React.useState(defaultColumns); const [managedRows, setManagedRows] = React.useState(defaultRows); - const [isModalOpen, setIsModalOpen] = React.useState(false); + 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 [page, setPage] = React.useState(1); + const [perPage, setPerPage] = React.useState(10); const [paginatedRows, setPaginatedRows] = React.useState(rows); const matchCheckboxNameToColumn = (name: string): string => { @@ -108,7 +108,7 @@ export const TableColumnManagement: React.FunctionComponent = () => { setPerPage(newPerPage); }; - const renderPagination = (variant: 'top' | 'bottom' | PaginationVariant, isCompact?: boolean) => ( + const renderPagination = (variant: 'top' | 'bottom' | PaginationVariant, isCompact: boolean) => ( { return ; case 'Stopped': return ; - case 'Needs Maintenance': + case 'Needs maintenance': return ; case 'Down': return ; @@ -425,7 +425,7 @@ export const TableColumnManagement: React.FunctionComponent = () => { - {renderPagination('top')} + {renderPagination('top', false)} @@ -476,7 +476,7 @@ export const TableColumnManagement: React.FunctionComponent = () => { ))} - {renderPagination('bottom')} + {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 840420452d3..e3c8c08cccc 100644 --- a/packages/react-table/src/demos/examples/TableColumnManagementWithDraggable.tsx +++ b/packages/react-table/src/demos/examples/TableColumnManagementWithDraggable.tsx @@ -323,7 +323,7 @@ export const TableColumnManagementWithDraggable: React.FunctionComponent = () => const [check5, setCheck5] = React.useState(true); const canSelectAll = true; - const matchCheckboxNameToColumn = (name) => { + const matchCheckboxNameToColumn = (name: string) => { switch (name) { case 'check1': return 'Repositories'; @@ -335,10 +335,12 @@ export const TableColumnManagementWithDraggable: React.FunctionComponent = () => return 'Workspaces'; case 'check5': return 'Last commit'; + default: + return ''; } }; - const filterData = (checked, name) => { + const filterData = (checked: boolean, name: string) => { if (checked) { const updatedFilters = filters.filter((item) => item !== name); const updatedFilteredColumns = defaultColumns.filter((column) => !updatedFilters.includes(column)); @@ -356,11 +358,13 @@ export const TableColumnManagementWithDraggable: React.FunctionComponent = () => setFilters([]); setFilteredColumns(defaultColumns); }; - const handleChange = (event, checked) => { - const target = event.target; - const value = target.type === 'checkbox' ? target.checked : target.value; + 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 (target.name) { + switch (name) { case 'check1': setCheck1(value); break; @@ -382,7 +386,6 @@ export const TableColumnManagementWithDraggable: React.FunctionComponent = () => setIsModalOpen(!isModalOpen); }; const onSave = () => { - // const orderedColumns: string[] = itemOrder.map((item) => matchDataListNameToColumn(item)); // concat empty string at the end for actions column const filteredOrderedColumns: string[] = columns .filter((col) => filteredColumns.length === 0 || filteredColumns.indexOf(col as string) > -1) @@ -421,7 +424,7 @@ export const TableColumnManagementWithDraggable: React.FunctionComponent = () => setCheck5(true); }; - const onSelect = (event, isSelected, rowId) => { + const onSelect = (event: React.FormEvent, isSelected: boolean, rowId: number) => { let rows; if (rowId === -1) { rows = rows.map((oneRow) => { diff --git a/packages/react-table/src/demos/examples/TableCompact.tsx b/packages/react-table/src/demos/examples/TableCompact.tsx index 639dcfc26e5..d31ca17a8e1 100644 --- a/packages/react-table/src/demos/examples/TableCompact.tsx +++ b/packages/react-table/src/demos/examples/TableCompact.tsx @@ -26,12 +26,24 @@ export const TableCompact: React.FunctionComponent = () => { const [perPage, setPerPage] = React.useState(10); const [paginatedRows, setPaginatedRows] = React.useState(rows.slice(0, 10)); - const handleSetPage = (_evt, newPage, _perPage, startIdx, endIdx) => { + const handleSetPage = ( + _evt: React.MouseEvent | React.KeyboardEvent | MouseEvent, + newPage: number, + _perPage: number, + startIdx: number, + endIdx: number + ) => { setPaginatedRows(rows.slice(startIdx, endIdx)); setPage(newPage); }; - const handlePerPageSelect = (_evt, newPerPage, newPage, startIdx, endIdx) => { + const handlePerPageSelect = ( + _evt: React.MouseEvent | React.KeyboardEvent | MouseEvent, + newPerPage: number, + newPage: number, + startIdx: number, + endIdx: number + ) => { setPaginatedRows(rows.slice(startIdx, endIdx)); setPage(newPage); setPerPage(newPerPage); diff --git a/packages/react-table/src/demos/examples/TableFilterable.tsx b/packages/react-table/src/demos/examples/TableFilterable.tsx index 639978b351a..e5b0793efc9 100644 --- a/packages/react-table/src/demos/examples/TableFilterable.tsx +++ b/packages/react-table/src/demos/examples/TableFilterable.tsx @@ -75,12 +75,12 @@ export const TableFilterable: React.FunctionComponent = () => { setIsFilterDropdownOpen(!isFilterDropdownOpen); }; - const onInputChange = (newValue) => { + const onInputChange = (newValue: string) => { setInputValue(newValue); }; - const onStatusSelect = (event, selection) => { - const checked = event.target.checked; + const onStatusSelect = (event: React.MouseEvent, selection: string) => { + const checked = (event.target as HTMLInputElement).checked; setFilters({ ...filters, status: checked ? [...filters.status, selection] : filters.status.filter((value) => value !== selection) @@ -88,7 +88,7 @@ export const TableFilterable: React.FunctionComponent = () => { setIsFilterDropdownOpen(false); }; - const onNameInput = (event) => { + const onNameInput = (event: React.KeyboardEvent) => { if (event.key && event.key !== 'Enter') { return; } @@ -97,7 +97,7 @@ export const TableFilterable: React.FunctionComponent = () => { setFilters({ ...filters, name: prevFilters.includes(inputValue) ? prevFilters : [...prevFilters, inputValue] }); }; - const onLocationSelect = (event, selection) => { + const onLocationSelect = (event: React.MouseEvent, selection: string) => { setFilters({ ...filters, location: [selection] }); setIsFilterDropdownOpen(false); diff --git a/packages/react-table/src/demos/examples/TableSortableResponsive.tsx b/packages/react-table/src/demos/examples/TableSortableResponsive.tsx index 00f6bc604a9..794aee7c78b 100644 --- a/packages/react-table/src/demos/examples/TableSortableResponsive.tsx +++ b/packages/react-table/src/demos/examples/TableSortableResponsive.tsx @@ -91,11 +91,11 @@ export const TableSortableResponsive: React.FunctionComponent = () => { setSortedRows(sortedData.slice((page - 1) * perPage, page * perPage - 1)); }, [sortedData, page, perPage]); - const handleSetPage = (_evt: any, newPage: number) => { + const handleSetPage = (_evt: React.MouseEvent | React.KeyboardEvent | MouseEvent, newPage: number) => { setPage(newPage); }; - const handlePerPageSelect = (_evt: any, newPerPage: number) => { + const handlePerPageSelect = (_evt: React.MouseEvent | React.KeyboardEvent | MouseEvent, newPerPage: number) => { setPerPage(newPerPage); }; @@ -141,7 +141,7 @@ export const TableSortableResponsive: React.FunctionComponent = () => { isOpen={isSortDropdownOpen} selected={[activeSortDirection, activeSortIndex]} onOpenChange={(isOpen: boolean) => setIsSortDropdownOpen(isOpen)} - onSelect={(event, value) => { + onSelect={(event: React.MouseEvent, value: string | number) => { if (value === 'asc' || value === 'desc') { onSort(event, activeSortIndex, value); } else { diff --git a/packages/react-table/src/demos/examples/TableStaticBottomPagination.tsx b/packages/react-table/src/demos/examples/TableStaticBottomPagination.tsx index 8bd1e93ce2e..10fcacf2e8c 100644 --- a/packages/react-table/src/demos/examples/TableStaticBottomPagination.tsx +++ b/packages/react-table/src/demos/examples/TableStaticBottomPagination.tsx @@ -26,11 +26,23 @@ export const TableStaticBottomPagination: React.FunctionComponent = () => { const [page, setPage] = React.useState(1); const [perPage, setPerPage] = React.useState(10); const [paginatedRows, setPaginatedRows] = React.useState(rows.slice(0, 10)); - const handleSetPage = (_evt, newPage, _perPage, startIdx, endIdx) => { + const handleSetPage = ( + _evt: React.MouseEvent | React.KeyboardEvent | MouseEvent, + newPage: number, + _perPage: number, + startIdx: number, + endIdx: number + ) => { setPaginatedRows(rows.slice(startIdx, endIdx)); setPage(newPage); }; - const handlePerPageSelect = (_evt, newPerPage, newPage, startIdx, endIdx) => { + const handlePerPageSelect = ( + _evt: React.MouseEvent | React.KeyboardEvent | MouseEvent, + newPerPage: number, + newPage: number, + startIdx: number, + endIdx: number + ) => { setPaginatedRows(rows.slice(startIdx, endIdx)); setPage(newPage); setPerPage(newPerPage); diff --git a/packages/react-table/src/demos/examples/TableStickyFirstColumn.tsx b/packages/react-table/src/demos/examples/TableStickyFirstColumn.tsx index 62a51bb876f..a22359b5ddd 100644 --- a/packages/react-table/src/demos/examples/TableStickyFirstColumn.tsx +++ b/packages/react-table/src/demos/examples/TableStickyFirstColumn.tsx @@ -3,6 +3,8 @@ import { Table, Thead, Tr, Th, Tbody, Td, InnerScrollContainer } from '@patternf import { Card, PageSection } from '@patternfly/react-core'; import { DashboardWrapper } from '@patternfly/react-core/dist/esm/demos/DashboardWrapper'; +type Direction = 'asc' | 'desc' | undefined; + interface Fact { name: string; state: string; @@ -64,8 +66,9 @@ export const TableStickyFirstColumn = () => { header15: 'Header 15', header16: 'Header 16' }; + const [activeSortIndex, setActiveSortIndex] = React.useState(-1); - const [activeSortDirection, setActiveSortDirection] = React.useState(); + const [activeSortDirection, setActiveSortDirection] = React.useState('asc'); const getSortableRowValues = (fact: Fact) => { const { name, @@ -105,7 +108,7 @@ export const TableStickyFirstColumn = () => { ]; }; let sortedFacts = facts; - if (activeSortIndex !== null) { + if (activeSortIndex > -1) { sortedFacts = facts.sort((a, b) => { const aValue = getSortableRowValues(a)[activeSortIndex]; const bValue = getSortableRowValues(b)[activeSortIndex]; @@ -124,7 +127,7 @@ export const TableStickyFirstColumn = () => { index: activeSortIndex, direction: activeSortDirection }, - onSort: (_event, index, direction) => { + onSort: (_event: React.MouseEvent, index: number, direction: Direction) => { setActiveSortIndex(index); setActiveSortDirection(direction); }, From e47c99a83f682fd8935947e40bbac99881b123a8 Mon Sep 17 00:00:00 2001 From: Jenny <32821331+jenny-s51@users.noreply.github.com> Date: Fri, 3 Nov 2023 16:16:28 -0400 Subject: [PATCH 11/15] fix category dropdown --- packages/react-table/src/demos/examples/TableFilterable.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-table/src/demos/examples/TableFilterable.tsx b/packages/react-table/src/demos/examples/TableFilterable.tsx index e5b0793efc9..038470539bb 100644 --- a/packages/react-table/src/demos/examples/TableFilterable.tsx +++ b/packages/react-table/src/demos/examples/TableFilterable.tsx @@ -62,8 +62,8 @@ export const TableFilterable: React.FunctionComponent = () => { setIsCategoryDropdownOpen(!isCategoryDropdownOpen); }; - const onCategorySelect = (event) => { - setCurrentCategory(event.target.innerText); + const onCategorySelect = (event: React.MouseEvent, value: string) => { + setCurrentCategory(value); setIsCategoryDropdownOpen(false); }; From 7483d4ae096278e1dc0e8bfa13b1b24722f564bb Mon Sep 17 00:00:00 2001 From: Jenny <32821331+jenny-s51@users.noreply.github.com> Date: Mon, 6 Nov 2023 14:35:28 -0500 Subject: [PATCH 12/15] fix demos, remove table actions that do not support main purpose of column management demos --- .../demos/examples/TableColumnManagement.tsx | 12 +++--- .../TableColumnManagementWithDraggable.tsx | 43 +------------------ 2 files changed, 7 insertions(+), 48 deletions(-) diff --git a/packages/react-table/src/demos/examples/TableColumnManagement.tsx b/packages/react-table/src/demos/examples/TableColumnManagement.tsx index 6d129e5c36d..518bbef4033 100644 --- a/packages/react-table/src/demos/examples/TableColumnManagement.tsx +++ b/packages/react-table/src/demos/examples/TableColumnManagement.tsx @@ -137,14 +137,14 @@ export const TableColumnManagement: React.FunctionComponent = () => { // Filters columns out of table that are not selected in the column management modal const filterData = (checked: boolean, name: string) => { - const selectedColumn: string = matchSelectedColumnNameToAttr(name); + const selectedColumn = matchSelectedColumnNameToAttr(name); - const filteredRows: any[] = []; + const filteredRows: SampleDataRow[] = []; if (checked) { - const updatedFilters: string[] = filters.filter((item) => item !== selectedColumn); + const updatedFilters = filters.filter((item) => item !== selectedColumn); // Only show the names of columns that were selected in the modal - const filteredColumns: string[] = defaultColumns.filter( + const filteredColumns = defaultColumns.filter( (column) => !updatedFilters.includes(matchSelectedColumnNameToAttr(column)) ); @@ -155,11 +155,11 @@ export const TableColumnManagement: React.FunctionComponent = () => { setFilteredColumns(filteredColumns); setFilteredRows(filteredRows); } else { - const updatedFilters: string[] = [...filters]; + const updatedFilters = filters; updatedFilters.push(selectedColumn); // Only show the names of columns that were selected in the modal - const filteredColumns: string[] = managedColumns.filter( + const filteredColumns = managedColumns.filter( (column) => !filters.includes(matchSelectedColumnNameToAttr(column)) ); diff --git a/packages/react-table/src/demos/examples/TableColumnManagementWithDraggable.tsx b/packages/react-table/src/demos/examples/TableColumnManagementWithDraggable.tsx index e3c8c08cccc..41123b47396 100644 --- a/packages/react-table/src/demos/examples/TableColumnManagementWithDraggable.tsx +++ b/packages/react-table/src/demos/examples/TableColumnManagementWithDraggable.tsx @@ -16,8 +16,6 @@ import { OverflowMenu, OverflowMenuGroup, OverflowMenuItem, - Pagination, - PaginationVariant, Text, TextContent, TextVariants, @@ -321,7 +319,6 @@ export const TableColumnManagementWithDraggable: React.FunctionComponent = () => const [check3, setCheck3] = React.useState(true); const [check4, setCheck4] = React.useState(true); const [check5, setCheck5] = React.useState(true); - const canSelectAll = true; const matchCheckboxNameToColumn = (name: string) => { switch (name) { @@ -424,19 +421,6 @@ export const TableColumnManagementWithDraggable: React.FunctionComponent = () => setCheck5(true); }; - const onSelect = (event: React.FormEvent, isSelected: boolean, rowId: number) => { - let rows; - if (rowId === -1) { - rows = rows.map((oneRow) => { - oneRow.selected = isSelected; - return oneRow; - }); - } else { - rows = [...rows]; - rows[rowId] = { ...rows[rowId], selected: isSelected }; - } - }; - const renderModal = () => ( - - - ); @@ -655,27 +627,14 @@ export const TableColumnManagementWithDraggable: React.FunctionComponent = () => {toolbarItems} } - aria-label="This is a table with checkboxes" - onSelect={onSelect} + aria-label="Column Management with Draggable Table" cells={columns} rows={rows} actions={actions} - canSelectAll={canSelectAll} > - {renderModal()} ); From 50818b76e1fdd462ac1a5e5fd271c95529e7c28f Mon Sep 17 00:00:00 2001 From: Jenny <32821331+jenny-s51@users.noreply.github.com> Date: Thu, 16 Nov 2023 13:45:06 -0500 Subject: [PATCH 13/15] add fix for a11y tests as suggested by Eric --- .../react-core/src/components/Toolbar/ToolbarToggleGroup.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-core/src/components/Toolbar/ToolbarToggleGroup.tsx b/packages/react-core/src/components/Toolbar/ToolbarToggleGroup.tsx index 3a69a25ad7b..05a2f40b1a2 100644 --- a/packages/react-core/src/components/Toolbar/ToolbarToggleGroup.tsx +++ b/packages/react-core/src/components/Toolbar/ToolbarToggleGroup.tsx @@ -149,7 +149,7 @@ class ToolbarToggleGroup extends React.Component { aria-label="Show Filters" {...(_isExpanded && { 'aria-expanded': true })} aria-haspopup={_isExpanded && this.isContentPopup()} - aria-controls={expandableContentId} + aria-controls={_isExpanded ? expandableContentId : undefined} ref={this.toggleRef} > {toggleIcon} From e553f142b811a514a9669a59547ee41857129f6c Mon Sep 17 00:00:00 2001 From: Jenny <32821331+jenny-s51@users.noreply.github.com> Date: Thu, 16 Nov 2023 14:32:56 -0500 Subject: [PATCH 14/15] update toolbar snap --- .../Toolbar/__tests__/__snapshots__/Toolbar.test.tsx.snap | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/react-core/src/components/Toolbar/__tests__/__snapshots__/Toolbar.test.tsx.snap b/packages/react-core/src/components/Toolbar/__tests__/__snapshots__/Toolbar.test.tsx.snap index 13b971baed6..c5bdf52faec 100644 --- a/packages/react-core/src/components/Toolbar/__tests__/__snapshots__/Toolbar.test.tsx.snap +++ b/packages/react-core/src/components/Toolbar/__tests__/__snapshots__/Toolbar.test.tsx.snap @@ -69,7 +69,6 @@ exports[`Toolbar should render with custom chip content 1`] = ` class="pf-v5-c-toolbar__toggle" >