feat(xo-web/sr/general): add a link to disks group (#4754)

Fixes #4747
This commit is contained in:
Rajaa.BARHTAOUI
2020-02-25 16:06:08 +01:00
committed by GitHub
parent 555b1a16da
commit 6abe399e36
3 changed files with 47 additions and 15 deletions

View File

@@ -11,6 +11,7 @@
- [SDN Controller] Automatically handle new, connected and disconnected servers (PR [#4677](https://github.com/vatesfr/xen-orchestra/pull/4677)) - [SDN Controller] Automatically handle new, connected and disconnected servers (PR [#4677](https://github.com/vatesfr/xen-orchestra/pull/4677))
- [Proxy] Support network configuration for the deployed proxy (PR [#4810](https://github.com/vatesfr/xen-orchestra/pull/4810)) - [Proxy] Support network configuration for the deployed proxy (PR [#4810](https://github.com/vatesfr/xen-orchestra/pull/4810))
- [Menu] Display a warning icon in case of missing patches [#4475](https://github.com/vatesfr/xen-orchestra/issues/4475) (PR [#4683](https://github.com/vatesfr/xen-orchestra/pull/4683)) - [Menu] Display a warning icon in case of missing patches [#4475](https://github.com/vatesfr/xen-orchestra/issues/4475) (PR [#4683](https://github.com/vatesfr/xen-orchestra/pull/4683))
- [SR/general] Clickable SR usage graph: shows the corresponding disks when you click on one of the sections [#4747](https://github.com/vatesfr/xen-orchestra/issues/4747) (PR [#4754](https://github.com/vatesfr/xen-orchestra/pull/4754))
### Bug fixes ### Bug fixes

View File

@@ -2,30 +2,37 @@ import _ from 'intl'
import classNames from 'classnames' import classNames from 'classnames'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import React, { cloneElement } from 'react' import React, { cloneElement } from 'react'
import { compact, sum } from 'lodash' import { compact, sumBy } from 'lodash'
import Tooltip from '../tooltip' import Tooltip from '../tooltip'
const Usage = ({ total, children }) => { const Usage = ({ total, children, link }) => {
const limit = total / 400 const limit = total / 400
const othersValues = compact( const othersProps = compact(
React.Children.map(children, child => { React.Children.map(children, child => {
const { value } = child.props const { value } = child.props
return value < limit && value return value < limit && child.props
}) })
) )
const othersTotal = sum(othersValues) const othersTotal = sumBy(othersProps, 'value')
const nOthers = othersValues.length const nOthers = othersProps.length
const getLink = typeof link === 'function' ? link : () => link
return ( return (
<span className='usage'> <span className='usage'>
{nOthers > 1 ? ( {nOthers > 1 ? (
<span> <span>
{React.Children.map( {React.Children.map(children, (child, index) => {
children, const { id, href, value } = child.props
(child, index) => return (
child.props.value > limit && cloneElement(child, { total }) value > limit &&
)} cloneElement(child, {
href: href === undefined ? getLink(id) : href,
total,
})
)
})}
<Element <Element
href={getLink(othersProps.map(_ => _.id))}
others others
tooltip={_('others', { nOthers })} tooltip={_('others', { nOthers })}
total={total} total={total}
@@ -33,14 +40,19 @@ const Usage = ({ total, children }) => {
/> />
</span> </span>
) : ( ) : (
React.Children.map(children, (child, index) => React.Children.map(children, (child, index) => {
cloneElement(child, { total }) const { id, href } = child.props
) return cloneElement(child, {
href: href === undefined ? getLink(id) : href,
total,
})
})
)} )}
</span> </span>
) )
} }
Usage.propTypes = { Usage.propTypes = {
link: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
total: PropTypes.number.isRequired, total: PropTypes.number.isRequired,
} }
export { Usage as default } export { Usage as default }

View File

@@ -14,12 +14,14 @@ import {
createSelector, createSelector,
} from 'selectors' } from 'selectors'
import { import {
flattenDeep,
flatMap, flatMap,
forEach, forEach,
groupBy, groupBy,
keyBy, keyBy,
map, map,
mapValues, mapValues,
pick,
sumBy, sumBy,
uniq, uniq,
} from 'lodash' } from 'lodash'
@@ -238,6 +240,22 @@ export default class TabGeneral extends Component {
} }
) )
_getGenerateLink = createSelector(this._getDiskGroups, diskGroups => ids =>
`#/srs/${this.props.sr.id}/disks?s=${encodeURIComponent(
`id:|(${flattenDeep(
map(
pick(keyBy(diskGroups, 'id'), ids),
({ id, baseCopies, vdis, snapshots, type }) =>
type === 'orphanedSnapshot'
? id
: [map(baseCopies, 'id'), map(vdis, 'id'), map(snapshots, 'id')]
)
)
.sort()
.join(' ')})`
)}`
)
render() { render() {
const { sr } = this.props const { sr } = this.props
return ( return (
@@ -273,10 +291,11 @@ export default class TabGeneral extends Component {
</Row> </Row>
<Row> <Row>
<Col smallOffset={1} mediumSize={10}> <Col smallOffset={1} mediumSize={10}>
<Usage total={sr.size} type='disk'> <Usage total={sr.size} type='disk' link={this._getGenerateLink()}>
{this._getDiskGroups().map(group => ( {this._getDiskGroups().map(group => (
<UsageElement <UsageElement
highlight={group.type === 'orphanedSnapshot'} highlight={group.type === 'orphanedSnapshot'}
id={group.id}
key={group.id} key={group.id}
tooltip={<UsageTooltip group={group} />} tooltip={<UsageTooltip group={group} />}
value={group.usage} value={group.usage}