Skip to content

Commit ad2ebb1

Browse files
committed
Merge branch 'main' of https://github.com/oslabs-beta/ReacType into treetesting
2 parents 817d94a + c06eaaf commit ad2ebb1

File tree

12 files changed

+370
-151
lines changed

12 files changed

+370
-151
lines changed

app/electron/main.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,9 @@ app.on('web-contents-created', (event, contents) => {
229229
'https://github.com',
230230
'https://nextjs.org',
231231
'https://www.facebook.com',
232-
'https://developer.mozilla.org'
232+
'https://developer.mozilla.org',
233+
'https://www.smashingmagazine.com',
234+
'https://www.html5rocks.com'
233235
];
234236
// Log and prevent the app from navigating to a new page if that page's origin is not whitelisted
235237
if (!validOrigins.includes(parsedUrl.origin)) {
@@ -251,7 +253,9 @@ app.on('web-contents-created', (event, contents) => {
251253
'https://github.com',
252254
'https://nextjs.org',
253255
'https://developer.mozilla.org',
254-
'https://www.facebook.com'
256+
'https://www.facebook.com',
257+
'https://www.smashingmagazine.com',
258+
'https://www.html5rocks.com'
255259
];
256260

257261
// Log and prevent the app from redirecting to a new page
@@ -292,7 +296,9 @@ app.on('web-contents-created', (event, contents) => {
292296
'https://nextjs.org',
293297
'https://developer.mozilla.org',
294298
'https://github.com',
295-
'https://www.facebook.com'
299+
'https://www.facebook.com',
300+
'https://www.smashingmagazine.com',
301+
'https://www.html5rocks.com'
296302
];
297303
// Log and prevent the app from navigating to a new page if that page's origin is not whitelisted
298304
if (!validOrigins.includes(parsedUrl.origin)) {

app/electron/menu.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const fs = require('fs');
44
const path = require('path');
55
const isMac = process.platform === 'darwin';
66
const port = 5000;
7+
const Protocol = require('./protocol');
78
const tutorialRoute = `http://localhost:${port}/tutorial`;
89

910
// Create a template for a menu and create menu using that template
@@ -30,7 +31,12 @@ var MenuBuilder = function(mainWindow, appName) {
3031
devTools: false
3132
}
3233
});
33-
tutorial.loadURL(`http://localhost:8080/#/tutorial`);
34+
console.log(process.env.NODE_ENV);
35+
if (process.env.NODE_ENV === 'development') {
36+
tutorial.loadURL(`http://localhost:8080/#/tutorial`);}
37+
else {
38+
tutorial.loadURL(`${Protocol.scheme}://rse/index-prod.html#/tutorial`);
39+
}
3440
tutorial.show();
3541
};
3642

app/src/components/left/HTMLItem.tsx

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
import React from 'react';
1+
import React, { useState } from 'react';
22
import { useDrag } from 'react-dnd';
33
import { ItemTypes } from '../../constants/ItemTypes';
44
import Grid from '@material-ui/core/Grid';
55
import { makeStyles } from '@material-ui/core/styles';
6+
import List from '@material-ui/core/List';
7+
import ListItem from '@material-ui/core/ListItem';
8+
import ListItemText from '@material-ui/core/ListItemText';
9+
import createModal from '../right/createModal';
610

711
const buttonClasses =
812
'MuiButtonBase-root MuiButton-root MuiButton-text makeStyles-button-12 MuiButton-textPrimary';
@@ -34,7 +38,7 @@ const HTMLItem: React.FC<{
3438
handleDelete: (id: number) => void;
3539
}> = ({ name, id, Icon, handleDelete }) => {
3640
const classes = useStyles();
37-
41+
const [modal, setModal] = useState(null);
3842
const [{ isDragging }, drag] = useDrag({
3943
item: {
4044
type: ItemTypes.INSTANCE,
@@ -48,8 +52,66 @@ const HTMLItem: React.FC<{
4852
})
4953
});
5054

55+
const closeModal = () => setModal(null);
56+
57+
// creates modal that asks if user wants to clear workspace
58+
// if user clears their workspace, then their components are removed from state and the modal is closed
59+
const deleteAllInstances = (deleteID: number) => {
60+
// set modal options
61+
const children = (
62+
<List className="export-preference">
63+
<ListItem
64+
key={`clear${deleteID}`}
65+
button
66+
onClick={() => handleDelete(deleteID)}
67+
style={{
68+
border: '1px solid #3f51b5',
69+
marginBottom: '2%',
70+
marginTop: '5%'
71+
}}
72+
>
73+
<ListItemText
74+
primary={'Yes, delete all instances'}
75+
style={{ textAlign: 'center' }}
76+
onClick={closeModal}
77+
/>
78+
</ListItem>
79+
<ListItem
80+
key={`close${deleteID}`}
81+
button
82+
onClick={closeModal}
83+
style={{
84+
border: '1px solid #3f51b5',
85+
marginBottom: '2%',
86+
marginTop: '5%'
87+
}}
88+
>
89+
<ListItemText
90+
primary={'No, do not delete element'}
91+
style={{ textAlign: 'center' }}
92+
onClick={closeModal}
93+
/>
94+
</ListItem>
95+
</List>
96+
);
97+
98+
// create modal
99+
setModal(
100+
createModal({
101+
closeModal,
102+
children,
103+
message: 'Deleting this element will delete all instances of this element within the application.\nDo you still wish to proceed?',
104+
primBtnLabel: null,
105+
primBtnAction: null,
106+
secBtnAction: null,
107+
secBtnLabel: null,
108+
open: true
109+
})
110+
);
111+
};
112+
51113
return (
52-
<Grid item xs={5} key={`html-${name}`}>
114+
<Grid item xs={5} key={`html-g${name}`}>
53115
<div ref={drag} className={classes.HTMLPanelItem}>
54116
<h3>{name}</h3>
55117
<span
@@ -62,8 +124,9 @@ const HTMLItem: React.FC<{
62124
{Icon && <Icon />}
63125
</span>
64126
{id > 11 &&
65-
<button className={buttonClasses} onClick={() => { handleDelete(id) }} > X </button> }
127+
<button className={buttonClasses} onClick={() => deleteAllInstances(id)} > X </button> }
66128
</div>
129+
{modal}
67130
</Grid>
68131
);
69132
}

app/src/components/main/Canvas.tsx

Lines changed: 97 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,38 @@
1-
import React, { useContext } from 'react';
1+
import React, { useState, useContext } from 'react';
22
import { useDrop, DropTargetMonitor } from 'react-dnd';
33
import { ItemTypes } from '../../constants/ItemTypes';
44
import StateContext from '../../context/context';
55
import { Component, DragItem } from '../../interfaces/Interfaces';
66
import { combineStyles } from '../../helperFunctions/combineStyles';
77
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';
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

1827
function Canvas() {
28+
const [modal, setModal] = useState(null);
29+
1930
const [state, dispatch] = useContext(StateContext);
20-
console.log('components', state.components);
2131
// find the current component to render on the canvas
2232
const currentComponent: Component = state.components.find(
2333
(elem: Component) => elem.id === state.canvasFocus.componentId
2434
);
2535

26-
findNestedChild(currentComponent, state.components);
27-
2836
// changes focus of the canvas to a new component / child
2937
const changeFocus = (componentId: number, childId: number | null) => {
3038
dispatch({ type: 'CHANGE FOCUS', payload: { componentId, childId } });
@@ -37,6 +45,48 @@ function Canvas() {
3745
changeFocus(state.canvasFocus.componentId, null);
3846
}
3947

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+
4090
// This hook will allow the user to drag items from the left panel on to the canvas
4191
const [{ isOver }, drop] = useDrop({
4292
accept: ItemTypes.INSTANCE,
@@ -46,26 +96,41 @@ function Canvas() {
4696
return;
4797
}
4898

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+
}
59120
}
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();
69134
}
70135
},
71136
collect: monitor => ({
@@ -85,10 +150,12 @@ function Canvas() {
85150
// The render children function renders all direct children of a given component
86151
// Direct children are draggable/clickable
87152

153+
88154
const canvasStyle = combineStyles(defaultCanvasStyle, currentComponent.style);
89155
return (
90156
<div ref={drop} style={canvasStyle} onClick={onClickHandler}>
91157
{renderChildren(currentComponent.children)}
158+
{modal}
92159
</div>
93160
);
94161
}

app/src/components/main/DirectChildComponent.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ function DirectChildComponent({ childId, type, typeId, style }: ChildElement) {
125125
placeHolder={HTMLDefaultPlaceholder}
126126
linkId={null}
127127
key={
128-
'indChild' +
128+
'indChildHTML' +
129129
child.childId.toString() +
130130
child.typeId.toString()
131131
}
@@ -138,7 +138,7 @@ function DirectChildComponent({ childId, type, typeId, style }: ChildElement) {
138138
placeHolder={HTMLDefaultPlaceholder}
139139
linkId={null}
140140
key={
141-
'indChild' +
141+
'indChildNest' +
142142
child.childId.toString() +
143143
child.typeId.toString()
144144
}
@@ -155,7 +155,7 @@ function DirectChildComponent({ childId, type, typeId, style }: ChildElement) {
155155
return (
156156
<IndirectChild
157157
key={
158-
'indChild' + child.childId.toString() + child.typeId.toString()
158+
'RouteLink' + child.childId.toString() + child.typeId.toString()
159159
}
160160
style={combinedStyle}
161161
placeHolder=""

0 commit comments

Comments
 (0)