1- import React , { useContext } from 'react' ;
1+ import React , { useState , useContext } from 'react' ;
22import { useDrop , DropTargetMonitor } from 'react-dnd' ;
33import { ItemTypes } from '../../constants/ItemTypes' ;
44import StateContext from '../../context/context' ;
55import { Component , DragItem } from '../../interfaces/Interfaces' ;
66import { combineStyles } from '../../helperFunctions/combineStyles' ;
77import 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' ;
812
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 ;
1625} ;
1726
1827function Canvas ( ) {
28+ const [ modal , setModal ] = useState ( null ) ;
29+
1930 const [ state , dispatch ] = useContext ( StateContext ) ;
2031 // find the current component to render on the canvas
2132 const currentComponent : Component = state . components . find (
2233 ( elem : Component ) => elem . id === state . canvasFocus . componentId
2334 ) ;
2435
25- findNestedChild ( currentComponent , state . components ) ;
26-
2736 // changes focus of the canvas to a new component / child
2837 const changeFocus = ( componentId : number , childId : number | null ) => {
2938 dispatch ( { type : 'CHANGE FOCUS' , payload : { componentId, childId } } ) ;
@@ -36,6 +45,48 @@ function Canvas() {
3645 changeFocus ( state . canvasFocus . componentId , null ) ;
3746 }
3847
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+
3990 // This hook will allow the user to drag items from the left panel on to the canvas
4091 const [ { isOver } , drop ] = useDrop ( {
4192 accept : ItemTypes . INSTANCE ,
@@ -45,26 +96,41 @@ function Canvas() {
4596 return ;
4697 }
4798
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+ }
58120 }
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 ( ) ;
68134 }
69135 } ,
70136 collect : monitor => ( {
@@ -84,10 +150,12 @@ function Canvas() {
84150 // The render children function renders all direct children of a given component
85151 // Direct children are draggable/clickable
86152
153+
87154 const canvasStyle = combineStyles ( defaultCanvasStyle , currentComponent . style ) ;
88155 return (
89156 < div ref = { drop } style = { canvasStyle } onClick = { onClickHandler } >
90157 { renderChildren ( currentComponent . children ) }
158+ { modal }
91159 </ div >
92160 ) ;
93161}
0 commit comments