diff --git a/examples/examples.js b/examples/examples.js index 342ad72bb..3721e598c 100644 --- a/examples/examples.js +++ b/examples/examples.js @@ -14,7 +14,6 @@ import CustomizeSearchRender from './customize-search-render'; import CustomizeSorting from './customize-sorting'; import CustomizeStyling from './customize-styling'; import CustomizeToolbar from './customize-toolbar'; -import CustomizeToolbarIcons from './customize-toolbar-icons'; import CustomizeToolbarSelect from './customize-toolbarselect'; import DataAsObjects from './data-as-objects'; import DraggableColumns from './draggable-columns'; @@ -35,6 +34,7 @@ import CustomComponents from './custom-components'; import InfiniteScrolling from './infinite-scrolling'; import Themes from './themes'; import LargeDataSet from './large-data-set'; +import ToolbarPosition from './toolbar-position'; /** * Here you can add any extra examples with the Card label as the key, and the component to render as the value @@ -56,7 +56,6 @@ export default { 'Customize Sorting': CustomizeSorting, 'Customize Styling': CustomizeStyling, 'Customize Toolbar': CustomizeToolbar, - 'Customize Toolbar Icons': CustomizeToolbarIcons, 'Customize Toolbar Select': CustomizeToolbarSelect, 'Data As Objects': DataAsObjects, 'Draggable Columns': DraggableColumns, @@ -77,4 +76,5 @@ export default { 'Text Localization': TextLocalization, 'Custom Components': CustomComponents, Themes: Themes, + 'Toolbar Position': ToolbarPosition, }; diff --git a/examples/toolbar-position/index.js b/examples/toolbar-position/index.js new file mode 100644 index 000000000..dd75eebe2 --- /dev/null +++ b/examples/toolbar-position/index.js @@ -0,0 +1,60 @@ +import React from "react"; +import ReactDOM from "react-dom"; +import MUIDataTable from "../../src/"; + +class Example extends React.Component { + + render() { + + const columns = ["Name", "Title", "Location", "Age", "Salary"]; + + let data = [ + ["Gabby George", "Business Analyst", "Minneapolis", 30, 238500], + ["Aiden Lloyd", "Business Consultant", "Dallas", 55, 200000], + ["Jaden Collins", "Attorney", "Santa Ana", 27, 500000], + ["Franky Rees", "Business Analyst", "St. Petersburg", 22, 50000], + ["Aaren Rose", "Business Consultant", "Toledo", 28, 75000], + ["Blake Duncan", "Business Management Analyst", "San Diego", 65, 94000], + ["Frankie Parry", "Agency Legal Counsel", "Jacksonville", 71, 210000], + ["Lane Wilson", "Commercial Specialist", "Omaha", 19, 65000], + ["Robin Duncan", "Business Analyst", "Los Angeles", 20, 77000], + ["Mel Brooks", "Business Consultant", "Oklahoma City", 37, 135000], + ["Harper White", "Attorney", "Pittsburgh", 52, 420000], + ["Kris Humphrey", "Agency Legal Counsel", "Laredo", 30, 150000], + ["Frankie Long", "Industrial Analyst", "Austin", 31, 170000], + ["Brynn Robbins", "Business Analyst", "Norfolk", 22, 90000], + ["Justice Mann", "Business Consultant", "Chicago", 24, 133000], + ["Addison Navarro", "Business Management Analyst", "New York", 50, 295000], + ["Jesse Welch", "Agency Legal Counsel", "Seattle", 28, 200000], + ["Eli Mejia", "Commercial Specialist", "Long Beach", 65, 400000], + ["Gene Leblanc", "Industrial Analyst", "Hartford", 34, 110000], + ["Danny Leon", "Computer Scientist", "Newark", 60, 220000], + ["Lane Lee", "Corporate Counselor", "Cincinnati", 52, 180000], + ["Jesse Hall", "Business Analyst", "Baltimore", 44, 99000], + ["Danni Hudson", "Agency Legal Counsel", "Tampa", 37, 90000], + ["Terry Macdonald", "Commercial Specialist", "Miami", 39, 140000], + ["Justice Mccarthy", "Attorney", "Tucson", 26, 330000], + ["Silver Carey", "Computer Scientist", "Memphis", 47, 250000], + ["Franky Miles", "Industrial Analyst", "Buffalo", 49, 190000], + ["Glen Nixon", "Corporate Counselor", "Arlington", 44, 80000], + ["Gabby Strickland", "Business Process Consultant", "Scottsdale", 26, 45000], + ["Mason Ray", "Computer Scientist", "San Francisco", 39, 238500] + ]; + + const options = { + filter: true, + selectableRows: 'multiple', + filterType: 'dropdown', + responsive: 'vertical', + rowsPerPage: 10, + toolbarPosition: 'bottom' // Ubica la barra de herramientas al mismo nivel que TablePagination + }; + + return ( + + ); + + } +} + +export default Example; diff --git a/package-lock.json b/package-lock.json index a2d7284ce..5e2d05b6d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "mui-datatables", - "version": "3.7.6", + "version": "3.7.8", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/src/MUIDataTable.js b/src/MUIDataTable.js index 5f7a50f30..6d51179c6 100644 --- a/src/MUIDataTable.js +++ b/src/MUIDataTable.js @@ -1,7 +1,6 @@ import Paper from '@material-ui/core/Paper'; -import MuiTable from '@material-ui/core/Table'; -import MuiTooltip from '@material-ui/core/Tooltip'; import { withStyles } from '@material-ui/core/styles'; +import MuiTable from '@material-ui/core/Table'; import clsx from 'clsx'; import assignwith from 'lodash.assignwith'; import cloneDeep from 'lodash.clonedeep'; @@ -19,6 +18,7 @@ import DefaultTableHead from './components/TableHead'; import DefaultTableResize from './components/TableResize'; import DefaultTableToolbar from './components/TableToolbar'; import DefaultTableToolbarSelect from './components/TableToolbarSelect'; +import MuiTooltip from '@material-ui/core/Tooltip'; import getTextLabels from './textLabels'; import { buildMap, getCollatorComparator, getPageValue, sortCompare, warnDeprecated, warnInfo } from './utils'; import { DndProvider } from 'react-dnd'; @@ -122,7 +122,7 @@ class MUIDataTable extends React.Component { label: PropTypes.string, name: PropTypes.string.isRequired, options: PropTypes.shape({ - display: PropTypes.oneOf(['true', 'false', 'excluded', 'always', true, false]), + display: PropTypes.oneOf(['true', 'false', 'excluded', 'always']), empty: PropTypes.bool, filter: PropTypes.bool, sort: PropTypes.bool, @@ -155,6 +155,7 @@ class MUIDataTable extends React.Component { setCellHeaderProps: PropTypes.func, sortThirdClickReset: PropTypes.bool, sortDescFirst: PropTypes.bool, + toolbarPosition: PropTypes.string, }), }), ]), @@ -233,7 +234,6 @@ class MUIDataTable extends React.Component { rowsSelected: PropTypes.array, search: PropTypes.oneOf([true, false, 'true', 'false', 'disabled']), searchOpen: PropTypes.bool, - searchAlwaysOpen: PropTypes.bool, searchPlaceholder: PropTypes.string, searchText: PropTypes.string, setFilterChipProps: PropTypes.func, @@ -267,7 +267,6 @@ class MUIDataTable extends React.Component { TableToolbar: DefaultTableToolbar, TableToolbarSelect: DefaultTableToolbarSelect, Tooltip: MuiTooltip, - icons: {}, }, }; @@ -362,8 +361,8 @@ class MUIDataTable extends React.Component { props.options.selectToolbarPlacement = STP.NONE; } - // provide default tableId when no tableId has been passed as prop - if (!props.options.tableId) { + // provide default tableId when draggableColumns is enabled and no tableId has been passed as prop + if (props.options.draggableColumns && props.options.draggableColumns.enabled === true && !props.options.tableId) { props.options.tableId = (Math.random() + '').replace(/\./, ''); } @@ -422,6 +421,7 @@ class MUIDataTable extends React.Component { textLabels: getTextLabels(), viewColumns: true, selectToolbarPlacement: STP.REPLACE, + toolbarPosition: 'top' }); warnDep = (msg, consoleWarnings) => { @@ -1935,7 +1935,7 @@ class MUIDataTable extends React.Component { )} {(selectedRows.data.length === 0 || [STP.ABOVE, STP.NONE].indexOf(this.options.selectToolbarPlacement) !== -1) && - showToolbar && ( + showToolbar && this.options.toolbarPosition != 'bottom' && ( } />
{announceText} diff --git a/src/components/TableFooter.js b/src/components/TableFooter.js index 580edceeb..80aae63b8 100644 --- a/src/components/TableFooter.js +++ b/src/components/TableFooter.js @@ -15,7 +15,7 @@ const useStyles = makeStyles( { name: 'MUIDataTableFooter' }, ); -const TableFooter = ({ options, rowCount, page, rowsPerPage, changeRowsPerPage, changePage }) => { +const TableFooter = ({ options, rowCount, page, rowsPerPage, changeRowsPerPage, changePage, toolbar }) => { const classes = useStyles(); const { customFooter, pagination = true } = options; @@ -45,6 +45,7 @@ const TableFooter = ({ options, rowCount, page, rowsPerPage, changeRowsPerPage, changePage={changePage} component={'div'} options={options} + toolbar={toolbar} /> ); diff --git a/src/components/TablePagination.js b/src/components/TablePagination.js index 62fe7b25e..96264ff62 100644 --- a/src/components/TablePagination.js +++ b/src/components/TablePagination.js @@ -45,12 +45,15 @@ function TablePagination(props) { props.changePage(page); }; - const { count, options, rowsPerPage, page } = props; + const { count, options, rowsPerPage, page, toolbar } = props; const textLabels = options.textLabels.pagination; return ( + {toolbar && + {toolbar} + }
{options.jumpToPage ? ( diff --git a/src/components/TableToolbar.js b/src/components/TableToolbar.js index 700d0b820..ff70d6acb 100644 --- a/src/components/TableToolbar.js +++ b/src/components/TableToolbar.js @@ -15,6 +15,7 @@ import ReactToPrint, { PrintContextConsumer } from 'react-to-print'; import find from 'lodash.find'; import { withStyles } from '@material-ui/core/styles'; import { createCSVDownload, downloadCSV } from '../utils'; +import cloneDeep from 'lodash.clonedeep'; import MuiTooltip from '@material-ui/core/Tooltip'; export const defaultToolbarStyles = theme => ({ @@ -34,6 +35,10 @@ export const defaultToolbarStyles = theme => ({ flex: '1 1 auto', textAlign: 'right', }, + actionsLeft: { + flex: '1 1 auto', + textAlign: 'left', + }, fullWidthActions: { flex: '1 1 auto', textAlign: 'right', @@ -107,12 +112,7 @@ const RESPONSIVE_FULL_WIDTH_NAME = 'scrollFullHeightFullWidth'; class TableToolbar extends React.Component { state = { iconActive: null, - showSearch: Boolean( - this.props.searchText || - this.props.options.searchText || - this.props.options.searchOpen || - this.props.options.searchAlwaysOpen, - ), + showSearch: Boolean(this.props.searchText || this.props.options.searchText || this.props.options.searchOpen), searchText: this.props.searchText || null, }; @@ -295,22 +295,16 @@ class TableToolbar extends React.Component { components = {}, updateFilterByType, } = this.props; - const { icons = {} } = components; const Tooltip = components.Tooltip || MuiTooltip; const TableViewColComponent = components.TableViewCol || TableViewCol; const TableFilterComponent = components.TableFilter || TableFilter; - const SearchIconComponent = icons.SearchIcon || SearchIcon; - const DownloadIconComponent = icons.DownloadIcon || DownloadIcon; - const PrintIconComponent = icons.PrintIcon || PrintIcon; - const ViewColumnIconComponent = icons.ViewColumnIcon || ViewColumnIcon; - const FilterIconComponent = icons.FilterIcon || FilterIcon; const { search, downloadCsv, print, viewColumns, filterTable } = options.textLabels.toolbar; const { showSearch, searchText } = this.state; const filterPopoverExit = () => { this.setState({ hideFilterPopover: false }); - this.setActiveIcon(); + this.setActiveIcon.bind(null); }; const closeFilterPopover = () => { @@ -321,8 +315,8 @@ class TableToolbar extends React.Component { -
+ aria-label={'Table Toolbar'} disableGutters={this.props.bottom ? true : false}> + {!this.props.bottom &&
{showSearch === true ? ( options.customSearchRender ? ( options.customSearchRender(searchText, this.handleSearch, this.hideSearch, options) @@ -347,9 +341,9 @@ class TableToolbar extends React.Component {
)} -
-
- {!(options.search === false || options.search === 'false' || options.searchAlwaysOpen === true) && ( +
} +
+ {!(options.search === false || options.search === 'false') && ( - + )} {!(options.download === false || options.download === 'false') && ( - + )} @@ -387,7 +381,7 @@ class TableToolbar extends React.Component { disabled={options.print === 'disabled'} onClick={handlePrint} classes={{ root: classes.icon }}> - + @@ -409,7 +403,7 @@ class TableToolbar extends React.Component { classes={{ root: this.getActiveIcon(classes, 'viewcolumns') }} disabled={options.viewColumns === 'disabled'} onClick={this.setActiveIcon.bind(null, 'viewcolumns')}> - + } @@ -438,7 +432,7 @@ class TableToolbar extends React.Component { classes={{ root: this.getActiveIcon(classes, 'filter') }} disabled={options.filter === 'disabled'} onClick={this.setActiveIcon.bind(null, 'filter')}> - + } @@ -460,6 +454,32 @@ class TableToolbar extends React.Component { )} {options.customToolbar && options.customToolbar({ displayData: this.props.displayData })}
+ {this.props.bottom &&
+ {showSearch === true ? ( + options.customSearchRender ? ( + options.customSearchRender(searchText, this.handleSearch, this.hideSearch, options) + ) : ( + + ) + ) : typeof title !== 'string' ? ( + title + ) : ( +
+ + {title} + +
+ )} +
}
); } diff --git a/test/MUIDataTableToolbar.test.js b/test/MUIDataTableToolbar.test.js index a3df19d3e..df6a009c0 100644 --- a/test/MUIDataTableToolbar.test.js +++ b/test/MUIDataTableToolbar.test.js @@ -3,7 +3,7 @@ import DownloadIcon from '@material-ui/icons/CloudDownload'; import FilterIcon from '@material-ui/icons/FilterList'; import PrintIcon from '@material-ui/icons/Print'; import SearchIcon from '@material-ui/icons/Search'; -import CloseIcon from "@material-ui/icons/Close"; +import CloseIcon from '@material-ui/icons/Close'; import ViewColumnIcon from '@material-ui/icons/ViewColumn'; import { assert } from 'chai'; import { mount, shallow } from 'enzyme'; @@ -106,7 +106,7 @@ describe('', function() { it('should render a toolbar with search box and no search icon if option.searchAlwaysOpen = true', () => { const newOptions = { ...options, searchAlwaysOpen: true }; const mountWrapper = mount( - , + , ); // check that textfield is rendered