1
- import React , { useContext } from 'react' ;
1
+ import React , { useState , useContext } from 'react' ;
2
2
import { useDrop , DropTargetMonitor } from 'react-dnd' ;
3
3
import { ItemTypes } from '../../constants/ItemTypes' ;
4
4
import StateContext from '../../context/context' ;
5
5
import { Component , DragItem } from '../../interfaces/Interfaces' ;
6
6
import { combineStyles } from '../../helperFunctions/combineStyles' ;
7
7
import renderChildren from '../../helperFunctions/renderChildren' ;
8
+ import List from '@material-ui/core/List' ;
9
+ import ListItem from '@material-ui/core/ListItem' ;
10
+ import ListItemText from '@material-ui/core/ListItemText' ;
11
+ import createModal from '../right/createModal' ;
8
12
9
- const findNestedChild = ( curr , components ) => {
10
- components . forEach ( ( comp , i ) => {
11
- comp . children . forEach ( child => {
12
- if ( child . name === curr . name ) console . log ( 'childname' , child . name ) ;
13
- } ) ;
14
- if ( comp . children . length !== 0 ) findNestedChild ( curr , comp . children ) ;
15
- } ) ;
13
+ const checkChildren = ( child , currentComponent ) => {
14
+ for ( let i = 0 ; i < child . length ; i += 1 ) {
15
+ if ( child [ i ] . children . length ) {
16
+ for ( let j = 0 ; j < child [ i ] . children . length ; j += 1 ) {
17
+ if ( child [ i ] . children [ j ] . name === currentComponent . name ) {
18
+ return true ;
19
+ }
20
+ }
21
+ return checkChildren ( child [ i ] . children , currentComponent ) ;
22
+ }
23
+ }
24
+ return false ;
16
25
} ;
17
26
18
27
function Canvas ( ) {
28
+ const [ modal , setModal ] = useState ( null ) ;
29
+
19
30
const [ state , dispatch ] = useContext ( StateContext ) ;
20
31
// find the current component to render on the canvas
21
32
const currentComponent : Component = state . components . find (
22
33
( elem : Component ) => elem . id === state . canvasFocus . componentId
23
34
) ;
24
35
25
- findNestedChild ( currentComponent , state . components ) ;
26
-
27
36
// changes focus of the canvas to a new component / child
28
37
const changeFocus = ( componentId : number , childId : number | null ) => {
29
38
dispatch ( { type : 'CHANGE FOCUS' , payload : { componentId, childId } } ) ;
@@ -36,6 +45,48 @@ function Canvas() {
36
45
changeFocus ( state . canvasFocus . componentId , null ) ;
37
46
}
38
47
48
+ const closeModal = ( ) => setModal ( null ) ;
49
+
50
+ // creates modal that asks if user wants to clear workspace
51
+ // if user clears their workspace, then their components are removed from state and the modal is closed
52
+ const triedToNestIncorrectly = ( ) => {
53
+ // set modal options
54
+ const children = (
55
+ < List className = "export-preference" >
56
+ < ListItem
57
+ key = { `gotIt${ state . canvasFocus . componentId } ` }
58
+ button
59
+ onClick = { closeModal }
60
+ style = { {
61
+ border : '1px solid #3f51b5' ,
62
+ marginBottom : '2%' ,
63
+ marginTop : '5%'
64
+ } }
65
+ >
66
+ < ListItemText
67
+ primary = { 'Got it' }
68
+ style = { { textAlign : 'center' } }
69
+ onClick = { closeModal }
70
+ />
71
+ </ ListItem >
72
+ </ List >
73
+ ) ;
74
+
75
+ // create modal
76
+ setModal (
77
+ createModal ( {
78
+ closeModal,
79
+ children,
80
+ message : 'Unable to nest component in another component that contains that component.' ,
81
+ primBtnLabel : null ,
82
+ primBtnAction : null ,
83
+ secBtnAction : null ,
84
+ secBtnLabel : null ,
85
+ open : true
86
+ } )
87
+ ) ;
88
+ } ;
89
+
39
90
// This hook will allow the user to drag items from the left panel on to the canvas
40
91
const [ { isOver } , drop ] = useDrop ( {
41
92
accept : ItemTypes . INSTANCE ,
@@ -45,26 +96,41 @@ function Canvas() {
45
96
return ;
46
97
}
47
98
48
- // if item dropped is going to be a new instance (i.e. it came from the left panel), then create a new child component
49
- if ( item . newInstance ) {
50
- dispatch ( {
51
- type : 'ADD CHILD' ,
52
- payload : {
53
- type : item . instanceType ,
54
- typeId : item . instanceTypeId ,
55
- childId : null
56
- }
57
- } ) ;
99
+ const runReducers = ( ) => {
100
+ if ( item . newInstance ) {
101
+ dispatch ( {
102
+ type : 'ADD CHILD' ,
103
+ payload : {
104
+ type : item . instanceType ,
105
+ typeId : item . instanceTypeId ,
106
+ childId : null
107
+ }
108
+ } ) ;
109
+ }
110
+ // if item is not a new instance, change position of element dragged inside div so that the div is the new parent
111
+ else {
112
+ dispatch ( {
113
+ type : 'CHANGE POSITION' ,
114
+ payload : {
115
+ currentChildId : item . childId ,
116
+ newParentChildId : null
117
+ }
118
+ } ) ;
119
+ }
58
120
}
59
- // if item is not a new instance, change position of element dragged inside div so that the div is the new parent
60
- else {
61
- dispatch ( {
62
- type : 'CHANGE POSITION' ,
63
- payload : {
64
- currentChildId : item . childId ,
65
- newParentChildId : null
66
- }
67
- } ) ;
121
+
122
+ const addingComponent = state . components . find ( elem => elem . id === item . instanceTypeId ) ;
123
+
124
+ if ( item . instanceType === "HTML Element" ) {
125
+ return runReducers ( ) ;
126
+ } else if ( item . instanceType === 'Route Link' ) {
127
+ return runReducers ( ) ;
128
+ } else if ( checkChildren ( [ addingComponent ] , currentComponent ) ) {
129
+ triedToNestIncorrectly ( ) ;
130
+ return ;
131
+ } else {
132
+ // if item dropped is going to be a new instance (i.e. it came from the left panel), then create a new child component
133
+ return runReducers ( ) ;
68
134
}
69
135
} ,
70
136
collect : monitor => ( {
@@ -84,10 +150,12 @@ function Canvas() {
84
150
// The render children function renders all direct children of a given component
85
151
// Direct children are draggable/clickable
86
152
153
+
87
154
const canvasStyle = combineStyles ( defaultCanvasStyle , currentComponent . style ) ;
88
155
return (
89
156
< div ref = { drop } style = { canvasStyle } onClick = { onClickHandler } >
90
157
{ renderChildren ( currentComponent . children ) }
158
+ { modal }
91
159
</ div >
92
160
) ;
93
161
}
0 commit comments