Skip to content

Commit 65f7f72

Browse files
committed
Working Undo Functionality.
> > Co-authored-by: eddypjr <[email protected]> Co-authored-by: Anthonytorrero <[email protected]>
1 parent 615d291 commit 65f7f72

File tree

5 files changed

+46
-215
lines changed

5 files changed

+46
-215
lines changed

app/src/components/main/Canvas.tsx

Lines changed: 8 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import React, { useState, useContext } from 'react';
22
import { useDrop, DropTargetMonitor } from 'react-dnd';
3-
import customHooks from '../helperFunctions/customHook';
43
import _ from 'lodash';
54
import { ItemTypes } from '../../constants/ItemTypes';
65
import StateContext from '../../context/context';
@@ -11,6 +10,7 @@ import renderChildren from '../../helperFunctions/renderChildren';
1110
// const snapStateArr = [];
1211
function Canvas() {
1312
const [state, dispatch] = useContext(StateContext);
13+
console.log('state in Canvas', state);
1414
// const [ prevState, setPrevState ] = useState<Array<object>>([]); // NOT USING
1515
// find the current component to render on the canvas
1616
const currentComponent: Component = state.components.find(
@@ -30,48 +30,23 @@ function Canvas() {
3030
// note: a null value for the child id means that we are focusing on the top-level component rather than any child
3131
changeFocus(state.canvasFocus.componentId, null);
3232
}
33-
function onChangeHandler(event) {
34-
// console.log('working', event.target)
35-
}
3633

37-
// stores a limited snapshot of previous state to use in the useDrop function, for UNDO functionality
38-
// const snapStateArr = [];
34+
// stores a snapshot of state into the past array for UNDO
3935
const snapShotFunc = () => {
40-
// make a deep clone of state ( JSON.parse(JSON.stringify(<object>)) ? )
41-
// function inner() {
36+
// make a deep clone of state
4237
const deepCopiedState = JSON.parse(JSON.stringify(state));
43-
// console.log('deepCopiedState', deepCopiedState);
44-
// stateSnapArr.push(deepCopiedState);
4538
state.past.push(deepCopiedState.components[0].children);
46-
// state.past.push(deepCopiedState);
47-
// console.log('state after push', state)
48-
console.log('state in canvas', state.past)
49-
// return;
50-
// snapStateArr.push(5);
51-
// return snapStateArr;
52-
// }
53-
// inner();
54-
55-
// return;
56-
// const prevCount = customHooks(state);
57-
// console.log('prevCount', prevCount);
58-
// console.log('state', state);
59-
60-
// setPrevState( previousState => {
61-
// return [...previousState].push(deepCopiedState);
62-
// })
63-
// console.log('prevState: ', prevState)
64-
}
39+
// console.log('state in snapShotFunc', state.past)
40+
}
6541

42+
6643
// This hook will allow the user to drag items from the left panel on to the canvas
6744
const [{ isOver }, drop] = useDrop({
6845
accept: ItemTypes.INSTANCE,
6946
drop: (item: DragItem, monitor: DropTargetMonitor) => {
7047
const didDrop = monitor.didDrop();
7148
// returns false for direct drop target
72-
//code here
73-
// 6.0 didDrop is firing when HTML tags are moved up
74-
snapShotFunc(); // < ------ snapShotFunc here
49+
snapShotFunc();
7550
if (didDrop) {
7651
return;
7752
}
@@ -118,7 +93,7 @@ function Canvas() {
11893
// Direct children are draggable/clickable
11994
const canvasStyle = combineStyles(defaultCanvasStyle, currentComponent.style);
12095
return (
121-
<div ref={drop} style={canvasStyle} onClick={onClickHandler} onChange={onChangeHandler}>
96+
<div ref={drop} style={canvasStyle} onClick={onClickHandler}>
12297
{/* currentComponent is the selected component on Left Panel (eg: App or Index with green dot to the left) */}
12398
{renderChildren(currentComponent.children)}
12499
</div>

app/src/components/main/DirectChildHTMLNestable.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,13 @@ 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+
// stores a snapshot of state into the past array for nested elements for the UNDO case
21+
const snapShotFunc = () => {
22+
const deepCopiedState = JSON.parse(JSON.stringify(state));
23+
state.past.push(deepCopiedState.components[0].children);
24+
// state.future.push(deepCopiedState.components[0].children);
25+
// console.log('state.past in directChildHTMLNest', state)
26+
};
2227
// find the HTML element corresponding with this instance of an HTML element
2328
// find the current component to render on the canvas
2429
const HTMLType: HTMLType = state.HTMLTypes.find(
@@ -50,6 +55,7 @@ function DirectChildHTMLNestable({
5055
// triggered on drop
5156
drop: (item: any, monitor: DropTargetMonitor) => {
5257
const didDrop = monitor.didDrop();
58+
snapShotFunc();
5359
if (didDrop) {
5460
return;
5561
}

app/src/containers/RightContainer.tsx

Lines changed: 3 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import React, {
55
useMemo,
66
useRef,
77
} from 'react';
8-
import customHooks from '../helperFunctions/customHook';
98
import initialState from '../context/initialState';
109
import { makeStyles } from '@material-ui/core/styles';
1110
import FormControl from '@material-ui/core/FormControl';
@@ -45,29 +44,6 @@ const RightContainer = ({isThemeLight}): JSX.Element => {
4544
const { style } = useContext(styleContext);
4645
const [modal, setModal] = useState(null);
4746
const [prevState, setPrevState] = useState(state);
48-
// const [ref, setRef] = useRef();
49-
50-
// const prevCountRef = useRef();
51-
// useEffect(() => {
52-
// prevCountRef.current = prevState;
53-
// });
54-
// const prevCount = prevCountRef.current;
55-
// console.log('prevCount <-- before', prevCount);
56-
// console.log('prevState <-- now', prevState);
57-
// console.log('prevState', prevState);
58-
//state.components[0].children
59-
// function usePrevious(value) {
60-
// const ref = useRef();
61-
// useEffect(() => {
62-
// ref.current = value;
63-
// });
64-
// return ref.current;
65-
// }
66-
// const prevCount = customHooks(state);
67-
// console.log('prevCount <-- before', prevCount);
68-
// console.log('prevState <-- now', prevState)
69-
// console.log('state in rightContainer', state);
70-
7147

7248

7349
const resetFields = () => {
@@ -227,38 +203,11 @@ const RightContainer = ({isThemeLight}): JSX.Element => {
227203
// set current state components.children to previous state and store current state children array in another place holder to not lose current state before reassigning to previous position.
228204
const undoAction = () => {
229205
dispatch({ type: 'UNDO', payload: {} });
230-
// const undoAction = () => {
231-
// dispatch({ type: 'UNDO', payload: {value} })
232-
// const ref = useRef();
233-
// useEffect(() => {
234-
// ref.current = value;
235-
// });
236-
// console.log('ref.curr', ref.current)
237-
// return ref.current;
238-
// dispatch({ type: 'UNDO', payload: {} });
239-
// const childrenArr = state.components[0].children;
240-
// const result = [];
241-
// // console.log('state.components', state.components[0].children)
242-
// for(let i = 0; i < prevState.children.length - 3; i++) {
243-
// result.push(prevState.children[i]);
244-
// }
245-
// setPrevState(result);
246206
};
247-
// };
248-
249-
// const prevCount = undoAction(prevState);
250-
// console.log('prevCount', prevCount);
251-
252-
const handleClick = (e, data) => {
253-
console.log(data);
254-
}
255207

256208
const redoAction = () => {
257209
dispatch({ type: 'REDO', payload: {} });
258-
}
259-
260-
261-
210+
};
262211

263212
// placeholder for handling deleting instance
264213
const handleDelete = () => {
@@ -583,6 +532,8 @@ const redoAction = () => {
583532
<Button
584533
color="primary"
585534
className={classes.button}
535+
onClick={redoAction}
536+
586537
// onClick={clearComps}
587538
// onClick={redoAction}
588539
// onClick = {handleClick}

app/src/reducers/componentReducer.ts

Lines changed: 26 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -622,46 +622,16 @@ const reducer = (state: State, action: Action) => {
622622
};
623623
}
624624
case 'UNDO': {
625-
//iterate through past arr, grab the 1 before the end, reassign state to equal that grabbed obj
626-
// let past: object[] = state.past[state.past.length - 1];
627-
// console.log()
628-
console.log('state before past', state);
629-
// const pastBy = state.past[state.past.length - 1];
630-
// console.log('pastBy', pastBy);
631-
// console.log('state.past - 1', state.past[state.past.length - 1])
632-
// state.past = [];
633-
634-
635-
//check if state.components[0].children is nested
636-
//if it is nested, go into that object and do something
637-
//else, have state.comp.children = state.past[state.past.length - 1]
638-
//pop from past
639-
// const child = state.components[0].children
640-
// for(let i = 0; i < child.length; i++) {
641-
// // console.log('each children obj', child[i])
642-
// if(child[i].children.length === 2) {
643-
// // child[i].children = state.past[state.past.length - 2]//[];
644-
// child[i].children = [];
645-
// console.log('children of div or form', child[i])
646-
647-
// // child[i].children = state.past[state.past.length - 1]
648-
// }
649-
// // child[i] = state.past[state.past.length - 1]
650-
// }
651-
let nestedChildren: any[] = state.components[0].children[0].children;
652-
// check if there are any tags in the children of the children (nested tags)
653-
if(nestedChildren.length === 2){
654-
// if there are, execute undo code specific to nested children, otherwise, execute code below for non-nested children
655-
nestedChildren = [];
656-
} else if(nestedChildren.length > 2) {
657-
nestedChildren = nestedChildren[nestedChildren.length - 2];
658-
} else {
659-
state.components[0].children = state.past[state.past.length - 1]
660-
state.past.pop();
661-
}
662-
console.log('state after past reassigned', state);
625+
//if past is empty, return state
626+
if (state.past.length === 0) return {...state};
627+
//the children array of state.components[0] will equal the last element of the past array
628+
state.components[0].children = state.past[state.past.length-1];
629+
//the last element of past array gets pushed into future;
630+
// state.future.push(state.past[state.past.length - 1]);
631+
//pop the last element off the past array
632+
state.past.pop();
633+
//generate code for the Code Preview
663634
state.components.forEach((el, i) => {
664-
console.log('el in undo', el)
665635
el.code = generateCode(
666636
state.components,
667637
state.components[i].id,
@@ -672,104 +642,33 @@ const reducer = (state: State, action: Action) => {
672642
});
673643
return {
674644
...state
675-
}
645+
};
676646
}
677-
678-
679-
680-
// console.log('state', state);
681-
// const childrenArr = state.components[0].children;
682-
// const children: Array<object | null> = [];
683-
// const children = [];
684-
// console.log('state.components', state.components[0].children)
685-
686-
// // console.log('state', state);
687-
// // const childrenArr = state.components[0].children;
688-
// // const children: Array<object | null> = [];
689-
// const children = state.components[0].children;
690-
// const past = [];
691-
692-
// // console.log('children', children)
693-
// // console.log('state.components', state.components)
694-
// children.forEach(htmlTag => past.push(htmlTag));
695-
// // console.log('past', past);
696-
// redoArr.push(past[past.length-2], past[past.length-1]);
697-
698-
699-
// if(state.past.length >= 2) {
700-
// // state.past.splice(0, state.past.length -1);
701-
// state.past.length = 2;
702-
// } else {
703-
// state.past.push(past[past.length-2], past[past.length-1])
704-
// }
705-
706-
707-
// // redoArrFunc(past[past.length - 2], past[past.length-1])
708-
// console.log('redoArr', redoArr);
709-
// state.components[0].children = past.slice(0, past.length - 2);
710-
// // console.log('state with past', state.components[0].children)
711-
// // console.log('entire state with new past', state)
712-
// state.components.forEach((el, i) => {
713-
// // console.log('el in undo', el)
714-
// el.code = generateCode(
715-
// state.components,
716-
// state.components[i].id,
717-
// state.rootComponents,
718-
// state.projectType,
719-
// state.HTMLTypes
720-
// );
721-
// });
722-
// // state.components[0].children.splice(0, state.components[0].children.length);
723-
// console.log('the final boss in UNDO', state)
724-
// return {
725-
// ...state,
726-
// }
727-
728-
// console.log('state', state);
729-
// let stateSnap = [state];
730-
// stateSnap = stateSnap.slice(0, stateSnap.length +1);
731-
// console.log('stateSnap in UNDOOOO', stateSnap);
732-
// console.log('stateSnap in UNDO before push', stateSnap)
733-
// stateSnap.push(state);
734-
// // redoArr.push(stateSnap);
735-
// console.log('stateSnap in UNDO after push', stateSnap)
736-
// console.log('redoArr in undo', redoArr);
737-
738-
739-
740-
// }
741-
////////////Reference ADD ELEMENT case to see how id is being incremented
742647
case 'REDO': {
743-
// const children = state.components[0].children;
744-
// if(redoArr.length >= 2) redoArr.length = 2;
745-
// children.push(redoArr);
746-
let {past} = state;
747-
const children = state.components[0].children;
748-
// while(past.length <= 2) {
749-
children.push(...past)
750-
// children.push(past[past.length -2]);
751-
// }
648+
//nothing left to undo
649+
if (state.past.length === 0) return {...state};
650+
//nothing left to redo
651+
else if(state.future.length === 0) return {...state};
652+
//the children array of state.components[0] will equal the last element of the future array
653+
state.components[0].children = state.future[state.future.length - 1];
654+
//the last element of the future array gets pushed into the past array
655+
state.past.push(state.future[state.future.length - 1])
656+
//the last element of the future array gets popped off
657+
state.future.pop();
658+
//generate code for the Code Preview
752659
state.components.forEach((el, i) => {
753-
// console.log('el in undo', el)
754660
el.code = generateCode(
755661
state.components,
756662
state.components[i].id,
757663
state.rootComponents,
758664
state.projectType,
759665
state.HTMLTypes
760-
);
761-
});
762-
past.splice(0, past.length);
763-
console.log('the final boss in REDO', state)
764-
// console.log('past destructured', past)
765-
// console.log('redoItems', redoItems)
766-
// console.log('state in redo', state)
767-
// console.log(redoArr())eeeeeeeeeeeeeeweeeee
768-
// console.log('children in Redo', children)
769-
return {
770-
...state
666+
);
667+
});
668+
return {
669+
...state
670+
};
771671
}
772-
}
773672

774673
default:
775674
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)