From bedc4f360cfa4754f7b73521cb5df8a69881c300 Mon Sep 17 00:00:00 2001 From: Ching En Cheng Date: Tue, 16 Jan 2024 13:33:41 +0000 Subject: [PATCH] fix(ExtJS): force hide msgbox if not initialized --- tine20/Tinebase/js/LoginPanel.js | 24 +++--- .../library/ExtJS/src/widgets/MessageBox.js | 84 +++++++++++-------- .../ExtJS/src/widgets/VueMessageBox/App.vue | 1 - .../src/widgets/VueMessageBox/_global_bs.scss | 47 ----------- .../src/widgets/VueMessageBox/_scoped_bs.scss | 52 ------------ .../src/widgets/VueMessageBox/styles.scss | 9 -- 6 files changed, 58 insertions(+), 159 deletions(-) delete mode 100644 tine20/library/ExtJS/src/widgets/VueMessageBox/_global_bs.scss delete mode 100644 tine20/library/ExtJS/src/widgets/VueMessageBox/_scoped_bs.scss delete mode 100644 tine20/library/ExtJS/src/widgets/VueMessageBox/styles.scss diff --git a/tine20/Tinebase/js/LoginPanel.js b/tine20/Tinebase/js/LoginPanel.js index 9d37658e0b5..25ffe92bcc1 100644 --- a/tine20/Tinebase/js/LoginPanel.js +++ b/tine20/Tinebase/js/LoginPanel.js @@ -627,19 +627,17 @@ Tine.Tinebase.LoginPanel = Ext.extend(Ext.Panel, { if (form.isValid()) { Ext.MessageBox.wait(i18n._('Logging you in...'), i18n._('Please wait')) - .then((r) => { - Ext.Ajax.request({ - scope: this, - params: _.assign({ - method: this.loginMethod, - username: values.username, - password: values.password - }, additionalParams), - timeout: 60000, // 1 minute - success: this.onLoginSuccess, - failure: this.onLoginFail - }); - }); + Ext.Ajax.request({ + scope: this, + params: _.assign({ + method: this.loginMethod, + username: values.username, + password: values.password + }, additionalParams), + timeout: 60000, // 1 minute + success: this.onLoginSuccess, + failure: this.onLoginFail + }); } else { Ext.MessageBox.alert(i18n._('Errors'), i18n._('Please fix the errors noted.')); diff --git a/tine20/library/ExtJS/src/widgets/MessageBox.js b/tine20/library/ExtJS/src/widgets/MessageBox.js index ecd8a7559fd..c54d1f3c203 100644 --- a/tine20/library/ExtJS/src/widgets/MessageBox.js +++ b/tine20/library/ExtJS/src/widgets/MessageBox.js @@ -4,6 +4,7 @@ * licensing@extjs.com * http://www.extjs.com/license */ +import {BootstrapVueNext} from 'bootstrap-vue-next' /** * @class Ext.MessageBox @@ -25,6 +26,7 @@ Ext.Msg.prompt('Name', 'Please enter your name:', function(btn, text){ }); + // Show a dialog using config options: Ext.Msg.show({ title:'Save Changes?', @@ -38,10 +40,16 @@ Ext.Msg.show({ * @singleton */ Ext.MessageBox = function(){ + const MSG_BOX_MOUNT_ID = "Vue-Message-Box-Mount-Point" + let opt, dlg; const skinShades = ["#ffffff", "#fad9b4", "#fcbf89", "#ec8f2e", "#d97103", "#b75b01", "#924500"] + const __HIDDEN = false // for readability and clarity + let synchronousVisibilityState = __HIDDEN + let initialized = false + // start vue properties let vueHandle, vueProps, vueEmitter; const defaultConfigs = Object.freeze({ @@ -87,12 +95,13 @@ Ext.MessageBox = function(){ // private const handleButton = function({buttonName, textElValue} = arg){ - vueProps.otherConfigs.visible = false; + handleHide() Ext.callback(opt.fn, opt.scope||window, [buttonName, textElValue, opt], 1); } // private const handleHide = function() { + synchronousVisibilityState = __HIDDEN if(vueProps) vueProps.otherConfigs.visible = false; } @@ -105,7 +114,7 @@ Ext.MessageBox = function(){ get(target, key){ switch(key){ case "hidden": - return !vueProps.otherConfigs.visible + return !synchronousVisibilityState case "setZIndex": return setZIndex case "setActive": @@ -235,60 +244,62 @@ Ext.Msg.show({ */ show: async function(options){ options.skinColor = skinShades[Math.floor(Math.random()*skinShades.length)] + synchronousVisibilityState = !__HIDDEN Ext.getBody().mask("Loading"); - window.vue = window.vue || await import(/* webpackChunkName: "Tinebase/js/Vue-Runtime"*/"tine-vue") - const {default: mitt} = await import(/* webpackChunkName: "Tinebase/js/Mitt"*/'mitt') - const {createApp, h} = await import("vue") const {MessageBoxApp, SymbolKeys} = await import(/* webpackChunkName: "Tinebase/js/VueMessageBox"*/'./VueMessageBox') - const {BootstrapVueNext} = await import(/* webpackChunkName: "Tinebase/js/BootstrapVueNext"*/'bootstrap-vue-next') - opt = {...defaultConfigs,...options}; - opt["closable"] = (opt.closable !== false && opt.progress !== true && opt.wait !== true); - opt["prompt"] = opt.prompt || (opt.multiline ? true : false); - // creating mount point - const mountId = "Vue-Message-Box-Mount-Point"; - let mp = document.getElementById(mountId); - if(!mp){ - mp = document.createElement("div"); - mp.id = mountId; - document.body.appendChild(mp); - } - // initializing the reactive prop. - if(!vueProps){ + // initializing vue stuff + if(!initialized){ + const {createApp, h, reactive} = window.vue + initialized = true otherConfigs.buttonText = this.buttonText; - const {reactive} = await import("vue") vueProps = reactive({ opt: JSON.parse(JSON.stringify(defaultConfigs)), otherConfigs: JSON.parse(JSON.stringify(otherConfigs)), }); - } - Ext.getBody().unmask(); - if(!vueEmitter){ - vueEmitter = mitt(); + + // app initialization and mounting + vueHandle = createApp({ + render: () => h(MessageBoxApp, vueProps) + }); + + // events initialization + vueEmitter = window.mitt(); vueEmitter.on("close", handleHide); vueEmitter.on("buttonClicked", handleButton); + + vueHandle.config.globalProperties.ExtEventBus = vueEmitter; + vueHandle.provide(SymbolKeys.ExtEventBusInjectKey, vueEmitter); + vueHandle.use(BootstrapVueNext) + + const mp = document.createElement("div"); + mp.id = MSG_BOX_MOUNT_ID; + document.body.appendChild(mp); + vueHandle.mount(mp); } + + opt = {...defaultConfigs,...options}; + opt["closable"] = (opt.closable !== false && opt.progress !== true && opt.wait !== true); + opt["prompt"] = opt.prompt || (opt.multiline ? true : false); + + // if a MessageBox.show() came right after the first MessageBox calls + // the async module are being loaded, so + if(!vueProps || !vueEmitter || !vueHandle) return // setting the prop values to the ones passed in config option // only those values are taken whose keys are present in the - // defaultOpt as these are the only ones allowed + // defaultOpt, as these are the only ones allowed Object.keys(opt).forEach(key => { if(key in vueProps.opt){ vueProps.opt[key] = opt[key]; } }) - // initializing and mounting the app. - if(!vueHandle){ - vueHandle = createApp({ - render: () => h(MessageBoxApp, vueProps) - }); - vueHandle.config.globalProperties.ExtEventBus = vueEmitter; - vueHandle.provide(SymbolKeys.ExtEventBusInjectKey, vueEmitter); - vueHandle.use(BootstrapVueNext) - - vueHandle.mount(mp); - } + Ext.getBody().unmask(); + // as the other modules are async loaded, + // the following checks if the visibility state was changed while + // the modules were being loaded. + if (synchronousVisibilityState === __HIDDEN) return this; vueProps.otherConfigs.visible = true; const d = this.getDialog(""); Ext.WindowMgr.bringToFront(d) @@ -366,7 +377,6 @@ Ext.MessageBox.ERROR modal:true, minWidth: this.minProgressWidth, waitConfig: config, - fn: 'fake', }); }, diff --git a/tine20/library/ExtJS/src/widgets/VueMessageBox/App.vue b/tine20/library/ExtJS/src/widgets/VueMessageBox/App.vue index 3f54ae0fa96..655fd86d8b9 100644 --- a/tine20/library/ExtJS/src/widgets/VueMessageBox/App.vue +++ b/tine20/library/ExtJS/src/widgets/VueMessageBox/App.vue @@ -133,7 +133,6 @@ watch(() => props.otherConfigs.visible, newVal => { }) onBeforeMount(async () => { - await import(/* webpackChunkName: "Tinebase/js/CustomBootstrapVueStyles" */"library/ExtJS/src/widgets/VueMessageBox/styles.scss") await init(); }) diff --git a/tine20/library/ExtJS/src/widgets/VueMessageBox/_global_bs.scss b/tine20/library/ExtJS/src/widgets/VueMessageBox/_global_bs.scss deleted file mode 100644 index 029ef25b2a2..00000000000 --- a/tine20/library/ExtJS/src/widgets/VueMessageBox/_global_bs.scss +++ /dev/null @@ -1,47 +0,0 @@ -// scss-docs-start import-stack -// Configuration -@import "bootstrap/scss/functions"; -@import "bootstrap/scss/variables"; -@import "bootstrap/scss/maps"; -@import "bootstrap/scss/mixins"; -@import "bootstrap/scss/utilities"; - -// Layoutbootstrap/scss/ & components -@import "bootstrap/scss/root"; -// @import "bootstrap/scss/reboot"; -// @import "bootstrap/scss/type"; -// @import "bootstrap/scss/images"; -// @import "bootstrap/scss/containers"; -// @import "bootstrap/scss/grid"; -// @import "bootstrap/scss/tables"; -// @import "bootstrap/scss/forms"; -// @import "bootstrap/scss/buttons"; -// @import "bootstrap/scss/transitions"; -// @import "bootstrap/scss/dropdown"; -// @import "bootstrap/scss/button-group"; -// @import "bootstrap/scss/nav"; -// @import "bootstrap/scss/navbar"; -// @import "bootstrap/scss/card"; -// @import "bootstrap/scss/accordion"; -// @import "bootstrap/scss/breadcrumb"; -// @import "bootstrap/scss/pagination"; -// @import "bootstrap/scss/badge"; -// @import "bootstrap/scss/alert"; -// @import "bootstrap/scss/progress"; -// @import "bootstrap/scss/list-group"; -// @import "bootstrap/scss/close"; -// @import "bootstrap/scss/toasts"; -@import "bootstrap/scss/modal"; -// @import "bootstrap/scss/tooltip"; -// @import "bootstrap/scss/popover"; -// @import "bootstrap/scss/carousel"; -// @import "bootstrap/scss/spinners"; -// @import "bootstrap/scss/offcanvas"; -// @import "bootstrap/scss/placeholders"; - -// // Helperbootstrap/scss/s -// @import "bootstrap/scss/helpers"; - -// // Utilitbootstrap/scss/ies -// @import "bootstrap/scss/utilities/api"; -// // scss-docs-end import-stack \ No newline at end of file diff --git a/tine20/library/ExtJS/src/widgets/VueMessageBox/_scoped_bs.scss b/tine20/library/ExtJS/src/widgets/VueMessageBox/_scoped_bs.scss deleted file mode 100644 index d1c9cc6a93a..00000000000 --- a/tine20/library/ExtJS/src/widgets/VueMessageBox/_scoped_bs.scss +++ /dev/null @@ -1,52 +0,0 @@ -// This file imports all the styles that can be scoped. -// i.e. styles that need not be in the global scope -// css-selector { -// @import "" -// } - -// scss-docs-start import-stack -// Configuration -@import "bootstrap/scss/functions"; -@import "bootstrap/scss/variables"; -@import "bootstrap/scss/maps"; -@import "bootstrap/scss/mixins"; -@import "bootstrap/scss/utilities"; - -// Layoutbootstrap/scss/ & components -// @import "bootstrap/scss/root"; -@import "bootstrap/scss/reboot"; -@import "bootstrap/scss/type"; -@import "bootstrap/scss/images"; -@import "bootstrap/scss/containers"; -@import "bootstrap/scss/grid"; -@import "bootstrap/scss/tables"; -@import "bootstrap/scss/forms"; -@import "bootstrap/scss/buttons"; -@import "bootstrap/scss/transitions"; -@import "bootstrap/scss/dropdown"; -@import "bootstrap/scss/button-group"; -@import "bootstrap/scss/nav"; -@import "bootstrap/scss/navbar"; -@import "bootstrap/scss/card"; -@import "bootstrap/scss/accordion"; -@import "bootstrap/scss/breadcrumb"; -@import "bootstrap/scss/pagination"; -@import "bootstrap/scss/badge"; -@import "bootstrap/scss/alert"; -@import "bootstrap/scss/progress"; -@import "bootstrap/scss/list-group"; -@import "bootstrap/scss/close"; -@import "bootstrap/scss/toasts"; -// @import "bootstrap/scss/modal"; -@import "bootstrap/scss/tooltip"; -@import "bootstrap/scss/popover"; -@import "bootstrap/scss/carousel"; -@import "bootstrap/scss/spinners"; -@import "bootstrap/scss/offcanvas"; -@import "bootstrap/scss/placeholders"; - -// Helperbootstrap/scss/s -@import "bootstrap/scss/helpers"; - -// Utilitbootstrap/scss/ies -@import "bootstrap/scss/utilities/api"; \ No newline at end of file diff --git a/tine20/library/ExtJS/src/widgets/VueMessageBox/styles.scss b/tine20/library/ExtJS/src/widgets/VueMessageBox/styles.scss deleted file mode 100644 index 2b8bb1e92b7..00000000000 --- a/tine20/library/ExtJS/src/widgets/VueMessageBox/styles.scss +++ /dev/null @@ -1,9 +0,0 @@ -$primary: #0062a7; // setting the primary color -@import 'global_bs'; // global bs styles needed for modal -@import 'bootstrap-vue-next/dist/bootstrap-vue-next.css'; // bs-Vue styles - -.bootstrap-scope{ - @import "scoped_bs"; - font-size: 1.1em; - font-family: arial, tahoma, helvetica, sans-serif; // this seems to be the default font stack in tine -} \ No newline at end of file