Skip to content

Commit

Permalink
feat(xo-web/{host,vm}): state icons improvements (#4363)
Browse files Browse the repository at this point in the history
- Always use .xo-status-* classes
- Show host busy state in the host view as well (previously only in home/hosts view)
- Differentiate "disabled" state from "busy" state
- Host view state icon tooltip
- Homogenize state display between hosts and VMs
  • Loading branch information
pdonias committed Jul 19, 2019
1 parent 79a80a1 commit 619818f
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 62 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
- [Backup NG] Ability to bypass unhealthy VDI chains check [#4324](https://github.com/vatesfr/xen-orchestra/issues/4324) (PR [#4340](https://github.com/vatesfr/xen-orchestra/pull/4340))
- [Pool] Ability to add multiple hosts on the pool [#2402](https://github.com/vatesfr/xen-orchestra/issues/2402) (PR [#3716](https://github.com/vatesfr/xen-orchestra/pull/3716))
- [VM/console] Multiline copy/pasting [#4261](https://github.com/vatesfr/xen-orchestra/issues/4261) (PR [#4341](https://github.com/vatesfr/xen-orchestra/pull/4341))
- [VM,host] Improved state icons/pills (colors and tooltips) (PR [#4363](https://github.com/vatesfr/xen-orchestra/pull/4363))

### Bug fixes

Expand Down
2 changes: 2 additions & 0 deletions packages/xo-web/src/common/intl/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -946,6 +946,8 @@ const messages = {
powerStateRunning: 'Running',
powerStateSuspended: 'Suspended',
powerStatePaused: 'Paused',
powerStateDisabled: 'Disabled',
powerStateBusy: 'Busy',

// ----- VM home -----
vmCurrentStatus: 'Current status:',
Expand Down
28 changes: 14 additions & 14 deletions packages/xo-web/src/icons.scss
Original file line number Diff line number Diff line change
Expand Up @@ -328,27 +328,27 @@
&-running {
@extend .fa;
@extend .fa-desktop;
@extend .text-success;
@extend .xo-status-running;
}
&-suspended {
@extend .fa;
@extend .fa-desktop;
@extend .text-primary;
@extend .xo-status-suspended;
}
&-paused {
@extend .fa;
@extend .fa-desktop;
@extend .text-muted;
@extend .xo-status-paused;
}
&-halted {
@extend .fa;
@extend .fa-desktop;
@extend .text-danger;
@extend .xo-status-halted;
}
&-busy {
@extend .fa;
@extend .fa-desktop;
@extend .text-warning;
@extend .xo-status-busy;
}

// Actions
Expand Down Expand Up @@ -457,7 +457,7 @@
&-disabled {
@extend .fa;
@extend .fa-circle;
@extend .xo-status-busy;
@extend .xo-status-disabled;
}

&-all-connected {
Expand Down Expand Up @@ -530,26 +530,26 @@
&-running {
@extend .fa;
@extend .fa-server;
@extend .text-success;
@extend .xo-status-running;
}
&-halted {
@extend .fa;
@extend .fa-server;
@extend .text-danger;
@extend .xo-status-halted;
}
&-disabled {
@extend .fa;
@extend .fa-server;
@extend .text-warning;
@extend .xo-status-disabled;
}
&-forget {
&-busy {
@extend .fa;
@extend .fa-ban;
@extend .fa-server;
@extend .xo-status-busy;
}
&-working {
&-forget {
@extend .fa;
@extend .fa-circle;
@extend .text-warning;
@extend .fa-ban;
}

// Actions
Expand Down
2 changes: 1 addition & 1 deletion packages/xo-web/src/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ $select-input-height: 40px; // Bootstrap input height
@extend .text-info;
}

.xo-status-unknown, .xo-status-paused {
.xo-status-unknown, .xo-status-paused, .xo-status-disabled {
@extend .text-muted;
}

Expand Down
46 changes: 25 additions & 21 deletions packages/xo-web/src/xo-app/home/host-item.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,22 @@ export default class HostItem extends Component {
_toggleExpanded = () => this.setState({ expanded: !this.state.expanded })
_onSelect = () => this.props.onSelect(this.props.item.id)

_getHostState = createSelector(
() => this.props.item.power_state,
() => this.props.item.enabled,
() => this.props.item.current_operations,
(powerState, enabled, operations) =>
!isEmpty(operations)
? 'Busy'
: powerState === 'Running' && !enabled
? 'Disabled'
: powerState
)

render() {
const { item: host, container, expandAll, selected, nVms } = this.props
const toolTipContent =
host.power_state === `Running` && !host.enabled
? `disabled`
: _(`powerState${host.power_state}`)
const state = this._getHostState()

return (
<div className={styles.item}>
<BlockLink to={`/hosts/${host.id}`}>
Expand All @@ -86,25 +96,19 @@ export default class HostItem extends Component {
&nbsp;&nbsp;
<Tooltip
content={
isEmpty(host.current_operations) ? (
toolTipContent
) : (
<div>
{toolTipContent}
{' ('}
{map(host.current_operations)[0]}
{')'}
</div>
)
<span>
{_(`powerState${state}`)}
{state === 'Busy' && (
<span>
{' ('}
{map(host.current_operations)[0]}
{')'}
</span>
)}
</span>
}
>
{!isEmpty(host.current_operations) ? (
<Icon icon='busy' />
) : host.power_state === 'Running' && !host.enabled ? (
<Icon icon='disabled' />
) : (
<Icon icon={`${host.power_state.toLowerCase()}`} />
)}
<Icon icon={state.toLowerCase()} />
</Tooltip>
&nbsp;&nbsp;
<Ellipsis>
Expand Down
33 changes: 18 additions & 15 deletions packages/xo-web/src/xo-app/home/vm-item.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,16 @@ export default class VmItem extends Component {
_toggleExpanded = () => this.setState({ expanded: !this.state.expanded })
_onSelect = () => this.props.onSelect(this.props.item.id)

_getVmState = createSelector(
() => this.props.item.power_state,
() => this.props.item.current_operations,
(powerState, operations) => (!isEmpty(operations) ? 'Busy' : powerState)
)

render() {
const { item: vm, container, expandAll, selected } = this.props
const resourceSet = this._getResourceSet()
const state = this._getVmState()

return (
<div className={styles.item}>
Expand All @@ -99,23 +106,19 @@ export default class VmItem extends Component {
&nbsp;&nbsp;
<Tooltip
content={
isEmpty(vm.current_operations) ? (
_(`powerState${vm.power_state}`)
) : (
<div>
{_(`powerState${vm.power_state}`)}
{' ('}
{map(vm.current_operations)[0]}
{')'}
</div>
)
<span>
{_(`powerState${state}`)}
{state === 'Busy' && (
<span>
{' ('}
{map(vm.current_operations)[0]}
{')'}
</span>
)}
</span>
}
>
{isEmpty(vm.current_operations) ? (
<Icon icon={`${vm.power_state.toLowerCase()}`} />
) : (
<Icon icon='busy' />
)}
<Icon icon={state.toLowerCase()} />
</Tooltip>
&nbsp;&nbsp;
<Ellipsis>
Expand Down
34 changes: 28 additions & 6 deletions packages/xo-web/src/xo-app/host/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,22 @@ export default class Host extends Component {
_setNameLabel = nameLabel =>
editHost(this.props.host, { name_label: nameLabel })

_getHostState = createSelector(
() => this.props.host.power_state,
() => this.props.host.enabled,
() => this.props.host.current_operations,
(powerState, enabled, operations) =>
!isEmpty(operations)
? 'Busy'
: powerState === 'Running' && !enabled
? 'Disabled'
: powerState
)

header() {
const { host, pool } = this.props
const { missingPatches } = this.state || {}
const state = this._getHostState()
if (!host) {
return <Icon icon='loading' />
}
Expand All @@ -240,13 +253,22 @@ export default class Host extends Component {
<Col mediumSize={6} className='header-title'>
{pool !== undefined && <Pool id={pool.id} link />}
<h2>
<Icon
icon={
host.power_state === 'Running' && !host.enabled
? 'host-disabled'
: `host-${host.power_state.toLowerCase()}`
<Tooltip
content={
<span>
{_(`powerState${state}`)}
{state === 'Busy' && (
<span>
{' ('}
{map(host.current_operations)[0]}
{')'}
</span>
)}
</span>
}
/>{' '}
>
<Icon icon={`host-${state.toLowerCase()}`} />
</Tooltip>{' '}
<Text value={host.name_label} onChange={this._setNameLabel} />
{this.props.needsRestart && (
<Tooltip content={_('rebootUpdateHostLabel')}>
Expand Down
28 changes: 23 additions & 5 deletions packages/xo-web/src/xo-app/vm/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,14 +168,19 @@ export default class Vm extends BaseComponent {
_setNameLabel = nameLabel => editVm(this.props.vm, { name_label: nameLabel })
_migrateVm = host => migrateVm(this.props.vm, host)

_getVmState = createSelector(
() => this.props.vm.power_state,
() => this.props.vm.current_operations,
(powerState, operations) => (!isEmpty(operations) ? 'Busy' : powerState)
)

header() {
const { vm, container, pool } = this.props
if (!vm) {
return <Icon icon='loading' />
}
const state = isEmpty(vm.current_operations)
? vm.power_state.toLowerCase()
: 'busy'
const state = this._getVmState()

return (
<Container>
<Row>
Expand Down Expand Up @@ -207,8 +212,21 @@ export default class Vm extends BaseComponent {
</span>
</span>
<h2>
<Tooltip content={state}>
<Icon icon={`vm-${state}`} />
<Tooltip
content={
<span>
{_(`powerState${state}`)}
{state === 'Busy' && (
<span>
{' ('}
{map(vm.current_operations)[0]}
{')'}
</span>
)}
</span>
}
>
<Icon icon={`vm-${state.toLowerCase()}`} />
</Tooltip>{' '}
<Text value={vm.name_label} onChange={this._setNameLabel} />
</h2>{' '}
Expand Down

0 comments on commit 619818f

Please sign in to comment.