From a91762fb30edb8bb5344456754cd1da2d1b92c81 Mon Sep 17 00:00:00 2001 From: Aditya Toshniwal Date: Mon, 11 Apr 2022 17:25:19 +0530 Subject: [PATCH] Ensure that Columns should always be visible in the import/export dialog. Fixes #7252 --- docs/en_US/release_notes_6_9.rst | 1 + web/pgadmin/static/js/SchemaView/index.jsx | 26 ++++++++++- web/pgadmin/tools/erd/static/scss/_erd.scss | 43 +++++++++++++++++++ .../javascript/SchemaView/SchemaView.spec.js | 22 +++++----- .../javascript/browser/activity_spec.js | 11 ++--- .../javascript/components/CodeMirror.spec.js | 28 ++---------- web/regression/javascript/fake_pgadmin.js | 36 ++++++++++++++++ .../javascript/genericFunctions.jsx | 11 +++-- 8 files changed, 133 insertions(+), 45 deletions(-) create mode 100644 web/regression/javascript/fake_pgadmin.js diff --git a/docs/en_US/release_notes_6_9.rst b/docs/en_US/release_notes_6_9.rst index f476a9547..341de55d3 100644 --- a/docs/en_US/release_notes_6_9.rst +++ b/docs/en_US/release_notes_6_9.rst @@ -29,6 +29,7 @@ Bug fixes | `Issue #7187 `_ - Fixed an issue where the downloaded ERD diagram was 0 bytes. | `Issue #7188 `_ - Fixed an issue where the connection bar is not visible. | `Issue #7231 `_ - Don't strip binaries when packaging them in the server RPM as this might break cpython modules. + | `Issue #7252 `_ - Ensure that Columns should always be visible in the import/export dialog. | `Issue #7260 `_ - Fixed an issue where an Empty message popup after running a query. | `Issue #7262 `_ - Ensure that Autocomplete should work after changing the connection. | `Issue #7294 `_ - Fixed an issue where the copy and paste row does not work if the first column contains no data. diff --git a/web/pgadmin/static/js/SchemaView/index.jsx b/web/pgadmin/static/js/SchemaView/index.jsx index 3b85c67a0..c50d56e25 100644 --- a/web/pgadmin/static/js/SchemaView/index.jsx +++ b/web/pgadmin/static/js/SchemaView/index.jsx @@ -444,11 +444,25 @@ function SchemaDialogView({ const firstEleRef = useRef(); const isNew = schema.isNew(schema.origData); const checkIsMounted = useIsMounted(); + const preFormReadyQueue = useRef([]); const depListenerObj = useRef(new DepListener()); /* The session data */ const [sessData, sessDispatch] = useReducer(sessDataReducer, {}); + useEffect(()=>{ + /* Dispatch all the actions recorded before form ready */ + if(formReady) { + if(preFormReadyQueue.current.length > 0) { + for (const dispatchPayload of preFormReadyQueue.current) { + sessDispatch(dispatchPayload); + } + } + /* destroy the queue so that no one uses it */ + preFormReadyQueue.current = undefined; + } + }, [formReady]); + useEffect(()=>{ /* if sessData changes, validate the schema */ if(!formReady) return; @@ -663,11 +677,19 @@ function SchemaDialogView({ }; const sessDispatchWithListener = (action)=>{ - sessDispatch({ + let dispatchPayload = { ...action, depChange: (...args)=>depListenerObj.current.getDepChange(...args), deferredDepChange: (...args)=>depListenerObj.current.getDeferredDepChange(...args), - }); + }; + /* All the session changes coming before init should be queued up + They will be processed later when form is ready. + */ + if(preFormReadyQueue.current) { + preFormReadyQueue.current.push(dispatchPayload); + return; + } + sessDispatch(dispatchPayload); }; const stateUtils = useMemo(()=>({ diff --git a/web/pgadmin/tools/erd/static/scss/_erd.scss b/web/pgadmin/tools/erd/static/scss/_erd.scss index 6b6ccdf9d..246ceab4b 100644 --- a/web/pgadmin/tools/erd/static/scss/_erd.scss +++ b/web/pgadmin/tools/erd/static/scss/_erd.scss @@ -5,6 +5,49 @@ border-radius: $btn-border-radius; } +.connection_status_wrapper { + width: 100%; + border-top: $panel-border; + border-bottom: $panel-border; +} + +.connection_status .obtaining-conn { + background-image: $loader-icon-small !important; + background-position: center center; + background-repeat: no-repeat; + &:before { + content:''; + } + min-width: 50%; + min-height: 100%; +} + +.connection_status { + background-color: $sql-title-bg; + color: $sql-title-fg; + border-right: $border-width solid $border-color; + padding: 0px 8px; +} + +.editor-title { + padding: $sql-title-padding; + background: $sql-title-bg; + color: $sql-title-fg; +} + +.connection-info { + background: $sql-title-bg; + color: $sql-title-fg; + width:100%; + display: inherit; +} + +.connection-data { + display: inherit; + cursor: pointer; + width: auto; +} + #erd-tool-container { width: 100%; height: 100%; diff --git a/web/regression/javascript/SchemaView/SchemaView.spec.js b/web/regression/javascript/SchemaView/SchemaView.spec.js index d4b743026..777b344ba 100644 --- a/web/regression/javascript/SchemaView/SchemaView.spec.js +++ b/web/regression/javascript/SchemaView/SchemaView.spec.js @@ -340,18 +340,20 @@ describe('SchemaView', ()=>{ ctrlMount({ confirmOnCloseReset: false, }); - ctrl.update(); - simulateValidData(); - onDataChange.calls.reset(); - let confirmSpy = spyOn(Notify, 'confirm').and.callThrough(); - ctrl.find('DefaultButton[data-test="Reset"]').simulate('click'); setTimeout(()=>{ ctrl.update(); - expect(confirmSpy).not.toHaveBeenCalled(); - expect(ctrl.find('DefaultButton[data-test="Reset"]').prop('disabled')).toBeTrue(); - expect(ctrl.find('PrimaryButton[data-test="Save"]').prop('disabled')).toBeTrue(); - expect(onDataChange).toHaveBeenCalledWith(false, {}); - done(); + simulateValidData(); + onDataChange.calls.reset(); + let confirmSpy = spyOn(Notify, 'confirm').and.callThrough(); + ctrl.find('DefaultButton[data-test="Reset"]').simulate('click'); + setTimeout(()=>{ + ctrl.update(); + expect(confirmSpy).not.toHaveBeenCalled(); + expect(ctrl.find('DefaultButton[data-test="Reset"]').prop('disabled')).toBeTrue(); + expect(ctrl.find('PrimaryButton[data-test="Save"]').prop('disabled')).toBeTrue(); + expect(onDataChange).toHaveBeenCalledWith(false, {}); + done(); + }, 0); }, 0); }); }); diff --git a/web/regression/javascript/browser/activity_spec.js b/web/regression/javascript/browser/activity_spec.js index 865f4d59c..1388e52d5 100644 --- a/web/regression/javascript/browser/activity_spec.js +++ b/web/regression/javascript/browser/activity_spec.js @@ -10,6 +10,7 @@ import pgAdmin from 'sources/pgadmin'; import {pgBrowser} from 'pgadmin.browser.activity'; import { getEpoch } from 'sources/utils'; +import pgWindow from 'sources/window'; describe('For Activity', function(){ beforeEach(function(){ @@ -17,7 +18,7 @@ describe('For Activity', function(){ pgAdmin.override_user_inactivity_timeout = true; /* pgBrowser here is same as main window Browser */ - window.pgAdmin = { + pgWindow.pgAdmin = { Browser: pgBrowser, }; }); @@ -28,19 +29,19 @@ describe('For Activity', function(){ }); it('when timedout', function(){ - window.pgAdmin = undefined; + pgWindow.pgAdmin = undefined; expect(pgBrowser.is_pgadmin_timedout()).toEqual(true); }); }); describe('is_inactivity_timeout', function(){ it('when there is activity', function(){ - window.pgAdmin.Browser.inactivity_timeout_at = getEpoch() + 30; + pgWindow.pgAdmin.Browser.inactivity_timeout_at = getEpoch() + 30; expect(pgBrowser.is_inactivity_timeout()).toEqual(false); }); it('when there is no activity', function(){ - window.pgAdmin.Browser.inactivity_timeout_at = getEpoch() - 30; + pgWindow.pgAdmin.Browser.inactivity_timeout_at = getEpoch() - 30; expect(pgBrowser.is_inactivity_timeout()).toEqual(true); }); }); @@ -54,7 +55,7 @@ describe('For Activity', function(){ it('initial log activity', function(){ pgBrowser.log_activity(); - expect(window.pgAdmin.Browser.inactivity_timeout_at).not.toBe(null); + expect(pgWindow.pgAdmin.Browser.inactivity_timeout_at).not.toBe(null); expect(pgBrowser.get_epoch_now).toHaveBeenCalled(); }); diff --git a/web/regression/javascript/components/CodeMirror.spec.js b/web/regression/javascript/components/CodeMirror.spec.js index 6cec715d4..92151ad00 100644 --- a/web/regression/javascript/components/CodeMirror.spec.js +++ b/web/regression/javascript/components/CodeMirror.spec.js @@ -13,9 +13,11 @@ import '../helper/enzyme.helper'; import {default as OrigCodeMirror} from 'bundled_codemirror'; import { withTheme } from '../fake_theme'; +import pgWindow from 'sources/window'; import CodeMirror from 'sources/components/CodeMirror'; import { mount } from 'enzyme'; import { FindDialog } from '../../../pgadmin/static/js/components/CodeMirror'; +import fakePgAdmin from '../fake_pgadmin'; describe('CodeMirror', ()=>{ let cmInstance, options={ @@ -56,29 +58,7 @@ describe('CodeMirror', ()=>{ }); beforeEach(()=>{ jasmineEnzyme(); - window.pgAdmin = { - Browser: { - Events: { - on: jasmine.createSpy('on'), - }, - get_preferences_for_module: ()=>({}), - docker: { - findPanels: function() { - return [ - { - isVisible: function() { - return true; - }, - }, - ]; - }, - }, - onPreferencesChange: ()=>{/*This is intentional (SonarQube)*/}, - utils: { - app_version_int: 1234, - }, - }, - }; + pgWindow.pgAdmin = fakePgAdmin; spyOn(OrigCodeMirror, 'fromTextArea').and.returnValue(cmObj); const ThemedCM = withTheme(CodeMirror); cmInstance = mount( @@ -90,7 +70,7 @@ describe('CodeMirror', ()=>{ }); afterEach(()=>{ - window.pgAdmin = undefined; + pgWindow.pgAdmin = undefined; }); it('init', ()=>{ diff --git a/web/regression/javascript/fake_pgadmin.js b/web/regression/javascript/fake_pgadmin.js new file mode 100644 index 000000000..791cf337e --- /dev/null +++ b/web/regression/javascript/fake_pgadmin.js @@ -0,0 +1,36 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2022, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// +import {messages} from './fake_messages'; + +const fakePgAdmin = { + Browser: { + messages: messages, + Events: { + on: jasmine.createSpy('on'), + }, + get_preferences_for_module: ()=>({}), + docker: { + findPanels: function() { + return [ + { + isVisible: function() { + return true; + }, + }, + ]; + }, + }, + onPreferencesChange: ()=>{/*This is intentional (SonarQube)*/}, + utils: { + app_version_int: 1234, + }, + }, +}; + +export default fakePgAdmin; diff --git a/web/regression/javascript/genericFunctions.jsx b/web/regression/javascript/genericFunctions.jsx index 80e494779..2d93807d9 100644 --- a/web/regression/javascript/genericFunctions.jsx +++ b/web/regression/javascript/genericFunctions.jsx @@ -10,8 +10,9 @@ import jasmineEnzyme from 'jasmine-enzyme'; import React from 'react'; import pgAdmin from 'sources/pgadmin'; -import {messages} from './fake_messages'; import SchemaView from '../../pgadmin/static/js/SchemaView'; +import pgWindow from 'sources/window'; +import fakePgAdmin from './fake_pgadmin'; export let getEditView = (schemaObj, getInitData)=> { return { export let genericBeforeEach = ()=> { jasmineEnzyme(); /* messages used by validators */ - pgAdmin.Browser = pgAdmin.Browser || {}; - pgAdmin.Browser.messages = pgAdmin.Browser.messages || messages; - pgAdmin.Browser.utils = pgAdmin.Browser.utils || {}; + pgAdmin.Browser = { + ...pgAdmin.Browser, + ...fakePgAdmin.Browser + }; + pgWindow.pgAdmin = pgAdmin; };