mirror of
https://github.com/ansible/awx.git
synced 2026-02-02 01:58:09 -03:30
Refactor of DataListToolbar. Creates a number of smaller components used by the toolbar. Adds support for passing in an add button node to the toolbar.
This commit is contained in:
@@ -1,29 +1,18 @@
|
||||
import React from 'react';
|
||||
import React, { Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { I18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
Dropdown,
|
||||
DropdownPosition,
|
||||
DropdownToggle,
|
||||
DropdownItem,
|
||||
Level,
|
||||
LevelItem,
|
||||
TextInput,
|
||||
Toolbar,
|
||||
ToolbarGroup,
|
||||
ToolbarItem,
|
||||
Tooltip,
|
||||
} from '@patternfly/react-core';
|
||||
import {
|
||||
BarsIcon,
|
||||
EqualsIcon,
|
||||
SortAlphaDownIcon,
|
||||
SortAlphaUpIcon,
|
||||
SortNumericDownIcon,
|
||||
SortNumericUpIcon,
|
||||
TrashAltIcon,
|
||||
PlusIcon,
|
||||
} from '@patternfly/react-icons';
|
||||
@@ -31,97 +20,13 @@ import {
|
||||
Link
|
||||
} from 'react-router-dom';
|
||||
|
||||
import ExpandCollapse from '../ExpandCollapse';
|
||||
import Search from '../Search';
|
||||
import Sort from '../Sort';
|
||||
import VerticalSeparator from '../VerticalSeparator';
|
||||
|
||||
const flexGrowStyling = {
|
||||
flexGrow: '1'
|
||||
};
|
||||
|
||||
const ToolbarActiveStyle = {
|
||||
backgroundColor: '#007bba',
|
||||
color: 'white',
|
||||
padding: '0 5px',
|
||||
};
|
||||
|
||||
class DataListToolbar extends React.Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
|
||||
const { sortedColumnKey } = this.props;
|
||||
this.state = {
|
||||
isSearchDropdownOpen: false,
|
||||
isSortDropdownOpen: false,
|
||||
searchKey: sortedColumnKey,
|
||||
searchValue: '',
|
||||
};
|
||||
|
||||
this.handleSearchInputChange = this.handleSearchInputChange.bind(this);
|
||||
this.onSortDropdownToggle = this.onSortDropdownToggle.bind(this);
|
||||
this.onSortDropdownSelect = this.onSortDropdownSelect.bind(this);
|
||||
this.onSearchDropdownToggle = this.onSearchDropdownToggle.bind(this);
|
||||
this.onSearchDropdownSelect = this.onSearchDropdownSelect.bind(this);
|
||||
this.onSearch = this.onSearch.bind(this);
|
||||
this.onSort = this.onSort.bind(this);
|
||||
this.onExpand = this.onExpand.bind(this);
|
||||
this.onCompact = this.onCompact.bind(this);
|
||||
}
|
||||
|
||||
onExpand () {
|
||||
const { onExpand } = this.props;
|
||||
onExpand();
|
||||
}
|
||||
|
||||
onCompact () {
|
||||
const { onCompact } = this.props;
|
||||
onCompact();
|
||||
}
|
||||
|
||||
onSortDropdownToggle (isSortDropdownOpen) {
|
||||
this.setState({ isSortDropdownOpen });
|
||||
}
|
||||
|
||||
onSortDropdownSelect ({ target }) {
|
||||
const { columns, onSort, sortOrder } = this.props;
|
||||
const { innerText } = target;
|
||||
|
||||
const [{ key: searchKey }] = columns.filter(({ name }) => name === innerText);
|
||||
|
||||
this.setState({ isSortDropdownOpen: false });
|
||||
onSort(searchKey, sortOrder);
|
||||
}
|
||||
|
||||
onSearchDropdownToggle (isSearchDropdownOpen) {
|
||||
this.setState({ isSearchDropdownOpen });
|
||||
}
|
||||
|
||||
onSearchDropdownSelect ({ target }) {
|
||||
const { columns } = this.props;
|
||||
const { innerText } = target;
|
||||
|
||||
const [{ key: searchKey }] = columns.filter(({ name }) => name === innerText);
|
||||
this.setState({ isSearchDropdownOpen: false, searchKey });
|
||||
}
|
||||
|
||||
onSearch () {
|
||||
const { searchValue } = this.state;
|
||||
const { onSearch } = this.props;
|
||||
|
||||
onSearch(searchValue);
|
||||
}
|
||||
|
||||
onSort () {
|
||||
const { onSort, sortedColumnKey, sortOrder } = this.props;
|
||||
const newSortOrder = sortOrder === 'ascending' ? 'descending' : 'ascending';
|
||||
|
||||
onSort(sortedColumnKey, newSortOrder);
|
||||
}
|
||||
|
||||
handleSearchInputChange (searchValue) {
|
||||
this.setState({ searchValue });
|
||||
}
|
||||
|
||||
render () {
|
||||
const { up } = DropdownPosition;
|
||||
const {
|
||||
columns,
|
||||
isAllSelected,
|
||||
@@ -129,45 +34,18 @@ class DataListToolbar extends React.Component {
|
||||
sortedColumnKey,
|
||||
sortOrder,
|
||||
addUrl,
|
||||
showExpandCollapse,
|
||||
showDelete,
|
||||
showSelectAll,
|
||||
isLookup,
|
||||
isCompact,
|
||||
onSort,
|
||||
onSearch,
|
||||
onCompact,
|
||||
onExpand,
|
||||
add
|
||||
} = this.props;
|
||||
const {
|
||||
isSearchDropdownOpen,
|
||||
isSortDropdownOpen,
|
||||
searchKey,
|
||||
searchValue,
|
||||
} = this.state;
|
||||
|
||||
const [{ name: searchColumnName }] = columns.filter(({ key }) => key === searchKey);
|
||||
const [{ name: sortedColumnName, isNumeric }] = columns
|
||||
.filter(({ key }) => key === sortedColumnKey);
|
||||
|
||||
const searchDropdownItems = columns
|
||||
.filter(({ key }) => key !== searchKey)
|
||||
.map(({ key, name }) => (
|
||||
<DropdownItem key={key} component="button">
|
||||
{name}
|
||||
</DropdownItem>
|
||||
));
|
||||
|
||||
const sortDropdownItems = columns
|
||||
.filter(({ key, isSortable }) => isSortable && key !== sortedColumnKey)
|
||||
.map(({ key, name }) => (
|
||||
<DropdownItem key={key} component="button">
|
||||
{name}
|
||||
</DropdownItem>
|
||||
));
|
||||
|
||||
let SortIcon;
|
||||
if (isNumeric) {
|
||||
SortIcon = sortOrder === 'ascending' ? SortNumericUpIcon : SortNumericDownIcon;
|
||||
} else {
|
||||
SortIcon = sortOrder === 'ascending' ? SortAlphaUpIcon : SortAlphaDownIcon;
|
||||
}
|
||||
const showExpandCollapse = (onCompact && onExpand);
|
||||
|
||||
return (
|
||||
<I18n>
|
||||
@@ -189,102 +67,44 @@ class DataListToolbar extends React.Component {
|
||||
<VerticalSeparator />
|
||||
</ToolbarGroup>
|
||||
)}
|
||||
<ToolbarGroup style={flexGrowStyling}>
|
||||
<ToolbarItem style={flexGrowStyling}>
|
||||
<div className="pf-c-input-group">
|
||||
<Dropdown
|
||||
className="searchKeyDropdown"
|
||||
onToggle={this.onSearchDropdownToggle}
|
||||
onSelect={this.onSearchDropdownSelect}
|
||||
direction={up}
|
||||
isOpen={isSearchDropdownOpen}
|
||||
toggle={(
|
||||
<DropdownToggle
|
||||
onToggle={this.onSearchDropdownToggle}
|
||||
>
|
||||
{searchColumnName}
|
||||
</DropdownToggle>
|
||||
)}
|
||||
dropdownItems={searchDropdownItems}
|
||||
/>
|
||||
<TextInput
|
||||
type="search"
|
||||
aria-label={i18n._(t`Search text input`)}
|
||||
value={searchValue}
|
||||
onChange={this.handleSearchInputChange}
|
||||
style={{ height: '30px' }}
|
||||
/>
|
||||
<Button
|
||||
variant="tertiary"
|
||||
aria-label={i18n._(t`Search`)}
|
||||
onClick={this.onSearch}
|
||||
>
|
||||
<i className="fas fa-search" aria-hidden="true" />
|
||||
</Button>
|
||||
</div>
|
||||
<ToolbarGroup style={{ flexGrow: '1' }}>
|
||||
<ToolbarItem style={{ flexGrow: '1' }}>
|
||||
<Search
|
||||
columns={columns}
|
||||
onSearch={onSearch}
|
||||
sortedColumnKey={sortedColumnKey}
|
||||
/>
|
||||
</ToolbarItem>
|
||||
<VerticalSeparator />
|
||||
</ToolbarGroup>
|
||||
<ToolbarGroup
|
||||
className="sortDropdownGroup"
|
||||
>
|
||||
{ sortDropdownItems.length > 1 && (
|
||||
<ToolbarItem>
|
||||
<Dropdown
|
||||
onToggle={this.onSortDropdownToggle}
|
||||
onSelect={this.onSortDropdownSelect}
|
||||
direction={up}
|
||||
isOpen={isSortDropdownOpen}
|
||||
toggle={(
|
||||
<DropdownToggle
|
||||
onToggle={this.onSortDropdownToggle}
|
||||
>
|
||||
{sortedColumnName}
|
||||
</DropdownToggle>
|
||||
)}
|
||||
dropdownItems={sortDropdownItems}
|
||||
/>
|
||||
</ToolbarItem>
|
||||
)}
|
||||
<ToolbarItem>
|
||||
<Button
|
||||
onClick={this.onSort}
|
||||
variant="plain"
|
||||
aria-label={i18n._(t`Sort`)}
|
||||
>
|
||||
<SortIcon />
|
||||
</Button>
|
||||
<Sort
|
||||
columns={columns}
|
||||
onSort={onSort}
|
||||
sortOrder={sortOrder}
|
||||
sortedColumnKey={sortedColumnKey}
|
||||
/>
|
||||
</ToolbarItem>
|
||||
{ (showExpandCollapse || showDelete || addUrl) && (
|
||||
<VerticalSeparator />
|
||||
)}
|
||||
</ToolbarGroup>
|
||||
{ (showExpandCollapse || showDelete || addUrl || add) && (
|
||||
<VerticalSeparator />
|
||||
)}
|
||||
{showExpandCollapse && (
|
||||
<ToolbarGroup>
|
||||
<ToolbarItem>
|
||||
<Button
|
||||
variant="plain"
|
||||
aria-label={i18n._(t`Collapse`)}
|
||||
onClick={this.onCompact}
|
||||
style={isCompact ? ToolbarActiveStyle : null}
|
||||
>
|
||||
<BarsIcon />
|
||||
</Button>
|
||||
</ToolbarItem>
|
||||
<ToolbarItem>
|
||||
<Button
|
||||
variant="plain"
|
||||
aria-label={i18n._(t`Expand`)}
|
||||
onClick={this.onExpand}
|
||||
style={!isCompact ? ToolbarActiveStyle : null}
|
||||
>
|
||||
<EqualsIcon />
|
||||
</Button>
|
||||
</ToolbarItem>
|
||||
{ (showDelete || addUrl) && (
|
||||
<Fragment>
|
||||
<ToolbarGroup>
|
||||
<ExpandCollapse
|
||||
isCompact={isCompact}
|
||||
onCompact={onCompact}
|
||||
onExpand={onExpand}
|
||||
/>
|
||||
</ToolbarGroup>
|
||||
{ (showDelete || addUrl || add) && (
|
||||
<VerticalSeparator />
|
||||
)}
|
||||
</ToolbarGroup>
|
||||
</Fragment>
|
||||
)}
|
||||
</Toolbar>
|
||||
</LevelItem>
|
||||
@@ -312,6 +132,9 @@ class DataListToolbar extends React.Component {
|
||||
</Button>
|
||||
</Link>
|
||||
)}
|
||||
{add && (
|
||||
<Fragment>{add}</Fragment>
|
||||
)}
|
||||
</LevelItem>
|
||||
</Level>
|
||||
</div>
|
||||
@@ -329,10 +152,13 @@ DataListToolbar.propTypes = {
|
||||
onSelectAll: PropTypes.func,
|
||||
onSort: PropTypes.func,
|
||||
showDelete: PropTypes.bool,
|
||||
showExpandCollapse: PropTypes.bool,
|
||||
showSelectAll: PropTypes.bool,
|
||||
sortOrder: PropTypes.string,
|
||||
sortedColumnKey: PropTypes.string,
|
||||
onCompact: PropTypes.func,
|
||||
onExpand: PropTypes.func,
|
||||
isCompact: PropTypes.bool,
|
||||
add: PropTypes.node
|
||||
};
|
||||
|
||||
DataListToolbar.defaultProps = {
|
||||
@@ -341,11 +167,14 @@ DataListToolbar.defaultProps = {
|
||||
onSelectAll: null,
|
||||
onSort: null,
|
||||
showDelete: false,
|
||||
showExpandCollapse: false,
|
||||
showSelectAll: false,
|
||||
sortOrder: 'ascending',
|
||||
sortedColumnKey: 'name',
|
||||
isAllSelected: false,
|
||||
onCompact: null,
|
||||
onExpand: null,
|
||||
isCompact: false,
|
||||
add: null
|
||||
};
|
||||
|
||||
export default DataListToolbar;
|
||||
|
||||
67
src/components/ExpandCollapse/ExpandCollapse.jsx
Normal file
67
src/components/ExpandCollapse/ExpandCollapse.jsx
Normal file
@@ -0,0 +1,67 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { I18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
Button,
|
||||
ToolbarItem
|
||||
} from '@patternfly/react-core';
|
||||
import {
|
||||
BarsIcon,
|
||||
EqualsIcon,
|
||||
} from '@patternfly/react-icons';
|
||||
|
||||
const ToolbarActiveStyle = {
|
||||
backgroundColor: '#007bba',
|
||||
color: 'white',
|
||||
padding: '0 5px',
|
||||
};
|
||||
|
||||
class ExpandCollapse extends React.Component {
|
||||
render () {
|
||||
const {
|
||||
onCompact,
|
||||
onExpand,
|
||||
isCompact
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<Fragment>
|
||||
<ToolbarItem>
|
||||
<Button
|
||||
variant="plain"
|
||||
aria-label={i18n._(t`Collapse`)}
|
||||
onClick={onCompact}
|
||||
style={isCompact ? ToolbarActiveStyle : null}
|
||||
>
|
||||
<BarsIcon />
|
||||
</Button>
|
||||
</ToolbarItem>
|
||||
<ToolbarItem>
|
||||
<Button
|
||||
variant="plain"
|
||||
aria-label={i18n._(t`Expand`)}
|
||||
onClick={onExpand}
|
||||
style={!isCompact ? ToolbarActiveStyle : null}
|
||||
>
|
||||
<EqualsIcon />
|
||||
</Button>
|
||||
</ToolbarItem>
|
||||
</Fragment>
|
||||
)}
|
||||
</I18n>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ExpandCollapse.propTypes = {
|
||||
onCompact: PropTypes.func.isRequired,
|
||||
onExpand: PropTypes.func.isRequired,
|
||||
isCompact: PropTypes.bool.isRequired
|
||||
};
|
||||
|
||||
ExpandCollapse.defaultProps = {};
|
||||
|
||||
export default ExpandCollapse;
|
||||
3
src/components/ExpandCollapse/index.js
Normal file
3
src/components/ExpandCollapse/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import ExpandCollapse from './ExpandCollapse';
|
||||
|
||||
export default ExpandCollapse;
|
||||
126
src/components/Search/Search.jsx
Normal file
126
src/components/Search/Search.jsx
Normal file
@@ -0,0 +1,126 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { I18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
Button,
|
||||
Dropdown,
|
||||
DropdownPosition,
|
||||
DropdownToggle,
|
||||
DropdownItem,
|
||||
TextInput
|
||||
} from '@patternfly/react-core';
|
||||
|
||||
class Search extends React.Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
|
||||
const { sortedColumnKey } = this.props;
|
||||
this.state = {
|
||||
isSearchDropdownOpen: false,
|
||||
searchKey: sortedColumnKey,
|
||||
searchValue: '',
|
||||
};
|
||||
|
||||
this.handleSearchInputChange = this.handleSearchInputChange.bind(this);
|
||||
this.onSearchDropdownToggle = this.onSearchDropdownToggle.bind(this);
|
||||
this.onSearchDropdownSelect = this.onSearchDropdownSelect.bind(this);
|
||||
this.onSearch = this.onSearch.bind(this);
|
||||
}
|
||||
|
||||
onSearchDropdownToggle (isSearchDropdownOpen) {
|
||||
this.setState({ isSearchDropdownOpen });
|
||||
}
|
||||
|
||||
onSearchDropdownSelect ({ target }) {
|
||||
const { columns } = this.props;
|
||||
const { innerText } = target;
|
||||
|
||||
const [{ key: searchKey }] = columns.filter(({ name }) => name === innerText);
|
||||
this.setState({ isSearchDropdownOpen: false, searchKey });
|
||||
}
|
||||
|
||||
onSearch () {
|
||||
const { searchValue } = this.state;
|
||||
const { onSearch } = this.props;
|
||||
|
||||
onSearch(searchValue);
|
||||
}
|
||||
|
||||
handleSearchInputChange (searchValue) {
|
||||
this.setState({ searchValue });
|
||||
}
|
||||
|
||||
render () {
|
||||
const { up } = DropdownPosition;
|
||||
const {
|
||||
columns
|
||||
} = this.props;
|
||||
const {
|
||||
isSearchDropdownOpen,
|
||||
searchKey,
|
||||
searchValue,
|
||||
} = this.state;
|
||||
|
||||
const [{ name: searchColumnName }] = columns.filter(({ key }) => key === searchKey);
|
||||
|
||||
const searchDropdownItems = columns
|
||||
.filter(({ key }) => key !== searchKey)
|
||||
.map(({ key, name }) => (
|
||||
<DropdownItem key={key} component="button">
|
||||
{name}
|
||||
</DropdownItem>
|
||||
));
|
||||
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<div className="pf-c-input-group">
|
||||
<Dropdown
|
||||
className="searchKeyDropdown"
|
||||
onToggle={this.onSearchDropdownToggle}
|
||||
onSelect={this.onSearchDropdownSelect}
|
||||
direction={up}
|
||||
isOpen={isSearchDropdownOpen}
|
||||
toggle={(
|
||||
<DropdownToggle
|
||||
onToggle={this.onSearchDropdownToggle}
|
||||
>
|
||||
{searchColumnName}
|
||||
</DropdownToggle>
|
||||
)}
|
||||
dropdownItems={searchDropdownItems}
|
||||
/>
|
||||
<TextInput
|
||||
type="search"
|
||||
aria-label="Search text input"
|
||||
value={searchValue}
|
||||
onChange={this.handleSearchInputChange}
|
||||
style={{ height: '30px' }}
|
||||
/>
|
||||
<Button
|
||||
variant="tertiary"
|
||||
aria-label={i18n._(t`Search`)}
|
||||
onClick={this.onSearch}
|
||||
>
|
||||
<i className="fas fa-search" aria-hidden="true" />
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</I18n>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Search.propTypes = {
|
||||
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
onSearch: PropTypes.func,
|
||||
sortedColumnKey: PropTypes.string,
|
||||
};
|
||||
|
||||
Search.defaultProps = {
|
||||
onSearch: null,
|
||||
sortedColumnKey: 'name'
|
||||
};
|
||||
|
||||
export default Search;
|
||||
3
src/components/Search/index.js
Normal file
3
src/components/Search/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import Search from './Search';
|
||||
|
||||
export default Search;
|
||||
130
src/components/Sort/Sort.jsx
Normal file
130
src/components/Sort/Sort.jsx
Normal file
@@ -0,0 +1,130 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { I18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
Button,
|
||||
Dropdown,
|
||||
DropdownPosition,
|
||||
DropdownToggle,
|
||||
DropdownItem
|
||||
} from '@patternfly/react-core';
|
||||
import {
|
||||
SortAlphaDownIcon,
|
||||
SortAlphaUpIcon,
|
||||
SortNumericDownIcon,
|
||||
SortNumericUpIcon
|
||||
} from '@patternfly/react-icons';
|
||||
|
||||
class Sort extends React.Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
isSortDropdownOpen: false,
|
||||
};
|
||||
|
||||
this.onSortDropdownToggle = this.onSortDropdownToggle.bind(this);
|
||||
this.onSortDropdownSelect = this.onSortDropdownSelect.bind(this);
|
||||
this.onSort = this.onSort.bind(this);
|
||||
}
|
||||
|
||||
onSortDropdownToggle (isSortDropdownOpen) {
|
||||
this.setState({ isSortDropdownOpen });
|
||||
}
|
||||
|
||||
onSortDropdownSelect ({ target }) {
|
||||
const { columns, onSort, sortOrder } = this.props;
|
||||
const { innerText } = target;
|
||||
|
||||
const [{ key: searchKey }] = columns.filter(({ name }) => name === innerText);
|
||||
|
||||
this.setState({ isSortDropdownOpen: false });
|
||||
onSort(searchKey, sortOrder);
|
||||
}
|
||||
|
||||
onSort () {
|
||||
const { onSort, sortedColumnKey, sortOrder } = this.props;
|
||||
const newSortOrder = sortOrder === 'ascending' ? 'descending' : 'ascending';
|
||||
|
||||
onSort(sortedColumnKey, newSortOrder);
|
||||
}
|
||||
|
||||
render () {
|
||||
const { up } = DropdownPosition;
|
||||
const {
|
||||
columns,
|
||||
sortedColumnKey,
|
||||
sortOrder
|
||||
} = this.props;
|
||||
const {
|
||||
isSortDropdownOpen
|
||||
} = this.state;
|
||||
|
||||
const [{ name: sortedColumnName, isNumeric }] = columns
|
||||
.filter(({ key }) => key === sortedColumnKey);
|
||||
|
||||
const sortDropdownItems = columns
|
||||
.filter(({ key, isSortable }) => isSortable && key !== sortedColumnKey)
|
||||
.map(({ key, name }) => (
|
||||
<DropdownItem key={key} component="button">
|
||||
{name}
|
||||
</DropdownItem>
|
||||
));
|
||||
|
||||
let SortIcon;
|
||||
if (isNumeric) {
|
||||
SortIcon = sortOrder === 'ascending' ? SortNumericUpIcon : SortNumericDownIcon;
|
||||
} else {
|
||||
SortIcon = sortOrder === 'ascending' ? SortAlphaUpIcon : SortAlphaDownIcon;
|
||||
}
|
||||
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<React.Fragment>
|
||||
{ sortDropdownItems.length > 1 && (
|
||||
<Dropdown
|
||||
style={{ marginRight: '20px' }}
|
||||
onToggle={this.onSortDropdownToggle}
|
||||
onSelect={this.onSortDropdownSelect}
|
||||
direction={up}
|
||||
isOpen={isSortDropdownOpen}
|
||||
toggle={(
|
||||
<DropdownToggle
|
||||
onToggle={this.onSortDropdownToggle}
|
||||
>
|
||||
{sortedColumnName}
|
||||
</DropdownToggle>
|
||||
)}
|
||||
dropdownItems={sortDropdownItems}
|
||||
/>
|
||||
)}
|
||||
<Button
|
||||
onClick={this.onSort}
|
||||
variant="plain"
|
||||
aria-label={i18n._(t`Sort`)}
|
||||
>
|
||||
<SortIcon />
|
||||
</Button>
|
||||
</React.Fragment>
|
||||
)}
|
||||
</I18n>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Sort.propTypes = {
|
||||
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
onSort: PropTypes.func,
|
||||
sortOrder: PropTypes.string,
|
||||
sortedColumnKey: PropTypes.string
|
||||
};
|
||||
|
||||
Sort.defaultProps = {
|
||||
onSort: null,
|
||||
sortOrder: 'ascending',
|
||||
sortedColumnKey: 'name'
|
||||
};
|
||||
|
||||
export default Sort;
|
||||
3
src/components/Sort/index.js
Normal file
3
src/components/Sort/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import Sort from './Sort';
|
||||
|
||||
export default Sort;
|
||||
Reference in New Issue
Block a user