parent
3241c426a2
commit
3370014ddf
@ -11,6 +11,7 @@
|
|||||||
- [Backup NG form] Add offline snapshot info (PR [#3144](https://github.com/vatesfr/xen-orchestra/pull/3144))
|
- [Backup NG form] Add offline snapshot info (PR [#3144](https://github.com/vatesfr/xen-orchestra/pull/3144))
|
||||||
- [Backup NG overview] Display concurrency and offline snapshot value [3087](https://github.com/vatesfr/xen-orchestra/issues/3087) (PR [3145](https://github.com/vatesfr/xen-orchestra/pull/3145))
|
- [Backup NG overview] Display concurrency and offline snapshot value [3087](https://github.com/vatesfr/xen-orchestra/issues/3087) (PR [3145](https://github.com/vatesfr/xen-orchestra/pull/3145))
|
||||||
- [VM revert] notify the result of reverting a VM [3095](https://github.com/vatesfr/xen-orchestra/issues/3095) (PR [3150](https://github.com/vatesfr/xen-orchestra/pull/3150))
|
- [VM revert] notify the result of reverting a VM [3095](https://github.com/vatesfr/xen-orchestra/issues/3095) (PR [3150](https://github.com/vatesfr/xen-orchestra/pull/3150))
|
||||||
|
- [Backup NG logs] Link XO items in the details modal [#2711](https://github.com/vatesfr/xen-orchestra/issues/2711) (PR [#3171](https://github.com/vatesfr/xen-orchestra/pull/3171))
|
||||||
|
|
||||||
### Bug fixes
|
### Bug fixes
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ const messages = {
|
|||||||
statusLoading: 'Loading…',
|
statusLoading: 'Loading…',
|
||||||
errorPageNotFound: 'Page not found',
|
errorPageNotFound: 'Page not found',
|
||||||
errorNoSuchItem: 'no such item',
|
errorNoSuchItem: 'no such item',
|
||||||
|
errorUnknownItem: 'unknown item',
|
||||||
|
|
||||||
editableLongClickPlaceholder: 'Long click to edit',
|
editableLongClickPlaceholder: 'Long click to edit',
|
||||||
editableClickPlaceholder: 'Click to edit',
|
editableClickPlaceholder: 'Click to edit',
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
import _ from 'intl'
|
import _ from 'intl'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { startsWith } from 'lodash'
|
import { startsWith } from 'lodash'
|
||||||
|
|
||||||
import Icon from './icon'
|
import Icon from './icon'
|
||||||
|
import Link from './link'
|
||||||
import propTypes from './prop-types-decorator'
|
import propTypes from './prop-types-decorator'
|
||||||
import { createGetObject } from './selectors'
|
import { addSubscriptions, connectStore, formatSize } from './utils'
|
||||||
|
import { createGetObject, createSelector } from './selectors'
|
||||||
import { FormattedDate } from 'react-intl'
|
import { FormattedDate } from 'react-intl'
|
||||||
import { isSrWritable } from './xo'
|
import { get } from './xo-defined'
|
||||||
import { connectStore, formatSize } from './utils'
|
import { isSrWritable, subscribeRemotes } from './xo'
|
||||||
|
|
||||||
// ===================================================================
|
// ===================================================================
|
||||||
|
|
||||||
@ -17,6 +20,112 @@ const OBJECT_TYPE_TO_ICON = {
|
|||||||
network: 'network',
|
network: 'network',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const COMMON_PROP_TYPES = {
|
||||||
|
link: PropTypes.bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
const XoItem = ({ children, item, link, to }) =>
|
||||||
|
item !== undefined ? (
|
||||||
|
link ? (
|
||||||
|
<Link to={to} target='_blank'>
|
||||||
|
{children()}
|
||||||
|
</Link>
|
||||||
|
) : (
|
||||||
|
children()
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
<span className='text-muted'>{_('errorUnknownItem')}</span>
|
||||||
|
)
|
||||||
|
|
||||||
|
XoItem.propTypes = {
|
||||||
|
...COMMON_PROP_TYPES,
|
||||||
|
item: PropTypes.object,
|
||||||
|
to: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
|
||||||
|
}
|
||||||
|
// ===================================================================
|
||||||
|
|
||||||
|
const XO_ITEM_PROP_TYPES = {
|
||||||
|
...COMMON_PROP_TYPES,
|
||||||
|
id: PropTypes.string.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const VmItem = [
|
||||||
|
connectStore(() => {
|
||||||
|
const getVm = createGetObject()
|
||||||
|
return {
|
||||||
|
vm: getVm,
|
||||||
|
container: createGetObject(
|
||||||
|
createSelector(getVm, vm => get(() => vm.$container))
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
({ vm, container, ...props }) => (
|
||||||
|
<XoItem item={vm} to={`/vms/${get(() => vm.id)}`} {...props}>
|
||||||
|
{() => (
|
||||||
|
<span>
|
||||||
|
<Icon icon={`vm-${vm.power_state.toLowerCase()}`} />{' '}
|
||||||
|
{vm.name_label || vm.id}
|
||||||
|
{container !== undefined &&
|
||||||
|
` (${container.name_label || container.id})`}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</XoItem>
|
||||||
|
),
|
||||||
|
].reduceRight((value, decorator) => decorator(value))
|
||||||
|
|
||||||
|
VmItem.propTypes = XO_ITEM_PROP_TYPES
|
||||||
|
|
||||||
|
export const SrItem = [
|
||||||
|
connectStore(() => {
|
||||||
|
const getSr = createGetObject()
|
||||||
|
return {
|
||||||
|
sr: getSr,
|
||||||
|
container: createGetObject(
|
||||||
|
createSelector(getSr, sr => get(() => sr.$container))
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
({ sr, container, ...props }) => (
|
||||||
|
<XoItem item={sr} to={`/srs/${get(() => sr.id)}`} {...props}>
|
||||||
|
{() => (
|
||||||
|
<span>
|
||||||
|
<Icon icon='sr' /> {sr.name_label || sr.id}
|
||||||
|
{container !== undefined && (
|
||||||
|
<span className='text-muted'> - {container.name_label}</span>
|
||||||
|
)}
|
||||||
|
{isSrWritable(sr) && (
|
||||||
|
<span>{` (${formatSize(sr.size - sr.physical_usage)} free)`}</span>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</XoItem>
|
||||||
|
),
|
||||||
|
].reduceRight((value, decorator) => decorator(value))
|
||||||
|
|
||||||
|
SrItem.propTypes = XO_ITEM_PROP_TYPES
|
||||||
|
|
||||||
|
export const RemoteItem = [
|
||||||
|
addSubscriptions(({ id }) => ({
|
||||||
|
remote: cb =>
|
||||||
|
subscribeRemotes(remotes => {
|
||||||
|
cb(get(() => remotes.find(remote => remote.id === id)))
|
||||||
|
}),
|
||||||
|
})),
|
||||||
|
({ remote, ...props }) => (
|
||||||
|
<XoItem item={remote} to='/settings/remotes' {...props}>
|
||||||
|
{() => (
|
||||||
|
<span>
|
||||||
|
<Icon icon='remote' /> {remote.name}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</XoItem>
|
||||||
|
),
|
||||||
|
].reduceRight((value, decorator) => decorator(value))
|
||||||
|
|
||||||
|
RemoteItem.propTypes = XO_ITEM_PROP_TYPES
|
||||||
|
|
||||||
|
// ===================================================================
|
||||||
|
|
||||||
// Host, Network, VM-template.
|
// Host, Network, VM-template.
|
||||||
const PoolObjectItem = propTypes({
|
const PoolObjectItem = propTypes({
|
||||||
object: propTypes.object.isRequired,
|
object: propTypes.object.isRequired,
|
||||||
@ -40,48 +149,6 @@ const PoolObjectItem = propTypes({
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
// SR.
|
|
||||||
const SrItem = propTypes({
|
|
||||||
sr: propTypes.object.isRequired,
|
|
||||||
})(
|
|
||||||
connectStore(() => {
|
|
||||||
const getContainer = createGetObject((_, props) => props.sr.$container)
|
|
||||||
|
|
||||||
return (state, props) => ({
|
|
||||||
container: getContainer(state, props),
|
|
||||||
})
|
|
||||||
})(({ sr, container }) => (
|
|
||||||
<span>
|
|
||||||
<Icon icon='sr' /> {sr.name_label || sr.id}
|
|
||||||
{container !== undefined && (
|
|
||||||
<span className='text-muted'> - {container.name_label}</span>
|
|
||||||
)}
|
|
||||||
{isSrWritable(sr) && (
|
|
||||||
<span>{` (${formatSize(sr.size - sr.physical_usage)} free)`}</span>
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
))
|
|
||||||
)
|
|
||||||
|
|
||||||
// VM.
|
|
||||||
const VmItem = propTypes({
|
|
||||||
vm: propTypes.object.isRequired,
|
|
||||||
})(
|
|
||||||
connectStore(() => {
|
|
||||||
const getContainer = createGetObject((_, props) => props.vm.$container)
|
|
||||||
|
|
||||||
return (state, props) => ({
|
|
||||||
container: getContainer(state, props),
|
|
||||||
})
|
|
||||||
})(({ vm, container }) => (
|
|
||||||
<span>
|
|
||||||
<Icon icon={`vm-${vm.power_state.toLowerCase()}`} />{' '}
|
|
||||||
{vm.name_label || vm.id}
|
|
||||||
{container && ` (${container.name_label || container.id})`}
|
|
||||||
</span>
|
|
||||||
))
|
|
||||||
)
|
|
||||||
|
|
||||||
const VgpuItem = connectStore(() => ({
|
const VgpuItem = connectStore(() => ({
|
||||||
vgpuType: createGetObject((_, props) => props.vgpu.vgpuType),
|
vgpuType: createGetObject((_, props) => props.vgpu.vgpuType),
|
||||||
}))(({ vgpu, vgpuType }) => (
|
}))(({ vgpu, vgpuType }) => (
|
||||||
@ -104,11 +171,7 @@ const xoItemToRender = {
|
|||||||
<Icon icon='group' /> {group.name}
|
<Icon icon='group' /> {group.name}
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
remote: remote => (
|
remote: ({ value: { id } }) => <RemoteItem id={id} />,
|
||||||
<span>
|
|
||||||
<Icon icon='remote' /> {remote.value.name}
|
|
||||||
</span>
|
|
||||||
),
|
|
||||||
role: role => <span>{role.name}</span>,
|
role: role => <span>{role.name}</span>,
|
||||||
user: user => (
|
user: user => (
|
||||||
<span>
|
<span>
|
||||||
@ -160,14 +223,14 @@ const xoItemToRender = {
|
|||||||
network: network => <PoolObjectItem object={network} />,
|
network: network => <PoolObjectItem object={network} />,
|
||||||
|
|
||||||
// SR.
|
// SR.
|
||||||
SR: sr => <SrItem sr={sr} />,
|
SR: ({ id }) => <SrItem id={id} />,
|
||||||
|
|
||||||
// VM.
|
// VM.
|
||||||
VM: vm => <VmItem vm={vm} />,
|
VM: ({ id }) => <VmItem id={id} />,
|
||||||
'VM-snapshot': vm => <VmItem vm={vm} />,
|
'VM-snapshot': ({ id }) => <VmItem id={id} />,
|
||||||
'VM-controller': vm => (
|
'VM-controller': ({ id }) => (
|
||||||
<span>
|
<span>
|
||||||
<Icon icon='host' /> <VmItem vm={vm} />
|
<Icon icon='host' /> <VmItem id={id} />
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ import _, { FormattedDuration } from 'intl'
|
|||||||
import ActionButton from 'action-button'
|
import ActionButton from 'action-button'
|
||||||
import Icon from 'icon'
|
import Icon from 'icon'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import renderXoItem, { renderXoItemFromId } from 'render-xo-item'
|
|
||||||
import Select from 'form/select'
|
import Select from 'form/select'
|
||||||
import Tooltip from 'tooltip'
|
import Tooltip from 'tooltip'
|
||||||
import { addSubscriptions, formatSize, formatSpeed } from 'utils'
|
import { addSubscriptions, formatSize, formatSpeed } from 'utils'
|
||||||
@ -10,6 +9,7 @@ import { countBy, filter, get, keyBy, map } from 'lodash'
|
|||||||
import { FormattedDate } from 'react-intl'
|
import { FormattedDate } from 'react-intl'
|
||||||
import { injectState, provideState } from '@julien-f/freactal'
|
import { injectState, provideState } from '@julien-f/freactal'
|
||||||
import { runBackupNgJob, subscribeBackupNgLogs, subscribeRemotes } from 'xo'
|
import { runBackupNgJob, subscribeBackupNgLogs, subscribeRemotes } from 'xo'
|
||||||
|
import { VmItem, SrItem, RemoteItem } from 'render-xo-item'
|
||||||
|
|
||||||
const TASK_STATUS = {
|
const TASK_STATUS = {
|
||||||
failure: {
|
failure: {
|
||||||
@ -166,7 +166,7 @@ export default [
|
|||||||
let globalIsFull
|
let globalIsFull
|
||||||
return (
|
return (
|
||||||
<li key={taskLog.data.id} className='list-group-item'>
|
<li key={taskLog.data.id} className='list-group-item'>
|
||||||
{renderXoItemFromId(taskLog.data.id)} ({taskLog.data.id.slice(
|
<VmItem id={taskLog.data.id} link /> ({taskLog.data.id.slice(
|
||||||
4,
|
4,
|
||||||
8
|
8
|
||||||
)}) <TaskStateInfos status={taskLog.status} />{' '}
|
)}) <TaskStateInfos status={taskLog.status} />{' '}
|
||||||
@ -202,17 +202,14 @@ export default [
|
|||||||
</span>
|
</span>
|
||||||
) : subTaskLog.data.type === 'remote' ? (
|
) : subTaskLog.data.type === 'remote' ? (
|
||||||
<span>
|
<span>
|
||||||
{get(remotes, subTaskLog.data.id) !== undefined
|
<RemoteItem id={subTaskLog.data.id} link /> ({subTaskLog.data.id.slice(
|
||||||
? renderXoItem({
|
4,
|
||||||
type: 'remote',
|
8
|
||||||
value: remotes[subTaskLog.data.id],
|
)})
|
||||||
})
|
|
||||||
: _('errorNoSuchItem')}{' '}
|
|
||||||
({subTaskLog.data.id.slice(4, 8)})
|
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
<span>
|
<span>
|
||||||
{renderXoItemFromId(subTaskLog.data.id)} ({subTaskLog.data.id.slice(
|
<SrItem id={subTaskLog.data.id} link /> ({subTaskLog.data.id.slice(
|
||||||
4,
|
4,
|
||||||
8
|
8
|
||||||
)})
|
)})
|
||||||
|
Loading…
Reference in New Issue
Block a user