From 7a2716bf77e1d7dab092cf70d2e9cd6bdcf643ad Mon Sep 17 00:00:00 2001 From: Pradip Parkale Date: Thu, 3 Feb 2022 11:13:39 +0530 Subject: [PATCH] Fixed issues related to porting of dependent, dependencies, and statistics panel. refs #7016 --- .../xss_checks_panels_and_query_tool_test.py | 7 +-- .../dependencies/static/js/Dependencies.jsx | 15 ++++--- .../misc/dependents/static/js/Dependents.jsx | 15 ++++--- web/pgadmin/misc/static/utils/utils.js | 44 +++++++++++++++++++ .../misc/statistics/static/js/Statistics.jsx | 25 ++++------- web/pgadmin/static/js/components/PgTable.jsx | 16 +++++-- 6 files changed, 84 insertions(+), 38 deletions(-) create mode 100644 web/pgadmin/misc/static/utils/utils.js diff --git a/web/pgadmin/feature_tests/xss_checks_panels_and_query_tool_test.py b/web/pgadmin/feature_tests/xss_checks_panels_and_query_tool_test.py index 808e5377a..45c4beedc 100644 --- a/web/pgadmin/feature_tests/xss_checks_panels_and_query_tool_test.py +++ b/web/pgadmin/feature_tests/xss_checks_panels_and_query_tool_test.py @@ -168,9 +168,10 @@ class CheckForXssFeatureTest(BaseFeatureTest): try: self.page.click_tab("Dependents") source_code = \ - self.page.find_by_xpath("//*[@id='5']/table/tbody/tr/td/" - "div/div/div[2]/table/tbody/tr/" - "td[2]").get_attribute('innerHTML') + self.page.find_by_xpath( + "//*[@id='5']/table/tbody/tr/td/div/div[1]/div/" + "div[2]/div/div/div/div[2]").get_attribute( + 'innerHTML') retry = 0 except WebDriverException as e: print("Exception in dependent tab {0}".format(retry), diff --git a/web/pgadmin/misc/dependencies/static/js/Dependencies.jsx b/web/pgadmin/misc/dependencies/static/js/Dependencies.jsx index 94266ad32..ee7ea6e46 100644 --- a/web/pgadmin/misc/dependencies/static/js/Dependencies.jsx +++ b/web/pgadmin/misc/dependencies/static/js/Dependencies.jsx @@ -9,13 +9,13 @@ import _ from 'lodash'; import React, { useEffect } from 'react'; -import { generateNodeUrl } from '../../../../browser/static/js/node_ajax'; import PgTable from 'sources/components/PgTable'; import gettext from 'sources/gettext'; import PropTypes from 'prop-types'; import Notify from '../../../../static/js/helpers/Notifier'; import getApiInstance from 'sources/api_instance'; import { makeStyles } from '@material-ui/core/styles'; +import { getURL } from '../../../static/utils/utils'; const useStyles = makeStyles((theme) => ({ emptyPanel: { @@ -68,7 +68,7 @@ function parseData(data, node) { return data; } -export default function Dependencies({ nodeData, node, ...props }) { +export default function Dependencies({ nodeData, item, node, ...props }) { const classes = useStyles(); const [tableData, setTableData] = React.useState([]); @@ -101,13 +101,13 @@ export default function Dependencies({ nodeData, node, ...props }) { useEffect(() => { let message = gettext('Please select an object in the tree view.'); if (node) { - let url = generateNodeUrl.call( - node, - props.treeNodeInfo, - 'dependency', + let url = getURL( nodeData, true, - node.url_jump_after_node + props.treeNodeInfo, + node, + item, + 'dependency' ); message = gettext( 'No dependency information is available for the selected object.' @@ -172,4 +172,5 @@ Dependencies.propTypes = { nodeData: PropTypes.object, treeNodeInfo: PropTypes.object, node: PropTypes.func, + item: PropTypes.object, }; diff --git a/web/pgadmin/misc/dependents/static/js/Dependents.jsx b/web/pgadmin/misc/dependents/static/js/Dependents.jsx index 704ca9ef1..487e2d29b 100644 --- a/web/pgadmin/misc/dependents/static/js/Dependents.jsx +++ b/web/pgadmin/misc/dependents/static/js/Dependents.jsx @@ -9,13 +9,13 @@ import _ from 'lodash'; import React, { useEffect } from 'react'; -import { generateNodeUrl } from '../../../../browser/static/js/node_ajax'; import PgTable from 'sources/components/PgTable'; import gettext from 'sources/gettext'; import PropTypes from 'prop-types'; import Notify from '../../../../static/js/helpers/Notifier'; import getApiInstance from 'sources/api_instance'; import { makeStyles } from '@material-ui/core/styles'; +import { getURL } from '../../../static/utils/utils'; const useStyles = makeStyles((theme) => ({ emptyPanel: { @@ -68,7 +68,7 @@ function parseData(data, node) { return data; } -export default function Dependents({ nodeData, node, ...props }) { +export default function Dependents({ nodeData, item, node, ...props }) { const classes = useStyles(); const [tableData, setTableData] = React.useState([]); @@ -102,13 +102,13 @@ export default function Dependents({ nodeData, node, ...props }) { useEffect(() => { let message = gettext('Please select an object in the tree view.'); if (node) { - let url = generateNodeUrl.call( - node, - props.treeNodeInfo, - 'dependent', + let url = getURL( nodeData, true, - node.url_jump_after_node + props.treeNodeInfo, + node, + item, + 'dependent' ); message = gettext( 'No dependant information is available for the selected object.' @@ -173,4 +173,5 @@ Dependents.propTypes = { nodeData: PropTypes.object, treeNodeInfo: PropTypes.object, node: PropTypes.func, + item: PropTypes.object, }; diff --git a/web/pgadmin/misc/static/utils/utils.js b/web/pgadmin/misc/static/utils/utils.js new file mode 100644 index 000000000..8e9794fa5 --- /dev/null +++ b/web/pgadmin/misc/static/utils/utils.js @@ -0,0 +1,44 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2022, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import { generateNodeUrl, generateCollectionURL } from '../../../../pgadmin/browser/static/js/node_ajax'; +import { sprintf } from 'sources/utils'; + +export function getURL( + nodeData, + with_id, + getTreeNodeHierarchy, + node, + item, + panelType +) { + if (nodeData.is_collection && panelType === 'stats') { + return generateCollectionURL.call(node, item, panelType); + } + if (_.indexOf(['partition'], nodeData._type) == -1) { + return generateNodeUrl.call( + node, + getTreeNodeHierarchy, + panelType, + nodeData, + with_id, + node.url_jump_after_node + ); + } + + return sprintf( + 'table/%s/%s/%s/%s/%s/%s', + encodeURIComponent(panelType), + encodeURIComponent(getTreeNodeHierarchy['server_group']._id), + encodeURIComponent(getTreeNodeHierarchy['server']._id), + encodeURIComponent(getTreeNodeHierarchy['database']._id), + encodeURIComponent(getTreeNodeHierarchy['partition'].schema_id), + encodeURIComponent(getTreeNodeHierarchy['partition']._id) + ); +} diff --git a/web/pgadmin/misc/statistics/static/js/Statistics.jsx b/web/pgadmin/misc/statistics/static/js/Statistics.jsx index f2fb316f0..0d259b6d7 100644 --- a/web/pgadmin/misc/statistics/static/js/Statistics.jsx +++ b/web/pgadmin/misc/statistics/static/js/Statistics.jsx @@ -9,10 +9,6 @@ import _ from 'lodash'; import React, { useEffect } from 'react'; -import { - generateNodeUrl, - generateCollectionURL, -} from '../../../../browser/static/js/node_ajax'; import PgTable from 'sources/components/PgTable'; import gettext from 'sources/gettext'; import PropTypes from 'prop-types'; @@ -20,6 +16,7 @@ import Notify from '../../../../static/js/helpers/Notifier'; import getApiInstance from 'sources/api_instance'; import { makeStyles } from '@material-ui/core/styles'; import sizePrettify from 'sources/size_prettify'; +import { getURL } from '../../../static/utils/utils'; const useStyles = makeStyles((theme) => ({ emptyPanel: { @@ -66,6 +63,7 @@ function getColumn(data, singleLineStatistics) { columns.push(column); }); } + return columns; } else { columns = [ { @@ -104,6 +102,7 @@ function getTableData(res, node) { } return [nodeStats, colData]; } + function createSingleLineStatistics(data, prettifyFields) { var row = data['rows'][0], columns = data['columns'], @@ -157,19 +156,9 @@ export default function Statistics({ nodeData, item, node, ...props }) { useEffect(() => { let url, message = gettext('Please select an object in the tree view.'); + if (node) { - if (nodeData.is_collection) { - url = generateCollectionURL.call(node, item, 'stats'); - } else { - url = generateNodeUrl.call( - node, - props.treeNodeInfo, - 'stats', - nodeData, - true, - node.url_jump_after_node - ); - } + url = getURL(nodeData, true, props.treeNodeInfo, node, item, 'stats'); message = gettext('No statistics are available for the selected object.'); @@ -182,7 +171,9 @@ export default function Statistics({ nodeData, item, node, ...props }) { .then((res) => { let [nodeStats, colData] = getTableData(res, node); setTableData(nodeStats); - setColumns(colData); + if (!_.isUndefined(colData)) { + setColumns(colData); + } }) .catch((e) => { Notify.alert( diff --git a/web/pgadmin/static/js/components/PgTable.jsx b/web/pgadmin/static/js/components/PgTable.jsx index 8a433b08b..f17018a1c 100644 --- a/web/pgadmin/static/js/components/PgTable.jsx +++ b/web/pgadmin/static/js/components/PgTable.jsx @@ -6,8 +6,6 @@ // This software is released under the PostgreSQL Licence // ////////////////////////////////////////////////////////////// -/* eslint-disable react/display-name */ -/* eslint-disable react/prop-types */ import React from 'react'; import { useTable, useRowSelect, useSortBy, useResizeColumns, useFlexLayout, useGlobalFilter } from 'react-table'; @@ -17,7 +15,7 @@ import clsx from 'clsx'; import PropTypes from 'prop-types'; import AutoSizer from 'react-virtualized-auto-sizer'; import { Checkbox } from '@material-ui/core'; - +/* eslint-disable react/display-name */ const useStyles = makeStyles((theme) => ({ root: { display: 'flex', @@ -31,7 +29,7 @@ const useStyles = makeStyles((theme) => ({ width: '100% !important', }, fixedSizeList: { - position: 'relative', + // position: 'relative', direction: 'ltr', overflowX: 'hidden !important', overflow: 'overlay !important' @@ -318,6 +316,16 @@ PgTable.propTypes = { className: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]), getToggleAllRowsSelectedProps: PropTypes.func, + columns: PropTypes.array, + data: PropTypes.array, + isSelectRow: PropTypes.bool, + row: PropTypes.func, + setSelectedRows: PropTypes.func, + getSelectedRows: PropTypes.func, + searchText: PropTypes.string, + type: PropTypes.string, + sortOptions: PropTypes.array, + };