From 510d56b2455cd1d3d1082a73303dcc148d01d585 Mon Sep 17 00:00:00 2001 From: Keith Grant Date: Thu, 16 May 2019 21:37:12 -0400 Subject: [PATCH 1/2] refactor PaginatedDataList to renderToolbar prop --- .../OrganizationNotifications.test.jsx.snap | 11 +- src/components/AddRole/SelectResourceStep.jsx | 9 +- src/components/Lookup/Lookup.jsx | 5 +- .../PaginatedDataList/PaginatedDataList.jsx | 158 ++++++++---------- .../Organization/OrganizationAccess.jsx | 12 +- .../screens/OrganizationsList.jsx | 34 ++-- 6 files changed, 108 insertions(+), 121 deletions(-) diff --git a/__tests__/pages/Organizations/screens/Organization/__snapshots__/OrganizationNotifications.test.jsx.snap b/__tests__/pages/Organizations/screens/Organization/__snapshots__/OrganizationNotifications.test.jsx.snap index d9dfad9a1d..1a61793f72 100644 --- a/__tests__/pages/Organizations/screens/Organization/__snapshots__/OrganizationNotifications.test.jsx.snap +++ b/__tests__/pages/Organizations/screens/Organization/__snapshots__/OrganizationNotifications.test.jsx.snap @@ -176,11 +176,8 @@ exports[` initially renders succesfully 1`] = ` > initially renders succesfully 1`] = ` "url": "", } } - onSelectAll={null} qsConfig={ Object { "defaultParams": Object { @@ -232,8 +228,8 @@ exports[` initially renders succesfully 1`] = ` } } renderItem={[Function]} + renderToolbar={[Function]} showPageSizeOptions={true} - showSelectAll={false} toolbarColumns={ Array [ Object { @@ -257,7 +253,6 @@ exports[` initially renders succesfully 1`] = ` } > initially renders succesfully 1`] = ` }, ] } - isAllSelected={false} - noLeftMargin={false} onSearch={[Function]} - onSelectAll={null} onSort={[Function]} - showSelectAll={false} sortOrder="ascending" sortedColumnKey="name" > diff --git a/src/components/AddRole/SelectResourceStep.jsx b/src/components/AddRole/SelectResourceStep.jsx index 4f2668edce..4b9fe95ac6 100644 --- a/src/components/AddRole/SelectResourceStep.jsx +++ b/src/components/AddRole/SelectResourceStep.jsx @@ -4,6 +4,7 @@ import { withRouter } from 'react-router-dom'; import { withI18n } from '@lingui/react'; import { t } from '@lingui/macro'; import PaginatedDataList from '../PaginatedDataList'; +import DataListToolbar from '../DataListToolbar'; import CheckboxListItem from '../ListItem'; import SelectedList from '../SelectedList'; import { getQSConfig, parseNamespacedQueryString } from '../../util/qs'; @@ -102,9 +103,7 @@ class SelectResourceStep extends React.Component { itemCount={count} itemName={itemName} qsConfig={this.qsConfig} - toolbarColumns={ - columns - } + toolbarColumns={columns} renderItem={item => ( i.id === item.id)} @@ -114,7 +113,9 @@ class SelectResourceStep extends React.Component { onSelect={() => onRowClick(item)} /> )} - alignToolbarLeft + renderToolbar={(props) => ( + + )} showPageSizeOptions={false} /> diff --git a/src/components/Lookup/Lookup.jsx b/src/components/Lookup/Lookup.jsx index 64f59367a0..4df08cef8f 100644 --- a/src/components/Lookup/Lookup.jsx +++ b/src/components/Lookup/Lookup.jsx @@ -14,6 +14,7 @@ import { t } from '@lingui/macro'; import { withNetwork } from '../../contexts/Network'; import PaginatedDataList from '../PaginatedDataList'; +import DataListToolbar from '../DataListToolbar'; import CheckboxListItem from '../ListItem'; import SelectedList from '../SelectedList'; import { getQSConfig, parseNamespacedQueryString } from '../../util/qs'; @@ -176,7 +177,9 @@ class Lookup extends React.Component { onSelect={() => this.toggleSelected(item)} /> )} - alignToolbarLeft + renderToolbar={(props) => ( + + )} showPageSizeOptions={false} /> {lookupSelectedItems.length > 0 && ( diff --git a/src/components/PaginatedDataList/PaginatedDataList.jsx b/src/components/PaginatedDataList/PaginatedDataList.jsx index beb49253e0..ef517c8f43 100644 --- a/src/components/PaginatedDataList/PaginatedDataList.jsx +++ b/src/components/PaginatedDataList/PaginatedDataList.jsx @@ -1,5 +1,5 @@ import React, { Fragment } from 'react'; -import PropTypes, { arrayOf, shape, string, bool, node } from 'prop-types'; +import PropTypes, { arrayOf, shape, string, bool } from 'prop-types'; import { DataList, DataListItem, @@ -108,16 +108,12 @@ class PaginatedDataList extends React.Component { qsConfig, renderItem, toolbarColumns, - additionalControls, itemName, itemNamePlural, - showSelectAll, - isAllSelected, - onSelectAll, - alignToolbarLeft, showPageSizeOptions, location, - i18n + i18n, + renderToolbar, } = this.props; const { error } = this.state; const [orderBy, sortOrder] = this.getSortOrder(); @@ -133,78 +129,70 @@ class PaginatedDataList extends React.Component { )} // TODO: replace with proper error handling )} - {items.length === 0 - ? ( - - - {emptyStateControls} - -
- - - - {i18n._(t`No ${ucFirst(itemNamePlural || pluralize(itemName))} Found `)} - - - {i18n._(t`Please add ${ucFirst(itemNamePlural || pluralize(itemName))} to populate this list `)} - - - - ) - : ( - - { }} - onSort={this.handleSort} - showSelectAll={showSelectAll} - isAllSelected={isAllSelected} - onSelectAll={onSelectAll} - additionalControls={additionalControls} - noLeftMargin={alignToolbarLeft} - - /> - - {items.map(item => (renderItem ? renderItem(item) : ( - - - - - - - {item.name} - - - - - ]} - /> - - - )))} - - - - )} + {items.length === 0 ? ( + + + {emptyStateControls} + +
+ + + + {i18n._(t`No ${ucFirst(itemNamePlural || pluralize(itemName))} Found `)} + + + {i18n._(t`Please add ${ucFirst(itemNamePlural || pluralize(itemName))} to populate this list `)} + + + + ) : ( + + {renderToolbar({ + sortedColumnKey: orderBy, + sortOrder, + columns, + onSearch: () => { }, + onSort: this.handleSort, + })} + + {items.map(item => (renderItem ? renderItem(item) : ( + + + + + + + {item.name} + + + + + ]} + /> + + + )))} + + + + )} ); } @@ -228,25 +216,17 @@ PaginatedDataList.propTypes = { key: string.isRequired, isSortable: bool, })), - additionalControls: arrayOf(node), - showSelectAll: PropTypes.bool, - isAllSelected: PropTypes.bool, - onSelectAll: PropTypes.func, - alignToolbarLeft: PropTypes.bool, showPageSizeOptions: PropTypes.bool, + renderToolbar: PropTypes.func, }; PaginatedDataList.defaultProps = { renderItem: null, toolbarColumns: [], - additionalControls: [], itemName: 'item', itemNamePlural: '', - showSelectAll: false, - isAllSelected: false, - onSelectAll: null, - alignToolbarLeft: false, showPageSizeOptions: true, + renderToolbar: ({ ...props }) => (), }; export { PaginatedDataList as _PaginatedDataList }; diff --git a/src/pages/Organizations/screens/Organization/OrganizationAccess.jsx b/src/pages/Organizations/screens/Organization/OrganizationAccess.jsx index 2d974e5424..d4465b3a99 100644 --- a/src/pages/Organizations/screens/Organization/OrganizationAccess.jsx +++ b/src/pages/Organizations/screens/Organization/OrganizationAccess.jsx @@ -3,6 +3,7 @@ import { withRouter } from 'react-router-dom'; import { withI18n } from '@lingui/react'; import { t } from '@lingui/macro'; import PaginatedDataList, { ToolbarAddButton } from '../../../../components/PaginatedDataList'; +import DataListToolbar from '../../../../components/DataListToolbar'; import OrganizationAccessItem from '../../components/OrganizationAccessItem'; import DeleteRoleConfirmationModal from '../../components/DeleteRoleConfirmationModal'; import AddResourceRole from '../../../../components/AddRole/AddResourceRole'; @@ -172,9 +173,14 @@ class OrganizationAccess extends React.Component { { name: i18n._(t`Username`), key: 'username', isSortable: true }, { name: i18n._(t`Last Name`), key: 'last_name', isSortable: true }, ]} - additionalControls={canEdit ? [ - - ] : null} + renderToolbar={(props) => ( + + ] : null} + /> + )} renderItem={accessRecord => ( , - canAdd - ? - : null, - ]} + renderToolbar={(props) => ( + , + canAdd + ? + : null, + ]} + /> + )} renderItem={(o) => ( Date: Thu, 16 May 2019 21:51:43 -0400 Subject: [PATCH 2/2] extract out PaginatedDataListItem --- .../PaginatedDataList/PaginatedDataList.jsx | 48 ++----------------- .../PaginatedDataListItem.jsx | 42 ++++++++++++++++ src/components/PaginatedDataList/index.js | 1 + 3 files changed, 47 insertions(+), 44 deletions(-) create mode 100644 src/components/PaginatedDataList/PaginatedDataListItem.jsx diff --git a/src/components/PaginatedDataList/PaginatedDataList.jsx b/src/components/PaginatedDataList/PaginatedDataList.jsx index ef517c8f43..8c82774e65 100644 --- a/src/components/PaginatedDataList/PaginatedDataList.jsx +++ b/src/components/PaginatedDataList/PaginatedDataList.jsx @@ -2,11 +2,6 @@ import React, { Fragment } from 'react'; import PropTypes, { arrayOf, shape, string, bool } from 'prop-types'; import { DataList, - DataListItem, - DataListItemRow, - DataListItemCells, - DataListCell, - TextContent, Title, EmptyState, EmptyStateIcon, @@ -15,11 +10,12 @@ import { import { CubesIcon } from '@patternfly/react-icons'; import { withI18n } from '@lingui/react'; import { t } from '@lingui/macro'; -import { withRouter, Link } from 'react-router-dom'; +import { withRouter } from 'react-router-dom'; import styled from 'styled-components'; import Pagination from '../Pagination'; import DataListToolbar from '../DataListToolbar'; +import PaginatedDataListItem from './PaginatedDataListItem'; import { parseNamespacedQueryString, updateNamespacedQueryString, @@ -38,13 +34,6 @@ const EmptyStateControlsWrapper = styled.div` margin-left: 20px; } `; - -const ListItemGrid = styled(TextContent)` - display: grid; - grid-template-columns: minmax(70px,max-content) repeat(auto-fit, minmax(60px,max-content)); - grid-gap: 10px; -`; - class PaginatedDataList extends React.Component { constructor (props) { super(props); @@ -58,12 +47,6 @@ class PaginatedDataList extends React.Component { this.handleSort = this.handleSort.bind(this); } - getPageCount () { - const { itemCount, qsConfig, location } = this.props; - const queryParams = parseNamespacedQueryString(qsConfig, location.search); - return Math.ceil(itemCount / queryParams.page_size); - } - getSortOrder () { const { qsConfig, location } = this.props; const queryParams = parseNamespacedQueryString(qsConfig, location.search); @@ -95,11 +78,6 @@ class PaginatedDataList extends React.Component { history.push(`${pathname}?${qs}`); } - getPluralItemName () { - const { itemName, itemNamePlural } = this.props; - return itemNamePlural || `${itemName}s`; - } - render () { const { emptyStateControls, @@ -156,25 +134,7 @@ class PaginatedDataList extends React.Component { })} {items.map(item => (renderItem ? renderItem(item) : ( - - - - - - - {item.name} - - - - - ]} - /> - - + )))} (), + renderToolbar: (props) => (), }; export { PaginatedDataList as _PaginatedDataList }; diff --git a/src/components/PaginatedDataList/PaginatedDataListItem.jsx b/src/components/PaginatedDataList/PaginatedDataListItem.jsx new file mode 100644 index 0000000000..f0133a47e3 --- /dev/null +++ b/src/components/PaginatedDataList/PaginatedDataListItem.jsx @@ -0,0 +1,42 @@ +import React from 'react'; +import { Link } from 'react-router-dom'; +import { + DataListItem, + DataListItemRow, + DataListItemCells, + DataListCell, + TextContent, +} from '@patternfly/react-core'; +import styled from 'styled-components'; + +const DetailWrapper = styled(TextContent)` + display: grid; + grid-template-columns: + minmax(70px, max-content) + repeat(auto-fit, minmax(60px, max-content)); + grid-gap: 10px; +`; + +export default function PaginatedDataListItem ({ item }) { + return ( + + + + + + + {item.name} + + + + + ]} + /> + + + ); +} diff --git a/src/components/PaginatedDataList/index.js b/src/components/PaginatedDataList/index.js index 55cf1e8134..3ec615603d 100644 --- a/src/components/PaginatedDataList/index.js +++ b/src/components/PaginatedDataList/index.js @@ -1,5 +1,6 @@ import PaginatedDataList from './PaginatedDataList'; export default PaginatedDataList; +export { default as PaginatedDataListItem } from './PaginatedDataListItem'; export { default as ToolbarDeleteButton } from './ToolbarDeleteButton'; export { default as ToolbarAddButton } from './ToolbarAddButton';