feat(xo-web/SortedTable): allow to change the number of items per page (#5355)

See xoa-support#3020
This commit is contained in:
Rajaa.BARHTAOUI 2020-11-27 14:20:33 +01:00 committed by GitHub
parent 7961ff0785
commit fbf906d97c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 21 deletions

View File

@ -16,6 +16,7 @@
- [Web Hooks] `backupNg.runJob` is now triggered by scheduled runs [#5205](https://github.com/vatesfr/xen-orchestra/issues/5205) (PR [#5360](https://github.com/vatesfr/xen-orchestra/pull/5360)) - [Web Hooks] `backupNg.runJob` is now triggered by scheduled runs [#5205](https://github.com/vatesfr/xen-orchestra/issues/5205) (PR [#5360](https://github.com/vatesfr/xen-orchestra/pull/5360))
- [Licensing] Add trial end information banner (PR [#5374](https://github.com/vatesfr/xen-orchestra/pull/5374)) - [Licensing] Add trial end information banner (PR [#5374](https://github.com/vatesfr/xen-orchestra/pull/5374))
- Assign custom fields on pools, hosts, SRs, and VMs in advanced tab [#4730](https://github.com/vatesfr/xen-orchestra/issues/4730) (PR [#5387](https://github.com/vatesfr/xen-orchestra/pull/5387)) - Assign custom fields on pools, hosts, SRs, and VMs in advanced tab [#4730](https://github.com/vatesfr/xen-orchestra/issues/4730) (PR [#5387](https://github.com/vatesfr/xen-orchestra/pull/5387))
- Ability to change the number of items displayed per table or page (PR [#5355](https://github.com/vatesfr/xen-orchestra/pull/5355))
### Bug fixes ### Bug fixes

View File

@ -1,13 +1,14 @@
import * as CM from 'complex-matcher' import * as CM from 'complex-matcher'
import _ from 'intl' import _ from 'intl'
import classNames from 'classnames' import classNames from 'classnames'
import cookies from 'js-cookie'
import defined, { ifDef } from '@xen-orchestra/defined' import defined, { ifDef } from '@xen-orchestra/defined'
import DropdownMenu from 'react-bootstrap-4/lib/DropdownMenu' // https://phabricator.babeljs.io/T6662 so Dropdown.Menu won't work like https://react-bootstrap.github.io/components.html#btn-dropdowns-custom import DropdownMenu from 'react-bootstrap-4/lib/DropdownMenu' // https://phabricator.babeljs.io/T6662 so Dropdown.Menu won't work like https://react-bootstrap.github.io/components.html#btn-dropdowns-custom
import DropdownToggle from 'react-bootstrap-4/lib/DropdownToggle' // https://phabricator.babeljs.io/T6662 so Dropdown.Toggle won't work https://react-bootstrap.github.io/components.html#btn-dropdowns-custom import DropdownToggle from 'react-bootstrap-4/lib/DropdownToggle' // https://phabricator.babeljs.io/T6662 so Dropdown.Toggle won't work https://react-bootstrap.github.io/components.html#btn-dropdowns-custom
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import React from 'react' import React from 'react'
import Shortcuts from 'shortcuts' import Shortcuts from 'shortcuts'
import { Dropdown, MenuItem } from 'react-bootstrap-4/lib' import { Dropdown, DropdownButton, MenuItem } from 'react-bootstrap-4/lib'
import { Portal } from 'react-overlays' import { Portal } from 'react-overlays'
import { Set } from 'immutable' import { Set } from 'immutable'
import { injectState, provideState } from 'reaclette' import { injectState, provideState } from 'reaclette'
@ -38,9 +39,12 @@ import {
createSelector, createSelector,
createSort, createSort,
} from '../selectors' } from '../selectors'
import { ITEMS_PER_PAGE_OPTIONS } from '../xo'
import styles from './index.css' import styles from './index.css'
const DEFAULT_ITEMS_PER_PAGE = 10
// =================================================================== // ===================================================================
class ColumnHead extends Component { class ColumnHead extends Component {
@ -268,7 +272,6 @@ class SortedTable extends Component {
), ),
groupedActions: actionsShape, groupedActions: actionsShape,
individualActions: actionsShape, individualActions: actionsShape,
itemsPerPage: PropTypes.number,
onSelect: PropTypes.func, onSelect: PropTypes.func,
paginationContainer: PropTypes.func, paginationContainer: PropTypes.func,
rowAction: PropTypes.func, rowAction: PropTypes.func,
@ -283,10 +286,6 @@ class SortedTable extends Component {
userData: PropTypes.any, userData: PropTypes.any,
} }
static defaultProps = {
itemsPerPage: 10,
}
constructor(props, context) { constructor(props, context) {
super(props, context) super(props, context)
@ -306,6 +305,7 @@ class SortedTable extends Component {
const state = (this.state = { const state = (this.state = {
all: false, // whether all items are selected (accross pages) all: false, // whether all items are selected (accross pages)
itemsPerPage: +defined(cookies.get(`${props.location.pathname}-${props.stateUrlParam}`), DEFAULT_ITEMS_PER_PAGE),
}) })
this._getSelectedColumn = () => this.props.columns[this._getSelectedColumnId()] this._getSelectedColumn = () => this.props.columns[this._getSelectedColumnId()]
@ -340,7 +340,7 @@ class SortedTable extends Component {
this._getSortOrder this._getSortOrder
) )
this._getVisibleItems = createPager(this._getItems, this._getPage, () => this.props.itemsPerPage) this._getVisibleItems = createPager(this._getItems, this._getPage, () => this.state.itemsPerPage)
state.selectedItemsIds = new Set() state.selectedItemsIds = new Set()
@ -468,7 +468,7 @@ class SortedTable extends Component {
_setPage = this._setPage.bind(this) _setPage = this._setPage.bind(this)
goTo(id) { goTo(id) {
this._setPage(Math.floor(this._getItems().findIndex(item => item.id === id) / this.props.itemsPerPage) + 1) this._setPage(Math.floor(this._getItems().findIndex(item => item.id === id) / this.state.itemsPerPage) + 1)
} }
_selectAllVisibleItems = event => { _selectAllVisibleItems = event => {
@ -584,7 +584,7 @@ class SortedTable extends Component {
_getNPages = createSelector( _getNPages = createSelector(
() => this._getItems().length, () => this._getItems().length,
() => this.props.itemsPerPage, () => this.state.itemsPerPage,
(nItems, itemsPerPage) => ceil(nItems / itemsPerPage) (nItems, itemsPerPage) => ceil(nItems / itemsPerPage)
) )
@ -727,18 +727,16 @@ class SortedTable extends Component {
) )
} }
_setNItemsPerPage = itemsPerPage => {
const { location, stateUrlParam } = this.props
this.setState({ itemsPerPage })
cookies.set(`${location.pathname}-${stateUrlParam}`, itemsPerPage)
}
render() { render() {
const { props, state } = this const { props, state } = this
const { const { actions, filterContainer, individualActions, onSelect, paginationContainer, shortcutsTarget } = props
actions, const { all, itemsPerPage } = state
filterContainer,
individualActions,
itemsPerPage,
onSelect,
paginationContainer,
shortcutsTarget,
} = props
const { all } = state
const groupedActions = this._getGroupedActions() const groupedActions = this._getGroupedActions()
const nAllItems = this._getTotalNumberOfItems() const nAllItems = this._getTotalNumberOfItems()
@ -860,7 +858,7 @@ class SortedTable extends Component {
</table> </table>
<Container> <Container>
<SingleLineRow> <SingleLineRow>
<Col mediumSize={8}> <Col mediumSize={7}>
{displayPagination && {displayPagination &&
(paginationContainer !== undefined ? ( (paginationContainer !== undefined ? (
// Rebuild container function to refresh Portal component. // Rebuild container function to refresh Portal component.
@ -872,6 +870,15 @@ class SortedTable extends Component {
<Col mediumSize={4}> <Col mediumSize={4}>
{filterContainer ? <Portal container={() => filterContainer()}>{filterInstance}</Portal> : filterInstance} {filterContainer ? <Portal container={() => filterContainer()}>{filterInstance}</Portal> : filterInstance}
</Col> </Col>
<Col mediumSize={1} className='pull-right'>
<DropdownButton bsStyle='info' title={itemsPerPage}>
{ITEMS_PER_PAGE_OPTIONS.map(nItems => (
<MenuItem key={nItems} onClick={() => this._setNItemsPerPage(nItems)}>
{nItems}
</MenuItem>
))}
</DropdownButton>
</Col>
</SingleLineRow> </SingleLineRow>
</Container> </Container>
</div> </div>

View File

@ -37,6 +37,10 @@ import parseNdJson from './_parseNdJson'
// =================================================================== // ===================================================================
export const ITEMS_PER_PAGE_OPTIONS = [10, 20, 50, 100]
// ===================================================================
export const XEN_DEFAULT_CPU_WEIGHT = 256 export const XEN_DEFAULT_CPU_WEIGHT = 256
export const XEN_DEFAULT_CPU_CAP = 0 export const XEN_DEFAULT_CPU_CAP = 0

View File

@ -64,6 +64,7 @@ import {
subscribeResourceSets, subscribeResourceSets,
subscribeServers, subscribeServers,
suspendVms, suspendVms,
ITEMS_PER_PAGE_OPTIONS,
} from 'xo' } from 'xo'
import { Container, Row, Col } from 'grid' import { Container, Row, Col } from 'grid'
import { createPredicate } from 'value-matcher' import { createPredicate } from 'value-matcher'
@ -92,7 +93,6 @@ import TemplateItem from './template-item'
import SrItem from './sr-item' import SrItem from './sr-item'
const DEFAULT_ITEMS_PER_PAGE = 20 const DEFAULT_ITEMS_PER_PAGE = 20
const ITEMS_PER_PAGE_OPTIONS = [20, 50, 100]
const OPTIONS = { const OPTIONS = {
host: { host: {