@@ -80,39 +80,80 @@ export default function PgTreeView({ data = [], hasCheckbox = false,
8080 const [ checkedState , setCheckedState ] = React . useState ( { } ) ;
8181 const { ref : containerRef , width, height } = useResizeObserver ( ) ;
8282
83+ // Handle checkbox toggle and collect all checked nodes
84+ // to pass complete selection state to the backup dialog
8385 const toggleCheck = ( node , isChecked ) => {
8486 const newState = { ...checkedState } ;
85- const selectedChNodes = [ ] ;
8687
87- // Update the node itself and all descendants
88+ // Update the clicked node and all its descendants with the new checked value
8889 const updateDescendants = ( n , val ) => {
8990 newState [ n . id ] = val ;
90- if ( val ) {
91- selectedChNodes . push ( n ) ;
92- }
93- n . children ?. forEach ( child => updateDescendants ( child , val ) ) ;
91+ n . children ?. forEach ( child => { updateDescendants ( child , val ) ; } ) ;
9492 } ;
9593 updateDescendants ( node , isChecked ) ;
9694
97- // Update ancestors (Indeterminate logic)
95+ // Update ancestor nodes to reflect the correct state (checked/unchecked/indeterminate)
96+ // This ensures parent nodes show proper visual feedback based on children's state
9897 let parent = node . parent ;
9998 while ( parent && parent . id !== '__root__' ) {
100- const allChecked = parent . children . every ( c => newState [ c . id ] ) ;
99+ // Check if ALL children are fully checked (state must be exactly true,
100+ // not 'indeterminate') to mark parent as fully checked
101+ const allChecked = parent . children . every ( c => newState [ c . id ] === true ) ;
102+ // Check if ALL children are unchecked (falsy value: false, undefined, or null)
101103 const noneChecked = parent . children . every ( c => ! newState [ c . id ] ) ;
102104
103105 if ( allChecked ) {
106+ // All children checked -> parent is fully checked
104107 newState [ parent . id ] = true ;
105- // logic for custom indeterminate property if needed
106108 } else if ( noneChecked ) {
109+ // No children checked -> parent is unchecked
107110 newState [ parent . id ] = false ;
108111 } else {
109- newState [ parent . id ] = 'indeterminate' ; // Store string for 3rd state
112+ // Some children checked, some not -> parent shows indeterminate state
113+ newState [ parent . id ] = 'indeterminate' ;
110114 }
111115 parent = parent . parent ;
112116 }
113117
114118 setCheckedState ( newState ) ;
115- selectionChange ?. ( selectedChNodes ) ;
119+
120+ // Collect all checked/indeterminate nodes from the entire tree
121+ // to provide complete selection state to selectionChange callback.
122+ // We use wrapper objects to avoid mutating the original node data.
123+ const allCheckedNodes = [ ] ;
124+ const collectAllCheckedNodes = ( n ) => {
125+ if ( ! n ) return ;
126+ const state = newState [ n . id ] ;
127+ if ( state === true || state === 'indeterminate' ) {
128+ // Pass wrapper object with isIndeterminate flag to differentiate
129+ // full schema selection from partial selection in backup dialog
130+ allCheckedNodes . push ( {
131+ node : n ,
132+ isIndeterminate : state === 'indeterminate'
133+ } ) ;
134+ }
135+ // Recursively check all children
136+ n . children ?. forEach ( child => { collectAllCheckedNodes ( child ) ; } ) ;
137+ } ;
138+
139+ // Navigate up to find the root level of the tree (parent of root nodes is '__root__')
140+ let rootNode = node ;
141+ while ( rootNode . parent && rootNode . parent . id !== '__root__' ) {
142+ rootNode = rootNode . parent ;
143+ }
144+
145+ // Traverse all root-level nodes to collect checked nodes from entire tree
146+ const rootParent = rootNode . parent ;
147+ if ( rootParent && rootParent . children ) {
148+ // Iterate through all sibling root nodes to collect all checked nodes
149+ rootParent . children . forEach ( root => { collectAllCheckedNodes ( root ) ; } ) ;
150+ } else {
151+ // Fallback: if we can't find siblings, just traverse from the found root
152+ collectAllCheckedNodes ( rootNode ) ;
153+ }
154+
155+ // Pass all checked nodes to callback with current selection state.
156+ selectionChange ?. ( allCheckedNodes ) ;
116157 } ;
117158
118159 return ( < Root ref = { containerRef } className = { 'PgTree-tree' } >
0 commit comments