parent
55d7a1def0
commit
56a2f8858b
@ -2,7 +2,7 @@ import _ from 'intl'
|
||||
import PropTypes from 'prop-types'
|
||||
import React from 'react'
|
||||
import { get } from '@xen-orchestra/defined'
|
||||
import { startsWith } from 'lodash'
|
||||
import { find, startsWith } from 'lodash'
|
||||
|
||||
import decorate from './apply-decorators'
|
||||
import Icon from './icon'
|
||||
@ -14,186 +14,314 @@ import { isSrWritable, subscribeRemotes } from './xo'
|
||||
|
||||
// ===================================================================
|
||||
|
||||
const OBJECT_TYPE_TO_ICON = {
|
||||
'VM-template': 'vm',
|
||||
host: 'host',
|
||||
network: 'network',
|
||||
}
|
||||
const UNKNOWN_ITEM = <span className='text-muted'>{_('errorUnknownItem')}</span>
|
||||
|
||||
const COMMON_PROP_TYPES = {
|
||||
link: PropTypes.bool,
|
||||
}
|
||||
|
||||
const XoItem = ({ children, item, link, to, newTab }) =>
|
||||
item !== undefined ? (
|
||||
link ? (
|
||||
<Link to={to} target={newTab && '_blank'}>
|
||||
{children()}
|
||||
</Link>
|
||||
) : (
|
||||
children()
|
||||
)
|
||||
const LinkWrapper = ({ children, link, to, newTab }) =>
|
||||
link ? (
|
||||
<Link to={to} target={newTab && '_blank'}>
|
||||
{children}
|
||||
</Link>
|
||||
) : (
|
||||
<span className='text-muted'>{_('errorUnknownItem')}</span>
|
||||
<span>{children}</span>
|
||||
)
|
||||
|
||||
XoItem.propTypes = {
|
||||
...COMMON_PROP_TYPES,
|
||||
item: PropTypes.object,
|
||||
LinkWrapper.propTypes = {
|
||||
link: PropTypes.bool,
|
||||
newTab: PropTypes.bool,
|
||||
to: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
|
||||
const XO_ITEM_PROP_TYPES = {
|
||||
...COMMON_PROP_TYPES,
|
||||
export const Pool = decorate([
|
||||
connectStore(() => ({
|
||||
pool: createGetObject(),
|
||||
})),
|
||||
({ pool, link, newTab }) => {
|
||||
if (pool === undefined) {
|
||||
return UNKNOWN_ITEM
|
||||
}
|
||||
|
||||
return (
|
||||
<LinkWrapper link={link} newTab={newTab} to={`/pools/${pool.id}`}>
|
||||
<Icon icon='pool' /> {pool.name_label}
|
||||
</LinkWrapper>
|
||||
)
|
||||
},
|
||||
])
|
||||
|
||||
Pool.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
link: PropTypes.bool,
|
||||
newTab: PropTypes.bool,
|
||||
}
|
||||
|
||||
export const VmItem = decorate([
|
||||
Pool.defaultProps = {
|
||||
link: false,
|
||||
newTab: false,
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
|
||||
export const Host = decorate([
|
||||
connectStore(() => {
|
||||
const getHost = createGetObject()
|
||||
return {
|
||||
host: getHost,
|
||||
pool: createGetObject(
|
||||
createSelector(
|
||||
getHost,
|
||||
host => get(() => host.$pool)
|
||||
)
|
||||
),
|
||||
}
|
||||
}),
|
||||
({ host, pool, link, newTab }) => {
|
||||
if (host === undefined) {
|
||||
return UNKNOWN_ITEM
|
||||
}
|
||||
|
||||
return (
|
||||
<LinkWrapper link={link} newTab={newTab} to={`/hosts/${host.id}`}>
|
||||
<Icon icon='host' /> {host.name_label}
|
||||
{pool !== undefined && ` (${pool.name_label})`}
|
||||
</LinkWrapper>
|
||||
)
|
||||
},
|
||||
])
|
||||
|
||||
Host.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
link: PropTypes.bool,
|
||||
newTab: PropTypes.bool,
|
||||
}
|
||||
|
||||
Host.defaultProps = {
|
||||
link: false,
|
||||
newTab: false,
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
|
||||
export const Vm = decorate([
|
||||
connectStore(() => {
|
||||
const getVm = createGetObject()
|
||||
return {
|
||||
vm: getVm,
|
||||
container: createGetObject(
|
||||
createSelector(getVm, vm => get(() => vm.$container))
|
||||
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>
|
||||
),
|
||||
])
|
||||
|
||||
VmItem.propTypes = XO_ITEM_PROP_TYPES
|
||||
|
||||
export const SrItem = decorate([
|
||||
connectStore(() => {
|
||||
const getSr = createGetObject()
|
||||
return {
|
||||
sr: getSr,
|
||||
container: createGetObject(
|
||||
createSelector(getSr, sr => get(() => sr.$container))
|
||||
),
|
||||
({ vm, container, link, newTab }) => {
|
||||
if (vm === undefined) {
|
||||
return UNKNOWN_ITEM
|
||||
}
|
||||
}),
|
||||
({ 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>
|
||||
),
|
||||
|
||||
return (
|
||||
<LinkWrapper link={link} newTab={newTab} to={`/vms/${vm.id}`}>
|
||||
<Icon icon={`vm-${vm.power_state.toLowerCase()}`} /> {vm.name_label}
|
||||
{container !== undefined && ` (${container.name_label})`}
|
||||
</LinkWrapper>
|
||||
)
|
||||
},
|
||||
])
|
||||
|
||||
SrItem.propTypes = XO_ITEM_PROP_TYPES
|
||||
|
||||
export const RemoteItem = decorate([
|
||||
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>
|
||||
),
|
||||
])
|
||||
|
||||
RemoteItem.propTypes = XO_ITEM_PROP_TYPES
|
||||
|
||||
export const PoolItem = decorate([
|
||||
connectStore(() => ({
|
||||
pool: createGetObject(),
|
||||
})),
|
||||
({ pool, ...props }) => (
|
||||
<XoItem item={pool} to={`/pools/${get(() => pool.id)}`} {...props}>
|
||||
{() => (
|
||||
<span>
|
||||
<Icon icon='pool' /> {pool.name_label || pool.id}
|
||||
</span>
|
||||
)}
|
||||
</XoItem>
|
||||
),
|
||||
])
|
||||
|
||||
PoolItem.propTypes = XO_ITEM_PROP_TYPES
|
||||
|
||||
// ===================================================================
|
||||
|
||||
export const SrResourceSetItem = decorate([
|
||||
connectStore(() => {
|
||||
const getSr = createGetObject()
|
||||
return (state, props) => ({
|
||||
// true to bypass permissions as a self user
|
||||
sr: getSr(state, props, true),
|
||||
})
|
||||
}),
|
||||
({ sr, ...props }) => (
|
||||
<XoItem item={sr} to={sr !== undefined && `/srs/${sr.id}`} {...props}>
|
||||
{() => (
|
||||
<span>
|
||||
<Icon icon='sr' /> {sr.name_label || sr.id}
|
||||
{isSrWritable(sr) && (
|
||||
<span>{` (${formatSize(sr.size - sr.physical_usage)} free)`}</span>
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
</XoItem>
|
||||
),
|
||||
])
|
||||
|
||||
SrResourceSetItem.propTypes = XO_ITEM_PROP_TYPES
|
||||
|
||||
// ===================================================================
|
||||
|
||||
// Host, Network, VM-template.
|
||||
const PoolObjectItem = connectStore(() => {
|
||||
const getPool = createGetObject((_, props) => props.object.$pool)
|
||||
|
||||
return (state, props) => ({
|
||||
pool: getPool(state, props),
|
||||
})
|
||||
})(({ object, pool }) => {
|
||||
const icon = OBJECT_TYPE_TO_ICON[object.type]
|
||||
const { id } = object
|
||||
|
||||
return (
|
||||
<span>
|
||||
<Icon icon={icon} /> {`${object.name_label || id} `}
|
||||
{pool && `(${pool.name_label || pool.id})`}
|
||||
</span>
|
||||
)
|
||||
})
|
||||
|
||||
PoolObjectItem.propTypes = {
|
||||
object: PropTypes.object.isRequired,
|
||||
Vm.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
link: PropTypes.bool,
|
||||
newTab: PropTypes.bool,
|
||||
}
|
||||
|
||||
const VgpuItem = connectStore(() => ({
|
||||
Vm.defaultProps = {
|
||||
link: false,
|
||||
newTab: false,
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
|
||||
export const VmTemplate = decorate([
|
||||
connectStore(() => {
|
||||
const getObject = createGetObject()
|
||||
return (state, props) => ({
|
||||
// FIXME: props.self ugly workaround to get object as a self user
|
||||
template: getObject(state, props, props.self),
|
||||
})
|
||||
}),
|
||||
({ template }) => {
|
||||
if (template === undefined) {
|
||||
return UNKNOWN_ITEM
|
||||
}
|
||||
|
||||
return (
|
||||
<span>
|
||||
<Icon icon='vm' /> {template.name_label}
|
||||
</span>
|
||||
)
|
||||
},
|
||||
])
|
||||
|
||||
VmTemplate.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
self: PropTypes.bool,
|
||||
}
|
||||
|
||||
VmTemplate.defaultProps = {
|
||||
link: false,
|
||||
newTab: false,
|
||||
self: false,
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
|
||||
export const Sr = decorate([
|
||||
connectStore(() => {
|
||||
const getSr = createGetObject()
|
||||
const getContainer = createGetObject(
|
||||
createSelector(
|
||||
getSr,
|
||||
sr => get(() => sr.$container)
|
||||
)
|
||||
)
|
||||
return (state, props) => ({
|
||||
// FIXME: props.self ugly workaround to get object as a self user
|
||||
sr: getSr(state, props, props.self),
|
||||
container: getContainer(state, props),
|
||||
})
|
||||
}),
|
||||
({ sr, container, link, newTab }) => {
|
||||
if (sr === undefined) {
|
||||
return UNKNOWN_ITEM
|
||||
}
|
||||
|
||||
return (
|
||||
<LinkWrapper link={link} newTab={newTab} to={`/srs/${sr.id}`}>
|
||||
<Icon icon='sr' /> {sr.name_label}
|
||||
{container !== undefined && (
|
||||
<span className='text-muted'> - {container.name_label}</span>
|
||||
)}
|
||||
{isSrWritable(sr) && (
|
||||
<span>{` (${formatSize(sr.size - sr.physical_usage)} free)`}</span>
|
||||
)}
|
||||
</LinkWrapper>
|
||||
)
|
||||
},
|
||||
])
|
||||
|
||||
Sr.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
link: PropTypes.bool,
|
||||
newTab: PropTypes.bool,
|
||||
self: PropTypes.bool,
|
||||
}
|
||||
|
||||
Sr.defaultProps = {
|
||||
link: false,
|
||||
newTab: false,
|
||||
self: false,
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
|
||||
export const Vdi = decorate([
|
||||
connectStore(() => {
|
||||
const getObject = createGetObject()
|
||||
// FIXME: props.self ugly workaround to get object as a self user
|
||||
return (state, props) => ({
|
||||
vdi: getObject(state, props, props.self),
|
||||
})
|
||||
}),
|
||||
({ vdi }) => {
|
||||
if (vdi === undefined) {
|
||||
return UNKNOWN_ITEM
|
||||
}
|
||||
|
||||
return (
|
||||
<span>
|
||||
<Icon icon='disk' /> {vdi.name_label}
|
||||
{vdi.name_description && <span> ({vdi.name_description})</span>}
|
||||
</span>
|
||||
)
|
||||
},
|
||||
])
|
||||
|
||||
Vdi.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
self: PropTypes.bool,
|
||||
}
|
||||
|
||||
Vdi.defaultProps = {
|
||||
self: false,
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
|
||||
export const Network = decorate([
|
||||
connectStore(() => {
|
||||
const getObject = createGetObject()
|
||||
// FIXME: props.self ugly workaround to get object as a self user
|
||||
return (state, props) => ({
|
||||
network: getObject(state, props, props.self),
|
||||
})
|
||||
}),
|
||||
({ network }) => {
|
||||
if (network === undefined) {
|
||||
return UNKNOWN_ITEM
|
||||
}
|
||||
|
||||
return (
|
||||
<span>
|
||||
<Icon icon='network' /> {network.name_label}
|
||||
</span>
|
||||
)
|
||||
},
|
||||
])
|
||||
|
||||
Network.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
self: PropTypes.bool,
|
||||
}
|
||||
|
||||
Network.defaultProps = {
|
||||
self: false,
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
|
||||
export const Remote = decorate([
|
||||
addSubscriptions(({ id }) => ({
|
||||
remote: cb => subscribeRemotes(remotes => cb(find(remotes, { id }))),
|
||||
})),
|
||||
({ remote, link, newTab }) => {
|
||||
if (remote === undefined) {
|
||||
return UNKNOWN_ITEM // TODO: handle remotes not fetched yet
|
||||
}
|
||||
|
||||
return (
|
||||
<LinkWrapper link={link} newTab={newTab} to='/settings/remotes'>
|
||||
<Icon icon='remote' /> {remote.name}
|
||||
</LinkWrapper>
|
||||
)
|
||||
},
|
||||
])
|
||||
|
||||
Remote.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
link: PropTypes.bool,
|
||||
newTab: PropTypes.bool,
|
||||
}
|
||||
|
||||
Remote.defaultProps = {
|
||||
link: false,
|
||||
newTab: false,
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
|
||||
export const Vgpu = connectStore(() => ({
|
||||
vgpuType: createGetObject((_, props) => props.vgpu.vgpuType),
|
||||
}))(({ vgpu, vgpuType }) => (
|
||||
<span>
|
||||
@ -201,6 +329,10 @@ const VgpuItem = connectStore(() => ({
|
||||
</span>
|
||||
))
|
||||
|
||||
Vgpu.propTypes = {
|
||||
vgpu: PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
|
||||
const xoItemToRender = {
|
||||
@ -215,7 +347,7 @@ const xoItemToRender = {
|
||||
<Icon icon='group' /> {group.name}
|
||||
</span>
|
||||
),
|
||||
remote: ({ value: { id } }) => <RemoteItem id={id} />,
|
||||
remote: ({ value: { id } }) => <Remote id={id} />,
|
||||
role: role => <span>{role.name}</span>,
|
||||
user: user => (
|
||||
<span>
|
||||
@ -248,30 +380,28 @@ const xoItemToRender = {
|
||||
},
|
||||
|
||||
// XO objects.
|
||||
pool: ({ id }) => <PoolItem id={id} />,
|
||||
pool: ({ id }) => <Pool id={id} />,
|
||||
|
||||
VDI: vdi => (
|
||||
<span>
|
||||
<Icon icon='disk' /> {vdi.name_label}{' '}
|
||||
{vdi.name_description && <span> ({vdi.name_description})</span>}
|
||||
</span>
|
||||
),
|
||||
VDI: ({ id }) => <Vdi id={id} />,
|
||||
'VDI-resourceSet': ({ id }) => <Vdi id={id} self />,
|
||||
|
||||
// Pool objects.
|
||||
'VM-template': vmTemplate => <PoolObjectItem object={vmTemplate} />,
|
||||
host: host => <PoolObjectItem object={host} />,
|
||||
network: network => <PoolObjectItem object={network} />,
|
||||
'VM-template': ({ id }) => <VmTemplate id={id} />,
|
||||
'VM-template-resourceSet': ({ id }) => <VmTemplate id={id} self />,
|
||||
host: ({ id }) => <Host id={id} />,
|
||||
network: ({ id }) => <Network id={id} />,
|
||||
'network-resourceSet': ({ id }) => <Network id={id} self />,
|
||||
|
||||
// SR.
|
||||
SR: ({ id }) => <SrItem id={id} />,
|
||||
'SR-resourceSet': ({ id }) => <SrResourceSetItem id={id} />,
|
||||
SR: ({ id }) => <Sr id={id} />,
|
||||
'SR-resourceSet': ({ id }) => <Sr id={id} self />,
|
||||
|
||||
// VM.
|
||||
VM: ({ id }) => <VmItem id={id} />,
|
||||
'VM-snapshot': ({ id }) => <VmItem id={id} />,
|
||||
VM: ({ id }) => <Vm id={id} />,
|
||||
'VM-snapshot': ({ id }) => <Vm id={id} />,
|
||||
'VM-controller': ({ id }) => (
|
||||
<span>
|
||||
<Icon icon='host' /> <VmItem id={id} />
|
||||
<Icon icon='host' /> <Vm id={id} />
|
||||
</span>
|
||||
),
|
||||
|
||||
@ -295,7 +425,7 @@ const xoItemToRender = {
|
||||
|
||||
// GPUs
|
||||
|
||||
vgpu: vgpu => <VgpuItem vgpu={vgpu} />,
|
||||
vgpu: vgpu => <Vgpu vgpu={vgpu} />,
|
||||
|
||||
vgpuType: type => (
|
||||
<span>
|
||||
@ -318,9 +448,6 @@ const xoItemToRender = {
|
||||
{backup.mode}
|
||||
</span>{' '}
|
||||
<span className='tag tag-warning'>{backup.remote.name}</span>{' '}
|
||||
<span className='tag tag-success'>
|
||||
{backup.jobName !== undefined ? backup.jobName : _('unknownJob')}
|
||||
</span>{' '}
|
||||
<FormattedDate
|
||||
value={new Date(backup.timestamp)}
|
||||
month='long'
|
||||
|
@ -247,11 +247,6 @@ class GenericSelect extends React.Component {
|
||||
}
|
||||
|
||||
// GroupBy: Display option with margin if not disabled and containers exists.
|
||||
/* TODO: When all item components are implemented, change type to this:
|
||||
type: this.props.resourceSet !== undefined && option.xoItem.type !== undefined
|
||||
? `${option.xoItem.type}-resourceSet`
|
||||
: undefined
|
||||
*/
|
||||
_renderOption = option => (
|
||||
<span
|
||||
className={
|
||||
@ -262,8 +257,9 @@ class GenericSelect extends React.Component {
|
||||
>
|
||||
{renderXoItem(option.xoItem, {
|
||||
type:
|
||||
this.props.resourceSet && option.xoItem.type === 'SR'
|
||||
? 'SR-resourceSet'
|
||||
this.props.resourceSet !== undefined &&
|
||||
option.xoItem.type !== undefined
|
||||
? `${option.xoItem.type}-resourceSet`
|
||||
: undefined,
|
||||
})}
|
||||
</span>
|
||||
|
@ -16,7 +16,7 @@ import {
|
||||
} from 'selectors'
|
||||
import { forEach } from 'lodash'
|
||||
import { SelectSr } from 'select-objects'
|
||||
import { VmItem } from 'render-xo-item'
|
||||
import { Vm } from 'render-xo-item'
|
||||
import { ejectCd, isSrWritable, setDefaultSr } from 'xo'
|
||||
|
||||
@connectStore(
|
||||
@ -60,7 +60,7 @@ export default class InstallPoolPatchesModalBody extends Component {
|
||||
_getTooltip = createSelector(this._getVmsWithCds, vmIds =>
|
||||
vmIds.map(vmId => (
|
||||
<p className='m-0' key={vmId}>
|
||||
<VmItem id={vmId} />
|
||||
<Vm id={vmId} />
|
||||
</p>
|
||||
))
|
||||
)
|
||||
|
@ -21,7 +21,7 @@ import { injectIntl } from 'react-intl'
|
||||
import { injectState, provideState } from 'reaclette'
|
||||
import { Map } from 'immutable'
|
||||
import { Number } from 'form'
|
||||
import { renderXoItemFromId, RemoteItem } from 'render-xo-item'
|
||||
import { renderXoItemFromId, Remote } from 'render-xo-item'
|
||||
import { SelectRemote, SelectSr, SelectVm } from 'select-objects'
|
||||
import {
|
||||
addSubscriptions,
|
||||
@ -762,7 +762,7 @@ export default decorate([
|
||||
<Ul>
|
||||
{map(state.remotes, (id, key) => (
|
||||
<Li key={id}>
|
||||
<RemoteItem id={id} />
|
||||
<Remote id={id} />
|
||||
<div className='pull-right'>
|
||||
<DeleteOldBackupsFirst
|
||||
handler={effects.setTargetDeleteFirst}
|
||||
|
@ -18,7 +18,7 @@ import { injectState, provideState } from 'reaclette'
|
||||
import { isEmpty, groupBy, map, keyBy } from 'lodash'
|
||||
import { subscribeBackupNgJobs, subscribeBackupNgLogs } from 'xo'
|
||||
import { toggleState } from 'reaclette-utils'
|
||||
import { VmItem, SrItem } from 'render-xo-item'
|
||||
import { Vm, Sr } from 'render-xo-item'
|
||||
|
||||
import LogAlertBody from './log-alert-body'
|
||||
import LogAlertHeader from './log-alert-header'
|
||||
@ -195,7 +195,7 @@ const LOG_RESTORE_COLUMNS = [
|
||||
name: _('labelVm'),
|
||||
itemRenderer: ({ id, vm, status }) => (
|
||||
<div>
|
||||
{vm !== undefined && <VmItem id={vm.id} link newTab />}
|
||||
{vm !== undefined && <Vm id={vm.id} link newTab />}
|
||||
{vm === undefined && status === 'success' && (
|
||||
<span className='text-warning'>{_('logsVmNotFound')}</span>
|
||||
)}{' '}
|
||||
@ -216,7 +216,7 @@ const LOG_RESTORE_COLUMNS = [
|
||||
DURATION_COLUMN,
|
||||
{
|
||||
name: _('labelSr'),
|
||||
itemRenderer: ({ data: { srId } }) => <SrItem id={srId} link newTab />,
|
||||
itemRenderer: ({ data: { srId } }) => <Sr id={srId} link newTab />,
|
||||
sortCriteria: ({ data: { srId } }, { srs }) =>
|
||||
get(() => srs[srId].name_label),
|
||||
},
|
||||
|
@ -10,7 +10,7 @@ import { countBy, filter, get, keyBy, map } from 'lodash'
|
||||
import { FormattedDate } from 'react-intl'
|
||||
import { injectState, provideState } from 'reaclette'
|
||||
import { runBackupNgJob, subscribeBackupNgLogs, subscribeRemotes } from 'xo'
|
||||
import { VmItem, SrItem, RemoteItem } from 'render-xo-item'
|
||||
import { Vm, Sr, Remote } from 'render-xo-item'
|
||||
|
||||
const TASK_STATUS = {
|
||||
failure: {
|
||||
@ -195,7 +195,7 @@ export default decorate([
|
||||
let globalIsFull
|
||||
return (
|
||||
<li key={taskLog.data.id} className='list-group-item'>
|
||||
<VmItem id={taskLog.data.id} link newTab /> (
|
||||
<Vm id={taskLog.data.id} link newTab /> (
|
||||
{taskLog.data.id.slice(4, 8)}){' '}
|
||||
<TaskStateInfos status={taskLog.status} />{' '}
|
||||
{scheduleId !== undefined &&
|
||||
@ -231,12 +231,12 @@ export default decorate([
|
||||
</span>
|
||||
) : subTaskLog.data.type === 'remote' ? (
|
||||
<span>
|
||||
<RemoteItem id={subTaskLog.data.id} link newTab /> (
|
||||
<Remote id={subTaskLog.data.id} link newTab /> (
|
||||
{subTaskLog.data.id.slice(4, 8)})
|
||||
</span>
|
||||
) : (
|
||||
<span>
|
||||
<SrItem id={subTaskLog.data.id} link newTab /> (
|
||||
<Sr id={subTaskLog.data.id} link newTab /> (
|
||||
{subTaskLog.data.id.slice(4, 8)})
|
||||
</span>
|
||||
)}{' '}
|
||||
|
@ -18,7 +18,7 @@ import {
|
||||
some,
|
||||
toArray,
|
||||
} from 'lodash'
|
||||
import { PoolItem } from 'render-xo-item'
|
||||
import { Pool } from 'render-xo-item'
|
||||
import {
|
||||
createFilter,
|
||||
createGetObject,
|
||||
@ -73,7 +73,7 @@ export class TaskItem extends Component {
|
||||
const COLUMNS = [
|
||||
{
|
||||
default: true,
|
||||
itemRenderer: ({ $poolId }) => <PoolItem id={$poolId} link />,
|
||||
itemRenderer: ({ $poolId }) => <Pool id={$poolId} link />,
|
||||
name: _('pool'),
|
||||
sortCriteria: (task, userData) => {
|
||||
const pool = userData.pools[task.$poolId]
|
||||
@ -101,7 +101,7 @@ const COLUMNS = [
|
||||
|
||||
const FINISHED_TASKS_COLUMNS = [
|
||||
{
|
||||
itemRenderer: ({ $poolId }) => <PoolItem id={$poolId} link />,
|
||||
itemRenderer: ({ $poolId }) => <Pool id={$poolId} link />,
|
||||
name: _('pool'),
|
||||
},
|
||||
{
|
||||
|
@ -3,7 +3,7 @@ import ActionButton from 'action-button'
|
||||
import Component from 'base-component'
|
||||
import Link from 'link'
|
||||
import React from 'react'
|
||||
import renderXoItem, { PoolItem } from 'render-xo-item'
|
||||
import renderXoItem, { Pool } from 'render-xo-item'
|
||||
import SortedTable from 'sorted-table'
|
||||
import { connectStore } from 'utils'
|
||||
import { createSelector, createGetObjectsOfType, createFilter } from 'selectors'
|
||||
@ -69,7 +69,7 @@ const XOSAN_COLUMNS = [
|
||||
},
|
||||
{
|
||||
name: _('xosanPool'),
|
||||
itemRenderer: sr => <PoolItem id={sr.$pool} link />,
|
||||
itemRenderer: sr => <Pool id={sr.$pool} link />,
|
||||
},
|
||||
{
|
||||
name: _('xosanLicense'),
|
||||
|
Loading…
Reference in New Issue
Block a user