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
- console . log ( 'components' , state . components ) ;
21
31
// find the current component to render on the canvas
22
32
const currentComponent : Component = state . components . find (
23
33
( elem : Component ) => elem . id === state . canvasFocus . componentId
24
34
) ;
25
35
26
- findNestedChild ( currentComponent , state . components ) ;
27
-
28
36
// changes focus of the canvas to a new component / child
29
37
const changeFocus = ( componentId : number , childId : number | null ) => {
30
38
dispatch ( { type : 'CHANGE FOCUS' , payload : { componentId, childId } } ) ;
@@ -37,6 +45,48 @@ function Canvas() {
37
45
changeFocus ( state . canvasFocus . componentId , null ) ;
38
46
}
39
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
+
40
90
// This hook will allow the user to drag items from the left panel on to the canvas
41
91
const [ { isOver } , drop ] = useDrop ( {
42
92
accept : ItemTypes . INSTANCE ,
@@ -46,26 +96,41 @@ function Canvas() {
46
96
return ;
47
97
}
48
98
49
- // if item dropped is going to be a new instance (i.e. it came from the left panel), then create a new child component
50
- if ( item . newInstance ) {
51
- dispatch ( {
52
- type : 'ADD CHILD' ,
53
- payload : {
54
- type : item . instanceType ,
55
- typeId : item . instanceTypeId ,
56
- childId : null
57
- }
58
- } ) ;
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
+ }
59
120
}
60
- // if item is not a new instance, change position of element dragged inside div so that the div is the new parent
61
- else {
62
- dispatch ( {
63
- type : 'CHANGE POSITION' ,
64
- payload : {
65
- currentChildId : item . childId ,
66
- newParentChildId : null
67
- }
68
- } ) ;
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 ( ) ;
69
134
}
70
135
} ,
71
136
collect : monitor => ( {
@@ -85,10 +150,12 @@ function Canvas() {
85
150
// The render children function renders all direct children of a given component
86
151
// Direct children are draggable/clickable
87
152
153
+
88
154
const canvasStyle = combineStyles ( defaultCanvasStyle , currentComponent . style ) ;
89
155
return (
90
156
< div ref = { drop } style = { canvasStyle } onClick = { onClickHandler } >
91
157
{ renderChildren ( currentComponent . children ) }
158
+ { modal }
92
159
</ div >
93
160
) ;
94
161
}
0 commit comments