From 7cdb792bfeadecce8181f7e5b5d0d7d16ba1fbe9 Mon Sep 17 00:00:00 2001 From: Pierre Donias Date: Thu, 13 Aug 2026 15:15:25 +0200 Subject: [PATCH] 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) --- CHANGELOG.unreleased.md | 2 ++ packages/xo-web/src/xo-app/vm/index.js | 5 ++-- packages/xo-web/src/xo-app/vm/tab-console.js | 27 ++++++++++---------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index f5d3f55c5f..0dffb2f95b 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -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 diff --git a/packages/xo-web/src/xo-app/vm/index.js b/packages/xo-web/src/xo-app/vm/index.js index 08cee68280..ed058ebe29 100644 --- a/packages/xo-web/src/xo-app/vm/index.js +++ b/packages/xo-web/src/xo-app/vm/index.js @@ -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, })} ) diff --git a/packages/xo-web/src/xo-app/vm/tab-console.js b/packages/xo-web/src/xo-app/vm/tab-console.js index a105d28987..b2b9ee08e3 100644 --- a/packages/xo-web/src/xo-app/vm/tab-console.js +++ b/packages/xo-web/src/xo-app/vm/tab-console.js @@ -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 ( - {!minimalLayout && statsOverview && ( + {!collapsedHeader && statsOverview && (

@@ -253,9 +254,9 @@ export default class TabConsole extends Component { - -