diff --git a/web/pgadmin/static/js/PgTreeView/index.jsx b/web/pgadmin/static/js/PgTreeView/index.jsx index 9b5d1ca86..c79ddad59 100644 --- a/web/pgadmin/static/js/PgTreeView/index.jsx +++ b/web/pgadmin/static/js/PgTreeView/index.jsx @@ -13,7 +13,7 @@ import CheckBoxIcon from '@mui/icons-material/CheckBox'; -const Root = styled('div')(({theme}) => ({ +const Root = styled('div')(({ theme }) => ({ height: '100%', '& .PgTree-tree': { background: theme.palette.background.default, @@ -38,9 +38,11 @@ const Root = styled('div')(({theme}) => ({ export const PgTreeSelectionContext = React.createContext(); -export default function PgTreeView({ data = [], hasCheckbox = false, selectionChange = null}) { +export default function PgTreeView({ data = [], hasCheckbox = false, + selectionChange = null, NodeComponent = null, ...props }) { let treeData = data; + const Node = NodeComponent ?? DefaultNode; const treeObj = useRef(); const treeContainerRef = useRef(); const [selectedCheckBoxNodes, setSelectedCheckBoxNodes] = React.useState([]); @@ -51,9 +53,9 @@ export default function PgTreeView({ data = [], hasCheckbox = false, selectionCh let selectedChildNodes = []; treeObj.current.selectedNodes.forEach((node) => { - if(node.isInternal && !node.isOpen) { - node.children.forEach((ch)=>{ - if(ch.data.isSelected && ch.isLeaf && !selectedChildNodes.includes(ch.id)) { + if (node.isInternal && !node.isOpen) { + node.children.forEach((ch) => { + if (ch.data.isSelected && ch.isLeaf && !selectedChildNodes.includes(ch.id)) { selectedChildNodes.push(ch.id); selectedChNodes.push(ch); } @@ -68,7 +70,7 @@ export default function PgTreeView({ data = [], hasCheckbox = false, selectionCh }; return ( - { treeData.length > 0 ? + {treeData.length > 0 ?
treeContainerRef.current = containerRef} className={'PgTree-tree'}> @@ -83,9 +85,10 @@ export default function PgTreeView({ data = [], hasCheckbox = false, selectionCh disableDrag={true} disableDrop={true} dndRootElement={treeContainerRef.current} + {...props} > { - (props) => + (props) => } )} @@ -93,7 +96,7 @@ export default function PgTreeView({ data = [], hasCheckbox = false, selectionCh
: - + }
); @@ -103,22 +106,23 @@ PgTreeView.propTypes = { data: PropTypes.array, selectionChange: PropTypes.func, hasCheckbox: PropTypes.bool, + NodeComponent: PropTypes.func }; -function Node({ node, style, tree, hasCheckbox, onNodeSelectionChange}) { +function DefaultNode({ node, style, tree, hasCheckbox, onNodeSelectionChange }) { const pgTreeSelCtx = React.useContext(PgTreeSelectionContext); const [isSelected, setIsSelected] = React.useState(pgTreeSelCtx.includes(node.id) || node.data?.isSelected); - const [isIndeterminate, setIsIndeterminate] = React.useState(node?.parent.level==0); + const [isIndeterminate, setIsIndeterminate] = React.useState(node?.parent.level == 0); - useEffect(()=>{ + useEffect(() => { setIsIndeterminate(node.data.isIndeterminate); }, [node?.data?.isIndeterminate]); - useEffect(()=>{ - if(isSelected){ - if(!pgTreeSelCtx.includes(node.id)){ + useEffect(() => { + if (isSelected) { + if (!pgTreeSelCtx.includes(node.id)) { tree.selectMulti(node.id); onNodeSelectionChange(); } @@ -139,7 +143,7 @@ function Node({ node, style, tree, hasCheckbox, onNodeSelectionChange}) { checkAndSelectParent(node); } - if(node?.level == 0) { + if (node?.level == 0) { node.data.isIndeterminate = false; } node.focus(); @@ -149,7 +153,7 @@ function Node({ node, style, tree, hasCheckbox, onNodeSelectionChange}) { deselectAllChild(node); } - if(node?.parent){ + if (node?.parent) { node.parent.data.isIndeterminate = false; delectPrentNode(node.parent); } @@ -165,7 +169,7 @@ function Node({ node, style, tree, hasCheckbox, onNodeSelectionChange}) { }; const onKeyDown = (e) => { - if(e.code == 'Enter') { + if (e.code == 'Enter') { onSelect(e); } }; @@ -174,10 +178,10 @@ function Node({ node, style, tree, hasCheckbox, onNodeSelectionChange}) {
{ - hasCheckbox ? : } - onChange={onCheckboxSelection}/> : + checkedIcon={isIndeterminate ? : } + onChange={onCheckboxSelection} /> : }
{node.data.name}
@@ -185,7 +189,7 @@ function Node({ node, style, tree, hasCheckbox, onNodeSelectionChange}) { ); } -Node.propTypes = { +DefaultNode.propTypes = { node: PropTypes.object, style: PropTypes.any, tree: PropTypes.object, @@ -202,7 +206,7 @@ function CollectionArrow({ node, tree, selectedNodeIds }) { } }; return ( - {/* handled by parent */}}> + {/* handled by parent */ }}> {node.isInternal && node?.children.length > 0 ? : null} ); @@ -215,7 +219,7 @@ CollectionArrow.propTypes = { }; -function ToggleArrowIcon({node}){ +function ToggleArrowIcon({ node }) { return (<>{node.isOpen ? : }); } @@ -223,7 +227,7 @@ ToggleArrowIcon.propTypes = { node: PropTypes.object, }; -function checkAndSelectParent(chNode){ +function checkAndSelectParent(chNode) { let isAllChildSelected = true; chNode?.parent?.children?.forEach((child) => { if (!child.isSelected) { @@ -251,15 +255,15 @@ checkAndSelectParent.propTypes = { chNode: PropTypes.object }; -function delectPrentNode(chNode){ +function delectPrentNode(chNode) { if (chNode) { let isAnyChildSelected = false; - chNode.children.forEach((childNode)=>{ - if(childNode.isSelected && !isAnyChildSelected){ + chNode.children.forEach((childNode) => { + if (childNode.isSelected && !isAnyChildSelected) { isAnyChildSelected = true; } }); - if(isAnyChildSelected){ + if (isAnyChildSelected) { chNode.data.isSelected = true; chNode.data.isIndeterminate = true; } else { @@ -273,14 +277,14 @@ function delectPrentNode(chNode){ } } -function selectAllChild(chNode, tree, source, selectedNodeIds){ +function selectAllChild(chNode, tree, source, selectedNodeIds) { let selectedChild = 0; chNode?.children?.forEach(child => { - if(!child.isLeaf) { + if (!child.isLeaf) { child.data.isIndeterminate = false; } - if((source == 'expand' && selectedNodeIds.includes(child.id)) || source == 'checkbox') { + if ((source == 'expand' && selectedNodeIds.includes(child.id)) || source == 'checkbox') { child.data.isSelected = true; selectedChild += 1; } @@ -291,7 +295,7 @@ function selectAllChild(chNode, tree, source, selectedNodeIds){ } }); - if(selectedChild < chNode?.children.length ){ + if (selectedChild < chNode?.children.length) { chNode.data.isIndeterminate = true; } else { chNode.data.isIndeterminate = false; @@ -302,7 +306,7 @@ function selectAllChild(chNode, tree, source, selectedNodeIds){ } } -function deselectAllChild(chNode){ +function deselectAllChild(chNode) { chNode?.children.forEach(child => { child.deselect(child); child.data.isSelected = false;