Ensure that Columns should always be visible in the import/export dialog. Fixes #7252

This commit is contained in:
Aditya Toshniwal 2022-04-11 17:25:19 +05:30 committed by Akshay Joshi
parent 0c823455a0
commit a91762fb30
8 changed files with 133 additions and 45 deletions

View File

@ -29,6 +29,7 @@ Bug fixes
| `Issue #7187 <https://redmine.postgresql.org/issues/7187>`_ - Fixed an issue where the downloaded ERD diagram was 0 bytes. | `Issue #7187 <https://redmine.postgresql.org/issues/7187>`_ - Fixed an issue where the downloaded ERD diagram was 0 bytes.
| `Issue #7188 <https://redmine.postgresql.org/issues/7188>`_ - Fixed an issue where the connection bar is not visible. | `Issue #7188 <https://redmine.postgresql.org/issues/7188>`_ - Fixed an issue where the connection bar is not visible.
| `Issue #7231 <https://redmine.postgresql.org/issues/7231>`_ - Don't strip binaries when packaging them in the server RPM as this might break cpython modules. | `Issue #7231 <https://redmine.postgresql.org/issues/7231>`_ - Don't strip binaries when packaging them in the server RPM as this might break cpython modules.
| `Issue #7252 <https://redmine.postgresql.org/issues/7252>`_ - Ensure that Columns should always be visible in the import/export dialog.
| `Issue #7260 <https://redmine.postgresql.org/issues/7260>`_ - Fixed an issue where an Empty message popup after running a query. | `Issue #7260 <https://redmine.postgresql.org/issues/7260>`_ - Fixed an issue where an Empty message popup after running a query.
| `Issue #7262 <https://redmine.postgresql.org/issues/7262>`_ - Ensure that Autocomplete should work after changing the connection. | `Issue #7262 <https://redmine.postgresql.org/issues/7262>`_ - Ensure that Autocomplete should work after changing the connection.
| `Issue #7294 <https://redmine.postgresql.org/issues/7294>`_ - Fixed an issue where the copy and paste row does not work if the first column contains no data. | `Issue #7294 <https://redmine.postgresql.org/issues/7294>`_ - Fixed an issue where the copy and paste row does not work if the first column contains no data.

View File

@ -444,11 +444,25 @@ function SchemaDialogView({
const firstEleRef = useRef(); const firstEleRef = useRef();
const isNew = schema.isNew(schema.origData); const isNew = schema.isNew(schema.origData);
const checkIsMounted = useIsMounted(); const checkIsMounted = useIsMounted();
const preFormReadyQueue = useRef([]);
const depListenerObj = useRef(new DepListener()); const depListenerObj = useRef(new DepListener());
/* The session data */ /* The session data */
const [sessData, sessDispatch] = useReducer(sessDataReducer, {}); 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(()=>{ useEffect(()=>{
/* if sessData changes, validate the schema */ /* if sessData changes, validate the schema */
if(!formReady) return; if(!formReady) return;
@ -663,11 +677,19 @@ function SchemaDialogView({
}; };
const sessDispatchWithListener = (action)=>{ const sessDispatchWithListener = (action)=>{
sessDispatch({ let dispatchPayload = {
...action, ...action,
depChange: (...args)=>depListenerObj.current.getDepChange(...args), depChange: (...args)=>depListenerObj.current.getDepChange(...args),
deferredDepChange: (...args)=>depListenerObj.current.getDeferredDepChange(...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(()=>({ const stateUtils = useMemo(()=>({

View File

@ -5,6 +5,49 @@
border-radius: $btn-border-radius; 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 { #erd-tool-container {
width: 100%; width: 100%;
height: 100%; height: 100%;

View File

@ -340,18 +340,20 @@ describe('SchemaView', ()=>{
ctrlMount({ ctrlMount({
confirmOnCloseReset: false, confirmOnCloseReset: false,
}); });
ctrl.update();
simulateValidData();
onDataChange.calls.reset();
let confirmSpy = spyOn(Notify, 'confirm').and.callThrough();
ctrl.find('DefaultButton[data-test="Reset"]').simulate('click');
setTimeout(()=>{ setTimeout(()=>{
ctrl.update(); ctrl.update();
expect(confirmSpy).not.toHaveBeenCalled(); simulateValidData();
expect(ctrl.find('DefaultButton[data-test="Reset"]').prop('disabled')).toBeTrue(); onDataChange.calls.reset();
expect(ctrl.find('PrimaryButton[data-test="Save"]').prop('disabled')).toBeTrue(); let confirmSpy = spyOn(Notify, 'confirm').and.callThrough();
expect(onDataChange).toHaveBeenCalledWith(false, {}); ctrl.find('DefaultButton[data-test="Reset"]').simulate('click');
done(); 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); }, 0);
}); });
}); });

View File

@ -10,6 +10,7 @@
import pgAdmin from 'sources/pgadmin'; import pgAdmin from 'sources/pgadmin';
import {pgBrowser} from 'pgadmin.browser.activity'; import {pgBrowser} from 'pgadmin.browser.activity';
import { getEpoch } from 'sources/utils'; import { getEpoch } from 'sources/utils';
import pgWindow from 'sources/window';
describe('For Activity', function(){ describe('For Activity', function(){
beforeEach(function(){ beforeEach(function(){
@ -17,7 +18,7 @@ describe('For Activity', function(){
pgAdmin.override_user_inactivity_timeout = true; pgAdmin.override_user_inactivity_timeout = true;
/* pgBrowser here is same as main window Browser */ /* pgBrowser here is same as main window Browser */
window.pgAdmin = { pgWindow.pgAdmin = {
Browser: pgBrowser, Browser: pgBrowser,
}; };
}); });
@ -28,19 +29,19 @@ describe('For Activity', function(){
}); });
it('when timedout', function(){ it('when timedout', function(){
window.pgAdmin = undefined; pgWindow.pgAdmin = undefined;
expect(pgBrowser.is_pgadmin_timedout()).toEqual(true); expect(pgBrowser.is_pgadmin_timedout()).toEqual(true);
}); });
}); });
describe('is_inactivity_timeout', function(){ describe('is_inactivity_timeout', function(){
it('when there is activity', 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); expect(pgBrowser.is_inactivity_timeout()).toEqual(false);
}); });
it('when there is no activity', function(){ 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); expect(pgBrowser.is_inactivity_timeout()).toEqual(true);
}); });
}); });
@ -54,7 +55,7 @@ describe('For Activity', function(){
it('initial log activity', function(){ it('initial log activity', function(){
pgBrowser.log_activity(); 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(); expect(pgBrowser.get_epoch_now).toHaveBeenCalled();
}); });

View File

@ -13,9 +13,11 @@ import '../helper/enzyme.helper';
import {default as OrigCodeMirror} from 'bundled_codemirror'; import {default as OrigCodeMirror} from 'bundled_codemirror';
import { withTheme } from '../fake_theme'; import { withTheme } from '../fake_theme';
import pgWindow from 'sources/window';
import CodeMirror from 'sources/components/CodeMirror'; import CodeMirror from 'sources/components/CodeMirror';
import { mount } from 'enzyme'; import { mount } from 'enzyme';
import { FindDialog } from '../../../pgadmin/static/js/components/CodeMirror'; import { FindDialog } from '../../../pgadmin/static/js/components/CodeMirror';
import fakePgAdmin from '../fake_pgadmin';
describe('CodeMirror', ()=>{ describe('CodeMirror', ()=>{
let cmInstance, options={ let cmInstance, options={
@ -56,29 +58,7 @@ describe('CodeMirror', ()=>{
}); });
beforeEach(()=>{ beforeEach(()=>{
jasmineEnzyme(); jasmineEnzyme();
window.pgAdmin = { pgWindow.pgAdmin = fakePgAdmin;
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,
},
},
};
spyOn(OrigCodeMirror, 'fromTextArea').and.returnValue(cmObj); spyOn(OrigCodeMirror, 'fromTextArea').and.returnValue(cmObj);
const ThemedCM = withTheme(CodeMirror); const ThemedCM = withTheme(CodeMirror);
cmInstance = mount( cmInstance = mount(
@ -90,7 +70,7 @@ describe('CodeMirror', ()=>{
}); });
afterEach(()=>{ afterEach(()=>{
window.pgAdmin = undefined; pgWindow.pgAdmin = undefined;
}); });
it('init', ()=>{ it('init', ()=>{

View File

@ -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;

View File

@ -10,8 +10,9 @@
import jasmineEnzyme from 'jasmine-enzyme'; import jasmineEnzyme from 'jasmine-enzyme';
import React from 'react'; import React from 'react';
import pgAdmin from 'sources/pgadmin'; import pgAdmin from 'sources/pgadmin';
import {messages} from './fake_messages';
import SchemaView from '../../pgadmin/static/js/SchemaView'; import SchemaView from '../../pgadmin/static/js/SchemaView';
import pgWindow from 'sources/window';
import fakePgAdmin from './fake_pgadmin';
export let getEditView = (schemaObj, getInitData)=> { export let getEditView = (schemaObj, getInitData)=> {
return <SchemaView return <SchemaView
@ -68,7 +69,9 @@ export let getPropertiesView = (schemaObj, getInitData)=> {
export let genericBeforeEach = ()=> { export let genericBeforeEach = ()=> {
jasmineEnzyme(); jasmineEnzyme();
/* messages used by validators */ /* messages used by validators */
pgAdmin.Browser = pgAdmin.Browser || {}; pgAdmin.Browser = {
pgAdmin.Browser.messages = pgAdmin.Browser.messages || messages; ...pgAdmin.Browser,
pgAdmin.Browser.utils = pgAdmin.Browser.utils || {}; ...fakePgAdmin.Browser
};
pgWindow.pgAdmin = pgAdmin;
}; };