Skip to content

Commit 7e00a7c

Browse files
committed
added stateUsed object to childelement interface. this keeps track of which state has been used for that particular childelement. added stateusedobj in a react usestate hook to customizationpanel to update when state is used with corresponding comptext or complink values and a string that keeps track of the pathway to the property (can also handle nested objects). from there, we are dispatching the usestateobj to the reducer, which updates the stateusedobj in childelement from interface. the reducer also invokes generatecode to generate the appropriate code. finally, we edited generatecode.ts to have the correct syntax for accessing variables that are provided by state within html elements.
co-authored-by: Crys Lim [email protected]
1 parent ae92eb8 commit 7e00a7c

File tree

6 files changed

+98
-27
lines changed

6 files changed

+98
-27
lines changed

app/src/components/bottom/UseStateModal.tsx

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import TableStateProps from '../right/TableStateProps';
77
function UseStateModal({ updateAttributeWithState, attributeToChange, childId }) {
88
const [state, dispatch] = useContext(StateContext);
99
const [open, setOpen] = useState(false);
10+
const [displayObject, setDisplayObject] = useState(null)
11+
const [stateKey, setStateKey] = useState('');
1012

1113
// make buttons to choose which component to get state from
1214
const [componentProviderId, setComponentProviderId] = useState(1) // for now set to App
@@ -23,7 +25,10 @@ function UseStateModal({ updateAttributeWithState, attributeToChange, childId })
2325
<span>Choose State Source</span>
2426
<button
2527
style={{ margin: '5px 5px' ,padding: '1px', float: 'right' }}
26-
onClick={() => setOpen(false)}
28+
onClick={() => {
29+
setStateKey('');
30+
setDisplayObject(null)
31+
setOpen(false)}}
2732
>
2833
X
2934
</button>
@@ -35,14 +40,19 @@ function UseStateModal({ updateAttributeWithState, attributeToChange, childId })
3540
<div className="useState-stateDisplay">
3641
<TableStateProps
3742
providerId = {componentProviderId}
38-
// objectId
43+
displayObject = {displayObject}
3944
selectHandler={(table) => {
40-
// if object => show object -> rerender
41-
// setObjectId
42-
43-
// if not object => actually update state
44-
updateAttributeWithState(attributeToChange, componentProviderId, table.row.id);
45-
setOpen(false);
45+
// if object => show object table
46+
if (table.row.type === "object") {
47+
setStateKey(stateKey + table.row.key + '.');
48+
setDisplayObject(table.row.value);
49+
} else {
50+
// if not object => actually update state
51+
setDisplayObject(null);
52+
updateAttributeWithState(attributeToChange, componentProviderId, table.row, stateKey + table.row.key);
53+
setStateKey('')
54+
setOpen(false);
55+
}
4656
}}
4757
deleteHandler={() => func()}
4858
isThemeLight={true}

app/src/components/right/TableStateProps.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,20 @@ const TableStateProps = (props) => {
8787
rows = currentComponent.stateProps.slice();
8888
} else {
8989
const providerComponent = state.components[props.providerId - 1];
90-
rows = providerComponent.stateProps.slice();
90+
// changed to get whole object
91+
if (props.displayObject){
92+
const displayObject = props.displayObject;
93+
// const displayObject = providerComponent.stateProps[props.displayObjectId - 1].value;
94+
// format the object to match the table data format {id:_, key:_, value:_, type:<might do typeof or leave blank>}
95+
let id=1;
96+
for (const key in displayObject) {
97+
rows.push({id: id++, key:key, value: displayObject[key], type: typeof(displayObject[key])});
98+
}
99+
} else {
100+
rows = providerComponent.stateProps.slice();
101+
}
91102
}
103+
console.log(rows);
92104

93105
const { selectHandler } : StatePropsPanelProps = props;
94106

app/src/containers/CustomizationPanel.tsx

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ const CustomizationPanel = ({ isThemeLight }): JSX.Element => {
5151
const { style } = useContext(styleContext);
5252
const [modal, setModal] = useState(null);
5353
const [useContextObj, setUseContextObj] = useState({});
54+
const [stateUsedObj, setStateUsedObj] = useState({});
5455

5556
const resetFields = () => {
5657
const childrenArray = state.components[0].children;
@@ -206,20 +207,25 @@ const CustomizationPanel = ({ isThemeLight }): JSX.Element => {
206207
};
207208

208209
// function to pass into UseStateModal to use state to update attribute
209-
const updateAttributeWithState = (attributeName, componentProviderId, statePropsId) => {
210+
const updateAttributeWithState = (attributeName, componentProviderId, statePropsRow, stateKey='') => {
210211

211212
// get the stateProps of the componentProvider
212-
const currentComponent = state.components[componentProviderId - 1];
213-
const currentComponentProps = currentComponent.stateProps;
214-
const newInput = currentComponentProps[statePropsId - 1].value;
213+
// const currentComponent = state.components[componentProviderId - 1];
214+
// const currentComponentProps = currentComponent.stateProps;
215+
// const newInput = currentComponentProps[statePropsRow.id - 1].value;
216+
217+
console.log('stateKey', stateKey);
218+
const newInput = statePropsRow.value;
215219

216220
if (attributeName === 'compText') {
217221
const newContextObj = useContextObj;
218222
if (!newContextObj[componentProviderId]) {
219223
newContextObj[componentProviderId] = {};
220224
}
221-
newContextObj[componentProviderId].compText = statePropsId;
222-
225+
newContextObj[componentProviderId].compText = statePropsRow.id;
226+
227+
// update/create stateUsed.compText
228+
setStateUsedObj(Object.assign(stateUsedObj, {compText: stateKey}));
223229
setCompText(newInput);
224230
setUseContextObj(newContextObj);
225231
}
@@ -228,8 +234,10 @@ const CustomizationPanel = ({ isThemeLight }): JSX.Element => {
228234
if (!newContextObj[componentProviderId]) {
229235
newContextObj[componentProviderId] = {};
230236
}
231-
newContextObj[componentProviderId].compLink = statePropsId;
237+
newContextObj[componentProviderId].compLink = statePropsRow.id;
232238

239+
// update/create stateUsed.compLink
240+
setStateUsedObj(Object.assign(stateUsedObj, {compLink: stateKey}));
233241
setCompLink(newInput);
234242
setUseContextObj(newContextObj);
235243
}
@@ -257,10 +265,11 @@ const CustomizationPanel = ({ isThemeLight }): JSX.Element => {
257265
if (compText !== '') attributesObj.compText = compText;
258266
if (compLink !== '') attributesObj.compLink = compLink;
259267
if (cssClasses !== '') attributesObj.cssClasses = cssClasses;
260-
261-
// dispatch to update useContext
262-
// type: 'UPDATE USE CONTEXT'
263-
// payload: useContext object
268+
269+
dispatch({
270+
type: 'UPDATE STATE USED',
271+
payload: {stateUsedObj: stateUsedObj}
272+
})
264273

265274
dispatch({
266275
type: 'UPDATE USE CONTEXT',

app/src/helperFunctions/generateCode.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,21 @@ const generateUnformattedCode = (
126126
const elementGenerator = (childElement: object, level: number = 2) => {
127127
let innerText = '';
128128
let activeLink = '';
129-
if (childElement.attributes && childElement.attributes.compText) innerText = childElement.attributes.compText;
130-
if (childElement.attributes && childElement.attributes.compLink) activeLink = childElement.attributes.compLink;
131-
129+
130+
if (childElement.attributes && childElement.attributes.compText) {
131+
if (childElement.stateUsed && childElement.stateUsed.compText) {
132+
innerText = '{' + childElement.stateUsed.compText + '}';
133+
} else {
134+
innerText = childElement.attributes.compText;
135+
}
136+
}
137+
if (childElement.attributes && childElement.attributes.compLink) {
138+
if (childElement.stateUsed && childElement.stateUsed.compLink) {
139+
activeLink = '{' + childElement.stateUsed.compLink + '}';
140+
} else {
141+
activeLink = '"' +childElement.attributes.compLink + '"';
142+
}
143+
}
132144
const nestable = childElement.tag === 'div' ||
133145
childElement.tag === 'form' ||
134146
childElement.tag === 'ol' ||
@@ -139,17 +151,17 @@ const generateUnformattedCode = (
139151
childElement.tag === 'Route';
140152

141153
if (childElement.tag === 'img') {
142-
return `${levelSpacer(level, 5)}<${childElement.tag} src="${activeLink}" ${elementTagDetails(childElement)}/>${levelSpacer(2, (3 + level))}`;
154+
return `${levelSpacer(level, 5)}<${childElement.tag} src=${activeLink} ${elementTagDetails(childElement)}/>${levelSpacer(2, (3 + level))}`;
143155
} else if (childElement.tag === 'a') {
144-
return `${levelSpacer(level, 5)}<${childElement.tag} href="${activeLink}" ${elementTagDetails(childElement)}>${innerText}</${childElement.tag}>${levelSpacer(2, (3 + level))}`;
156+
return `${levelSpacer(level, 5)}<${childElement.tag} href=${activeLink} ${elementTagDetails(childElement)}>${innerText}</${childElement.tag}>${levelSpacer(2, (3 + level))}`;
145157
} else if (childElement.tag === 'input') {
146158
return `${levelSpacer(level, 5)}<${childElement.tag}${elementTagDetails(childElement)}></${childElement.tag}>${levelSpacer(2, (3 + level))}`;
147159
} else if (childElement.tag === 'LinkTo') {
148-
return `${levelSpacer(level, 5)}<Link to="${activeLink}"${elementTagDetails(childElement)}>${innerText}
160+
return `${levelSpacer(level, 5)}<Link to=${activeLink}${elementTagDetails(childElement)}>${innerText}
149161
${tabSpacer(level)}${writeNestedElements(childElement.children, level + 1)}
150162
${tabSpacer(level - 1)}</Link>${levelSpacer(2, (3 + level))}`;
151163
} else if (nestable) {
152-
const routePath = (childElement.tag === 'Route') ? (' ' + 'exact path="' + activeLink + '"') : '';
164+
const routePath = (childElement.tag === 'Route') ? (' ' + 'exact path=' + activeLink) : '';
153165
return `${levelSpacer(level, 5)}<${childElement.tag}${elementTagDetails(childElement)}${routePath}>${innerText}
154166
${tabSpacer(level)}${writeNestedElements(childElement.children, level + 1)}
155167
${tabSpacer(level - 1)}</${childElement.tag}>${levelSpacer(2, (3 + level))}`;

app/src/interfaces/Interfaces.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export interface ChildElement {
2525
attributes?: object;
2626
children?: ChildElement[];
2727
annotations?: string;
28+
stateUsed?: object; // {compText: 'key1.key2.a', compLink: 'key3.b'}
2829
}
2930
export interface Component {
3031
id: number;

app/src/reducers/componentReducer.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,31 @@ const reducer = (state: State, action: Action) => {
451451
}
452452
return { ...state };
453453
}
454+
455+
case 'UPDATE STATE USED': {
456+
457+
const { stateUsedObj } = action.payload;
458+
459+
const components = [...state.components];
460+
461+
const component = findComponent(
462+
components,
463+
state.canvasFocus.componentId
464+
);
465+
const targetChild = findChild(component, state.canvasFocus.childId);
466+
targetChild.stateUsed = stateUsedObj;
467+
468+
component.code = generateCode(
469+
components,
470+
state.canvasFocus.componentId,
471+
[...state.rootComponents],
472+
state.projectType,
473+
state.HTMLTypes
474+
);
475+
476+
return { ...state, components };
477+
}
478+
454479
case 'UPDATE USE CONTEXT': {
455480
const { useContextObj } = action.payload;
456481

@@ -472,6 +497,7 @@ const reducer = (state: State, action: Action) => {
472497
return {...state, components }
473498

474499
}
500+
475501
case 'UPDATE CSS': {
476502
const { style } = action.payload;
477503
const components = [...state.components];
@@ -493,6 +519,7 @@ const reducer = (state: State, action: Action) => {
493519

494520
return { ...state, components };
495521
}
522+
496523
case 'UPDATE ATTRIBUTES': {
497524
const { attributes } = action.payload;
498525
const components = [...state.components];

0 commit comments

Comments
 (0)