@@ -15,7 +15,7 @@ import {
15
15
UnfoldIcon ,
16
16
UnShow ,
17
17
} from "lowcoder-design" ;
18
- import React , { ReactNode , useCallback , useContext , useMemo , useState } from "react" ;
18
+ import React , { ReactNode , useCallback , useContext , useMemo , useState , useEffect } from "react" ;
19
19
import { hookCompCategory } from "comps/hooks/hookCompTypes" ;
20
20
import _ from "lodash" ;
21
21
import styled from "styled-components" ;
@@ -32,6 +32,7 @@ import { UICompType } from "comps/uiCompRegistry";
32
32
import { CollapseWrapper , DirectoryTreeStyle , Node } from "./styledComponents" ;
33
33
import { DataNode , EventDataNode } from "antd/lib/tree" ;
34
34
import { isAggregationApp } from "util/appUtils" ;
35
+ import cloneDeep from 'lodash/cloneDeep' ;
35
36
36
37
const CollapseTitleWrapper = styled . div `
37
38
display: flex;
@@ -408,17 +409,94 @@ export const LeftContent = (props: LeftContentProps) => {
408
409
) ;
409
410
} ;
410
411
411
- const getTreeUI = ( type : TreeUIKey ) => {
412
- const uiCompInfos = _ . sortBy ( editorState . uiCompInfoList ( ) , [ ( x ) => x . name ] ) ;
412
+ const [ componentTreeData , setComponentTreeData ] = useState < NodeItem [ ] > ( [ ] ) ;
413
+ const [ modalsTreeData , setModalsTreeData ] = useState < NodeItem [ ] > ( [ ] ) ;
414
+
415
+ useEffect ( ( ) => {
416
+ const compData = getTreeUIData ( TreeUIKey . Components ) ;
417
+ setComponentTreeData ( compData ) ;
418
+ } , [ editorState ] ) ;
419
+
420
+ useEffect ( ( ) => {
421
+ const modalsData = getTreeUIData ( TreeUIKey . Modals ) ;
422
+ setModalsTreeData ( modalsData ) ;
423
+ } , [ editorState ] ) ;
424
+
425
+ const getTreeUIData = ( type : TreeUIKey ) => {
413
426
const tree =
414
427
type === TreeUIKey . Components
415
428
? editorState . getUIComp ( ) . getTree ( )
416
429
: editorState . getHooksComp ( ) . getUITree ( ) ;
417
430
const explorerData : NodeItem [ ] = getTree ( tree , [ ] ) ;
431
+ return explorerData ;
432
+ }
433
+
434
+ interface DropInfo {
435
+ node : { key : string ; pos : string } ;
436
+ dragNode : { key : string ; pos : string } ;
437
+ }
438
+
439
+ const handleDragEnter = ( info : { node ?: any ; expandedKeys ?: any ; } ) => {
440
+ // Assuming 'info' has a property 'expandedKeys' which is an array of keys
441
+ const { expandedKeys } = info ;
442
+ if ( ! expandedKeys . includes ( info . node . key ) ) {
443
+ setExpandedKeys ( expandedKeys ) ;
444
+ }
445
+ } ;
446
+
447
+ const handleDrop = ( info : { node : { key : any ; pos : string ; } ; dragNode : { key : any ; pos : string ; } ; } , type : TreeUIKey ) => {
448
+ const dropPos = info . node . pos . split ( '-' ) ;
449
+ const dragPos = info . dragNode . pos . split ( '-' ) ;
450
+
451
+ if ( dropPos . length === dragPos . length ) {
452
+ setComponentTreeData ( prevData => {
453
+ let newTreeData = cloneDeep ( prevData ) ;
454
+ const dropIndex = Number ( dropPos [ dropPos . length - 1 ] ) ;
455
+ const dragIndex = Number ( dragPos [ dragPos . length - 1 ] ) ;
456
+ const parentNodePos = dropPos . slice ( 0 , - 1 ) . join ( '-' ) ;
457
+
458
+ // TODO: handle drag and drop for childen of root (container components for example)
459
+ // findNodeByPos does not work yet
460
+ const parentNode = parentNodePos === "0" ? { children : newTreeData } : findNodeByPos ( newTreeData , parentNodePos ) ;
461
+
462
+ console . log ( 'parentNode' , parentNode ) ;
463
+
464
+ if ( parentNode && parentNode . children ) {
465
+ const draggedNodeIndex = parentNode . children . findIndex ( node => node . key === info . dragNode . key ) ;
466
+ if ( draggedNodeIndex !== - 1 ) {
467
+ const [ draggedNode ] = parentNode . children . splice ( draggedNodeIndex , 1 ) ;
468
+ parentNode . children . splice ( dropIndex > dragIndex ? dropIndex - 1 : dropIndex , 0 , draggedNode ) ;
469
+ }
470
+ }
471
+
472
+ return newTreeData ;
473
+ } ) ;
474
+ }
475
+ } ;
476
+
477
+ const findNodeByPos = ( nodes : NodeItem [ ] , pos : string ) : { children : NodeItem [ ] } => {
478
+ const posArr = pos . split ( '-' ) . map ( p => Number ( p ) ) ;
479
+ let currentNode = { children : nodes } ;
480
+ for ( let i = 0 ; i < posArr . length ; i ++ ) {
481
+ currentNode = currentNode . children [ posArr [ i ] ] ;
482
+ }
483
+ return currentNode ;
484
+ } ;
485
+
486
+ const getTreeUI = ( type : TreeUIKey ) => {
487
+ // here the components get sorted by name
488
+ // TODO: sort by category
489
+ // TODO: sort by Types etc.
490
+ const uiCompInfos = _ . sortBy ( editorState . uiCompInfoList ( ) , [ ( x ) => x . name ] ) ;
491
+ /* const tree =
492
+ type === TreeUIKey.Components
493
+ ? editorState.getUIComp().getTree()
494
+ : editorState.getHooksComp().getUITree();
495
+ const explorerData: NodeItem[] = getTree(tree, []); */
418
496
let selectedKeys = [ ] ;
419
497
if ( editorState . selectedCompNames . size === 1 ) {
420
498
const key = Object . keys ( editorState . selectedComps ( ) ) [ 0 ] ;
421
- const parentKeys = getParentNodeKeysByKey ( explorerData , key ) ;
499
+ const parentKeys = getParentNodeKeysByKey ( type === TreeUIKey . Components ? componentTreeData : modalsTreeData , key ) ;
422
500
if ( parentKeys && parentKeys . length ) {
423
501
let needSet = false ;
424
502
parentKeys . forEach ( ( key ) => {
@@ -433,12 +511,11 @@ export const LeftContent = (props: LeftContentProps) => {
433
511
434
512
return (
435
513
< DirectoryTreeStyle
436
- treeData = { explorerData }
437
- // icon={(props: NodeItem) => props.type && (CompStateIcon[props.type] || <LeftCommon />)}
514
+ draggable = { type === TreeUIKey . Components ? true : false }
515
+ onDragEnter = { handleDragEnter }
516
+ onDrop = { ( info ) => handleDrop ( info , type ) }
517
+ treeData = { type === TreeUIKey . Components ? componentTreeData : modalsTreeData }
438
518
icon = { ( props : any ) => props . type && ( CompStateIcon [ props . type as UICompType ] || < LeftCommon /> ) }
439
- // switcherIcon={({ expanded }: { expanded: boolean }) =>
440
- // expanded ? <FoldedIcon /> : <UnfoldIcon />
441
- // }
442
519
switcherIcon = { ( props : any ) =>
443
520
props . expanded ? < FoldedIcon /> : < UnfoldIcon />
444
521
}
@@ -455,15 +532,15 @@ export const LeftContent = (props: LeftContentProps) => {
455
532
if ( isAggregationApp ( editorState . getAppType ( ) ) ) {
456
533
return ;
457
534
}
458
- return getTreeUI ( TreeUIKey . Components ) ;
459
- } , [ editorState , uiCollapseClick , expandedKeys , showData ] ) ;
460
-
535
+ return getTreeUI ( TreeUIKey . Components ) ; // Pass componentTreeData
536
+ } , [ editorState , uiCollapseClick , expandedKeys , showData , componentTreeData ] ) ;
537
+
461
538
const modalsCollapse = useMemo ( ( ) => {
462
539
if ( isAggregationApp ( editorState . getAppType ( ) ) ) {
463
540
return ;
464
541
}
465
- return getTreeUI ( TreeUIKey . Modals ) ;
466
- } , [ editorState , uiCollapseClick , expandedKeys , showData ] ) ;
542
+ return getTreeUI ( TreeUIKey . Modals ) ; // Pass modalsTreeData
543
+ } , [ editorState , uiCollapseClick , expandedKeys , showData , modalsTreeData ] ) ;
467
544
468
545
const bottomResCollapse = useMemo ( ( ) => {
469
546
return editorState
@@ -549,4 +626,4 @@ export const LeftContent = (props: LeftContentProps) => {
549
626
</ LeftContentTabs >
550
627
</ LeftContentWrapper >
551
628
) ;
552
- } ;
629
+ } ;
0 commit comments