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))
- [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))
- Ability to change the number of items displayed per table or page (PR [#5355](https://github.com/vatesfr/xen-orchestra/pull/5355))
### Bug fixes

View File

@ -1,13 +1,14 @@
import * as CM from 'complex-matcher'
import _ from 'intl'
import classNames from 'classnames'
import cookies from 'js-cookie'
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 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 React from 'react'
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 { Set } from 'immutable'
import { injectState, provideState } from 'reaclette'
@ -38,9 +39,12 @@ import {
createSelector,
createSort,
} from '../selectors'
import { ITEMS_PER_PAGE_OPTIONS } from '../xo'
import styles from './index.css'
const DEFAULT_ITEMS_PER_PAGE = 10
// ===================================================================
class ColumnHead extends Component {
@ -268,7 +272,6 @@ class SortedTable extends Component {
),
groupedActions: actionsShape,
individualActions: actionsShape,
itemsPerPage: PropTypes.number,
onSelect: PropTypes.func,
paginationContainer: PropTypes.func,
rowAction: PropTypes.func,
@ -283,10 +286,6 @@ class SortedTable extends Component {
userData: PropTypes.any,
}
static defaultProps = {
itemsPerPage: 10,
}
constructor(props, context) {
super(props, context)
@ -306,6 +305,7 @@ class SortedTable extends Component {
const state = (this.state = {
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()]
@ -340,7 +340,7 @@ class SortedTable extends Component {
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()
@ -468,7 +468,7 @@ class SortedTable extends Component {
_setPage = this._setPage.bind(this)
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 => {
@ -584,7 +584,7 @@ class SortedTable extends Component {
_getNPages = createSelector(
() => this._getItems().length,
() => this.props.itemsPerPage,
() => this.state.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() {
const { props, state } = this
const {
actions,
filterContainer,
individualActions,
itemsPerPage,
onSelect,
paginationContainer,
shortcutsTarget,
} = props
const { all } = state
const { actions, filterContainer, individualActions, onSelect, paginationContainer, shortcutsTarget } = props
const { all, itemsPerPage } = state
const groupedActions = this._getGroupedActions()
const nAllItems = this._getTotalNumberOfItems()
@ -860,7 +858,7 @@ class SortedTable extends Component {
</table>
<Container>
<SingleLineRow>
<Col mediumSize={8}>
<Col mediumSize={7}>
{displayPagination &&
(paginationContainer !== undefined ? (
// Rebuild container function to refresh Portal component.
@ -872,6 +870,15 @@ class SortedTable extends Component {
<Col mediumSize={4}>
{filterContainer ? <Portal container={() => filterContainer()}>{filterInstance}</Portal> : filterInstance}
</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>
</Container>
</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_CAP = 0

View File

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