From eee662afe979eebd18e6877859f2017becd6c80a Mon Sep 17 00:00:00 2001 From: Andreas Kienast <a.fernandez@scripting-base.de> Date: Mon, 26 Feb 2024 08:24:45 +0100 Subject: [PATCH] [BUGFIX] Do not race tree node loading When (de-)mounting pages in the page tree, always two requests are sent to the server that fetch the tree data: * when the `mountPointPath` path property is changed as it's a state property * explicitly after changing said property Especially when de-mounting a page, this tends to race conditions, as the mount state is additionally stored in the backend user's UC that needs to get unset as well. This bugfix now changes the handling when the state property, that triggers a re-rendering of the tree component, is updated. The de-mounting process now unsets the backend user's UC first and then changes the property to make sure that 1. the state is updated once the configuration is flushed 2. the tree nodes are fetched only once In the mounting process, the UC is correctly updated first. However, the state was updated and then the nodes were reloaded explicitly. The latter is not required at all. Resolves: #103185 Releases: main, 12.4 Change-Id: I7a06852c6af40e1a41691a7cc7acd41db4f84adc Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/83126 Tested-by: core-ci <typo3@b13.com> Reviewed-by: Benjamin Kott <benjamin.kott@outlook.com> Reviewed-by: Andreas Kienast <a.fernandez@scripting-base.de> Reviewed-by: Garvin Hicking <gh@faktor-e.de> Tested-by: Andreas Kienast <a.fernandez@scripting-base.de> Tested-by: Benjamin Kott <benjamin.kott@outlook.com> Tested-by: Garvin Hicking <gh@faktor-e.de> --- Build/Sources/TypeScript/backend/tree/page-browser.ts | 4 +--- Build/Sources/TypeScript/backend/tree/page-tree-element.ts | 4 +--- .../backend/Resources/Public/JavaScript/tree/page-browser.js | 4 ++-- .../Resources/Public/JavaScript/tree/page-tree-element.js | 4 ++-- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/Build/Sources/TypeScript/backend/tree/page-browser.ts b/Build/Sources/TypeScript/backend/tree/page-browser.ts index c741190af0e9..f2bebb8b13a0 100644 --- a/Build/Sources/TypeScript/backend/tree/page-browser.ts +++ b/Build/Sources/TypeScript/backend/tree/page-browser.ts @@ -219,9 +219,8 @@ export class PageBrowser extends LitElement { }; private unsetTemporaryMountPoint() { - this.mountPointPath = null; Persistent.unset('pageTree_temporaryMountPoint').then(() => { - this.tree.loadData(); + this.mountPointPath = null; }); } @@ -252,7 +251,6 @@ export class PageBrowser extends LitElement { this.tree.loadData(); } else { this.mountPointPath = response.mountPointPath; - this.tree.refreshOrFilterTree(); } }) .catch((error) => { diff --git a/Build/Sources/TypeScript/backend/tree/page-tree-element.ts b/Build/Sources/TypeScript/backend/tree/page-tree-element.ts index a1257d83ecba..57c16d5df624 100644 --- a/Build/Sources/TypeScript/backend/tree/page-tree-element.ts +++ b/Build/Sources/TypeScript/backend/tree/page-tree-element.ts @@ -386,9 +386,8 @@ export class PageTreeNavigationComponent extends LitElement { }; private unsetTemporaryMountPoint() { - this.mountPointPath = null; Persistent.unset('pageTree_temporaryMountPoint').then(() => { - this.tree.loadData(); + this.mountPointPath = null; }); } @@ -419,7 +418,6 @@ export class PageTreeNavigationComponent extends LitElement { this.tree.loadData(); } else { this.mountPointPath = response.mountPointPath; - this.tree.refreshOrFilterTree(); } }) .catch((error) => { diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/tree/page-browser.js b/typo3/sysext/backend/Resources/Public/JavaScript/tree/page-browser.js index 11ce629c6735..c872de60de91 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/tree/page-browser.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/tree/page-browser.js @@ -28,7 +28,7 @@ var __decorate=function(e,t,n,o){var r,i=arguments.length,s=i<3?t:null===o?o=Obj ${this.renderMountPoint()} <typo3-backend-component-page-browser-tree id="typo3-pagetree-tree" class="tree-wrapper" .setup=${e} @tree:initialized=${()=>{this.tree.addEventListener("typo3:tree:node-selected",this.loadRecordsOfPage),this.tree.addEventListener("typo3:tree:nodes-prepared",this.selectActivePageInTree);this.querySelector("typo3-backend-tree-toolbar").tree=this.tree}}></typo3-backend-component-page-browser-tree> </div> - `))}unsetTemporaryMountPoint(){this.mountPointPath=null,Persistent.unset("pageTree_temporaryMountPoint").then((()=>{this.tree.loadData()}))}renderMountPoint(){return null===this.mountPointPath?nothing:html` + `))}unsetTemporaryMountPoint(){Persistent.unset("pageTree_temporaryMountPoint").then((()=>{this.mountPointPath=null}))}renderMountPoint(){return null===this.mountPointPath?nothing:html` <div class="node-mount-point"> <div class="node-mount-point__icon"><typo3-backend-icon identifier="actions-info-circle" size="small"></typo3-backend-icon></div> <div class="node-mount-point__text">${this.mountPointPath}</div> @@ -36,4 +36,4 @@ var __decorate=function(e,t,n,o){var r,i=arguments.length,s=i<3?t:null===o?o=Obj <typo3-backend-icon identifier="actions-close" size="small"></typo3-backend-icon> </div> </div> - `}setTemporaryMountPoint(e){new AjaxRequest(this.configuration.setTemporaryMountPointUrl).post("pid="+e,{headers:{"Content-Type":"application/x-www-form-urlencoded","X-Requested-With":"XMLHttpRequest"}}).then((e=>e.resolve())).then((e=>{e&&e.hasErrors?(this.tree.errorNotification(e.message),this.tree.loadData()):(this.mountPointPath=e.mountPointPath,this.tree.refreshOrFilterTree())})).catch((e=>{this.tree.errorNotification(e),this.tree.loadData()}))}};__decorate([property({type:String})],PageBrowser.prototype,"mountPointPath",void 0),__decorate([query(".tree-wrapper")],PageBrowser.prototype,"tree",void 0),PageBrowser=__decorate([customElement("typo3-backend-component-page-browser")],PageBrowser);export{PageBrowser}; \ No newline at end of file + `}setTemporaryMountPoint(e){new AjaxRequest(this.configuration.setTemporaryMountPointUrl).post("pid="+e,{headers:{"Content-Type":"application/x-www-form-urlencoded","X-Requested-With":"XMLHttpRequest"}}).then((e=>e.resolve())).then((e=>{e&&e.hasErrors?(this.tree.errorNotification(e.message),this.tree.loadData()):this.mountPointPath=e.mountPointPath})).catch((e=>{this.tree.errorNotification(e),this.tree.loadData()}))}};__decorate([property({type:String})],PageBrowser.prototype,"mountPointPath",void 0),__decorate([query(".tree-wrapper")],PageBrowser.prototype,"tree",void 0),PageBrowser=__decorate([customElement("typo3-backend-component-page-browser")],PageBrowser);export{PageBrowser}; \ No newline at end of file diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/tree/page-tree-element.js b/typo3/sysext/backend/Resources/Public/JavaScript/tree/page-tree-element.js index e428485036af..f399fbf820c8 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/tree/page-tree-element.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/tree/page-tree-element.js @@ -20,7 +20,7 @@ var __decorate=function(e,t,o,n){var a,r=arguments.length,i=r<3?t:null===n?n=Obj ${this.renderMountPoint()} <typo3-backend-navigation-component-pagetree-tree id="typo3-pagetree-tree" class="tree-wrapper" .setup=${e} @tree:initialized=${()=>{this.toolbar.tree=this.tree,this.tree.addEventListener("typo3:tree:node-selected",this.loadContent),this.tree.addEventListener("typo3:tree:node-context",this.showContextMenu),this.tree.addEventListener("typo3:tree:nodes-prepared",this.selectActiveNode)}}></typo3-backend-navigation-component-pagetree-tree> </div> - `))}unsetTemporaryMountPoint(){this.mountPointPath=null,Persistent.unset("pageTree_temporaryMountPoint").then((()=>{this.tree.loadData()}))}renderMountPoint(){return null===this.mountPointPath?nothing:html` + `))}unsetTemporaryMountPoint(){Persistent.unset("pageTree_temporaryMountPoint").then((()=>{this.mountPointPath=null}))}renderMountPoint(){return null===this.mountPointPath?nothing:html` <div class="node-mount-point"> <div class="node-mount-point__icon"><typo3-backend-icon identifier="actions-info-circle" size="small"></typo3-backend-icon></div> <div class="node-mount-point__text">${this.mountPointPath}</div> @@ -28,7 +28,7 @@ var __decorate=function(e,t,o,n){var a,r=arguments.length,i=r<3?t:null===n?n=Obj <typo3-backend-icon identifier="actions-close" size="small"></typo3-backend-icon> </div> </div> - `}setTemporaryMountPoint(e){new AjaxRequest(this.configuration.setTemporaryMountPointUrl).post("pid="+e,{headers:{"Content-Type":"application/x-www-form-urlencoded","X-Requested-With":"XMLHttpRequest"}}).then((e=>e.resolve())).then((e=>{e&&e.hasErrors?(this.tree.errorNotification(e.message),this.tree.loadData()):(this.mountPointPath=e.mountPointPath,this.tree.refreshOrFilterTree())})).catch((e=>{this.tree.errorNotification(e),this.tree.loadData()}))}};__decorate([property({type:String})],PageTreeNavigationComponent.prototype,"mountPointPath",void 0),__decorate([query(".tree-wrapper")],PageTreeNavigationComponent.prototype,"tree",void 0),__decorate([query("typo3-backend-navigation-component-pagetree-toolbar")],PageTreeNavigationComponent.prototype,"toolbar",void 0),PageTreeNavigationComponent=__decorate([customElement("typo3-backend-navigation-component-pagetree")],PageTreeNavigationComponent);export{PageTreeNavigationComponent};let PageTreeToolbar=class extends TreeToolbar{constructor(){super(...arguments),this.tree=null}render(){return html` + `}setTemporaryMountPoint(e){new AjaxRequest(this.configuration.setTemporaryMountPointUrl).post("pid="+e,{headers:{"Content-Type":"application/x-www-form-urlencoded","X-Requested-With":"XMLHttpRequest"}}).then((e=>e.resolve())).then((e=>{e&&e.hasErrors?(this.tree.errorNotification(e.message),this.tree.loadData()):this.mountPointPath=e.mountPointPath})).catch((e=>{this.tree.errorNotification(e),this.tree.loadData()}))}};__decorate([property({type:String})],PageTreeNavigationComponent.prototype,"mountPointPath",void 0),__decorate([query(".tree-wrapper")],PageTreeNavigationComponent.prototype,"tree",void 0),__decorate([query("typo3-backend-navigation-component-pagetree-toolbar")],PageTreeNavigationComponent.prototype,"toolbar",void 0),PageTreeNavigationComponent=__decorate([customElement("typo3-backend-navigation-component-pagetree")],PageTreeNavigationComponent);export{PageTreeNavigationComponent};let PageTreeToolbar=class extends TreeToolbar{constructor(){super(...arguments),this.tree=null}render(){return html` <div class="tree-toolbar"> <div class="tree-toolbar__menu"> <div class="tree-toolbar__search"> -- GitLab