Skip to content

Commit 8bf7711

Browse files
Merge branch 'CaretDevelopment' into codepreview
2 parents 2c74a26 + 3cd21dc commit 8bf7711

20 files changed

+655
-138
lines changed

app/src/components/bottom/BottomTabs.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import StateContext from '../../context/context';
44
import Tabs from '@material-ui/core/Tabs';
55
import Tab from '@material-ui/core/Tab';
66
import CodePreview from './CodePreview';
7+
import StylesEditor from './StylesEditor';
78
import Box from '@material-ui/core/Box';
89
import Tree from '../../tree/TreeChart';
910
import { emitKeypressEvents } from 'readline';
@@ -39,6 +40,8 @@ const BottomTabs = () => {
3940
setTheme(e.target.value);
4041
};
4142

43+
console.log("Editor Theme: ", theme);
44+
4245
return (
4346
<div className={classes.root} style={style}>
4447
<Box display="flex" justifyContent="space-between" alignItems="center" paddingBottom="10px" paddingRight="10px">
@@ -60,6 +63,11 @@ const BottomTabs = () => {
6063
classes={{ root: classes.tabRoot, selected: classes.tabSelected }}
6164
label="Component Tree"
6265
/>
66+
<Tab
67+
disableRipple
68+
classes={{ root: classes.tabRoot, selected: classes.tabSelected }}
69+
label="CSS Editor"
70+
/>
6371
</Tabs>
6472
<div className={classes.projectTypeWrapper}>
6573
<FormControl size='small'>
@@ -80,6 +88,7 @@ const BottomTabs = () => {
8088
</Box>
8189
{tab === 0 && <CodePreview theme={theme} setTheme={setTheme} />}
8290
{tab === 1 && <Tree data={components} />}
91+
{tab === 2 && <StylesEditor theme={theme} setTheme={setTheme} />}
8392
</div>
8493
);
8594
};
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import React, { useContext, useState, useRef, useEffect } from 'react';
2+
import StateContext from '../../context/context';
3+
import AceEditor from 'react-ace';
4+
import 'ace-builds/src-noconflict/mode-css';
5+
import 'ace-builds/src-noconflict/theme-monokai';
6+
import 'ace-builds/src-noconflict/theme-github';
7+
import 'ace-builds/src-noconflict/theme-solarized_dark';
8+
import 'ace-builds/src-noconflict/theme-solarized_light';
9+
import 'ace-builds/src-noconflict/theme-terminal';
10+
import 'ace-builds/src-min-noconflict/ext-searchbox';
11+
import { Component } from '../../interfaces/Interfaces';
12+
import useResizeObserver from '../../tree/useResizeObserver';
13+
import { string } from 'prop-types';
14+
import Fab from '@material-ui/core/Fab';
15+
import SaveIcon from '@material-ui/icons/Save';
16+
17+
const StylesEditor: React.FC<{
18+
theme: string | null;
19+
setTheme: any | null;
20+
}> = ({ theme, setTheme }) => {
21+
const wrapper = useRef();
22+
const [css, setCss] = useState();
23+
// const [state, dispatch] = useContext(StateContext);
24+
25+
useEffect(() => {
26+
loadFile();
27+
}, []);
28+
29+
const loadFile = () => {
30+
const myHeaders = new Headers({
31+
'Content-Type': 'text/css',
32+
Accept: 'text/css',
33+
});
34+
fetch('/demoRender', {
35+
headers: myHeaders,
36+
})
37+
.then(response => response.text())
38+
.then((data) => {
39+
setCss(data);
40+
});
41+
}
42+
43+
const saveFile = () => {
44+
console.log('saveFile: ', css);
45+
// const myHeaders = new Headers({
46+
// headers: { 'Content-Type': 'application/json' },
47+
// });
48+
fetch('/user-styles/save', {
49+
method: 'POST',
50+
headers: { 'Content-Type': 'application/json' },
51+
body: JSON.stringify({ data: css }),
52+
})
53+
.then(response => response.text())
54+
.then((data) => {
55+
// setCss(data);
56+
//message save!
57+
});
58+
}
59+
const saveCss = (e) => {
60+
e.preventDefault();
61+
saveFile();
62+
}
63+
64+
const handleChange = (text) => {
65+
setCss(text);
66+
}
67+
68+
return (
69+
<div
70+
className='text-editor'
71+
ref={wrapper}
72+
style={{
73+
height: '40vh',
74+
maxWidth: '100%',
75+
justifyContent: 'center',
76+
}}
77+
>
78+
<AceEditor
79+
mode="css"
80+
theme={'solarized_dark'}
81+
width="100%"
82+
height="100%"
83+
onChange={handleChange}
84+
value={css}
85+
name="Css_div"
86+
// readOnly={false}
87+
fontSize={16}
88+
tabSize={2}
89+
enableBasicAutocompletion={true}
90+
enableLiveAutocompletion={true}
91+
/>
92+
<Fab className='btn' onClick={saveCss} color="secondary" aria-label="add">
93+
<SaveIcon />
94+
</Fab>
95+
</div>
96+
);
97+
};
98+
99+
export default StylesEditor;
Lines changed: 57 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,92 @@
1-
import React, { useContext, useRef } from 'react';
2-
import { ChildElement, HTMLType } from '../../interfaces/Interfaces';
3-
import { ItemTypes } from '../../constants/ItemTypes';
4-
import StateContext from '../../context/context';
5-
import { combineStyles } from '../../helperFunctions/combineStyles';
6-
import globalDefaultStyle from '../../public/styles/globalDefaultStyles';
1+
// Caret Start
2+
import React, {
3+
useRef, useState, useContext, useEffect,
4+
} from 'react';
5+
import { Annotations } from '../../interfaces/Interfaces';
76
import Modal from '@material-ui/core/Modal';
7+
import StateContext from '../../context/context';
88

99
function Annotation({
10-
childId,
11-
type,
12-
typeId,
13-
style,
14-
children
15-
}: ChildElement) {
10+
id,
11+
name,
12+
}: Annotations) {
13+
const [annotations, setAnnotations] = useState('');
1614
const [state, dispatch] = useContext(StateContext);
1715
const ref = useRef(null);
1816

19-
// find the HTML element corresponding with this instance of an HTML element
20-
// find the current component to render on the canvas
21-
const HTMLType: HTMLType = state.HTMLTypes.find(
22-
(type: HTMLType) => type.id === typeId
23-
);
24-
25-
// hook that allows component to be draggable
26-
27-
// combine all styles so that higher priority style specifications overrule lower priority style specifications
28-
// priority order is 1) style directly set for this child (style), 2) style of the referenced HTML element, and 3) default styling
29-
const defaultNestableStyle = { ...globalDefaultStyle };
30-
const separatorStyle = {
31-
padding: '5px 10px',
32-
margin: '1px 10px',
33-
};
34-
35-
36-
const combinedStyle = combineStyles(
37-
combineStyles(combineStyles(defaultNestableStyle, HTMLType.style), style),
38-
separatorStyle
39-
);
40-
17+
// React hook setting the annotation button modal open/close state
4118
const [open, setOpen] = React.useState(false);
4219

43-
const handleAnnoOpen = (id) => {
20+
// For showing the modal
21+
const handleOpen = (id) => {
4422
setOpen(true);
45-
//annotateOpen(id);
4623
};
4724

25+
// For closing the modal
4826
const handleClose = () => {
4927
setOpen(false);
5028
};
5129

30+
// Handles when text exists in the textarea of the modal. If text exists/does not exist, corresponding button changes colors.
5231
const handleAnnoChange = (event) => {
5332
const { value } = event.target;
33+
const focusIndex = state.canvasFocus.componentId - 1;
34+
const childrenArray = state.components[focusIndex].children;
5435

55-
console.log("ID ", event.target.id)
56-
console.log(event.target);
5736
if(value === '') {
58-
document.getElementById("btn" + event.target.id).style.background = '#3ec1ac';
59-
document.getElementById("btn" + event.target.id).id = 'btn' + event.target.id;
37+
ref.current.style.background = '#3ec1ac';
38+
ref.current.id = 'btn' + event.target.id;
6039
} else {
61-
document.getElementById("btn" + event.target.id).style.background = '#cc99ff';
62-
document.getElementById("btn" + event.target.id).id = 'btn' + event.target.id;
40+
ref.current.style.background = '#cc99ff';
41+
ref.current.id = 'btn' + event.target.id;
42+
setAnnotations(value);
43+
44+
let childEle = handleSaveAnno(childrenArray, event.target.id);
45+
46+
if(childEle) {
47+
childEle.annotations = annotations;
48+
setState(childEle.annotations);
49+
}
50+
}
51+
}
52+
53+
54+
const handleSaveAnno = (array, id) => {
55+
for(let i = 0; i < array.length; i++) {
56+
if(array[i].childId === id) {
57+
return array[i];
58+
}
59+
if(array[i].children.length > 0) {
60+
return handleSaveAnno(array[i], id);
61+
}
6362
}
6463
}
6564

65+
/*
66+
<span className='annotate-textarea-footer'>
67+
<button className='annotate-textarea-savebutton'>Save Notes</button>
68+
</span>
69+
*/
70+
const body = (
71+
<div className='annotate-position'>
72+
<span className='annotate-textarea-header'>Notes for: {name} ( {id} )</span>
73+
<textarea className='annotate-textarea' id={id.toString()} onChange={handleAnnoChange}></textarea>
74+
</div>
75+
)
76+
6677
return (
67-
<div>
68-
{/* Caret start */}
69-
<button className='annotate-button-empty' id={"btn" + childId} onClick={() => handleAnnoOpen(childId)}>DIRECT CHILD HTML NESTABLE HERE</button>
78+
<div style={{padding: '1px', float: 'right'}}>
79+
<button className='annotate-button-empty' id={"btn" + id} onClick={() => handleOpen(id)} ref={ref}>Notes</button>
7080
<Modal
7181
open={open}
7282
onClose={handleClose}
7383
keepMounted={true}
7484
>
75-
<textarea className='annotate-textarea' id={state.canvasFocus.childId} onChange={handleAnnoChange}></textarea>
85+
{body}
7686
</Modal>
77-
{/* Caret end */}
7887
</div>
7988
);
8089
}
8190

8291
export default Annotation;
92+
// Caret End

app/src/components/main/DirectChildHTML.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@ import { ItemTypes } from '../../constants/ItemTypes';
88
import StateContext from '../../context/context';
99
import { combineStyles } from '../../helperFunctions/combineStyles';
1010
import globalDefaultStyle from '../../public/styles/globalDefaultStyles';
11+
// Caret
12+
import Annotation from './Annotation'
1113

1214
function DirectChildHTML({
1315
childId,
16+
name,
1417
type,
1518
typeId,
1619
style,
@@ -66,7 +69,14 @@ function DirectChildHTML({
6669

6770
return (
6871
<div onClick={onClickHandler} style={combinedStyle} ref={drag}>
69-
{HTMLType.placeHolderShort}
72+
<strong>{HTMLType.placeHolderShort}</strong>
73+
{/* Caret start */}
74+
{` (${childId})`}
75+
<Annotation
76+
id={childId}
77+
name={name}
78+
/>
79+
{/* Caret end */}
7080
</div>
7181
);
7282
}

app/src/components/main/DirectChildHTMLNestable.tsx

Lines changed: 9 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
11
import React, { useContext, useEffect, useRef } from 'react';
2-
import { ChildElement, HTMLType } from '../../interfaces/Interfaces';
2+
import { ChildElement, HTMLType} from '../../interfaces/Interfaces';
33
import { useDrag, useDrop, DropTargetMonitor } from 'react-dnd';
44
import { ItemTypes } from '../../constants/ItemTypes';
55
import StateContext from '../../context/context';
66
import { combineStyles } from '../../helperFunctions/combineStyles';
77
import globalDefaultStyle from '../../public/styles/globalDefaultStyles';
88
import renderChildren from '../../helperFunctions/renderChildren';
9-
import Modal from '@material-ui/core/Modal';
10-
import Annotation from './Annotation'
11-
// Caret
12-
import { makeStyles } from '@material-ui/core';
13-
import validateNewParent from '../../helperFunctions/changePositionValidation'
149
// Caret
15-
import TextField from '@material-ui/core/TextField';
16-
import uniqid from 'uniqid';
10+
import Annotation from './Annotation'
1711

1812
function DirectChildHTMLNestable({
1913
childId,
@@ -116,30 +110,6 @@ const snapShotFunc = () => {
116110
changeFocus(state.canvasFocus.componentId, childId);
117111
}
118112

119-
// Caret Start
120-
const [open, setOpen] = React.useState(false);
121-
122-
const handleAnnoOpen = (id) => {
123-
setOpen(true);
124-
//annotateOpen(id);
125-
};
126-
127-
const handleClose = () => {
128-
setOpen(false);
129-
};
130-
131-
const handleAnnoChange = (event) => {
132-
const { value } = event.target;
133-
if(value === '') {
134-
document.getElementById("btn" + event.target.id).style.background = '#3ec1ac';
135-
document.getElementById("btn" + event.target.id).id = 'btn' + event.target.id;
136-
} else {
137-
document.getElementById("btn" + event.target.id).style.background = '#cc99ff';
138-
document.getElementById("btn" + event.target.id).id = 'btn' + event.target.id;
139-
}
140-
}
141-
// Caret End
142-
143113
// combine all styles so that higher priority style specifications overrule lower priority style specifications
144114
// priority order is 1) style directly set for this child (style), 2) style of the referenced HTML element, and 3) default styling
145115
const defaultNestableStyle = { ...globalDefaultStyle };
@@ -156,20 +126,19 @@ const snapShotFunc = () => {
156126
combineStyles(combineStyles(defaultNestableStyle, HTMLType.style), style),
157127
interactiveStyle
158128
);
129+
159130
drag(drop(ref));
131+
160132
return (
161133
<div onClick={onClickHandler} style={combinedStyle} ref={ref}>
162-
{HTMLType.placeHolderShort}
163-
{renderChildren(children)}
134+
<strong>{HTMLType.placeHolderShort}</strong>
164135
{/* Caret start */}
136+
{` ( ${childId} )`}
165137
<Annotation
166-
childId={childId}
167-
typeId={typeId}
168-
type={type}
138+
id={childId}
169139
name={name}
170-
style={style}
171-
>
172-
</Annotation>
140+
/>
141+
{renderChildren(children)}
173142
{/* Caret end */}
174143
</div>
175144
);

0 commit comments

Comments
 (0)