Skip to content

Commit 80fd9d3

Browse files
committed
Merge branch 'master' into feature/server/graphQL
2 parents cc6dff5 + 50c2a72 commit 80fd9d3

File tree

12 files changed

+123
-17
lines changed

12 files changed

+123
-17
lines changed

app/src/components/bottom/BottomTabs.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ const BottomTabs = () => {
2525

2626
// breaks if handleChange is commented out
2727
const handleChange = (event: React.ChangeEvent, value: number) => {
28-
// console.log('value', value)
29-
// console.log('setTab', setTab)
3028
setTab(value);
3129
};
3230
// Allows users to toggle project between "next.js" and "Classic React"
@@ -36,7 +34,6 @@ const BottomTabs = () => {
3634
dispatch({ type: 'CHANGE PROJECT TYPE', payload: { projectType } });
3735
};
3836
const { components, HTMLTypes } = state;
39-
// console.log('components', components)
4037

4138
const changeTheme = e => {
4239
setTheme(e.target.value);

app/src/components/bottom/CodePreview.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@ const CodePreview: React.FC<{
1616
setTheme: any | null;
1717
}> = ({ theme, setTheme }) => {
1818
const wrapper = useRef();
19-
// console.log('wrapper', wrapper)
2019
const dimensions = useResizeObserver(wrapper);
21-
// console.log('dimensions', dimensions)
2220
const { width, height } =
2321
dimensions || 0;
2422

@@ -27,7 +25,7 @@ const CodePreview: React.FC<{
2725
const currentComponent = state.components.find(
2826
(elem: Component) => elem.id === state.canvasFocus.componentId
2927
);
30-
console.log('currentComp in CodePreview', currentComponent)
28+
3129
const handleCodeSnipChange = val => {
3230
currentComponent.code = val;
3331
};

app/src/components/main/Canvas.tsx

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,50 @@
1-
import React, { useContext } from 'react';
1+
import React, { useState, useContext } from 'react';
22
import { useDrop, DropTargetMonitor } from 'react-dnd';
3+
import _ from 'lodash';
34
import { ItemTypes } from '../../constants/ItemTypes';
45
import StateContext from '../../context/context';
56
import { Component, DragItem } from '../../interfaces/Interfaces';
67
import { combineStyles } from '../../helperFunctions/combineStyles';
78
import renderChildren from '../../helperFunctions/renderChildren';
89

10+
911
function Canvas() {
1012
const [state, dispatch] = useContext(StateContext);
1113
// find the current component to render on the canvas
1214
const currentComponent: Component = state.components.find(
1315
(elem: Component) => elem.id === state.canvasFocus.componentId
14-
);
15-
// console.log('currentComponent', currentComponent)
16+
);
1617

1718
// changes focus of the canvas to a new component / child
1819
const changeFocus = (componentId: number, childId: number | null) => {
1920
dispatch({ type: 'CHANGE FOCUS', payload: { componentId, childId } });
2021
};
22+
2123
// onClickHandler is responsible for changing the focused component and child component
2224
function onClickHandler(event) {
2325
event.stopPropagation();
2426
// note: a null value for the child id means that we are focusing on the top-level component rather than any child
2527
changeFocus(state.canvasFocus.componentId, null);
26-
}
28+
};
29+
30+
// stores a snapshot of state into the past array for UNDO
31+
const snapShotFunc = () => {
32+
// make a deep clone of state
33+
const deepCopiedState = JSON.parse(JSON.stringify(state));
34+
state.past.push(deepCopiedState.components[0].children);
35+
};
36+
2737
// This hook will allow the user to drag items from the left panel on to the canvas
2838
const [{ isOver }, drop] = useDrop({
2939
accept: ItemTypes.INSTANCE,
3040
drop: (item: DragItem, monitor: DropTargetMonitor) => {
31-
const didDrop = monitor.didDrop(); // returns false for direct drop target
41+
const didDrop = monitor.didDrop();
42+
// takes a snapshot of state to be used in UNDO and REDO cases
43+
snapShotFunc();
44+
// returns false for direct drop target
3245
if (didDrop) {
3346
return;
3447
}
35-
console.log('item', item)
3648
// if item dropped is going to be a new instance (i.e. it came from the left panel), then create a new child component
3749
if (item.newInstance) {
3850
dispatch({
@@ -81,4 +93,6 @@ function Canvas() {
8193
</div>
8294
);
8395
}
96+
// export { snapStateArr };
8497
export default Canvas;
98+

app/src/components/main/CanvasContainer.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ function CanvasContainer() {
99
border: '2px Solid grey',
1010
};
1111

12+
function onChangeHandler(event) {
13+
console.log('working', event.target);
14+
}
15+
1216
return (
1317
<div style={canvasContainerStyle}>
1418
<Canvas />

app/src/components/main/DirectChildHTMLNestable.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@ function DirectChildHTMLNestable({
1717
}: ChildElement) {
1818
const [state, dispatch] = useContext(StateContext);
1919
const ref = useRef(null);
20-
// console.log('name', name)
21-
// console.log('children', children)
20+
// takes a snapshot of state to be used in UNDO and REDO cases
21+
const snapShotFunc = () => {
22+
const deepCopiedState = JSON.parse(JSON.stringify(state));
23+
state.past.push(deepCopiedState.components[0].children);
24+
};
2225
// find the HTML element corresponding with this instance of an HTML element
2326
// find the current component to render on the canvas
2427
const HTMLType: HTMLType = state.HTMLTypes.find(
@@ -50,6 +53,8 @@ function DirectChildHTMLNestable({
5053
// triggered on drop
5154
drop: (item: any, monitor: DropTargetMonitor) => {
5255
const didDrop = monitor.didDrop();
56+
// takes a snapshot of state to be used in UNDO and REDO cases
57+
snapShotFunc();
5358
if (didDrop) {
5459
return;
5560
}

app/src/containers/RightContainer.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ import React, {
33
useContext,
44
useEffect,
55
useMemo,
6+
useRef,
67
} from 'react';
8+
import initialState from '../context/initialState';
79
import { makeStyles } from '@material-ui/core/styles';
810
import FormControl from '@material-ui/core/FormControl';
911
import Select from '@material-ui/core/Select';
@@ -42,6 +44,7 @@ const RightContainer = ({isThemeLight}): JSX.Element => {
4244
const { style } = useContext(styleContext);
4345
const [modal, setModal] = useState(null);
4446

47+
4548
const resetFields = () => {
4649
const style = configTarget.child
4750
? configTarget.child.style
@@ -193,6 +196,15 @@ const RightContainer = ({isThemeLight}): JSX.Element => {
193196
return styleObj;
194197
};
195198

199+
// UNDO/REDO functionality--onClick these functions will be invoked.
200+
const undoAction = () => {
201+
dispatch({ type: 'UNDO', payload: {} });
202+
};
203+
204+
const redoAction = () => {
205+
dispatch({ type: 'REDO', payload: {} });
206+
};
207+
196208
// placeholder for handling deleting instance
197209
const handleDelete = () => {
198210
dispatch({ type: 'DELETE CHILD', payload: {} });
@@ -502,6 +514,22 @@ const RightContainer = ({isThemeLight}): JSX.Element => {
502514
</Button>
503515
</div>
504516
)}
517+
<div className = {classes.buttonRow}>
518+
<Button
519+
color="primary"
520+
className={classes.button}
521+
onClick={undoAction}
522+
>
523+
<i className="fas fa-undo"></i>
524+
</Button>
525+
<Button
526+
color="primary"
527+
className={classes.button}
528+
onClick={redoAction}
529+
>
530+
<i className="fas fa-redo"></i>
531+
</Button>
532+
</div>
505533
</div>
506534

507535
</div>

app/src/context/initialState.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ const initialState: State = {
2121
nextComponentId: 2,
2222
nextChildId: 1,
2323
nextTopSeparatorId: 1000,
24-
HTMLTypes
24+
HTMLTypes,
25+
past: [],
26+
future: []
2527
};
2628

2729
export default initialState;

app/src/interfaces/Interfaces.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,18 @@ export interface State {
1313
nextBottomSeparatorId: number;
1414
nextChildId: number;
1515
HTMLTypes: HTMLType[];
16+
past: any[];
17+
future: any[];
18+
}
19+
20+
export interface PastElement {
21+
type: string;
22+
typeId: number;
23+
name: string;
24+
childId: number;
25+
style: object;
26+
attributes?: object;
27+
children?: PastElement[];
1628
}
1729

1830
export interface ChildElement {

app/src/public/index-prod.ejs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
<html lang="en-US">
33
<head>
44
<meta charset="UTF-8" />
5+
<!-- <script src = "lodash.js"></script> -->
6+
<script src="https://kit.fontawesome.com/7e1cebd082.js" crossorigin="anonymous"></script>
57
<!-- This file is .ejs rather than .html so that we can dynamically add a nonce into the header -->
68
<!-- the nonce is used in the Content security policy webpack plugin so that Material UI styles can be injected into the DOM -->
79
<!-- https://github.com/reZach/secure-electron-template/issues/14 -->

app/src/public/index.ejs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
<html lang="en-US">
33
<head>
44
<meta charset="UTF-8" />
5+
<!-- <script src = "lodash.js"></script> -->
6+
<script src="https://kit.fontawesome.com/7e1cebd082.js" crossorigin="anonymous"></script>
57
<!-- This file is .ejs rather than .html so that we can dynamically add a nonce into the header -->
68
<!-- the nonce is used in the Content security policy webpack plugin so that Material UI styles can be injected into the DOM -->
79
<!-- https://github.com/reZach/secure-electron-template/issues/14 -->

app/src/reducers/componentReducer.ts

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import manageSeparators from '../helperFunctions/manageSeparators';
1111

1212
let separator = initialState.HTMLTypes[1];
1313

14-
// }
14+
1515
const reducer = (state: State, action: Action) => {
1616
// if the project type is set as Next.js or Gatsby.js, next/gatsby component code should be generated
1717
// otherwise generate classic react code
@@ -612,6 +612,48 @@ const reducer = (state: State, action: Action) => {
612612
HTMLTypes
613613
};
614614
}
615+
case 'UNDO': {
616+
//if past is empty, return state
617+
if (state.past.length === 0) return {...state};
618+
//the children array of state.components[0] will equal the last element of the past array
619+
state.components[0].children = state.past[state.past.length-1];
620+
//the last element of past array gets pushed into future;
621+
state.future.push(state.past.pop());
622+
//generate code for the Code Preview
623+
state.components.forEach((el, i) => {
624+
el.code = generateCode(
625+
state.components,
626+
state.components[i].id,
627+
state.rootComponents,
628+
state.projectType,
629+
state.HTMLTypes
630+
);
631+
});
632+
return {
633+
...state
634+
};
635+
}
636+
case 'REDO': {
637+
//nothing left to redo
638+
if(state.future.length === 0) return {...state};
639+
//the children array of state.components[0] will equal the last element of the future array
640+
state.components[0].children = state.future[state.future.length - 1];
641+
//the last element of the future array gets pushed into the past array and the last element of the future array gets popped off
642+
state.past.push(state.future.pop());
643+
//generate code for the Code Preview
644+
state.components.forEach((el, i) => {
645+
el.code = generateCode(
646+
state.components,
647+
state.components[i].id,
648+
state.rootComponents,
649+
state.projectType,
650+
state.HTMLTypes
651+
);
652+
});
653+
return {
654+
...state
655+
};
656+
}
615657

616658
default:
617659
return state;

app/src/tree/TreeChart.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ function TreeChart({ data }) { // data is components from state - passed in from
3737
i -= 1;
3838
}
3939
// if element has a children array and that array has length, recursive call
40-
else if ((arr[i].name === 'div' || arr[i].type === 'Component') && arr[i].children.length) {
40+
else if ((arr[i].name === 'div' || arr[i].name === 'form' || arr[i].type === 'Component') && arr[i].children.length) {
4141
// if element is a component, replace it with deep clone of latest version (to update with new HTML elements)
4242
if (arr[i].type === 'Component') arr[i] = cloneDeep(data.find(component => component.name === arr[i].name));
4343
removeSeparators(arr[i].children);

0 commit comments

Comments
 (0)