public inbox for [email protected]  
help / color / mirror / Atom feed
[pgAdmin][patch] Improvements in PgTable component
4+ messages / 2 participants
[nested] [flat]

* [pgAdmin][patch] Improvements in PgTable component
@ 2022-04-04 13:24 Aditya Toshniwal <[email protected]>
  2022-04-04 13:37 ` Re: [pgAdmin][patch] Improvements in PgTable component Akshay Joshi <[email protected]>
  0 siblings, 1 reply; 4+ messages in thread

From: Aditya Toshniwal @ 2022-04-04 13:24 UTC (permalink / raw)
  To: pgadmin-hackers

Hi Hackers,

Attached patch makes some necessary cleanup/restructuring in PgTable
component.
Please review.

-- 
Thanks,
Aditya Toshniwal
pgAdmin Hacker | Software Architect | *edbpostgres.com*
<http://edbpostgres.com;
"Don't Complain about Heat, Plant a TREE"


Attachments:

  [application/octet-stream] pgtable.improve.patch (22.2K, 3-pgtable.improve.patch)
  download | inline diff:
diff --git a/web/pgadmin/dashboard/static/js/ActiveQuery.ui.js b/web/pgadmin/dashboard/static/js/ActiveQuery.ui.js
index a1450df7b..5cce03308 100644
--- a/web/pgadmin/dashboard/static/js/ActiveQuery.ui.js
+++ b/web/pgadmin/dashboard/static/js/ActiveQuery.ui.js
@@ -30,7 +30,6 @@ export default class ActiveQuery extends BaseUISchema {
         readonly: true,
         mode: ['properties'],
         group: gettext('Details'),
-        disabled: true
       },
       {
         id: 'query_start',
@@ -39,8 +38,6 @@ export default class ActiveQuery extends BaseUISchema {
         editable: false,
         readonly: true,
         group: gettext('Details'),
-        disabled: true
-
       },
       {
         id: 'state_change',
@@ -49,7 +46,6 @@ export default class ActiveQuery extends BaseUISchema {
         editable: false,
         readonly: true,
         group: gettext('Details'),
-        disabled: true
       },
       {
         id: 'query',
diff --git a/web/pgadmin/dashboard/static/js/Dashboard.jsx b/web/pgadmin/dashboard/static/js/Dashboard.jsx
index 637f6cde4..779b406cc 100644
--- a/web/pgadmin/dashboard/static/js/Dashboard.jsx
+++ b/web/pgadmin/dashboard/static/js/Dashboard.jsx
@@ -85,11 +85,11 @@ const useStyles = makeStyles((theme) => ({
   },
   panelContent: {
     ...theme.mixins.panelBorder,
+    display: 'flex',
     flexDirection: 'column',
     overflow: 'hidden !important',
-    flexGrow: 1,
-    minWidth: '300px',
-    minHeight: '300px'
+    height: '100%',
+    minHeight: '400px'
   },
   arrowButton: {
     fontSize: '2rem !important',
@@ -339,6 +339,7 @@ export default function Dashboard({
         let canEditRow = true;
         return (
           <PgIconButton
+            size="xs"
             className={row.isExpanded ?classes.buttonClick : ''}
             icon={
               row.isExpanded ? (
@@ -809,31 +810,34 @@ export default function Dashboard({
               >
                 {gettext('Server activity')}{' '}
               </Box>
-              <Tabs
-                value={val}
-                onChange={tabChanged}
-                className={classes.searchInput}
-              >
-                {tab.map((tabValue, i) => {
-                  return <Tab key={i} label={tabValue} />;
-                })}
+              <Box display="flex">
+                <Tabs
+                  value={val}
+                  onChange={tabChanged}
+                  className={classes.searchInput}
+                >
+                  {tab.map((tabValue, i) => {
+                    return <Tab key={i} label={tabValue} />;
+                  })}
+                </Tabs>
                 <RefreshButton/>
-              </Tabs>
-
-              <PgTable
-                columns={
-                  val === 0
-                    ? activityColumns
-                    : val === 1
-                      ? databaseLocksColumns
-                      : val == 2
-                        ? databasePreparedColumns
-                        : serverConfigColumns
-                }
-                data={dashData}
-                schema={schemaDict}
-                offset={145}
-              ></PgTable>
+              </Box>
+              <Box flexGrow={1}>
+                <PgTable
+                  caveTable={false}
+                  columns={
+                    val === 0
+                      ? activityColumns
+                      : val === 1
+                        ? databaseLocksColumns
+                        : val == 2
+                          ? databasePreparedColumns
+                          : serverConfigColumns
+                  }
+                  data={dashData}
+                  schema={schemaDict}
+                ></PgTable>
+              </Box>
             </Box>
           </Box>
         </Box>
diff --git a/web/pgadmin/static/js/Theme/dark.js b/web/pgadmin/static/js/Theme/dark.js
index cafaaae3e..8808262ac 100644
--- a/web/pgadmin/static/js/Theme/dark.js
+++ b/web/pgadmin/static/js/Theme/dark.js
@@ -94,6 +94,7 @@ export default function(basicSettings) {
       stepFg: '#000',
       toggleBtnBg: '#000',
       colorFg: '#FFFFFF',
+      emptySpaceBg: '#212121',
     }
   });
 }
diff --git a/web/pgadmin/static/js/Theme/high_contrast.js b/web/pgadmin/static/js/Theme/high_contrast.js
index a9c172ac7..0fb330ae3 100644
--- a/web/pgadmin/static/js/Theme/high_contrast.js
+++ b/web/pgadmin/static/js/Theme/high_contrast.js
@@ -92,6 +92,7 @@ export default function(basicSettings) {
       stepFg: '#000',
       toggleBtnBg: '#6B6B6B',
       colorFg: '#FFFFFF',
+      emptySpaceBg: '#010B15',
     }
   });
 }
diff --git a/web/pgadmin/static/js/Theme/standard.js b/web/pgadmin/static/js/Theme/standard.js
index 8cf463a71..b4e2b88b1 100644
--- a/web/pgadmin/static/js/Theme/standard.js
+++ b/web/pgadmin/static/js/Theme/standard.js
@@ -103,7 +103,7 @@ export default function(basicSettings) {
       toggleBtnBg: '#000',
       editorToolbarBg: '#ebeef3',
       datagridBg: '#fff',
-
+      emptySpaceBg: '#ebeef3',
     }
   });
 }
diff --git a/web/pgadmin/static/js/components/PgTable.jsx b/web/pgadmin/static/js/components/PgTable.jsx
index 265d833f3..5626271a4 100644
--- a/web/pgadmin/static/js/components/PgTable.jsx
+++ b/web/pgadmin/static/js/components/PgTable.jsx
@@ -24,9 +24,9 @@ import PropTypes from 'prop-types';
 import AutoSizer from 'react-virtualized-auto-sizer';
 import { Checkbox, Box } from '@material-ui/core';
 import { InputText } from './FormComponents';
-import FormView from 'sources/SchemaView';
 import _ from 'lodash';
 import gettext from 'sources/gettext';
+import SchemaView from '../SchemaView';
 
 /* eslint-disable react/display-name */
 const useStyles = makeStyles((theme) => ({
@@ -37,8 +37,11 @@ const useStyles = makeStyles((theme) => ({
     ...theme.mixins.panelBorder,
     backgroundColor: theme.palette.background.default,
   },
+  autoResizerContainer: {
+    flexGrow: 1,
+    minHeight: 0
+  },
   autoResizer: {
-    height: '100% !important',
     width: '100% !important',
   },
   fixedSizeList: {
@@ -51,7 +54,6 @@ const useStyles = makeStyles((theme) => ({
     marginLeft: '4px'
   },
   searchBox: {
-    marginBottom: '5px',
     display: 'flex',
     background: theme.palette.background.default
   },
@@ -61,10 +63,6 @@ const useStyles = makeStyles((theme) => ({
   alert: {
     backgroundColor: theme.palette.error.main + '!important'
   },
-
-  tableContentWidth: {
-    width: 'calc(100% - 3px)',
-  },
   searchPadding: {
     flex: 2.5
   },
@@ -77,14 +75,22 @@ const useStyles = makeStyles((theme) => ({
     marginBottom: 8,
 
   },
-  table: {
+  tableContainer: {
+    overflowX: 'auto',
     flexGrow: 1,
     minHeight: 0,
+    display: 'flex',
+    flexDirection: 'column',
+    backgroundColor: theme.otherVars.emptySpaceBg,
+  },
+  table: {
     borderSpacing: 0,
-    width: '100%',
     overflow: 'hidden',
     borderRadius: theme.shape.borderRadius,
-    border: '1px solid'+ theme.palette.grey[400]
+    border: '1px solid '+theme.otherVars.borderColor,
+    display: 'flex',
+    flexDirection: 'column',
+    height: '100%',
   },
   pgTableHeadar: {
     display: 'flex',
@@ -94,11 +100,16 @@ const useStyles = makeStyles((theme) => ({
     flexDirection: 'column'
   },
 
+  tableRowContent:{
+    display: 'flex',
+    flexDirection: 'column',
+    minHeight: 0,
+  },
+
   expandedForm: {
-    ...theme.mixins.panelBorder,
+    ...theme.mixins.panelBorder.all,
     margin: '8px',
-    paddingBottom: '12px',
-    marginRight: '15px',
+    flexGrow: 1,
   },
 
   tableCell: {
@@ -155,6 +166,9 @@ const useStyles = makeStyles((theme) => ({
     overflow: 'auto',
     padding: '7.5px',
   },
+  caveTable: {
+    margin: '8px',
+  },
   panelIcon: {
     width: '80%',
     margin: '0 auto',
@@ -177,30 +191,63 @@ const useStyles = makeStyles((theme) => ({
   },
 }));
 
-export default function PgTable({ columns, data, isSelectRow, offset=105, ...props }) {
+const IndeterminateCheckbox = React.forwardRef(
+  ({ indeterminate, ...rest }, ref) => {
+    const defaultRef = React.useRef();
+    const resolvedRef = ref || defaultRef;
+
+    React.useEffect(() => {
+      resolvedRef.current.indeterminate = indeterminate;
+    }, [resolvedRef, indeterminate]);
+    return (
+      <>
+        <Checkbox
+          color="primary"
+          ref={resolvedRef} {...rest}
+        />
+      </>
+    );
+  },
+);
+
+IndeterminateCheckbox.displayName = 'SelectCheckbox';
+
+IndeterminateCheckbox.propTypes = {
+  indeterminate: PropTypes.bool,
+  rest: PropTypes.func,
+  getToggleAllRowsSelectedProps: PropTypes.func,
+  row: PropTypes.object,
+};
+
+const ROW_HEIGHT = 35;
+export default function PgTable({ columns, data, isSelectRow, caveTable=true, ...props }) {
   // Use the state and functions returned from useTable to build your UI
   const classes = useStyles();
   const [searchVal, setSearchVal] = React.useState('');
   const tableRef = React.useRef();
   const rowHeights = React.useRef({});
-  const rowRef = React.useRef({});
 
   // Reset Search vakue in tab changed.
   React.useEffect(()=>{
     setSearchVal('');
-  },[columns]);
-  function getRowHeight(index, size) {
-    return rowHeights.current[index] + size || 35;
+    rowHeights.current = {};
+    tableRef.current?.resetAfterIndex(0);
+  }, [columns]);
+
+  function getRowHeight(index) {
+    return rowHeights.current[index] || ROW_HEIGHT;
   }
 
-  const setRowHeight = React.useCallback((index, size) => {
+  const setRowHeight = (index, size) => {
     if(tableRef.current) {
-      tableRef.current.resetAfterIndex(index);
-      if (!(rowHeights.current.hasOwnProperty(index))){
-        rowHeights.current = { ...rowHeights.current, [index]: size };
+      if(size == ROW_HEIGHT) {
+        delete rowHeights.current[index];
+      } else {
+        rowHeights.current[index] = size;
       }
+      tableRef.current.resetAfterIndex(index);
     }
-  }, []);
+  };
 
   const defaultColumn = React.useMemo(
     () => ({
@@ -209,34 +256,6 @@ export default function PgTable({ columns, data, isSelectRow, offset=105, ...pro
     []
   );
 
-  const IndeterminateCheckbox = React.forwardRef(
-    ({ indeterminate, ...rest }, ref) => {
-      const defaultRef = React.useRef();
-      const resolvedRef = ref || defaultRef;
-
-      React.useEffect(() => {
-        resolvedRef.current.indeterminate = indeterminate;
-      }, [resolvedRef, indeterminate]);
-      return (
-        <>
-          <Checkbox
-            color="primary"
-            ref={resolvedRef} {...rest}
-          />
-        </>
-      );
-    },
-  );
-
-  IndeterminateCheckbox.displayName = 'SelectCheckbox';
-
-  IndeterminateCheckbox.propTypes = {
-    indeterminate: PropTypes.bool,
-    rest: PropTypes.func,
-    getToggleAllRowsSelectedProps: PropTypes.func,
-    row: PropTypes.object,
-  };
-
   const {
     getTableProps,
     getTableBodyProps,
@@ -244,7 +263,7 @@ export default function PgTable({ columns, data, isSelectRow, offset=105, ...pro
     rows,
     prepareRow,
     selectedFlatRows,
-    state: { selectedRowIds, expanded },
+    state: { selectedRowIds },
     setGlobalFilter,
     setHiddenColumns,
   } = useTable(
@@ -327,11 +346,6 @@ export default function PgTable({ columns, data, isSelectRow, offset=105, ...pro
     }
   );
 
-  React.useEffect(()=>{
-    tableRef.current?.resetAfterIndex(0);
-  },[expanded]);
-
-
   React.useEffect(() => {
     setHiddenColumns(
       columns
@@ -365,45 +379,72 @@ export default function PgTable({ columns, data, isSelectRow, offset=105, ...pro
   const RenderRow = React.useCallback(
     ({ index, style }) => {
       const row = rows[index];
+      const [expandComplete, setExpandComplete] = React.useState(null);
+      const rowRef = React.useRef() ;
       prepareRow(row);
+
+      React.useEffect(()=>{
+        if(expandComplete && !row.isExpanded) {
+          setExpandComplete(false);
+        }
+      }, [row.isExpanded]);
+
+      React.useEffect(()=>{
+        if(rowRef.current) {
+          if(expandComplete == null) {
+            return;
+          }
+          let rowHeight;
+          rowRef.current.style.height='unset';
+          if(expandComplete) {
+            rowHeight = rowRef.current.offsetHeight;
+          } else {
+            rowHeight = ROW_HEIGHT;
+            rowRef.current.style.height = ROW_HEIGHT;
+          }
+          rowRef.current.style.height = rowHeight + 'px';
+          setRowHeight(index, rowHeight);
+        }
+      }, [expandComplete]);
+
       return (
-        <div className={classes.tableContentWidth} style={style} key={row.id}>
-          <div {...row.getRowProps()} className={classes.tr}>
-            {row.cells.map((cell) => {
-              let classNames = [classes.tableCell];
-              if(typeof(cell.column.id) == 'string' && cell.column.id.startsWith('btn-')) {
-                classNames.push(classes.btnCell);
-              }
-              if(cell.column.id == 'btn-edit' && row.isExpanded) {
-                classNames.push(classes.expandedIconCell);
-              }
-              if (row.original.row_type === 'warning'){
-                classNames.push(classes.warning);
-              }
-              if (row.original.row_type === 'alert'){
-                classNames.push(classes.alert);
-              }
-              return (
-                <div key={cell.column.id} {...cell.getCellProps()} className={clsx(classNames, row.original.icon && row.original.icon[cell.column.id], row.original.icon[cell.column.id] && classes.cellIcon)}
-                  title={_.isUndefined(cell.value) || _.isNull(cell.value) ? '': String(cell.value)}>
-                  {cell.render('Cell')}
-                </div>
-              );
-            })}
+        <div style={style} key={row.id} ref={rowRef}>
+          <div className={classes.tableRowContent}>
+            <div {...row.getRowProps()} className={classes.tr}>
+              {row.cells.map((cell) => {
+                let classNames = [classes.tableCell];
+                if(typeof(cell.column.id) == 'string' && cell.column.id.startsWith('btn-')) {
+                  classNames.push(classes.btnCell);
+                }
+                if(cell.column.id == 'btn-edit' && row.isExpanded) {
+                  classNames.push(classes.expandedIconCell);
+                }
+                if (row.original.row_type === 'warning'){
+                  classNames.push(classes.warning);
+                }
+                if (row.original.row_type === 'alert'){
+                  classNames.push(classes.alert);
+                }
+                return (
+                  <div key={cell.column.id} {...cell.getCellProps()} className={clsx(classNames, row.original.icon && row.original.icon[cell.column.id], row.original.icon[cell.column.id] && classes.cellIcon)}
+                    title={_.isUndefined(cell.value) || _.isNull(cell.value) ? '': String(cell.value)}>
+                    {cell.render('Cell')}
+                  </div>
+                );
+              })}
+            </div>
+            {!_.isUndefined(row) && row.isExpanded && (
+              <Box key={row.id} className={classes.expandedForm}>
+                <SchemaView
+                  getInitData={()=>Promise.resolve({})}
+                  viewHelperProps={{ mode: 'properties' }}
+                  schema={props.schema[row.id]}
+                  showFooter={false}
+                  onDataChange={()=>{setExpandComplete(true);}}
+                />
+              </Box>
+            )}
           </div>
-          {!_.isUndefined(row) && row.isExpanded && (
-            <Box key={row.id} className={classes.expandedForm} ref={rowRef} style={{height: rowHeights.current[index]}}>
-              <FormView
-                getInitData={() => {
-                  /*This is intentional (SonarQube)*/
-                }}
-                viewHelperProps={{ mode: 'properties' }}
-                schema={props.schema[row.id]}
-                showFooter={false}
-                onDataChange={() => { }}
-              />
-            </Box>
-          )}
         </div>
       );
     },
@@ -424,80 +465,70 @@ export default function PgTable({ columns, data, isSelectRow, offset=105, ...pro
           }}
         />
       </Box>
-      <AutoSizer
-        className={props.type === 'panel' ? props.className : classes.autoResizer}
-      >
-        {({ height }) => (
-          <div {...getTableProps()} className={classes.table}>
-            <div>
-              {headerGroups.map((headerGroup) => (
-                <div key={''} {...headerGroup.getHeaderGroupProps()}>
-                  {headerGroup.headers.map((column) => (
+      <div className={classes.tableContainer}>
+        <div {...getTableProps()} className={clsx(classes.table, caveTable ? classes.caveTable : '')}>
+          <div>
+            {headerGroups.map((headerGroup) => (
+              <div key={''} {...headerGroup.getHeaderGroupProps()}>
+                {headerGroup.headers.map((column) => (
+                  <div
+                    key={column.id}
+                    {...column.getHeaderProps()}
+                    className={clsx(classes.tableCellHeader, column.className)}
+                  >
                     <div
-                      key={column.id}
-                      {...column.getHeaderProps()}
-                      className={clsx(classes.tableCellHeader, column.className)}
+                      {...(column.sortble ? column.getSortByToggleProps() : {})}
                     >
-                      <div
-                        {...(column.sortble ? column.getSortByToggleProps() : {})}
-                      >
-                        {column.render('Header')}
-                        <span>
-                          {column.isSorted
-                            ? column.isSortedDesc
-                              ? ' 🔽'
-                              : ' 🔼'
-                            : ''}
-                        </span>
-                        {column.resizable && (
-                          <div
-                            {...column.getResizerProps()}
-                            className={classes.resizer}
-                          />
-                        )}
-                      </div>
+                      {column.render('Header')}
+                      <span>
+                        {column.isSorted
+                          ? column.isSortedDesc
+                            ? ' 🔽'
+                            : ' 🔼'
+                          : ''}
+                      </span>
+                      {column.resizable && (
+                        <div
+                          {...column.getResizerProps()}
+                          className={classes.resizer}
+                        />
+                      )}
                     </div>
-                  ))}
-                </div>
-              ))}
-            </div>
-
-            {
-              data.length > 0 ? (
-                <div {...getTableBodyProps()} >
-                  <VariableSizeList
-                    ref={tableRef}
-                    className={props.type === 'dashboard' ? props.fixedSizeList : classes.fixedSizeList}
-                    height={height - offset}
-                    itemCount={rows.length}
-                    itemSize={(i) => {
-                      if (_.isUndefined(rows[i].isExpanded)) {
-                        rows[i].isExpanded = false;
-                      }
-                      if (rowRef.current && rows[i].isExpanded) {
-                        setRowHeight(i, rowRef.current.offsetHeight + 35);
-                      }
-                      return rows[i].isExpanded ? getRowHeight(i, 35) : 35;
-                    }}
-                    sorted={props?.sortOptions}
-                  >
-                    {RenderRow}
-
-                  </VariableSizeList>
-                </div>
-              ) : (
-
-                <div className={classes.emptyPanel}>
-                  <div className={classes.panelIcon}>
-                    <i className="fa fa-exclamation-circle"></i>
-                    <span className={classes.panelMessage}>{gettext('No record found')}</span>
                   </div>
-
-                </div>
-              )}
+                ))}
+              </div>
+            ))}
           </div>
-        )}
-      </AutoSizer>
+          {
+            data.length > 0 ? (
+              <div {...getTableBodyProps()} className={classes.autoResizerContainer}>
+                <AutoSizer
+                  className={classes.autoResizer}
+                >
+                  {({ height }) => (
+                    <VariableSizeList
+                      ref={tableRef}
+                      className={classes.fixedSizeList}
+                      height={height}
+                      itemCount={rows.length}
+                      itemSize={getRowHeight}
+                      sorted={props?.sortOptions}
+                    >
+                      {RenderRow}
+                    </VariableSizeList>)}
+                </AutoSizer>
+              </div>
+            ) : (
+              <div className={classes.emptyPanel}>
+                <div className={classes.panelIcon}>
+                  <i className="fa fa-exclamation-circle"></i>
+                  <span className={classes.panelMessage}>{gettext('No record found')}</span>
+                </div>
+              </div>
+            )
+          }
+        </div>
+      </div>
     </Box>
   );
 }
@@ -505,9 +536,9 @@ export default function PgTable({ columns, data, isSelectRow, offset=105, ...pro
 PgTable.propTypes = {
   stepId: PropTypes.number,
   height: PropTypes.number,
-  offset: PropTypes.number,
   customHeader: PropTypes.func,
   className: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
+  caveTable: PropTypes.bool,
   fixedSizeList: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
   children: PropTypes.oneOfType([
     PropTypes.arrayOf(PropTypes.node),
diff --git a/web/pgadmin/tools/grant_wizard/static/js/GrantWizard.jsx b/web/pgadmin/tools/grant_wizard/static/js/GrantWizard.jsx
index 015c3939d..2bf300b9c 100644
--- a/web/pgadmin/tools/grant_wizard/static/js/GrantWizard.jsx
+++ b/web/pgadmin/tools/grant_wizard/static/js/GrantWizard.jsx
@@ -315,6 +315,7 @@ export default function GrantWizard({ sid, did, nodeInfo, nodeData }) {
       <WizardStep stepId={0}>
         <Box className={classes.panelContent}>
           <PgTable
+            caveTable={false}
             className={classes.table}
             height={window.innerHeight - 450}
             columns={columns}


^ permalink  raw  reply  [nested|flat] 4+ messages in thread

* Re: [pgAdmin][patch] Improvements in PgTable component
  2022-04-04 13:24 [pgAdmin][patch] Improvements in PgTable component Aditya Toshniwal <[email protected]>
@ 2022-04-04 13:37 ` Akshay Joshi <[email protected]>
  2022-04-05 06:23   ` Re: [pgAdmin][patch] Improvements in PgTable component Aditya Toshniwal <[email protected]>
  0 siblings, 1 reply; 4+ messages in thread

From: Akshay Joshi @ 2022-04-04 13:37 UTC (permalink / raw)
  To: Aditya Toshniwal <[email protected]>; +Cc: pgadmin-hackers

Thanks, the patch applied.

On Mon, Apr 4, 2022 at 6:55 PM Aditya Toshniwal <
[email protected]> wrote:

> Hi Hackers,
>
> Attached patch makes some necessary cleanup/restructuring in PgTable
> component.
> Please review.
>
> --
> Thanks,
> Aditya Toshniwal
> pgAdmin Hacker | Software Architect | *edbpostgres.com*
> <http://edbpostgres.com;
> "Don't Complain about Heat, Plant a TREE"
>


-- 
*Thanks & Regards*
*Akshay Joshi*
*pgAdmin Hacker | Principal Software Architect*
*EDB Postgres <http://edbpostgres.com>*

*Mobile: +91 976-788-8246*


^ permalink  raw  reply  [nested|flat] 4+ messages in thread

* Re: [pgAdmin][patch] Improvements in PgTable component
  2022-04-04 13:24 [pgAdmin][patch] Improvements in PgTable component Aditya Toshniwal <[email protected]>
  2022-04-04 13:37 ` Re: [pgAdmin][patch] Improvements in PgTable component Akshay Joshi <[email protected]>
@ 2022-04-05 06:23   ` Aditya Toshniwal <[email protected]>
  2022-04-05 06:52     ` Re: [pgAdmin][patch] Improvements in PgTable component Akshay Joshi <[email protected]>
  0 siblings, 1 reply; 4+ messages in thread

From: Aditya Toshniwal @ 2022-04-05 06:23 UTC (permalink / raw)
  To: Akshay Joshi <[email protected]>; +Cc: pgadmin-hackers

Hi Hackers,

Attached patch fixes more issues and improvements for the PgTable component.
Please review.

On Mon, Apr 4, 2022 at 7:08 PM Akshay Joshi <[email protected]>
wrote:

> Thanks, the patch applied.
>
> On Mon, Apr 4, 2022 at 6:55 PM Aditya Toshniwal <
> [email protected]> wrote:
>
>> Hi Hackers,
>>
>> Attached patch makes some necessary cleanup/restructuring in PgTable
>> component.
>> Please review.
>>
>> --
>> Thanks,
>> Aditya Toshniwal
>> pgAdmin Hacker | Software Architect | *edbpostgres.com*
>> <http://edbpostgres.com;
>> "Don't Complain about Heat, Plant a TREE"
>>
>
>
> --
> *Thanks & Regards*
> *Akshay Joshi*
> *pgAdmin Hacker | Principal Software Architect*
> *EDB Postgres <http://edbpostgres.com>*
>
> *Mobile: +91 976-788-8246*
>


-- 
Thanks,
Aditya Toshniwal
pgAdmin Hacker | Software Architect | *edbpostgres.com*
<http://edbpostgres.com;
"Don't Complain about Heat, Plant a TREE"


Attachments:

  [application/octet-stream] pgtable.improve_part2.patch (12.6K, 3-pgtable.improve_part2.patch)
  download | inline diff:
diff --git a/web/pgadmin/dashboard/static/js/Dashboard.jsx b/web/pgadmin/dashboard/static/js/Dashboard.jsx
index 779b406cc..d2340f63a 100644
--- a/web/pgadmin/dashboard/static/js/Dashboard.jsx
+++ b/web/pgadmin/dashboard/static/js/Dashboard.jsx
@@ -26,6 +26,7 @@ import WelcomeDashboard from './WelcomeDashboard';
 import ActiveQuery from './ActiveQuery.ui';
 import _ from 'lodash';
 import CachedIcon from '@mui/icons-material/Cached';
+import EmptyPanelMessage from '../../../static/js/components/EmptyPanelMessage';
 
 function parseData(data) {
   var res = [];
@@ -191,8 +192,8 @@ export default function Dashboard({
       sortble: true,
       resizable: true,
       disableGlobalFilter: false,
-      minWidth: 16,
-      maxWidth: 30,
+      width: 35,
+      minWidth: 0,
       id: 'btn-terminate',
       // eslint-disable-next-line react/display-name
       Cell: ({ row }) => {
@@ -264,8 +265,8 @@ export default function Dashboard({
       sortble: true,
       resizable: true,
       disableGlobalFilter: false,
-      minWidth: 16,
-      maxWidth: 30,
+      width: 35,
+      minWidth: 0,
       id: 'btn-cancel',
       Cell: ({ row }) => {
         var cancel_query_url =
@@ -332,8 +333,8 @@ export default function Dashboard({
       sortble: true,
       resizable: true,
       disableGlobalFilter: false,
-      minWidth: 16,
-      maxWidth: 30,
+      width: 35,
+      minWidth: 0,
       id: 'btn-edit',
       Cell: ({ row }) => {
         let canEditRow = true;
@@ -844,10 +845,7 @@ export default function Dashboard({
       ) : sid && !props.serverConnected ? (
         <Box className={classes.dashboardPanel}>
           <div className={classes.emptyPanel}>
-            <div className={classes.panelIcon}>
-              <i className="fa fa-exclamation-circle"></i>
-              <span className={classes.panelMessage}>{gettext(msg)}</span>
-            </div>
+            <EmptyPanelMessage text={gettext(msg)}/>
           </div>
         </Box>
       ) : (
diff --git a/web/pgadmin/misc/dependencies/static/js/Dependencies.jsx b/web/pgadmin/misc/dependencies/static/js/Dependencies.jsx
index b2aec80a7..1fe327036 100644
--- a/web/pgadmin/misc/dependencies/static/js/Dependencies.jsx
+++ b/web/pgadmin/misc/dependencies/static/js/Dependencies.jsx
@@ -17,14 +17,16 @@ import getApiInstance from 'sources/api_instance';
 import { makeStyles } from '@material-ui/core/styles';
 import { getURL } from '../../../static/utils/utils';
 import Loader from 'sources/components/Loader';
+import EmptyPanelMessage from '../../../../static/js/components/EmptyPanelMessage';
 
 const useStyles = makeStyles((theme) => ({
   emptyPanel: {
     minHeight: '100%',
     minWidth: '100%',
-    background: theme.palette.grey[400],
+    background: theme.otherVars.emptySpaceBg,
     overflow: 'auto',
-    padding: '7.5px',
+    padding: '8px',
+    display: 'flex',
   },
   panelIcon: {
     width: '80%',
@@ -162,10 +164,7 @@ export default function Dependencies({ nodeData, item, node, ...props }) {
       ) : (
         <div className={classes.emptyPanel}>
           {loaderText ? (<Loader message={loaderText} className={classes.loading} />) :
-            <div className={classes.panelIcon}>
-              <i className="fa fa-exclamation-circle"></i>
-              <span className={classes.panelMessage}>{gettext(msg)}</span>
-            </div>
+            <EmptyPanelMessage text={gettext(msg)}/>
           }
         </div>
       )}
diff --git a/web/pgadmin/misc/dependents/static/js/Dependents.jsx b/web/pgadmin/misc/dependents/static/js/Dependents.jsx
index 6b66e1c50..293da8041 100644
--- a/web/pgadmin/misc/dependents/static/js/Dependents.jsx
+++ b/web/pgadmin/misc/dependents/static/js/Dependents.jsx
@@ -17,14 +17,16 @@ import getApiInstance from 'sources/api_instance';
 import { makeStyles } from '@material-ui/core/styles';
 import { getURL } from '../../../static/utils/utils';
 import Loader from 'sources/components/Loader';
+import EmptyPanelMessage from '../../../../static/js/components/EmptyPanelMessage';
 
 const useStyles = makeStyles((theme) => ({
   emptyPanel: {
     minHeight: '100%',
     minWidth: '100%',
-    background: theme.palette.grey[400],
+    background: theme.otherVars.emptySpaceBg,
     overflow: 'auto',
-    padding: '7.5px',
+    padding: '8px',
+    display: 'flex',
   },
   panelIcon: {
     width: '80%',
@@ -163,10 +165,7 @@ export default function Dependents({ nodeData, item, node, ...props }) {
       ) : (
         <div className={classes.emptyPanel}>
           {loaderText ? (<Loader message={loaderText} className={classes.loading} />) :
-            <div className={classes.panelIcon}>
-              <i className="fa fa-exclamation-circle"></i>
-              <span className={classes.panelMessage}>{gettext(msg)}</span>
-            </div>
+            <EmptyPanelMessage text={gettext(msg)}/>
           }
         </div>
 
diff --git a/web/pgadmin/misc/properties/CollectionNodeProperties.jsx b/web/pgadmin/misc/properties/CollectionNodeProperties.jsx
index fb16de07d..1b8f56730 100644
--- a/web/pgadmin/misc/properties/CollectionNodeProperties.jsx
+++ b/web/pgadmin/misc/properties/CollectionNodeProperties.jsx
@@ -21,14 +21,16 @@ import PropTypes from 'prop-types';
 import { PgIconButton } from '../../static/js/components/Buttons';
 import DeleteIcon from '@material-ui/icons/Delete';
 import DeleteSweepIcon from '@material-ui/icons/DeleteSweep';
+import EmptyPanelMessage from '../../static/js/components/EmptyPanelMessage';
 
 const useStyles = makeStyles((theme) => ({
   emptyPanel: {
     minHeight: '100%',
     minWidth: '100%',
-    background: theme.palette.grey[400],
+    background: theme.otherVars.emptySpaceBg,
     overflow: 'auto',
-    padding: '7.5px',
+    padding: '8px',
+    display: 'flex',
   },
   panelIcon: {
     width: '80%',
@@ -201,7 +203,7 @@ export function CollectionNodeView({
                 sortble: true,
                 resizable: false,
                 disableGlobalFilter: false,
-                minWidth: 100,
+                minWidth: 0,
                 // eslint-disable-next-line react/display-name
                 Cell: ({ value }) => {
                   return (<Switch color="primary" checked={value} className={classes.readOnlySwitch} value={value} readOnly title={String(value)} />);
@@ -214,7 +216,7 @@ export function CollectionNodeView({
                 sortble: true,
                 resizable: false,
                 disableGlobalFilter: false,
-                minWidth: 100,
+                minWidth: 0,
               };
             }
             tableColumns.push(column);
@@ -228,10 +230,9 @@ export function CollectionNodeView({
             sortble: true,
             resizable: false,
             disableGlobalFilter: false,
-            minWidth: 100,
+            minWidth: 0,
           };
           tableColumns.push(column);
-
         });
       }
 
@@ -261,7 +262,6 @@ export function CollectionNodeView({
       <Box >
         <PgIconButton
           className={classes.dropButton}
-
           icon={<DeleteIcon/>}
           aria-label="Delete/Drop"
           title={gettext('Delete/Drop')}
@@ -310,12 +310,8 @@ export function CollectionNodeView({
           :
           (
             <div className={classes.emptyPanel}>
-              <div className={classes.panelIcon}>
-                <i className="fa fa-exclamation-circle"></i>
-                <span className={classes.panelMessage}>{gettext(infoMsg)}</span>
-              </div>
+              <EmptyPanelMessage text={gettext(infoMsg)}/>
             </div>
-
           )
         }
       </Box>
diff --git a/web/pgadmin/misc/statistics/static/js/Statistics.jsx b/web/pgadmin/misc/statistics/static/js/Statistics.jsx
index 7b5233818..50fa4965a 100644
--- a/web/pgadmin/misc/statistics/static/js/Statistics.jsx
+++ b/web/pgadmin/misc/statistics/static/js/Statistics.jsx
@@ -18,13 +18,15 @@ import { makeStyles } from '@material-ui/core/styles';
 import sizePrettify from 'sources/size_prettify';
 import { getURL } from '../../../static/utils/utils';
 import Loader from 'sources/components/Loader';
+import EmptyPanelMessage from '../../../../static/js/components/EmptyPanelMessage';
 const useStyles = makeStyles((theme) => ({
   emptyPanel: {
     minHeight: '100%',
     minWidth: '100%',
-    background: theme.palette.grey[400],
+    background: theme.otherVars.emptySpaceBg,
     overflow: 'auto',
-    padding: '7.5px',
+    padding: '8px',
+    display: 'flex',
   },
   panelIcon: {
     width: '80%',
@@ -239,10 +241,7 @@ export default function Statistics({ nodeData, item, node, ...props }) {
       ) : (
         <div className={classes.emptyPanel}>
           {loaderText ? (<Loader message={loaderText} className={classes.loading} />) :
-            <div className={classes.panelIcon}>
-              <i className="fa fa-exclamation-circle"></i>
-              <span className={classes.panelMessage}>{gettext(msg)}</span>
-            </div>
+            <EmptyPanelMessage text={gettext(msg)}/>
           }
         </div>
       )}
diff --git a/web/pgadmin/static/js/components/EmptyPanelMessage.jsx b/web/pgadmin/static/js/components/EmptyPanelMessage.jsx
new file mode 100644
index 000000000..8b96374f5
--- /dev/null
+++ b/web/pgadmin/static/js/components/EmptyPanelMessage.jsx
@@ -0,0 +1,27 @@
+import React from 'react';
+import { Box } from '@material-ui/core';
+import InfoRoundedIcon from '@material-ui/icons/InfoRounded';
+import { makeStyles } from '@material-ui/styles';
+import PropTypes from 'prop-types';
+
+const useStyles = makeStyles((theme)=>({
+  root: {
+    color: theme.palette.text.primary,
+    margin: 'auto',
+    marginTop: '24px',
+    fontSize: '0.9em',
+  },
+}));
+
+export default function EmptyPanelMessage({text}) {
+  const classes = useStyles();
+  return (
+    <Box className={classes.root}>
+      <InfoRoundedIcon />
+      <span marginLeft='4px'>{text}</span>
+    </Box>
+  );
+}
+EmptyPanelMessage.propTypes = {
+  text: PropTypes.string,
+};
diff --git a/web/pgadmin/static/js/components/PgTable.jsx b/web/pgadmin/static/js/components/PgTable.jsx
index 5626271a4..5ea0c0c7e 100644
--- a/web/pgadmin/static/js/components/PgTable.jsx
+++ b/web/pgadmin/static/js/components/PgTable.jsx
@@ -27,6 +27,7 @@ import { InputText } from './FormComponents';
 import _ from 'lodash';
 import gettext from 'sources/gettext';
 import SchemaView from '../SchemaView';
+import EmptyPanelMessage from './EmptyPanelMessage';
 
 /* eslint-disable react/display-name */
 const useStyles = makeStyles((theme) => ({
@@ -162,9 +163,9 @@ const useStyles = makeStyles((theme) => ({
   emptyPanel: {
     minHeight: '100%',
     minWidth: '100%',
-    background: theme.palette.background.default,
     overflow: 'auto',
-    padding: '7.5px',
+    padding: '8px',
+    display: 'flex',
   },
   caveTable: {
     margin: '8px',
@@ -251,7 +252,7 @@ export default function PgTable({ columns, data, isSelectRow, caveTable=true, ..
 
   const defaultColumn = React.useMemo(
     () => ({
-      minWidth: 150,
+      minWidth: 50,
     }),
     []
   );
@@ -266,6 +267,7 @@ export default function PgTable({ columns, data, isSelectRow, caveTable=true, ..
     state: { selectedRowIds },
     setGlobalFilter,
     setHiddenColumns,
+    totalColumnsWidth
   } = useTable(
     {
       columns,
@@ -328,8 +330,8 @@ export default function PgTable({ columns, data, isSelectRow, caveTable=true, ..
                 </div>
               ),
               sortble: false,
-              width: 30,
-              maxWidth: 30,
+              width: 35,
+              maxWidth: 35,
               minWidth: 0
             },
             ...CLOUMNS,
@@ -466,7 +468,7 @@ export default function PgTable({ columns, data, isSelectRow, caveTable=true, ..
         />
       </Box>
       <div className={classes.tableContainer}>
-        <div {...getTableProps()} className={clsx(classes.table, caveTable ? classes.caveTable : '')}>
+        <div {...getTableProps({style:{minWidth: totalColumnsWidth}})} className={clsx(classes.table, caveTable ? classes.caveTable : '')}>
           <div>
             {headerGroups.map((headerGroup) => (
               <div key={''} {...headerGroup.getHeaderGroupProps()}>
@@ -519,12 +521,7 @@ export default function PgTable({ columns, data, isSelectRow, caveTable=true, ..
                 </AutoSizer>
               </div>
             ) : (
-              <div className={classes.emptyPanel}>
-                <div className={classes.panelIcon}>
-                  <i className="fa fa-exclamation-circle"></i>
-                  <span className={classes.panelMessage}>{gettext('No record found')}</span>
-                </div>
-              </div>
+              <EmptyPanelMessage text={gettext('No record found')}/>
             )
           }
         </div>


^ permalink  raw  reply  [nested|flat] 4+ messages in thread

* Re: [pgAdmin][patch] Improvements in PgTable component
  2022-04-04 13:24 [pgAdmin][patch] Improvements in PgTable component Aditya Toshniwal <[email protected]>
  2022-04-04 13:37 ` Re: [pgAdmin][patch] Improvements in PgTable component Akshay Joshi <[email protected]>
  2022-04-05 06:23   ` Re: [pgAdmin][patch] Improvements in PgTable component Aditya Toshniwal <[email protected]>
@ 2022-04-05 06:52     ` Akshay Joshi <[email protected]>
  0 siblings, 0 replies; 4+ messages in thread

From: Akshay Joshi @ 2022-04-05 06:52 UTC (permalink / raw)
  To: Aditya Toshniwal <[email protected]>; +Cc: pgadmin-hackers

Thanks, the patch applied.

On Tue, Apr 5, 2022 at 11:54 AM Aditya Toshniwal <
[email protected]> wrote:

> Hi Hackers,
>
> Attached patch fixes more issues and improvements for the PgTable
> component.
> Please review.
>
> On Mon, Apr 4, 2022 at 7:08 PM Akshay Joshi <[email protected]>
> wrote:
>
>> Thanks, the patch applied.
>>
>> On Mon, Apr 4, 2022 at 6:55 PM Aditya Toshniwal <
>> [email protected]> wrote:
>>
>>> Hi Hackers,
>>>
>>> Attached patch makes some necessary cleanup/restructuring in PgTable
>>> component.
>>> Please review.
>>>
>>> --
>>> Thanks,
>>> Aditya Toshniwal
>>> pgAdmin Hacker | Software Architect | *edbpostgres.com*
>>> <http://edbpostgres.com;
>>> "Don't Complain about Heat, Plant a TREE"
>>>
>>
>>
>> --
>> *Thanks & Regards*
>> *Akshay Joshi*
>> *pgAdmin Hacker | Principal Software Architect*
>> *EDB Postgres <http://edbpostgres.com>*
>>
>> *Mobile: +91 976-788-8246*
>>
>
>
> --
> Thanks,
> Aditya Toshniwal
> pgAdmin Hacker | Software Architect | *edbpostgres.com*
> <http://edbpostgres.com;
> "Don't Complain about Heat, Plant a TREE"
>


-- 
*Thanks & Regards*
*Akshay Joshi*
*pgAdmin Hacker | Principal Software Architect*
*EDB Postgres <http://edbpostgres.com>*

*Mobile: +91 976-788-8246*


^ permalink  raw  reply  [nested|flat] 4+ messages in thread


end of thread, other threads:[~2022-04-05 06:52 UTC | newest]

Thread overview: 4+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2022-04-04 13:24 [pgAdmin][patch] Improvements in PgTable component Aditya Toshniwal <[email protected]>
2022-04-04 13:37 ` Akshay Joshi <[email protected]>
2022-04-05 06:23   ` Aditya Toshniwal <[email protected]>
2022-04-05 06:52     ` Akshay Joshi <[email protected]>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox