fix(xo-web/vm/console): make collapsed header state reliable (#10007)

The console tab kept its own `minimalLayout` state to track whether the page header was collapsed, separate from the VM page's `collapsedHeader`. The two desynced because the tab remounts on navigation while the VM page stays mounted.

Fix:
- Single source of truth `collapsedHeader` in the parent index.js
- Pass it to the child tab-console.js along with `setCollapsedHeader`
- Replace the `_toggleHeader` toggle with an explicit `_setCollapsedHeader(value)` setter
- Remove the duplicate local `minimalLayout` state that could get out of sync and use `collapsedHeader` instead
- Force off on VM shutdown (console no longer displayed) and on unmount (user changed page)
This commit is contained in:
Pierre Donias
2026-08-13 15:15:25 +02:00
committed by GitHub
parent 0601716fa4
commit 7cdb792bfe
3 changed files with 19 additions and 15 deletions

View File

@@ -26,6 +26,8 @@
- [REST API] Fix `/users/:id/authentication_tokens` sometimes did not return the token used to make the request (PR [#10233](https://github.com/vatesfr/xen-orchestra/pull/10233))
- [XO server] Fix a random behavior regarding `coresPerSocket` update (PR [#10201](https://github.com/vatesfr/xen-orchestra/pull/10201))
- [Warm migration] Fix `Vm target of warm migration not found` error at the end of a migration (PR [#10210](https://github.com/vatesfr/xen-orchestra/pull/10210))
- **XO 5**:
- [VM/Console] Fix the page header and tab navigation disappearing permanently in the console tab (PR [#10007](https://github.com/vatesfr/xen-orchestra/pull/10007))
### Packages to release

View File

@@ -264,7 +264,7 @@ export default class Vm extends BaseComponent {
)
}
_toggleHeader = () => this.setState({ collapsedHeader: !this.state.collapsedHeader })
_setCollapsedHeader = collapsedHeader => this.setState({ collapsedHeader })
render() {
const { container, vm } = this.props
@@ -284,7 +284,8 @@ export default class Vm extends BaseComponent {
>
{cloneElement(this.props.children, {
...childProps,
toggleHeader: this._toggleHeader,
collapsedHeader: this.state.collapsedHeader,
setCollapsedHeader: this._setCollapsedHeader,
})}
</Page>
)

View File

@@ -52,8 +52,14 @@ export default class TabConsole extends Component {
state = { clipboard: '', scale: 1 }
componentWillReceiveProps(props) {
if (isVmRunning(this.props.vm) && !isVmRunning(props.vm) && this.state.minimalLayout) {
this._toggleMinimalLayout()
if (isVmRunning(this.props.vm) && !isVmRunning(props.vm) && props.collapsedHeader) {
props.setCollapsedHeader(false)
}
}
componentWillUnmount() {
if (this.props.collapsedHeader) {
this.props.setCollapsedHeader(false)
}
}
@@ -87,11 +93,6 @@ export default class TabConsole extends Component {
})
)
_toggleMinimalLayout = () => {
this.props.toggleHeader()
this.setState({ minimalLayout: !this.state.minimalLayout })
}
_openSsh = (username = 'root') => {
window.location = `ssh://${encodeURIComponent(username)}@${formatHostname(this.props.vm.mainIpAddress)}`
}
@@ -123,8 +124,8 @@ export default class TabConsole extends Component {
}
render() {
const { statsOverview, vm } = this.props
const { minimalLayout, scale } = this.state
const { collapsedHeader, setCollapsedHeader, statsOverview, vm } = this.props
const { scale } = this.state
const canSshOrRdp = vm.mainIpAddress !== undefined
if (!isVmRunning(vm)) {
@@ -137,7 +138,7 @@ export default class TabConsole extends Component {
return (
<Container>
{!minimalLayout && statsOverview && (
{!collapsedHeader && statsOverview && (
<Row className='text-xs-center'>
<Col mediumSize={3}>
<p>
@@ -253,9 +254,9 @@ export default class TabConsole extends Component {
</Row>
</Col>
<Col mediumSize={1}>
<Tooltip content={minimalLayout ? _('showHeaderTooltip') : _('hideHeaderTooltip')}>
<Button onClick={this._toggleMinimalLayout}>
<Icon icon={minimalLayout ? 'caret' : 'caret-up'} />
<Tooltip content={collapsedHeader ? _('showHeaderTooltip') : _('hideHeaderTooltip')}>
<Button onClick={() => setCollapsedHeader(!collapsedHeader)}>
<Icon icon={collapsedHeader ? 'caret' : 'caret-up'} />
</Button>
</Tooltip>
</Col>