simplify ActionsTd interface; add ActionItem component

This commit is contained in:
Keith Grant
2020-12-03 15:28:33 -08:00
parent a8159273eb
commit 6a47899dbb
6 changed files with 72 additions and 45 deletions

View File

@@ -159,7 +159,7 @@ DataListToolbar.propTypes = {
searchColumns: SearchColumns.isRequired, searchColumns: SearchColumns.isRequired,
searchableKeys: PropTypes.arrayOf(PropTypes.string), searchableKeys: PropTypes.arrayOf(PropTypes.string),
relatedSearchableKeys: PropTypes.arrayOf(PropTypes.string), relatedSearchableKeys: PropTypes.arrayOf(PropTypes.string),
sortColumns: SortColumns.isRequired, sortColumns: SortColumns,
showSelectAll: PropTypes.bool, showSelectAll: PropTypes.bool,
isAllSelected: PropTypes.bool, isAllSelected: PropTypes.bool,
isCompact: PropTypes.bool, isCompact: PropTypes.bool,
@@ -176,6 +176,7 @@ DataListToolbar.defaultProps = {
itemCount: 0, itemCount: 0,
searchableKeys: [], searchableKeys: [],
relatedSearchableKeys: [], relatedSearchableKeys: [],
sortColumns: null,
clearAllFilters: null, clearAllFilters: null,
showSelectAll: false, showSelectAll: false,
isAllSelected: false, isAllSelected: false,

View File

@@ -0,0 +1,21 @@
import 'styled-components/macro';
import React from 'react';
import { Tooltip } from '@patternfly/react-core';
export default function ActionItem({ column, tooltip, visible, children }) {
if (!visible) {
return null;
}
return (
<div
css={`
grid-column: ${column};
`}
>
<Tooltip content={tooltip} position="top">
{children}
</Tooltip>
</div>
);
}

View File

@@ -3,8 +3,6 @@ import React from 'react';
import { Td } from '@patternfly/react-table'; import { Td } from '@patternfly/react-table';
import styled, { css } from 'styled-components'; import styled, { css } from 'styled-components';
// table cells will automatically grow beyond specified width to accomodate
// multiple action buttons
const ActionsGrid = styled.div` const ActionsGrid = styled.div`
display: grid; display: grid;
grid-gap: 16px; grid-gap: 16px;
@@ -18,7 +16,8 @@ const ActionsGrid = styled.div`
}} }}
`; `;
export default function ActionsTd({ numActions = 1, children }) { export default function ActionsTd({ children }) {
const numActions = children.length;
const width = numActions * 40; const width = numActions * 40;
return ( return (
<Td <Td
@@ -27,7 +26,13 @@ export default function ActionsTd({ numActions = 1, children }) {
--pf-c-table--cell--Width: ${width}px; --pf-c-table--cell--Width: ${width}px;
`} `}
> >
<ActionsGrid numActions={numActions}>{children}</ActionsGrid> <ActionsGrid numActions={numActions}>
{React.Children.map(children, (child, i) =>
React.cloneElement(child, {
column: i + 1,
})
)}
</ActionsGrid>
</Td> </Td>
); );
} }

View File

@@ -2,5 +2,4 @@ export { default } from './PaginatedTable';
export { default as PaginatedTableRow } from './PaginatedTableRow'; export { default as PaginatedTableRow } from './PaginatedTableRow';
export { default as ActionsTd } from './ActionsTd'; export { default as ActionsTd } from './ActionsTd';
export { default as HeaderRow, HeaderCell } from './HeaderRow'; export { default as HeaderRow, HeaderCell } from './HeaderRow';
// export { default as ToolbarDeleteButton } from './ToolbarDeleteButton'; export { default as ActionItem } from './ActionItem';
// export { default as ToolbarAddButton } from './ToolbarAddButton';

View File

@@ -1,7 +1,7 @@
import React, { useState, useCallback } from 'react'; import React, { useState, useCallback } from 'react';
import { string, bool, func } from 'prop-types'; import { string, bool, func } from 'prop-types';
import { withI18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { Button, Label, Tooltip } from '@patternfly/react-core'; import { Button, Label } from '@patternfly/react-core';
import { Tr, Td } from '@patternfly/react-table'; import { Tr, Td } from '@patternfly/react-table';
import { PencilAltIcon } from '@patternfly/react-icons'; import { PencilAltIcon } from '@patternfly/react-icons';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
@@ -9,7 +9,7 @@ import { Link } from 'react-router-dom';
import { timeOfDay } from '../../../util/dates'; import { timeOfDay } from '../../../util/dates';
import { InventoriesAPI } from '../../../api'; import { InventoriesAPI } from '../../../api';
import { Inventory } from '../../../types'; import { Inventory } from '../../../types';
import { ActionsTd } from '../../../components/PaginatedTable'; import { ActionsTd, ActionItem } from '../../../components/PaginatedTable';
import CopyButton from '../../../components/CopyButton'; import CopyButton from '../../../components/CopyButton';
import SyncStatusIndicator from '../../../components/SyncStatusIndicator'; import SyncStatusIndicator from '../../../components/SyncStatusIndicator';
@@ -98,25 +98,27 @@ function InventoryListItem({
<Label color="red">{i18n._(t`Pending delete`)}</Label> <Label color="red">{i18n._(t`Pending delete`)}</Label>
</Td> </Td>
) : ( ) : (
<ActionsTd numActions={2}> <ActionsTd>
{inventory.summary_fields.user_capabilities.edit ? ( <ActionItem
<Tooltip content={i18n._(t`Edit Inventory`)} position="top"> visible={inventory.summary_fields.user_capabilities.edit}
<Button tooltip={i18n._(t`Edit Inventory`)}
isDisabled={isDisabled} >
aria-label={i18n._(t`Edit Inventory`)} <Button
variant="plain" isDisabled={isDisabled}
component={Link} aria-label={i18n._(t`Edit Inventory`)}
to={`/inventories/${ variant="plain"
inventory.kind === 'smart' ? 'smart_inventory' : 'inventory' component={Link}
}/${inventory.id}/edit`} to={`/inventories/${
> inventory.kind === 'smart' ? 'smart_inventory' : 'inventory'
<PencilAltIcon /> }/${inventory.id}/edit`}
</Button> >
</Tooltip> <PencilAltIcon />
) : ( </Button>
<div /> </ActionItem>
)} <ActionItem
{inventory.summary_fields.user_capabilities.copy && ( visible={inventory.summary_fields.user_capabilities.copy}
tooltip={i18n._(t`Copy Inventory`)}
>
<CopyButton <CopyButton
copyItem={copyInventory} copyItem={copyInventory}
isDisabled={isDisabled} isDisabled={isDisabled}
@@ -127,7 +129,7 @@ function InventoryListItem({
errorMessage: i18n._(t`Failed to copy inventory.`), errorMessage: i18n._(t`Failed to copy inventory.`),
}} }}
/> />
)} </ActionItem>
</ActionsTd> </ActionsTd>
)} )}
</Tr> </Tr>

View File

@@ -6,7 +6,7 @@ import { Button, Tooltip } from '@patternfly/react-core';
import { Tr, Td } from '@patternfly/react-table'; import { Tr, Td } from '@patternfly/react-table';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { PencilAltIcon } from '@patternfly/react-icons'; import { PencilAltIcon } from '@patternfly/react-icons';
import { ActionsTd } from '../../../components/PaginatedTable'; import { ActionsTd, ActionItem } from '../../../components/PaginatedTable';
import { Organization } from '../../../types'; import { Organization } from '../../../types';
@@ -36,21 +36,20 @@ function OrganizationListItem({
</Td> </Td>
<Td>{organization.summary_fields.related_field_counts.users}</Td> <Td>{organization.summary_fields.related_field_counts.users}</Td>
<Td>{organization.summary_fields.related_field_counts.teams}</Td> <Td>{organization.summary_fields.related_field_counts.teams}</Td>
<ActionsTd numActions={1}> <ActionsTd>
{organization.summary_fields.user_capabilities.edit ? ( <ActionItem
<Tooltip content={i18n._(t`Edit Organization`)} position="top"> visible={organization.summary_fields.user_capabilities.edit}
<Button tooltip={i18n._(t`Edit Organization`)}
aria-label={i18n._(t`Edit Organization`)} >
variant="plain" <Button
component={Link} aria-label={i18n._(t`Edit Organization`)}
to={`/organizations/${organization.id}/edit`} variant="plain"
> component={Link}
<PencilAltIcon /> to={`/organizations/${organization.id}/edit`}
</Button> >
</Tooltip> <PencilAltIcon />
) : ( </Button>
'' </ActionItem>
)}
</ActionsTd> </ActionsTd>
</Tr> </Tr>
); );