@@ -9,7 +9,7 @@ import { GenericContent, User } from '@sensenet/default-content-types'
99import { Query , QueryExpression , QueryOperators } from '@sensenet/query'
1010import { ColDef } from 'ag-grid-community'
1111import { AgGridReact } from 'ag-grid-react'
12- import React , { useCallback , useEffect , useRef , useState } from 'react'
12+ import React , { useCallback , useEffect , useMemo , useRef , useState } from 'react'
1313import { GenericContentWithIsParent } from '../types'
1414
1515// Icons
@@ -204,25 +204,47 @@ const TreeNode = ({
204204 const [ childNodes , setChildNodes ] = useState < GenericContent [ ] > ( [ ] )
205205 const [ isLoaded , setIsLoaded ] = useState < boolean > ( false )
206206
207- const handleNodeClick = async ( ) => {
207+ const getChildren = useCallback ( async ( ) => {
208208 const abortController = new AbortController ( )
209209 const childrenResult = await repository . loadCollection < GenericContent > ( {
210210 path : node . Path ,
211211 requestInit : { signal : abortController . signal } ,
212212 } )
213+ return sortResults ( childrenResult . d . results )
214+ } , [ node . Path , repository ] )
213215
214- onSetCurrentNode ( node )
215- setChildNodes ( sortResults ( childrenResult . d . results ) )
216- setIsLoaded ( true )
216+ const setStates = async ( ) => {
217+ if ( ! isLoaded ) {
218+ const children = await getChildren ( )
219+ setChildNodes ( children )
220+ setIsLoaded ( true )
221+ }
222+ }
217223
224+ const setExpandedItems = useCallback ( ( ) => {
218225 setExpanded ( ( prevExpanded ) =>
219226 prevExpanded . includes ( node . Id . toString ( ) ) ? prevExpanded : [ ...prevExpanded , node . Id . toString ( ) ] ,
220227 )
228+ } , [ node . Id , setExpanded ] )
229+
230+ const onLabelClick = async ( ) => {
231+ onSetCurrentNode ( node )
232+ setStates ( )
233+ setExpandedItems ( )
234+ }
235+
236+ const onIconClick = async ( ) => {
237+ setStates ( )
238+ setExpandedItems ( )
221239 }
222240
223241 useEffect ( ( ) => {
224- if ( expanded . includes ( node . Id . toString ( ) ) && ! isLoaded ) {
225- handleNodeClick ( )
242+ if ( ! isLoaded ) {
243+ if ( currentPath === node . Path ) {
244+ onLabelClick ( )
245+ } else if ( expanded . includes ( node . Id . toString ( ) ) ) {
246+ onIconClick ( )
247+ }
226248 }
227249 // eslint-disable-next-line react-hooks/exhaustive-deps
228250 } , [ expanded ] )
@@ -233,14 +255,16 @@ const TreeNode = ({
233255 key = { node . Id }
234256 nodeId = { node . Id . toString ( ) }
235257 label = {
236- < div style = { { display : 'flex' , alignItems : 'center' , gap : 6 , cursor : 'pointer' } } onClick = { handleNodeClick } >
258+ < div style = { { display : 'flex' , alignItems : 'center' , gap : 6 , cursor : 'pointer' } } >
237259 < div className = { classes . treeIcon } > { renderIcon ( node ) } </ div >
238260 < div className = { classes . treeLabel } > { node . Name } </ div >
239261 </ div >
240262 }
263+ onIconClick = { onIconClick }
264+ onLabelClick = { onLabelClick }
241265 collapseIcon = { < MinusSquare /> }
242266 expandIcon = { < PlusSquare /> }
243- endIcon = { < PlusSquare /> } >
267+ endIcon = { isLoaded && childNodes . length === 0 ? null : < PlusSquare /> } >
244268 { childNodes . map ( ( childNode ) => (
245269 < TreeNode
246270 key = { childNode . Id }
@@ -317,49 +341,77 @@ export const PickerAdvanced: React.FC<PickerAdvancedProps> = ({
317341 const searchFieldRef = useRef < HTMLInputElement | null > ( null )
318342
319343 //Grid Columns
320- const addCol : ColDef = {
321- headerName : '' ,
322- field : '' ,
323- width : 66 ,
324- cellRenderer : ( props : { data : GenericContent } ) => {
325- if ( selectionRoots && selectionRoots . length > 0 ) {
326- const isInSelectionRoots = selectionRoots . some (
327- ( availablePath ) => props . data . Path === availablePath || props . data . Path . startsWith ( `${ availablePath } /` ) ,
328- )
329- if ( ! isInSelectionRoots ) return < > </ >
330- }
331- const isDisabled =
332- selectedItems . some ( ( item ) => item . Id === props . data . Id ) || ( ! allowMultiple && selectedItems . length > 0 )
333- if ( isDisabled ) return < > </ >
334- return (
335- < Button className = { classes . actionButton } onClick = { ( ) => handleAdd ( props . data ) } >
336- ✙
337- </ Button >
338- )
339- } ,
340- }
341- const removeCol : ColDef = {
342- headerName : '' ,
343- field : '' ,
344- width : 66 ,
345- cellRenderer : ( props : { data : GenericContent } ) => {
346- return (
347- < Button className = { classes . actionButton } onClick = { ( ) => handleRemove ( props . data ) } >
348- ✖
349- </ Button >
350- )
351- } ,
352- }
353- const iconCol : ColDef = {
354- headerName : '' ,
355- field : 'Icon' ,
356- width : 24 ,
357- minWidth : 24 ,
358- cellRenderer : ( props : { data : GenericContent } ) => renderIcon ( props . data ) ,
359- cellStyle : { padding : 0 } ,
360- }
361- const availableCols = [ iconCol , ...baseColumns , ...( canPick ? [ addCol ] : [ ] ) ]
362- const selectedCols = [ iconCol , ...baseColumns , ...( canPick ? [ removeCol ] : [ ] ) ]
344+ const availableCols = useMemo (
345+ ( ) => [
346+ {
347+ headerName : '' ,
348+ field : 'Icon' ,
349+ width : 24 ,
350+ minWidth : 24 ,
351+ cellRenderer : ( props : { data : GenericContent } ) => renderIcon ( props . data ) ,
352+ cellStyle : { padding : 0 } ,
353+ } ,
354+ ...baseColumns ,
355+ ...( canPick
356+ ? [
357+ {
358+ headerName : 'Add' ,
359+ field : '' ,
360+ width : 66 ,
361+ cellRenderer : ( props : { data : GenericContent } ) => {
362+ if ( selectionRoots && selectionRoots . length > 0 ) {
363+ const isInSelectionRoots = selectionRoots . some (
364+ ( availablePath ) =>
365+ props . data . Path === availablePath || props . data . Path . startsWith ( `${ availablePath } /` ) ,
366+ )
367+ if ( ! isInSelectionRoots ) return < > </ >
368+ }
369+ const isDisabled =
370+ selectedItems . some ( ( item ) => item . Id === props . data . Id ) ||
371+ ( ! allowMultiple && selectedItems . length > 0 )
372+ if ( isDisabled ) return < > </ >
373+ return (
374+ < Button className = { classes . actionButton } onClick = { ( ) => handleAdd ( props . data ) } >
375+ ✙
376+ </ Button >
377+ )
378+ } ,
379+ } ,
380+ ]
381+ : [ ] ) ,
382+ ] ,
383+ [ allowMultiple , canPick , classes . actionButton , renderIcon , selectedItems , selectionRoots ] ,
384+ )
385+ const selectedCols = useMemo (
386+ ( ) => [
387+ {
388+ headerName : '' ,
389+ field : 'Icon' ,
390+ width : 24 ,
391+ minWidth : 24 ,
392+ cellRenderer : ( props : { data : GenericContent } ) => renderIcon ( props . data ) ,
393+ cellStyle : { padding : 0 } ,
394+ } ,
395+ ...baseColumns ,
396+ ...( canPick
397+ ? [
398+ {
399+ headerName : 'Remove' ,
400+ field : '' ,
401+ width : 69 ,
402+ cellRenderer : ( props : { data : GenericContent } ) => {
403+ return (
404+ < Button className = { classes . actionButton } onClick = { ( ) => handleRemove ( props . data ) } >
405+ ✖
406+ </ Button >
407+ )
408+ } ,
409+ } ,
410+ ]
411+ : [ ] ) ,
412+ ] ,
413+ [ canPick , classes . actionButton , renderIcon ] ,
414+ )
363415
364416 //Button Actions
365417 const handleAdd = ( item : GenericContent ) => {
0 commit comments