mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2024-11-22 00:37:36 -06:00
Fix multiple UI and SonarQube issues found when testing wcDocker changes. #6479
This commit is contained in:
parent
c5f4a56c0c
commit
3bcac26ff9
@ -117,7 +117,7 @@ export default function Processes() {
|
||||
/>
|
||||
</ErrorBoundary>
|
||||
)
|
||||
}, pgAdmin.Browser.stdW.md);
|
||||
}, pgAdmin.Browser.stdW.md, pgAdmin.Browser.stdH.md);
|
||||
}, []);
|
||||
|
||||
|
||||
|
@ -157,7 +157,6 @@ function createSingleLineStatistics(data, prettifyFields) {
|
||||
return res;
|
||||
}
|
||||
|
||||
// {nodeData, node, treeNodeInfo, isActive, isStale, setIsStale}
|
||||
function Statistics({ nodeData, nodeItem, node, treeNodeInfo, isActive, isStale, setIsStale }) {
|
||||
const classes = useStyles();
|
||||
const [tableData, setTableData] = React.useState([]);
|
||||
|
@ -559,7 +559,6 @@ export default function PreferencesComponent({ ...props }) {
|
||||
function () {
|
||||
pgAdmin.Browser.tree.destroy({
|
||||
success: function () {
|
||||
// pgAdmin.Browser.initializeBrowserTree(pgAdmin.Browser);
|
||||
return true;
|
||||
},
|
||||
});
|
||||
|
@ -50,21 +50,6 @@ define('app', [
|
||||
// Create menus after all modules are initialized.
|
||||
MainMenuFactory.createMainMenus();
|
||||
|
||||
// const menuContainerEle = document.querySelector('#main-menu-container');
|
||||
// if(menuContainerEle) {
|
||||
// ReactDOM.render(
|
||||
// <Theme>
|
||||
// <AppMenuBar />
|
||||
// </Theme>, menuContainerEle
|
||||
// );
|
||||
// }
|
||||
|
||||
// ReactDOM.render(
|
||||
// <Theme>
|
||||
// <ObjectBreadcrumbs pgAdmin={pgAdmin} />
|
||||
// </Theme>, document.querySelector('#object-breadcrumbs')
|
||||
// );
|
||||
|
||||
ReactDOM.render(
|
||||
<Theme>
|
||||
<BrowserComponent pgAdmin={pgAdmin} />
|
||||
|
@ -43,7 +43,7 @@ export const defaultTabsData = [
|
||||
id: BROWSER_PANELS.DASHBOARD, title: gettext('Dashboard'), content: <Dashboard />, closable: true, group: 'main'
|
||||
},
|
||||
{
|
||||
id: BROWSER_PANELS.PROPERTIES, title: gettext('Properties'), content: <Properties />, closable: true,
|
||||
id: BROWSER_PANELS.PROPERTIES, title: gettext('Properties'), content: <Properties />, closable: true, group: 'main'
|
||||
},
|
||||
{
|
||||
id: BROWSER_PANELS.SQL, title: gettext('SQL'), content: <SQL />, closable: true, group: 'main'
|
||||
|
@ -31,7 +31,7 @@ export default function ConnectServerContent({closeModal, data, onOK, setHeight}
|
||||
|
||||
const onTextChange = (e, id) => {
|
||||
let val = e;
|
||||
if(e && e.target) {
|
||||
if(e?.target) {
|
||||
val = e.target.value;
|
||||
}
|
||||
setFormData((prev)=>({...prev, [id]: val}));
|
||||
|
@ -34,7 +34,7 @@ export default function MasterPasswordContent({ closeModal, onResetPassowrd, onO
|
||||
|
||||
const onTextChange = (e, id) => {
|
||||
let val = e;
|
||||
if (e && e.target) {
|
||||
if (e?.target) {
|
||||
val = e.target.value;
|
||||
}
|
||||
setFormData((prev) => ({ ...prev, [id]: val }));
|
||||
|
@ -29,7 +29,7 @@ export default function NamedRestoreContent({closeModal, onOK, setHeight}) {
|
||||
|
||||
const onTextChange = (e, id) => {
|
||||
let val = e;
|
||||
if(e && e.target) {
|
||||
if(e?.target) {
|
||||
val = e.target.value;
|
||||
}
|
||||
setFormData((prev)=>({...prev, [id]: val}));
|
||||
|
@ -33,7 +33,7 @@ export default function RenameTabContent({ panelId, panelDocker, closeModal}) {
|
||||
|
||||
const onTextChange = (e, id) => {
|
||||
let val = e;
|
||||
if (e && e.target) {
|
||||
if (e?.target) {
|
||||
val = e.target.value;
|
||||
}
|
||||
setFormData((prev) => ({ ...prev, [id]: val }));
|
||||
|
@ -25,7 +25,7 @@ function MappedFormControlBase({ type, value, id, onChange, className, visible,
|
||||
const name = id;
|
||||
const onTextChange = useCallback((e) => {
|
||||
let val = e;
|
||||
if(e && e.target) {
|
||||
if(e?.target) {
|
||||
val = e.target.value;
|
||||
}
|
||||
onChange && onChange(val);
|
||||
@ -124,7 +124,7 @@ function MappedCellControlBase({ cell, value, id, optionsLoaded, onCellChange, v
|
||||
const name = id;
|
||||
const onTextChange = useCallback((e) => {
|
||||
let val = e;
|
||||
if (e && e.target) {
|
||||
if (e?.target) {
|
||||
val = e.target.value;
|
||||
}
|
||||
|
||||
@ -133,7 +133,7 @@ function MappedCellControlBase({ cell, value, id, optionsLoaded, onCellChange, v
|
||||
|
||||
const onRadioChange = useCallback((e) => {
|
||||
let val =e;
|
||||
if(e && e.target) {
|
||||
if(e?.target) {
|
||||
val = e.target.checked;
|
||||
}
|
||||
onCellChange && onCellChange(val);
|
||||
|
@ -320,6 +320,10 @@ function getFinalTheme(baseTheme) {
|
||||
textarea: {
|
||||
fontFamily: 'inherit',
|
||||
},
|
||||
iframe: {
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
},
|
||||
...pickrOverride(baseTheme),
|
||||
...uplotOverride(baseTheme),
|
||||
...rcdockOverride(baseTheme),
|
||||
|
@ -195,7 +195,7 @@ function UtilityViewContent({panelId, schema, treeNodeInfo, actionType, formType
|
||||
onHelp={onHelp}
|
||||
onDataChange={()=>{/*This is intentional (SonarQube)*/}}
|
||||
confirmOnCloseReset={confirmOnReset}
|
||||
hasSQL={nodeObj?nodeObj.hasSQL:false && (actionType === 'create' || actionType === 'edit')}
|
||||
hasSQL={nodeObj?.hasSQL && (actionType === 'create' || actionType === 'edit')}
|
||||
getSQLValue={getSQLValue}
|
||||
isTabView={isTabView}
|
||||
disableSqlHelp={sqlHelpUrl == undefined || sqlHelpUrl == ''}
|
||||
|
@ -34,7 +34,7 @@ export default function ContextMenu({menuItems, position, onClose, label='contex
|
||||
{menuItems.length !=0 && menuItems.map((menuItem, i)=>{
|
||||
const submenus = menuItem.getMenuItems?.();
|
||||
if(submenus) {
|
||||
return <PgSubMenu key={i} label={menuItem.label}>
|
||||
return <PgSubMenu key={label+'-'+menuItem.label} label={menuItem.label}>
|
||||
{submenus.map((submenuItem, si)=>{
|
||||
return getPgMenuItem(submenuItem, i+'-'+si);
|
||||
})}
|
||||
|
@ -13,7 +13,7 @@ const useStyles = makeStyles((theme)=>({
|
||||
bottom: 0,
|
||||
width: 'auto',
|
||||
maxWidth: '99%',
|
||||
zIndex: 9999,
|
||||
zIndex: 1004,
|
||||
padding: '0.25rem 0.5rem',
|
||||
fontSize: '0.95em',
|
||||
color: theme.palette.background.default,
|
||||
|
@ -16,6 +16,7 @@ export default function LayoutIframeTab({target, src, children}) {
|
||||
const updatePositionAndSize = () => {
|
||||
if (!selfRef.current) return;
|
||||
const rect = selfRef.current.getBoundingClientRect();
|
||||
rect.visibility = selfRef.current.closest('#'+target).style.visibility;
|
||||
|
||||
// Only update the iframe's position if the position has actually changed
|
||||
if (
|
||||
@ -23,13 +24,15 @@ export default function LayoutIframeTab({target, src, children}) {
|
||||
rect.top !== lastKnownPosition.top ||
|
||||
rect.left !== lastKnownPosition.left ||
|
||||
rect.width !== lastKnownPosition.width ||
|
||||
rect.height !== lastKnownPosition.height
|
||||
rect.height !== lastKnownPosition.height ||
|
||||
rect.visibility !== lastKnownPosition.visibility
|
||||
) {
|
||||
iframeTarget.style.position = 'fixed'; // You can adjust this if needed
|
||||
iframeTarget.style.top = `${rect.top}px`;
|
||||
iframeTarget.style.left = `${rect.left}px`;
|
||||
iframeTarget.style.width = `${rect.width}px`;
|
||||
iframeTarget.style.height = `${rect.height}px`;
|
||||
iframeTarget.style.display = rect.visibility == 'hidden' ? 'none' : '';
|
||||
|
||||
lastKnownPosition = rect;
|
||||
}
|
||||
@ -45,17 +48,18 @@ export default function LayoutIframeTab({target, src, children}) {
|
||||
}, [iframeTarget]);
|
||||
|
||||
return <>
|
||||
<div ref={selfRef} data-target={target} style={{width: '100%', height: '100%'}}></div>
|
||||
<Portal ref={(r)=>{
|
||||
if(r) setIframeTarget(r.querySelector('#'+target));
|
||||
}} container={document.querySelector('#layout-portal')}>
|
||||
{src ?
|
||||
<iframe src={src} id={target} style={{position: 'fixed'}} />:
|
||||
<Frame src={src} id={target} style={{position: 'fixed'}}>
|
||||
{children}
|
||||
</Frame>
|
||||
}
|
||||
</Portal>
|
||||
<div ref={selfRef} data-target={target} style={{width: '100%', height: '100%'}}>
|
||||
<Portal ref={(r)=>{
|
||||
if(r) setIframeTarget(r.querySelector('#'+target));
|
||||
}} container={document.querySelector('#layout-portal')}>
|
||||
{src ?
|
||||
<iframe src={src} id={target} style={{position: 'fixed', border: 0}} />:
|
||||
<Frame src={src} id={target} style={{position: 'fixed', border: 0}}>
|
||||
{children}
|
||||
</Frame>
|
||||
}
|
||||
</Portal>
|
||||
</div>
|
||||
</>;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useRef, useMemo, useState, useEffect, useCallback } from 'react';
|
||||
import React, { useRef, useMemo, useEffect, useCallback } from 'react';
|
||||
import DockLayout from 'rc-dock';
|
||||
import PropTypes from 'prop-types';
|
||||
import EventBus from '../EventBus';
|
||||
@ -18,16 +18,6 @@ import _ from 'lodash';
|
||||
|
||||
function TabTitle({id, icon, title, closable, tooltip}) {
|
||||
const layoutDocker = React.useContext(LayoutDockerContext);
|
||||
const dynamicTabsPref = useRef(usePreferences().getPreferencesForModule('browser')?.dynamic_tabs);
|
||||
const getMaxWidth = ()=>{
|
||||
if(layoutDocker.isTabVisible(id)) {
|
||||
return '100%';
|
||||
} else if(dynamicTabsPref.current) {
|
||||
return '100%';
|
||||
}
|
||||
return '125px';
|
||||
};
|
||||
const [maxWidth, setMaxWidth] = useState(getMaxWidth());
|
||||
|
||||
const onContextMenu = useCallback((e)=>{
|
||||
const g = layoutDocker.find(id)?.group??'';
|
||||
@ -37,26 +27,10 @@ function TabTitle({id, icon, title, closable, tooltip}) {
|
||||
layoutDocker.eventBus.fireEvent(LAYOUT_EVENTS.CONTEXT, e, id);
|
||||
}, []);
|
||||
|
||||
const onTabActive = _.debounce(()=>{
|
||||
setMaxWidth(getMaxWidth());
|
||||
}, 100);
|
||||
|
||||
useEffect(()=>{
|
||||
layoutDocker.eventBus.registerListener(LAYOUT_EVENTS.ACTIVE, onTabActive);
|
||||
return ()=>{
|
||||
onTabActive.cancel();
|
||||
layoutDocker.eventBus.deregisterListener(LAYOUT_EVENTS.ACTIVE, onTabActive);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(()=>{
|
||||
setMaxWidth(getMaxWidth());
|
||||
}, [usePreferences().version]);
|
||||
|
||||
return (
|
||||
<Box display="flex" alignItems="center" title={tooltip??title} onContextMenu={onContextMenu} maxWidth={maxWidth}>
|
||||
<Box display="flex" alignItems="center" title={tooltip??title} onContextMenu={onContextMenu} width="100%">
|
||||
{icon && <span style={{fontSize: '1rem', marginRight: '4px'}} className={icon}></span>}
|
||||
<span style={{maxWidth: maxWidth, textOverflow: 'ellipsis', overflow: 'hidden', whiteSpace: 'nowrap'}} data-visible={layoutDocker.isTabVisible(id)}>{title}</span>
|
||||
<span style={{textOverflow: 'ellipsis', overflow: 'hidden', whiteSpace: 'nowrap'}} data-visible={layoutDocker.isTabVisible(id)}>{title}</span>
|
||||
{closable && <PgIconButton title={gettext('Close')} icon={<CloseIcon style={{height: '0.7em'}} />} size="xs" noBorder onClick={()=>{
|
||||
layoutDocker.close(id);
|
||||
}} style={{margin: '-1px -10px -1px 0'}} />}
|
||||
@ -146,7 +120,7 @@ export class LayoutDocker {
|
||||
...panelData,
|
||||
internal: internal,
|
||||
title: <TabTitle id={panelData.id} icon={internal.icon} title={internal.title} closable={internal.closable} tooltip={internal.tooltip} />
|
||||
});
|
||||
}, false);
|
||||
}
|
||||
|
||||
setInternalAttrs(panelId, attrs) {
|
||||
@ -157,7 +131,7 @@ export class LayoutDocker {
|
||||
...panelData.internal,
|
||||
...attrs,
|
||||
},
|
||||
});
|
||||
}, false);
|
||||
}
|
||||
|
||||
getInternalAttrs(panelId) {
|
||||
@ -328,6 +302,22 @@ export class LayoutDocker {
|
||||
|
||||
export const LayoutDockerContext = React.createContext(new LayoutDocker(null, null));
|
||||
|
||||
function DialogClose({panelData}) {
|
||||
const layoutDocker = React.useContext(LayoutDockerContext);
|
||||
// In a dialog, panelData is the data of the container panel and not the
|
||||
// data of actual dialog tab. panelData.activeId gives the id of dialog tab.
|
||||
return (
|
||||
<Box display="flex" alignItems="center">
|
||||
<PgIconButton title={gettext('Close')} icon={<CloseIcon />} size="xs" noBorder onClick={()=>{
|
||||
layoutDocker.close(panelData.activeId);
|
||||
}} style={{marginRight: '-4px'}}/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
DialogClose.propTypes = {
|
||||
panelData: PropTypes.object
|
||||
};
|
||||
|
||||
function getDialogsGroup() {
|
||||
return {
|
||||
disableDock: true,
|
||||
@ -335,16 +325,7 @@ function getDialogsGroup() {
|
||||
floatable: 'singleTab',
|
||||
moreIcon: <ExpandMoreIcon style={{height: '0.9em'}} />,
|
||||
panelExtra: (panelData) => {
|
||||
const layoutDocker = React.useContext(LayoutDockerContext);
|
||||
// In a dialo, panelData is the data of the container panel and not the
|
||||
// data of actual dialog tab. panelData.activeId gives the id of dialog tab.
|
||||
return (
|
||||
<Box display="flex" alignItems="center">
|
||||
<PgIconButton title={gettext('Close')} icon={<CloseIcon />} size="xs" noBorder onClick={()=>{
|
||||
layoutDocker.close(panelData.activeId);
|
||||
}} style={{marginRight: '-4px'}}/>
|
||||
</Box>
|
||||
);
|
||||
return <DialogClose panelData={panelData} />;
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -379,6 +360,8 @@ export default function Layout({groups, noContextGroups, getLayoutInstance, layo
|
||||
...groups,
|
||||
}), [groups]);
|
||||
const layoutDockerObj = React.useMemo(()=>new LayoutDocker(layoutId, props.defaultLayout, resetToTabPanel, noContextGroups), []);
|
||||
const prefStore = usePreferences();
|
||||
const dynamicTabsStyleRef = useRef();
|
||||
|
||||
useEffect(()=>{
|
||||
layoutDockerObj.eventBus.registerListener(LAYOUT_EVENTS.REMOVE, (panelId)=>{
|
||||
@ -390,6 +373,22 @@ export default function Layout({groups, noContextGroups, getLayoutInstance, layo
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(()=>{
|
||||
const dynamicTabs = prefStore.getPreferencesForModule('browser')?.dynamic_tabs;
|
||||
// Add a class to set max width for non dynamic Tabs
|
||||
if(!dynamicTabs && !dynamicTabsStyleRef.current) {
|
||||
const css = '.dock-tab:not(div.dock-tab-active) { max-width: 180px; }',
|
||||
head = document.head || document.getElementsByTagName('head')[0];
|
||||
|
||||
dynamicTabsStyleRef.current = document.createElement('style');
|
||||
head.appendChild(dynamicTabsStyleRef.current);
|
||||
dynamicTabsStyleRef.current.appendChild(document.createTextNode(css));
|
||||
} else if(dynamicTabs && dynamicTabsStyleRef.current) {
|
||||
dynamicTabsStyleRef.current.remove();
|
||||
dynamicTabsStyleRef.current = null;
|
||||
}
|
||||
}, [prefStore]);
|
||||
|
||||
const getTabMenuItems = (panelId)=>{
|
||||
const ret = [];
|
||||
if(panelId) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useEffect, useLayoutEffect, useState } from 'react';
|
||||
import { usePgAdmin } from '../BrowserComponent';
|
||||
import { Box } from '@material-ui/core';
|
||||
import { QueryToolIcon, RowFilterIcon, TerminalIcon, ViewDataIcon } from '../components/ExternalIcon';
|
||||
@ -29,29 +29,35 @@ export default function ObjectExplorerToolbar() {
|
||||
'psql': undefined,
|
||||
});
|
||||
const pgAdmin = usePgAdmin();
|
||||
const checkMenuState = ()=>{
|
||||
const viewMenus = pgAdmin.Browser.MainMenus.
|
||||
find((m)=>(m.name=='object'))?.
|
||||
menuItems?.
|
||||
find((m)=>(m.name=='view_data'))?.
|
||||
menu_items;
|
||||
|
||||
const toolsMenus = pgAdmin.Browser.MainMenus.
|
||||
find((m)=>(m.name=='tools'))?.
|
||||
menuItems;
|
||||
|
||||
setMenus({
|
||||
'query_tool': toolsMenus?.find((m)=>(m.name=='query_tool')),
|
||||
'view_all_rows_context_table': viewMenus?.find((m)=>(m.name=='view_all_rows_context_table')),
|
||||
'view_filtered_rows_context_table': viewMenus?.find((m)=>(m.name=='view_filtered_rows_context_table')),
|
||||
'search_objects': toolsMenus?.find((m)=>(m.name=='search_objects')),
|
||||
'psql': toolsMenus?.find((m)=>(m.name=='psql'))
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(()=>{
|
||||
pgAdmin.Browser.Events.on('pgadmin:nw-enable-disable-menu-items', _.debounce(()=>{
|
||||
const viewMenus = pgAdmin.Browser.MainMenus.
|
||||
find((m)=>(m.name=='object'))?.
|
||||
menuItems?.
|
||||
find((m)=>(m.name=='view_data'))?.
|
||||
menu_items;
|
||||
|
||||
const toolsMenus = pgAdmin.Browser.MainMenus.
|
||||
find((m)=>(m.name=='tools'))?.
|
||||
menuItems;
|
||||
|
||||
setMenus({
|
||||
'query_tool': toolsMenus?.find((m)=>(m.name=='query_tool')),
|
||||
'view_all_rows_context_table': viewMenus?.find((m)=>(m.name=='view_all_rows_context_table')),
|
||||
'view_filtered_rows_context_table': viewMenus?.find((m)=>(m.name=='view_filtered_rows_context_table')),
|
||||
'search_objects': toolsMenus?.find((m)=>(m.name=='search_objects')),
|
||||
'psql': toolsMenus?.find((m)=>(m.name=='psql'))
|
||||
});
|
||||
}, 100));
|
||||
const deregister = pgAdmin.Browser.Events.on('pgadmin:nw-enable-disable-menu-items', _.debounce(checkMenuState, 100));
|
||||
return ()=>{
|
||||
deregister();
|
||||
};
|
||||
}, []);
|
||||
|
||||
useLayoutEffect(_.debounce(checkMenuState, 100), []);
|
||||
|
||||
return (
|
||||
<Box display="flex" alignItems="center" gridGap={'2px'}>
|
||||
<ToolbarButton icon={<QueryToolIcon />} menuItem={menus['query_tool']} />
|
||||
|
@ -9,10 +9,10 @@
|
||||
|
||||
/* Ref: https://github.com/heygrady/Units/blob/master/Length.js */
|
||||
|
||||
var testElem = document.createElement('test'),
|
||||
let testElem = document.createElement('test'),
|
||||
docElement = document.documentElement,
|
||||
defaultView = document.defaultView,
|
||||
getComputedStyle = defaultView && defaultView.getComputedStyle,
|
||||
getComputedStyle = defaultView?.getComputedStyle,
|
||||
computedValueBug,
|
||||
runit = /^(-?[\d+\.\-]+)([a-z]+|%)$/i,
|
||||
convert = {},
|
||||
@ -104,7 +104,7 @@ function curCSS(elem, prop) {
|
||||
var value,
|
||||
pixel,
|
||||
unit,
|
||||
rvpos = /^top|bottom/,
|
||||
rvpos = /^(top|bottom)/,
|
||||
outerProp = ['paddingTop', 'paddingBottom', 'borderTop', 'borderBottom'],
|
||||
innerHeight,
|
||||
parent,
|
||||
|
@ -59,7 +59,7 @@ function manageTreeEvents(event, eventName, item) {
|
||||
if (_.isObject(node.callbacks) &&
|
||||
eventName in node.callbacks &&
|
||||
typeof node.callbacks[eventName] == 'function') {
|
||||
!node.callbacks[eventName].apply(node, [item, d, obj, [], eventName]);
|
||||
node.callbacks[eventName].apply(node, [item, d, obj, [], eventName]);
|
||||
}
|
||||
|
||||
/* Raise tree events for the nodes */
|
||||
|
@ -31,42 +31,3 @@ module.exports = function(endpoint, substitutions) {
|
||||
|
||||
return interpolated;
|
||||
};
|
||||
|
||||
// define(['pgadmin.browser.endpoints'], function(endpoints) {
|
||||
// /***
|
||||
// * This method behaves as a drop-in replacement for flask url_for function.
|
||||
// * It uses the exposed URLs file under the hood, and replace the substitions provided by the modules.
|
||||
// *
|
||||
// * ex.
|
||||
// * url_for("help.static", {filename: "server_dialog.html"}) will produce the
|
||||
// * output string '/help/help/server_dialog.html' from the url ->
|
||||
// * '/help/help/<path:filename>'.
|
||||
// *
|
||||
// * @param {String} text
|
||||
// * @param {Object} substitutions
|
||||
// */
|
||||
// return function url_for(endpoint, substitutions) {
|
||||
|
||||
// let rawURL = endpoints[endpoint];
|
||||
|
||||
// // captures things of the form <path:substitutionName>
|
||||
// let substitutionGroupsRegExp = /([<])([^:^>]*:)?([^>]+)([>])/g,
|
||||
// interpolated = rawURL;
|
||||
|
||||
// if (!rawURL)
|
||||
// return rawURL;
|
||||
|
||||
// interpolated = interpolated.replace(
|
||||
// substitutionGroupsRegExp,
|
||||
// function(_origin, _1, _2, substitutionName) {
|
||||
// if (substitutionName in substitutions) {
|
||||
// return substitutions[substitutionName];
|
||||
// }
|
||||
// return _origin;
|
||||
// }
|
||||
// );
|
||||
|
||||
// return interpolated;
|
||||
// };
|
||||
|
||||
// });
|
||||
|
@ -77,6 +77,7 @@ export default function DebuggerArgumentComponent({ debuggerInfo, restartDebug,
|
||||
const [loaderText, setLoaderText] = React.useState('');
|
||||
const debuggerFinalArgs = useRef([]);
|
||||
const InputArgIds = useRef([]);
|
||||
const browserPreferences = usePreferences().getPreferencesForModule('browser');
|
||||
|
||||
function getURL() {
|
||||
let _Url = null;
|
||||
@ -714,7 +715,6 @@ export default function DebuggerArgumentComponent({ debuggerInfo, restartDebug,
|
||||
}
|
||||
);
|
||||
|
||||
let browserPreferences = usePreferences().getPreferencesForModule('browser');
|
||||
let open_new_tab = browserPreferences.new_browser_tab_open;
|
||||
let label = getAppropriateLabel(treeInfo);
|
||||
|
||||
@ -746,7 +746,6 @@ export default function DebuggerArgumentComponent({ debuggerInfo, restartDebug,
|
||||
/* Close the debugger modal dialog */
|
||||
props.closeModal();
|
||||
setLoaderText('');
|
||||
return;
|
||||
})
|
||||
.catch(function (error) {
|
||||
setLoaderText('');
|
||||
|
@ -110,9 +110,14 @@ const useStyles = makeStyles((theme) => ({
|
||||
display: 'table',
|
||||
blockSize: '100%',
|
||||
|
||||
'& span': {
|
||||
'& > span': {
|
||||
verticalAlign: 'middle',
|
||||
cursor: 'pointer',
|
||||
|
||||
'& > span': {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
}
|
||||
}
|
||||
},
|
||||
gridPanel: {
|
||||
|
@ -346,7 +346,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
|
||||
}
|
||||
}, 100));
|
||||
|
||||
/* If the tab or window is not visible */
|
||||
/* If the tab or window is not visible, applicable for open in new tab */
|
||||
document.addEventListener('visibilitychange', function() {
|
||||
if(document.hidden) {
|
||||
setQtState({is_visible: false});
|
||||
|
@ -83,7 +83,7 @@ export function getPanelTitle(pgBrowser, selected_item=null, custom_title=null,
|
||||
|
||||
export function getQueryToolIcon(title, isQt, isFile) {
|
||||
let panelIcon = '';
|
||||
let panelTooltip = title;
|
||||
let panelTooltip;
|
||||
|
||||
if(isFile || isFile == 'true'){
|
||||
panelIcon = 'fa fa-file-alt';
|
||||
|
@ -109,33 +109,6 @@ describe('SchemaView', ()=>{
|
||||
expect(ctrl.container.querySelector('[data-test="Save"]').hasAttribute('disabled')).toBe(true);
|
||||
});
|
||||
|
||||
it('onSave after change', async ()=>{
|
||||
pgAdmin.Browser.notifier.alert.mockClear();
|
||||
onSave.mockClear();
|
||||
// TODO: don't know why save button remains disabled.
|
||||
// await simulateChanges();
|
||||
// await user.click(ctrl.container.querySelector('[data-test="Save"]'));
|
||||
|
||||
// expect(onSave.mock.calls[0][0]).toBe(false);
|
||||
// expect(onSave.mock.calls[0][1]).toEqual({
|
||||
// id: 1,
|
||||
// field1: 'val1',
|
||||
// field5: 'val5',
|
||||
// fieldcoll: {
|
||||
// added: [
|
||||
// { field3: null, field4: null, field5: 'rval53'}
|
||||
// ],
|
||||
// changed: [
|
||||
// { field3: 2, field4: 'field4val2', field5: 'rvalnew'}
|
||||
// ],
|
||||
// deleted: [
|
||||
// { field3: 1, field4: 'field4val1', field5: 'field5val1'}
|
||||
// ]
|
||||
// }
|
||||
// });
|
||||
// expect(pgAdmin.Browser.notifier.alert).toHaveBeenCalledWith('Warning', 'some inform text');
|
||||
});
|
||||
|
||||
it('onReset after change', async ()=>{
|
||||
onDataChange.mockClear();
|
||||
await simulateChanges();
|
||||
|
@ -3,10 +3,9 @@ import CustomPropTypes from '../../../../pgadmin/static/js/custom_prop_types';
|
||||
export * from '@material-ui/core';
|
||||
|
||||
// mock popper
|
||||
export const Popper = React.forwardRef((props, ref)=>{
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
export const Popper = React.forwardRef((props, _ref)=>{
|
||||
const ele = useRef();
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
ref = {};
|
||||
return <div ref={ele} data-test="material-popper">{props.children}</div>;
|
||||
});
|
||||
|
||||
|
@ -3,11 +3,7 @@ import PopperJs from 'popper.js';
|
||||
export default class Popper {
|
||||
static placements = PopperJs.placements;
|
||||
|
||||
constructor() {
|
||||
return {
|
||||
destroy: () => {},
|
||||
scheduleUpdate: () => {},
|
||||
update: () => {},
|
||||
};
|
||||
}
|
||||
destroy() {/* mock */}
|
||||
scheduleUpdate() {/* mock */}
|
||||
update() {/* mock */}
|
||||
}
|
||||
|
@ -1,18 +1,10 @@
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import React, { useRef } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
export * from 'react-data-grid';
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const ReactDataGrid = React.forwardRef((props, ref)=>{
|
||||
const ReactDataGrid = React.forwardRef((props, _ref)=>{
|
||||
const ele = useRef();
|
||||
|
||||
useEffect(()=>{
|
||||
ref = {
|
||||
selectCell: jest.fn(),
|
||||
element: ele.current,
|
||||
};
|
||||
}, [ele.current]);
|
||||
|
||||
return <div id={props.id} ref={ele} data-test="react-data-grid"/>;
|
||||
});
|
||||
|
||||
|
@ -50,7 +50,7 @@ describe('Privilege', ()=>{
|
||||
}}
|
||||
onChange={onChange}
|
||||
/>
|
||||
),
|
||||
);
|
||||
ctrlRerender = (props)=>{
|
||||
ctrl.rerender(
|
||||
<ThemedPrivilege
|
||||
|
@ -1,472 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2023, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// The code is commented because:
|
||||
// 1. @testing-library/react doesn't give instance of class components.
|
||||
// 2. ERD code need to be separated from component to make it more testable
|
||||
// Adding dummy
|
||||
describe('ERDTool', ()=>{
|
||||
it('dummy', ()=>{});
|
||||
});
|
||||
|
||||
// import React from 'react';
|
||||
|
||||
// import MockAdapter from 'axios-mock-adapter';
|
||||
// import axios from 'axios/index';
|
||||
// import pgAdmin from '../../fake_pgadmin';
|
||||
|
||||
// import ERDCore from 'pgadmin.tools.erd/erd_tool/ERDCore';
|
||||
// import * as erdModule from 'pgadmin.tools.erd/ERDModule';
|
||||
// import erdPref from './erd_preferences';
|
||||
// import ERDTool from 'pgadmin.tools.erd/erd_tool/components/ERDTool';
|
||||
// import * as ERDSqlTool from 'tools/sqleditor/static/js/show_query_tool';
|
||||
// import { FakeLink, FakeNode, FakePort } from '../fake_item';
|
||||
// import Theme from '../../../../pgadmin/static/js/Theme';
|
||||
// import ModalProvider from '../../../../pgadmin/static/js/helpers/ModalProvider';
|
||||
// import { render } from '@testing-library/react';
|
||||
// import usePreferences from '../../../../pgadmin/preferences/static/js/store';
|
||||
// import userEvent from '@testing-library/user-event';
|
||||
|
||||
// let tableDialog = jest.fn();
|
||||
// let otmDialog = jest.fn();
|
||||
// let mtmDialog = jest.fn();
|
||||
|
||||
// let getDialog = (dialogName)=>{
|
||||
// switch(dialogName) {
|
||||
// case 'table_dialog': return tableDialog;
|
||||
// case 'onetomany_dialog': return otmDialog;
|
||||
// case 'manytomany_dialog': return mtmDialog;
|
||||
// }
|
||||
// };
|
||||
|
||||
// describe('ERDTool', ()=>{
|
||||
// let erd = null;
|
||||
// let body = null;
|
||||
// let bodyInstance = null;
|
||||
// let networkMock = null;
|
||||
// let serverVersion = 120000;
|
||||
// let colTypes = [
|
||||
// {'label': 'integer', 'value': 'integer'},
|
||||
// {'label': 'character varrying', 'value': 'character varrying'},
|
||||
// ];
|
||||
// let schemas = [
|
||||
// {'oid': 111, 'name': 'erd1'},
|
||||
// {'oid': 222, 'name': 'erd2'},
|
||||
// ];
|
||||
// let params = {
|
||||
// bgcolor: null,
|
||||
// client_platform: 'macos',
|
||||
// did: '13637',
|
||||
// fgcolor: null,
|
||||
// gen: true,
|
||||
// is_desktop_mode: true,
|
||||
// is_linux: false,
|
||||
// server_type: 'pg',
|
||||
// sgid: '1',
|
||||
// sid: '5',
|
||||
// title: 'postgres/postgres@PostgreSQL 12',
|
||||
// trans_id: 110008,
|
||||
// };
|
||||
// let newNode = new FakeNode({
|
||||
// columns: [{attnum: 0}, {attnum: 1}],
|
||||
// }, 'newid1');
|
||||
|
||||
// beforeAll(()=>{
|
||||
// jest.spyOn(erdModule, 'setPanelTitle').mockImplementation(() => {});
|
||||
// jest.spyOn(ERDCore.prototype, 'repaint').mockImplementation(() => {});
|
||||
// jest.spyOn(ERDCore.prototype, 'deserializeData').mockImplementation(() => {});
|
||||
// jest.spyOn(ERDCore.prototype, 'addNode').mockReturnValue(newNode);
|
||||
// jest.spyOn(ERDCore.prototype, 'addLink').mockReturnValue(new FakeLink());
|
||||
// jest.spyOn(usePreferences.getState(), 'getPreferencesForModule').mockImplementation((module)=>{
|
||||
// if(module == 'erd') {
|
||||
// return erdPref;
|
||||
// }
|
||||
// return {};
|
||||
// })
|
||||
// networkMock = new MockAdapter(axios);
|
||||
// networkMock.onPost('/erd/initialize/110008/1/5/13637').reply(200, {'data': {
|
||||
// serverVersion: serverVersion,
|
||||
// }});
|
||||
// networkMock.onGet('/erd/prequisite/110008/1/5/13637').reply(200, {'data': {
|
||||
// 'col_types': colTypes,
|
||||
// 'schemas': schemas,
|
||||
// }});
|
||||
// networkMock.onGet('/erd/tables/110008/1/5/13637').reply(200, {'data': []});
|
||||
|
||||
// networkMock.onPost('/erd/sql/110008/1/5/13637').reply(200, {'data': 'SELECT 1;'});
|
||||
|
||||
// networkMock.onPost('/sqleditor/load_file/').reply(200, {'data': 'data'});
|
||||
// networkMock.onPost('/sqleditor/save_file/').reply(200, {'data': 'data'});
|
||||
// });
|
||||
|
||||
// beforeEach(()=>{
|
||||
// erd = render(
|
||||
// <Theme>
|
||||
// <ModalProvider>
|
||||
// <ERDTool params={params} pgAdmin={pgAdmin} pgWindow={{
|
||||
// pgAdmin: pgAdmin
|
||||
// }} isTest={true} panelDocker={pgAdmin.Browser.docker}/>
|
||||
// </ModalProvider>
|
||||
// </Theme>
|
||||
// );
|
||||
// });
|
||||
|
||||
// afterAll(() => {
|
||||
// networkMock.restore();
|
||||
// });
|
||||
|
||||
// it('event offsetUpdated', (done)=>{
|
||||
// bodyInstance.diagram.fireEvent({offsetX: 4, offsetY: 5}, 'offsetUpdated', true);
|
||||
// setTimeout(()=>{
|
||||
// expect(bodyInstance.canvasEle.style.backgroundPosition).toBe('4px 5px');
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
|
||||
// it('event zoomUpdated', (done)=>{
|
||||
// jest.spyOn(bodyInstance.diagram.getModel(), 'getOptions').mockReturnValue({gridSize: 15});
|
||||
// bodyInstance.diagram.fireEvent({zoom: 20}, 'zoomUpdated', true);
|
||||
// setTimeout(()=>{
|
||||
// expect(bodyInstance.canvasEle.style.backgroundSize).toBe('9px 9px');
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
|
||||
// it('event nodesSelectionChanged', (done)=>{
|
||||
// jest.spyOn(bodyInstance.diagram, 'getSelectedNodes').mockReturnValue([new FakeNode({key:'value'})]);
|
||||
// bodyInstance.diagram.fireEvent({}, 'nodesSelectionChanged', true);
|
||||
// setTimeout(()=>{
|
||||
// expect(body.state().single_node_selected).toBe(true);
|
||||
// expect(body.state().any_item_selected).toBe(true);
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
|
||||
// it('event linksSelectionChanged', (done)=>{
|
||||
// jest.spyOn(bodyInstance.diagram, 'getSelectedLinks').mockReturnValue([{key:'value'}]);
|
||||
// bodyInstance.diagram.fireEvent({}, 'linksSelectionChanged', true);
|
||||
// setTimeout(()=>{
|
||||
// expect(body.state().single_link_selected).toBe(true);
|
||||
// expect(body.state().any_item_selected).toBe(true);
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
|
||||
// it('event linksUpdated', (done)=>{
|
||||
// bodyInstance.diagram.fireEvent({}, 'linksUpdated', true);
|
||||
// setTimeout(()=>{
|
||||
// expect(body.state().dirty).toBe(true);
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
|
||||
// it('event nodesUpdated', (done)=>{
|
||||
// bodyInstance.diagram.fireEvent({}, 'nodesUpdated', true);
|
||||
// setTimeout(()=>{
|
||||
// expect(body.state().dirty).toBe(true);
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
|
||||
// it('event showNote', (done)=>{
|
||||
// let noteNode = {key: 'value', getNote: ()=>'a note'};
|
||||
// jest.spyOn(bodyInstance, 'showNote').mockImplementation(() => {});
|
||||
// bodyInstance.diagram.fireEvent({node: noteNode}, 'showNote', true);
|
||||
// setTimeout(()=>{
|
||||
// expect(bodyInstance.showNote).toHaveBeenCalledWith(noteNode);
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
|
||||
// it('event editTable', (done)=>{
|
||||
// let node = {key: 'value', getNote: ()=>'a note'};
|
||||
// jest.spyOn(bodyInstance, 'addEditTable').mockImplementation(() => {});
|
||||
// bodyInstance.diagram.fireEvent({node: node}, 'editTable', true);
|
||||
// setTimeout(()=>{
|
||||
// expect(bodyInstance.addEditTable).toHaveBeenCalledWith(node);
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
|
||||
// it('addEditTable', ()=>{
|
||||
// let node1 = new FakeNode({'name': 'table1', schema: 'erd1', columns: [{name: 'col1', type: 'type1', attnum: 1}]}, 'id1');
|
||||
// let node2 = new FakeNode({'name': 'table2', schema: 'erd2', columns: [{name: 'col2', type: 'type2', attnum: 2}]}, 'id2');
|
||||
// let nodesDict = {
|
||||
// 'id1': node1,
|
||||
// 'id2': node2,
|
||||
// };
|
||||
// jest.spyOn(bodyInstance.diagram, 'getModel').mockReturnValue({
|
||||
// 'getNodesDict': ()=>nodesDict,
|
||||
// });
|
||||
// jest.spyOn(bodyInstance.diagram, 'addLink').mockImplementation(() => {});
|
||||
// jest.spyOn(bodyInstance.diagram, 'syncTableLinks').mockImplementation(() => {});
|
||||
// /* New */
|
||||
// tableDialog.mockClear();
|
||||
// bodyInstance.addEditTable();
|
||||
// expect(tableDialog).toHaveBeenCalled();
|
||||
|
||||
// let saveCallback = tableDialog.mock.calls[tableDialog.mock.calls.length - 1][3];
|
||||
// let newData = {key: 'value'};
|
||||
// saveCallback(newData);
|
||||
// expect(bodyInstance.diagram.addNode.mock.calls[bodyInstance.diagram.addNode.mock.calls.length - 1][0]).toEqual(newData);
|
||||
|
||||
// /* Existing */
|
||||
// tableDialog.mockClear();
|
||||
// let node = new FakeNode({name: 'table1', schema: 'erd1'});
|
||||
// jest.spyOn(node, 'setData').mockImplementation(() => {});
|
||||
// bodyInstance.addEditTable(node);
|
||||
// expect(tableDialog).toHaveBeenCalled();
|
||||
|
||||
// saveCallback = tableDialog.mock.calls[tableDialog.mock.calls.length - 1][3];
|
||||
// newData = {key: 'value'};
|
||||
// saveCallback(newData);
|
||||
// expect(node.setData).toHaveBeenCalledWith(newData);
|
||||
// });
|
||||
|
||||
// it('onEditTable', ()=>{
|
||||
// let node = {key: 'value'};
|
||||
// jest.spyOn(bodyInstance, 'addEditTable').mockImplementation(() => {});
|
||||
// jest.spyOn(bodyInstance.diagram, 'getSelectedNodes').mockReturnValue([node]);
|
||||
// bodyInstance.onEditTable();
|
||||
// expect(bodyInstance.addEditTable).toHaveBeenCalledWith(node);
|
||||
// });
|
||||
|
||||
// it('onAddNewNode', ()=>{
|
||||
// jest.spyOn(bodyInstance, 'addEditTable').mockImplementation(() => {});
|
||||
// bodyInstance.onAddNewNode();
|
||||
// expect(bodyInstance.addEditTable).toHaveBeenCalled();
|
||||
// });
|
||||
|
||||
// it('onCloneNode', ()=>{
|
||||
// let node = new FakeNode({name: 'table1', schema: 'erd1'});
|
||||
// jest.spyOn(bodyInstance.diagram, 'getSelectedNodes').mockReturnValue([node]);
|
||||
// jest.spyOn(bodyInstance.diagram, 'getNextTableName').mockReturnValue('newtable1');
|
||||
// bodyInstance.diagram.addNode.mockClear();
|
||||
// bodyInstance.onCloneNode();
|
||||
// let cloneArgs = bodyInstance.diagram.addNode.mock.calls[0];
|
||||
// expect(cloneArgs[0]).toEqual(expect.objectContaining({
|
||||
// name: 'newtable1',
|
||||
// schema: 'erd1',
|
||||
// }));
|
||||
// expect(cloneArgs[1]).toEqual([50, 50]);
|
||||
// });
|
||||
|
||||
// it('onDeleteNode', (done)=>{
|
||||
// let node = new FakeNode({name: 'table1', schema: 'erd1'});
|
||||
// let link = new FakeLink({local_table_uid: 'tid1'});
|
||||
// let port = new FakePort();
|
||||
// jest.spyOn(port, 'getLinks').mockReturnValue([link]);
|
||||
// jest.spyOn(node, 'remove').mockImplementation(() => {});
|
||||
// jest.spyOn(node, 'getPorts').mockReturnValue([port]);
|
||||
// let nodesDict = {
|
||||
// 'tid1': node
|
||||
// };
|
||||
// jest.spyOn(bodyInstance.diagram, 'getModel').mockReturnValue({
|
||||
// 'getNodesDict': ()=>nodesDict,
|
||||
// });
|
||||
// jest.spyOn(bodyInstance.diagram, 'removeOneToManyLink').mockImplementation(() => {});
|
||||
// jest.spyOn(bodyInstance.diagram, 'getSelectedNodes').mockReturnValue([node]);
|
||||
// jest.spyOn(bodyInstance.diagram, 'getSelectedLinks').mockReturnValue([link]);
|
||||
|
||||
// bodyInstance.onDeleteNode();
|
||||
// setTimeout(()=>{
|
||||
// expect(node.remove).toHaveBeenCalled();
|
||||
// expect(bodyInstance.diagram.removeOneToManyLink).toHaveBeenCalledWith(link);
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
|
||||
// it('onAutoDistribute', ()=>{
|
||||
// jest.spyOn(bodyInstance.diagram, 'dagreDistributeNodes').mockImplementation(()=>{/* intentionally empty */});
|
||||
// bodyInstance.onAutoDistribute();
|
||||
// expect(bodyInstance.diagram.dagreDistributeNodes).toHaveBeenCalled();
|
||||
// });
|
||||
|
||||
// it('onDetailsToggle', (done)=>{
|
||||
// let node = {
|
||||
// 'fireEvent': jest.fn()
|
||||
// };
|
||||
// jest.spyOn(bodyInstance.diagram, 'getModel').mockReturnValue({
|
||||
// 'getNodes': ()=>[node],
|
||||
// });
|
||||
|
||||
// let show_details = body.state().show_details;
|
||||
// bodyInstance.onDetailsToggle();
|
||||
// body.setState({}, ()=>{
|
||||
// expect(body.state().show_details).toBe(!show_details);
|
||||
// expect(node.fireEvent).toHaveBeenCalledWith({show_details: !show_details}, 'toggleDetails');
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
|
||||
// it('onLoadDiagram', ()=>{
|
||||
// bodyInstance.onLoadDiagram();
|
||||
// expect(pgAdmin.Tools.FileManager.show).toHaveBeenCalled();
|
||||
// });
|
||||
|
||||
// it('openFile', (done)=>{
|
||||
// jest.spyOn(bodyInstance.diagram, 'deserialize').mockImplementation(() => {});
|
||||
// bodyInstance.openFile('test.pgerd');
|
||||
// setTimeout(()=>{
|
||||
// expect(body.state()).toEqual(expect.objectContaining({
|
||||
// current_file: 'test.pgerd',
|
||||
// dirty: false,
|
||||
// }));
|
||||
// expect(bodyInstance.diagram.deserialize).toHaveBeenCalledWith({data: 'data'});
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
|
||||
// it('onSaveDiagram', (done)=>{
|
||||
// body.setState({
|
||||
// current_file: 'newfile.pgerd',
|
||||
// });
|
||||
// bodyInstance.onSaveDiagram();
|
||||
// setTimeout(()=>{
|
||||
// expect(body.state()).toEqual(expect.objectContaining({
|
||||
// current_file: 'newfile.pgerd',
|
||||
// dirty: false,
|
||||
// }));
|
||||
// done();
|
||||
// });
|
||||
|
||||
// pgAdmin.Tools.FileManager.show.mockClear();
|
||||
// bodyInstance.onSaveDiagram(true);
|
||||
// expect(pgAdmin.Tools.FileManager.show.mock.calls[0][0]).toEqual({
|
||||
// 'supported_types': ['*','pgerd'],
|
||||
// 'dialog_type': 'create_file',
|
||||
// 'dialog_title': 'Save File',
|
||||
// 'btn_primary': 'Save',
|
||||
// });
|
||||
// });
|
||||
|
||||
// it('onSaveAsDiagram', ()=>{
|
||||
// jest.spyOn(bodyInstance, 'onSaveDiagram').mockImplementation(() => {});
|
||||
// bodyInstance.onSaveAsDiagram();
|
||||
// expect(bodyInstance.onSaveDiagram).toHaveBeenCalledWith(true);
|
||||
// });
|
||||
|
||||
// it('onSQLClick', (done)=>{
|
||||
// jest.spyOn(bodyInstance.diagram, 'serializeData').mockReturnValue({key: 'value'});
|
||||
// jest.spyOn(ERDSqlTool, 'showERDSqlTool').mockImplementation(() => {});
|
||||
// jest.spyOn(localStorage, 'setItem').mockImplementation(() => {});
|
||||
// bodyInstance.onSQLClick();
|
||||
|
||||
// setTimeout(()=>{
|
||||
// let sql = '-- This script was generated by the ERD tool in pgAdmin 4.\n'
|
||||
// + '-- Please log an issue at https://redmine.postgresql.org/projects/pgadmin4/issues/new if you find any bugs, including reproduction steps.\n'
|
||||
// + 'BEGIN;\nSELECT 1;\nEND;';
|
||||
|
||||
// expect(localStorage.setItem).toHaveBeenCalledWith('erd'+params.trans_id, sql);
|
||||
// expect(ERDSqlTool.showERDSqlTool).toHaveBeenCalled();
|
||||
// done();
|
||||
// });
|
||||
// });
|
||||
|
||||
// it('onOneToManyClick', ()=>{
|
||||
// let node = new FakeNode({}, 'id1');
|
||||
// let node1 = new FakeNode({'name': 'table1', schema: 'erd1', columns: [{name: 'col1', type: 'type1', attnum: 1}]}, 'id1');
|
||||
// let node2 = new FakeNode({'name': 'table2', schema: 'erd2', columns: [{name: 'col2', type: 'type2', attnum: 2}]}, 'id2');
|
||||
// let nodesDict = {
|
||||
// 'id1': node1,
|
||||
// 'id2': node2,
|
||||
// };
|
||||
// jest.spyOn(bodyInstance.diagram, 'getModel').mockReturnValue({
|
||||
// 'getNodesDict': ()=>nodesDict,
|
||||
// });
|
||||
// jest.spyOn(bodyInstance.diagram, 'addLink').mockImplementation(() => {});
|
||||
// jest.spyOn(bodyInstance.diagram, 'getSelectedNodes').mockReturnValue([node]);
|
||||
|
||||
// bodyInstance.onOneToManyClick();
|
||||
// let saveCallback = otmDialog.mock.calls[otmDialog.mock.calls.length - 1][2];
|
||||
// let newData = {
|
||||
// local_table_uid: 'id1',
|
||||
// local_column_attnum: 1,
|
||||
// referenced_table_uid: 'id2',
|
||||
// referenced_column_attnum: 2,
|
||||
// };
|
||||
// saveCallback(newData);
|
||||
// expect(bodyInstance.diagram.addLink).toHaveBeenCalledWith(newData, 'onetomany');
|
||||
// });
|
||||
|
||||
// it('onManyToManyClick', ()=>{
|
||||
// let node = new FakeNode({}, 'id1');
|
||||
// let node1 = new FakeNode({'name': 'table1', schema: 'erd1', columns: [{name: 'col1', type: 'type1', attnum: 1}]}, 'id1');
|
||||
// let node2 = new FakeNode({'name': 'table2', schema: 'erd2', columns: [{name: 'col2', type: 'type2', attnum: 2}]}, 'id2');
|
||||
// let nodesDict = {
|
||||
// 'id1': node1,
|
||||
// 'id2': node2,
|
||||
// 'newid1': newNode,
|
||||
// };
|
||||
// jest.spyOn(bodyInstance.diagram, 'getModel').mockReturnValue({
|
||||
// 'getNodesDict': ()=>nodesDict,
|
||||
// });
|
||||
// jest.spyOn(bodyInstance.diagram, 'getSelectedNodes').mockReturnValue([node]);
|
||||
|
||||
// bodyInstance.onManyToManyClick();
|
||||
|
||||
// /* onSave */
|
||||
// jest.spyOn(bodyInstance.diagram, 'addLink').mockImplementation(() => {});
|
||||
// let saveCallback = mtmDialog.mock.calls[mtmDialog.mock.calls.length - 1][2];
|
||||
// let newData = {
|
||||
// left_table_uid: 'id1',
|
||||
// left_table_column_attnum: 1,
|
||||
// right_table_uid: 'id2',
|
||||
// right_table_column_attnum: 2,
|
||||
// };
|
||||
|
||||
// bodyInstance.diagram.addNode.mockClear();
|
||||
// bodyInstance.diagram.addLink.mockClear();
|
||||
// saveCallback(newData);
|
||||
// let tableData = bodyInstance.diagram.addNode.mock.calls[0][0];
|
||||
// expect(tableData).toEqual(expect.objectContaining({
|
||||
// name: 'table1_table2',
|
||||
// schema: 'erd1',
|
||||
// }));
|
||||
// expect(tableData.columns[0]).toEqual(expect.objectContaining({
|
||||
// type: 'type1',
|
||||
// name: 'table1_col1',
|
||||
// attnum: 0,
|
||||
// }));
|
||||
// expect(tableData.columns[1]).toEqual(expect.objectContaining({
|
||||
// type: 'type2',
|
||||
// name: 'table2_col2',
|
||||
// attnum: 1,
|
||||
// }));
|
||||
|
||||
// let linkData = {
|
||||
// local_table_uid: 'newid1',
|
||||
// local_column_attnum: 0,
|
||||
// referenced_table_uid: 'id1',
|
||||
// referenced_column_attnum : 1,
|
||||
// };
|
||||
// expect(bodyInstance.diagram.addLink.mock.calls[0]).toEqual([linkData, 'onetomany']);
|
||||
// linkData = {
|
||||
// local_table_uid: 'newid1',
|
||||
// local_column_attnum: 1,
|
||||
// referenced_table_uid: 'id2',
|
||||
// referenced_column_attnum : 2,
|
||||
// };
|
||||
// expect(bodyInstance.diagram.addLink.mock.calls[1]).toEqual([linkData, 'onetomany']);
|
||||
// });
|
||||
|
||||
// it('onNoteClick', ()=>{
|
||||
// let noteNode = {key: 'value', getNote: ()=>'a note'};
|
||||
// jest.spyOn(bodyInstance.diagram, 'getSelectedNodes').mockReturnValue([noteNode]);
|
||||
// jest.spyOn(bodyInstance.diagram.getEngine(), 'getNodeElement').mockReturnValue(null);
|
||||
// jest.spyOn(bodyInstance.diagram.getEngine(), 'getNodeElement').mockReturnValue(null);
|
||||
// jest.spyOn(bodyInstance, 'setState').mockImplementation(() => {});
|
||||
// bodyInstance.onNoteClick();
|
||||
// expect(bodyInstance.setState).toHaveBeenCalledWith({
|
||||
// note_node: noteNode,
|
||||
// note_open: true,
|
||||
// });
|
||||
// });
|
||||
// });
|
@ -1,7 +1,7 @@
|
||||
import '@testing-library/jest-dom';
|
||||
|
||||
class BroadcastChannelMock {
|
||||
onmessage() {}
|
||||
onmessage() {/* mock */}
|
||||
postMessage(data) {
|
||||
this.onmessage({ data });
|
||||
}
|
||||
|
@ -233,28 +233,6 @@ describe('#browserTreeState', () => {
|
||||
expect(browserTreeState.current_state).toMatchObject({1: {'paths': ['server_group/1,server/1']}});
|
||||
});
|
||||
});
|
||||
|
||||
describe('When server node is closed, both server and server_group should be removed', () => {
|
||||
// TODO: failing somehow
|
||||
// let item = {
|
||||
// _type: 'server',
|
||||
// hasId: true,
|
||||
// id: 'server/1',
|
||||
// _id: 1,
|
||||
// };
|
||||
// beforeEach(() => {
|
||||
// pgBrowser.tree.itemData.mockReturnValue(item);
|
||||
// pgBrowser.tree.pathId.mockReturnValue(['server_group/1']);
|
||||
// pgBrowser.tree.hasParent.mockReturnValue(true);
|
||||
// pgBrowser.tree.isOpen.mockReturnValue(true);
|
||||
// pgBrowser.tree.isClosed.mockReturnValue(true);
|
||||
// });
|
||||
|
||||
// it('The tree current state will remove server_group and server', () => {
|
||||
// browserTreeState.remove_from_cache(item);
|
||||
// expect(browserTreeState.current_state).toMatchObject({1: []});
|
||||
// });
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user