Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
CollectionNodeProperties.jsx359 linesDownload Raw Back to properties
1/////////////////////////////////////////////////////////////2//3// pgAdmin 4 - PostgreSQL Tools4//5// Copyright (C) 2013 - 2024, The pgAdmin Development Team6// This software is released under the PostgreSQL Licence7//8//////////////////////////////////////////////////////////////9import React from 'react';10import getApiInstance from 'sources/api_instance';11import { makeStyles } from '@mui/styles';12import { Box } from '@mui/material';13import { generateCollectionURL } from '../../browser/static/js/node_ajax';14import gettext from 'sources/gettext';15import PgTable from 'sources/components/PgTable';16import Theme from 'sources/Theme';17import PropTypes from 'prop-types';18import { PgButtonGroup, PgIconButton } from '../../static/js/components/Buttons';19import DeleteIcon from '@mui/icons-material/Delete';20import DeleteSweepIcon from '@mui/icons-material/DeleteSweep';21import DeleteForeverIcon from '@mui/icons-material/DeleteForever';22import EmptyPanelMessage from '../../static/js/components/EmptyPanelMessage';23import Loader from 'sources/components/Loader';24import { evalFunc } from '../../static/js/utils';25import { usePgAdmin } from '../../static/js/BrowserComponent';26import { getSwitchCell } from '../../static/js/components/PgTable';27 28const useStyles = makeStyles((theme) => ({29  emptyPanel: {30    minHeight: '100%',31    minWidth: '100%',32    background: theme.otherVars.emptySpaceBg,33    overflow: 'auto',34    padding: '8px',35    display: 'flex',36  },37  panelIcon: {38    width: '80%',39    margin: '0 auto',40    marginTop: '25px !important',41    position: 'relative',42    textAlign: 'center',43  },44  panelMessage: {45    marginLeft: '0.5rem',46    fontSize: '0.875rem',47  },48  searchPadding: {49    flex: 2.550  },51  searchInput: {52    flex: 1,53    margin: '4 0 4 0',54    borderLeft: 'none',55    paddingLeft: 556  },57  propertiesPanel: {58    height: '100%'59  },60  autoResizer: {61    height: '100% !important',62    width: '100% !important',63    background: theme.palette.grey[400],64    padding: '8px',65    overflow: 'hidden !important',66    overflowX: 'auto !important'67  },68}));69 70export default function CollectionNodeProperties({71  node,72  treeNodeInfo,73  nodeData,74  nodeItem,75  isActive,76  isStale,77  setIsStale78}) {79  const classes = useStyles();80  const pgAdmin = usePgAdmin();81 82  const [data, setData] = React.useState([]);83  const [infoMsg, setInfoMsg] = React.useState('Please select an object in the tree view.');84  const [selectedObject, setSelectedObject] = React.useState([]);85  const [loaderText, setLoaderText] = React.useState('');86  const schemaRef = React.useRef();87 88  const [pgTableColumns, setPgTableColumns] = React.useState([89    {90      Header: 'properties',91      accessor: 'Properties',92      sortable: true,93      resizable: true,94      disableGlobalFilter: false,95    },96    {97      Header: 'value',98      accessor: 'value',99      sortable: true,100      resizable: true,101      disableGlobalFilter: false,102    },103  ]);104 105  const getTableSelectedRows = (selRows) => {106    setSelectedObject(selRows);107  };108 109  const onDrop = (type) => {110    let selRowModels = selectedObject,111      selRows = [],112      selItem = pgAdmin.Browser.tree.selected(),113      selectedItemData = selItem ? pgAdmin.Browser.tree.itemData(selItem) : null,114      selNode = selectedItemData && pgAdmin.Browser.Nodes[selectedItemData._type],115      url, msg, title;116 117    if (selNode?.type == 'coll-constraints') {118      // In order to identify the constraint type, the type should be passed to the server119      selRows = selRowModels.map((row) => ({120        id: row.original.oid,121        _type: row.original._type,122      }));123    } else {124      selRows = selRowModels.map((row) => row.original[schemaRef.current.idAttribute]);125    }126 127    if (selRows.length === 0) {128      pgAdmin.Browser.notifier.alert(129        gettext('Delete Multiple'),130        gettext('Please select at least one object to delete.')131      );132      return;133    }134 135    if (!selNode) return;136 137    if (type === 'dropCascade') {138      url = selNode.generate_url(selItem, 'delete');139      msg = gettext(140        'Are you sure you want to delete all the selected objects and all the objects that depend on them?'141      );142      title = gettext('Delete CASCADE multiple objects?');143    } else if (type === 'dropForce') {144      url = selNode.generate_url(selItem, 'delete');145      msg = gettext(146        'Delete databases with the force option will attempt to terminate all the existing connections to the selected databases. Are you sure you want to proceed?'147      );148      title = gettext('Delete FORCE multiple objects?');149    } else {150      url = selNode.generate_url(selItem, 'drop');151      msg = gettext('Are you sure you want to delete all the selected objects?');152      title = gettext('Delete multiple objects?');153    }154 155    const api = getApiInstance();156    let dropNodeProperties = function () {157      setLoaderText(gettext('Deleting Objects...'));158      api159        .delete(url, {160          data: JSON.stringify({ ids: selRows }),161          contentType: 'application/json; charset=utf-8',162        })163        .then(function (res) {164          if (res.success == 0) {165            pgAdmin.Browser.notifier.alert(res.errormsg, res.info);166          }167          pgAdmin.Browser.tree.refresh(selItem);168          setIsStale(true);169        })170        .catch(function (error) {171          pgAdmin.Browser.notifier.alert(172            gettext('Error deleting %s', selectedItemData._label.toLowerCase()),173            _.isUndefined(error.response) ? error.message : error.response.data.errormsg174          );175        })176        .then(()=>{177          setLoaderText('');178        });179    };180 181    if (confirm) {182      pgAdmin.Browser.notifier.confirm(title, msg, dropNodeProperties, null);183    } else {184      dropNodeProperties();185    }186  };187 188  React.useEffect(() => {189    if (node) {190 191      let nodeObj =192      pgAdmin.Browser.Nodes[nodeData?._type.replace('coll-', '')];193 194      let url = generateCollectionURL.call(nodeObj, nodeItem, 'properties');195 196      const api = getApiInstance();197 198      let tableColumns = [];199      let column = {};200      if(!isStale || !isActive) {201        return;202      }203 204      setLoaderText(gettext('Loading...'));205 206      if (!_.isUndefined(nodeObj.getSchema)) {207        schemaRef.current = nodeObj.getSchema?.(treeNodeInfo, nodeData);208        schemaRef.current?.fields.forEach((field) => {209          if (node.columns.indexOf(field.id) > -1) {210            if (field.label.indexOf('?') > -1) {211              column = {212                Header: field.label,213                accessor: field.id,214                sortable: true,215                resizable: true,216                disableGlobalFilter: false,217                minWidth: 0,218                Cell: getSwitchCell()219              };220            } else {221              column = {222                Header: field.label,223                accessor: field.id,224                sortable: true,225                resizable: true,226                disableGlobalFilter: false,227                minWidth: 0,228              };229            }230            tableColumns.push(column);231          }232        });233      }else{234        node.columns.forEach((field) => {235          column = {236            Header: field,237            accessor: field,238            sortable: true,239            resizable: true,240            disableGlobalFilter: false,241            minWidth: 0,242          };243          tableColumns.push(column);244        });245      }246 247 248      api({249        url: url,250        type: 'GET',251      })252        .then((res) => {253          res.data.forEach((element) => {254            element['icon'] = '';255          });256          setPgTableColumns(tableColumns);257          setData(res.data);258          setInfoMsg('No properties are available for the selected object.');259          setLoaderText('');260        })261        .catch((err) => {262          pgAdmin.Browser.notifier.alert(263            gettext('Failed to retrieve data from the server.'),264            gettext(err.message)265          );266        });267      setIsStale(false);268    }269  }, [nodeData, node, nodeItem, isStale, isActive]);270 271  const CustomHeader = () => {272    const canDrop = evalFunc(node, node.canDrop, nodeData, nodeItem, treeNodeInfo);273    const canDropCascade = evalFunc(node, node.canDropCascade, nodeData, nodeItem, treeNodeInfo);274    const canDropForce = evalFunc(node, node.canDropForce, nodeData, nodeItem, treeNodeInfo);275    return (276      <Box >277        <PgButtonGroup size="small">278          <PgIconButton279            icon={<DeleteIcon style={{height: '1.35rem'}}/>}280            aria-label="Delete"281            title={gettext('Delete')}282            onClick={() => {283              onDrop('drop');284            }}285            disabled={286              (selectedObject.length > 0)287                ? !canDrop288                : true289            }290          ></PgIconButton>291          {node.type !== 'coll-database' ? <PgIconButton292            icon={<DeleteSweepIcon style={{height: '1.5rem'}} />}293            aria-label="Delete Cascade"294            title={gettext('Delete (Cascade)')}295            onClick={() => {296              onDrop('dropCascade');297            }}298            disabled={299              (selectedObject.length > 0)300                ? !canDropCascade301                : true302            }303          ></PgIconButton> :304            <PgIconButton305              icon={<DeleteForeverIcon style={{height: '1.4rem'}} />}306              aria-label="Delete Force"307              title={gettext('Delete (Force)')}308              onClick={() => {309                onDrop('dropForce');310              }}311              disabled={312                (selectedObject.length > 0)313                  ? !canDropForce314                  : true315              }316            ></PgIconButton>}317        </PgButtonGroup>318      </Box>);319  };320 321  return (322    <Theme className='obj_properties'>323      <Loader message={loaderText}/>324      <Box className={classes.propertiesPanel}>325        {data.length > 0 ?326          (327            <PgTable328              isSelectRow={!('catalog' in treeNodeInfo) && (nodeData.label !== 'Catalogs') && _.isUndefined(node?.canSelect)}329              CustomHeader={CustomHeader}330              className={classes.autoResizer}331              columns={pgTableColumns}332              data={data}333              type={'panel'}334              isSearch={false}335              getSelectedRows={getTableSelectedRows}336            />337          )338          :339          (340            <div className={classes.emptyPanel}>341              <EmptyPanelMessage text={gettext(infoMsg)}/>342            </div>343          )344        }345      </Box>346    </Theme>347  );348}349 350CollectionNodeProperties.propTypes = {351  node: PropTypes.func,352  nodeData: PropTypes.object,353  treeNodeInfo: PropTypes.object,354  nodeItem: PropTypes.object,355  isActive: PropTypes.bool,356  isStale: PropTypes.bool,357  setIsStale: PropTypes.func,358};359 
codekingpro/portable-devtools · Team Ai