@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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 }
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
Reference in New Issue
Block a user