Skip to content

Commit 092d6d3

Browse files
authored
Merge pull request #10 from oslabs-beta/final-bugs-fix
Final Merge, fixed delete bugs and state being replaced.
2 parents 61c34b6 + ae9f463 commit 092d6d3

File tree

10 files changed

+115
-127
lines changed

10 files changed

+115
-127
lines changed

README.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Download for [MacOS](https://github.com/team-reactype/ReacType/releases), [Windo
2424

2525
### How to use
2626

27-
- **Sign-in page**: Sign up for an account, sign in via Github, or just continue as a guest. Registered users enjoy additional project-saving functionality.
27+
- **Sign-in page**: Sign up for an account or just continue as a guest. Registered users enjoy additional project-saving functionality.
2828
- **Tutorial**: Click ‘Tutorial’ from the Help tab’s dropdown menu (at the top left of the application) to view a tutorial.
2929
- **Start a project (only after registration)**: Registered users can create a new project and select whether they want their project to be a Next.js, Gatsby.js, or classic React project. Also, registered users can save projects to return to them at a later time.
3030
- **Add Components**: Create components on the right panel. Components can be associated with a route, or they can be used within other components.
@@ -34,6 +34,7 @@ Download for [MacOS](https://github.com/team-reactype/ReacType/releases), [Windo
3434
- **Create Instances on the Canvas**: Each component has its own canvas. Add an element to a component by dragging it onto the canvas. Div components are arbitrarily nestable and useful for complex layouts. Next.js and Gatsby.js projects have Link components to enable client-side navigation to other routes.
3535
- **Component Tree**: Click on the Component Tree tab next to the Code Preview tab to view the component tree hierarchy.
3636
- **Update Styling**: Select an element on the canvas to update its basic style attributes on the right panel. As you create new instances and add styling, watch as your code dynamically generates in the code preview in the bottom panel.
37+
- **Using State in Elements**: As of 9.0.0, you can now select an HTML element on the canvas and then navigate to the customization panel to click a button to pass a variable from state into your element's text or link field.
3738
- **User Preference Features**: With the click of a button, toggle between light mode and dark mode, depending on your preference.
3839
- **Export project**: Click the “Export Project’ button to export the project’s application files into a TypeScript file. The exported project is fully functional with Webpack, Express server, routing, etc., and will match what is mocked on the canvas.
3940
- **Export project with Tests**: Click the "includes tests" checkbox while exporting to include pre-configured Webpack, Jest, and Typescript files along with tests for your project.
@@ -43,11 +44,17 @@ Download for [MacOS](https://github.com/team-reactype/ReacType/releases), [Windo
4344
- Modernized and cleaner UI, including enhanced dark mode
4445
- Tutorial has been updated to reflect other modifications
4546

46-
**New with version 8.0.0:**
47+
**New with version 9.0.0:**
4748

4849
![CSSEditor](https://raw.githubusercontent.com/open-source-labs/ReacType/master/resources/export_tests_images/export-new.gif)
4950

50-
### Features
51+
### 9.0.0 New Features
52+
- **React Router**: Drag-and-drop LinkTo and Router elements (located below the HTML elements list) to implement fully-functional React Router components into your application to dynamically and quickly render components in the live demo render and in your exported application.
53+
- **Global State Management**: For the first time in ReacType history, users can utilize
54+
- **Composite Data Structures in State**: State creation in ReacType can now handle composite data types, which includes arrays, objects, and any amount of nesting of composite data types within other composite data types (i.e. arrays of objects and objects with objects as values).
55+
- **Additional Improvements with Local State Management**:
56+
- **Annotations**:
57+
5158

5259
- **OAuth via Github**: Sign up with your github accounts.
5360
- **Live Render Demo**: Live render demo in React using Electron's sandbox environment. Updates in realtime to reflect canvas structure and customization options.
@@ -115,7 +122,7 @@ Download for [MacOS](https://github.com/team-reactype/ReacType/releases), [Windo
115122

116123
[Christian Padilla](https://linkedin.com/in/ChristianEdwardPadilla) [@ChristianEdwardPadilla](https://github.com/ChristianEdwardPadilla)
117124

118-
[Crys Lim] (https://linkedin.com/in/crystallim) [@crlim](https://github.com/crlim)
125+
[Crystal Lim] (https://linkedin.com/in/crystallim) [@crlim](https://github.com/crlim)
119126

120127
[Danial Reilley](https://linkedin.com/in/daniel-reilley)
121128
[@dreille](https://github.com/dreille)

app/electron/main.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ async function createWindow() {
7373
webPreferences: {
7474
zoomFactor: 0.7,
7575
// enable devtools when in development mode
76-
devTools: isDev,
76+
devTools: true,
7777
// crucial security feature - blocks rendering process from having access to node modules
7878
nodeIntegration: false,
7979
// web workers will not have access to node

app/src/components/bottom/UseStateModal.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,19 @@ function UseStateModal({ updateAttributeWithState, attributeToChange, childId })
5050
canDeleteState = {false}
5151
displayObject = {displayObject}
5252
selectHandler={(table) => {
53-
if (statePropsId < 0) setStatePropsId(table.row.id);
5453
// if object or array => show sub table
5554
if (table.row.type === "object") {
55+
if (statePropsId < 0) setStatePropsId(table.row.id);
5656
setStateKey(stateKey + table.row.key + '.');
5757
setDisplayObject(table.row.value);
5858
} else if (table.row.type === "array") {
59+
if (statePropsId < 0) setStatePropsId(table.row.id);
5960
setStateKey(stateKey + table.row.key)
6061
setDisplayObject(table.row.value);
6162
} else {
6263
// if not object or array => update state
6364
setDisplayObject(null);
64-
updateAttributeWithState(attributeToChange, componentProviderId, statePropsId, table.row, stateKey + table.row.key);
65+
updateAttributeWithState(attributeToChange, componentProviderId, statePropsId > 0 ? statePropsId : table.row.id, table.row, stateKey + table.row.key);
6566
setStateKey('')
6667
setStatePropsId(-1);
6768
setOpen(false);

app/src/components/right/TableStateProps.tsx

Lines changed: 5 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -95,43 +95,11 @@ const TableStateProps = props => {
9595
}
9696
}, [state.canvasFocus.componentId]);
9797

98-
// when we switch between tabs in our modal or focus of our current
99-
// component, we need to update the states displayed in our table
100-
// we also need to update the table when the state is changed by
101-
// deleting and adding component state
102-
// useEffect(() => {
103-
// // rows to show are either from current component or from a given provider
104-
// let rows = [];
105-
// if (!props.providerId) {
106-
// const currentId = state.canvasFocus.componentId;
107-
// const currentComponent = state.components[currentId - 1];
108-
// rows = currentComponent.stateProps.slice();
109-
// } else {
110-
// const providerComponent = state.components[props.providerId - 1];
111-
// // changed to get whole object
112-
// if (props.displayObject) {
113-
// const displayObject = props.displayObject;
114-
// // format for DataGrid
115-
// let id = 1;
116-
// for (const key in displayObject) {
117-
// // if key is a number make it a string with brackets aroung number
118-
// rows.push({
119-
// id: id++,
120-
// key: isNaN(key) ? key : '[' + key + ']',
121-
// value: displayObject[key],
122-
// type: typeof displayObject[key]
123-
// });
124-
// }
125-
// } else {
126-
// rows = providerComponent.stateProps.slice();
127-
// }
128-
// }
129-
// }, [props.providerId, state]);
13098

13199
// rows to show are either from current component or from a given provider
132100
let rows = [];
133101
if (!props.providerId) {
134-
const currentId = state.canvasFocus.componentId;
102+
const currentId = state.canvasFocus.componentId;
135103
const currentComponent = state.components[currentId - 1];
136104
rows = currentComponent.stateProps.slice();
137105
} else {
@@ -143,15 +111,16 @@ const TableStateProps = props => {
143111
let id=1;
144112
for (const key in displayObject) {
145113
// if key is a number make it a string with brackets aroung number
146-
rows.push({ id: id++, key: ( isNaN(key) ? key : '[' + key + ']' ), value: displayObject[key], type: typeof(displayObject[key])});
114+
const newKey = isNaN(key) ? key : '[' + key + ']';
115+
const type = Array.isArray(displayObject[key]) ? 'array' : typeof (displayObject[key]);
116+
rows.push({ id: id++, key: newKey, value: displayObject[key], type: type});
147117
}
148118
} else {
149-
rows = providerComponent.stateProps.slice();
119+
rows = providerComponent.stateProps.slice();
150120
}
151121
}
152122

153123

154-
155124
return (
156125
<div className={'state-prop-grid'}>
157126
<DataGrid

app/src/containers/CustomizationPanel.tsx

Lines changed: 15 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ const CustomizationPanel = ({ isThemeLight }): JSX.Element => {
5353
const [useContextObj, setUseContextObj] = useState({});
5454
const [stateUsedObj, setStateUsedObj] = useState({});
5555

56+
5657
const resetFields = () => {
5758
const childrenArray = state.components[0].children;
5859
let attributes;
@@ -206,70 +207,39 @@ const CustomizationPanel = ({ isThemeLight }): JSX.Element => {
206207
return isLinked;
207208
};
208209

209-
// function to pass into UseStateModal to use state to update attribute
210-
// const updateAttributeWithState = (attributeName, componentProviderId, statePropsId) => {
211-
// // get the stateProps of the componentProvider
212-
// const currentComponent = state.components[state.canvasFocus.componentId - 1];
213-
// const providerComponent = state.components[componentProviderId - 1];
214-
// const providerStates = providerComponent.stateProps;
215-
// const newInput = providerStates[statePropsId - 1].value;
216-
// let newContextObj = {...currentComponent.useContext};
217-
218-
// if(!newContextObj) {
219-
// newContextObj = {};
220-
// }
221-
222-
// if (!newContextObj[componentProviderId]) {
223-
// newContextObj[componentProviderId] = {statesFromProvider : new Set()};
224-
// }
225-
226-
// newContextObj[componentProviderId].statesFromProvider.add(statePropsId);
227-
// }
228-
210+
229211
const updateAttributeWithState = (attributeName, componentProviderId, statePropsId, statePropsRow, stateKey='') => {
230212
const newInput = statePropsRow.value;
231-
213+
232214
// get the stateProps of the componentProvider
233215
const currentComponent = state.components[state.canvasFocus.componentId - 1];
234-
const providerComponent = state.components[componentProviderId - 1];
235-
const providerStates = providerComponent.stateProps;
236-
let newContextObj = {...currentComponent.useContext};
216+
let newContextObj = {...currentComponent.useContext};
237217

238218
if(!newContextObj) {
239-
newContextObj = {};
219+
newContextObj = {};
240220
}
241221

242222
if (!newContextObj[componentProviderId]) {
243223
newContextObj[componentProviderId] = {statesFromProvider : new Set()};
244224
}
245225

246-
newContextObj[componentProviderId].statesFromProvider.add(statePropsId);
247-
248-
226+
newContextObj[componentProviderId].statesFromProvider.add(statePropsId);
249227

250228
if (attributeName === 'compText') {
251229
newContextObj[componentProviderId].compText = statePropsId;
252230
// update/create stateUsed.compText
253-
setStateUsedObj(Object.assign(stateUsedObj, {compText: stateKey}));
231+
setStateUsedObj({...stateUsedObj, compText: stateKey, compTextProviderId: componentProviderId, compTextPropsId: statePropsId});
254232
setCompText(newInput);
255-
dispatch({
256-
type: 'UPDATE USE CONTEXT',
257-
payload: { useContextObj: newContextObj}
258-
});
259-
// setUseContextObj(newContextObj);
233+
setUseContextObj(newContextObj);
260234
}
261235

262236
if (attributeName === 'compLink') {
263-
newContextObj[componentProviderId].compLink = statePropsId;
237+
newContextObj[componentProviderId].compLink = statePropsId;
264238

265239
// update/create stateUsed.compLink
266-
setStateUsedObj(Object.assign(stateUsedObj, {compLink: stateKey}));
240+
setStateUsedObj({...stateUsedObj, compLink: stateKey, compLinkProviderId: componentProviderId, compLinkPropsId: statePropsId});
267241
setCompLink(newInput);
268-
dispatch({
269-
type: 'UPDATE USE CONTEXT',
270-
payload: { useContextObj: newContextObj}
271-
});
272-
// setUseContextObj(newContextObj);
242+
setUseContextObj(newContextObj);
273243
}
274244
}
275245

@@ -293,11 +263,10 @@ const CustomizationPanel = ({ isThemeLight }): JSX.Element => {
293263
payload: {stateUsedObj: stateUsedObj}
294264
})
295265

296-
// console.log("useContextObj to be dispatched", useContextObj);
297-
// dispatch({
298-
// type: 'UPDATE USE CONTEXT',
299-
// payload: { useContextObj: useContextObj}
300-
// })
266+
dispatch({
267+
type: 'UPDATE USE CONTEXT',
268+
payload: { useContextObj: useContextObj}
269+
})
301270

302271
dispatch({
303272
type: 'UPDATE CSS',

app/src/helperFunctions/generateCode.ts

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ const generateUnformattedCode = (
109109
let styleString;
110110
for (let i in styleObj) {
111111
if(i === 'style') {
112-
styleString = i + ':' + JSON.stringify(styleObj[i]);
112+
styleString = i + '=' + '{' + JSON.stringify(styleObj[i]) + '}';
113113
formattedStyles.push(styleString);
114114
}
115115
}
@@ -143,7 +143,7 @@ const generateUnformattedCode = (
143143
// function to dynamically generate a complete html (& also other library type) elements
144144
const elementGenerator = (childElement: object, level: number = 2) => {
145145
let innerText = '';
146-
let activeLink = '';
146+
let activeLink = '""';
147147

148148
if (childElement.attributes && childElement.attributes.compText) {
149149
if (childElement.stateUsed && childElement.stateUsed.compText) {
@@ -253,14 +253,15 @@ const generateUnformattedCode = (
253253

254254
return state;
255255
}
256-
256+
257+
// Generate import
257258
let importContext = '';
258259
if(currComponent.useContext) {
259-
for (const providerId of Object.keys(currComponent.useContext)) {
260-
const providerComponent = components[parseInt(providerId) - 1];
261-
importContext += `import ${providerComponent.name}Context from './${providerComponent.name}.tsx'\n \t\t` ;
260+
for (const providerId of Object.keys(currComponent.useContext)) {
261+
const providerComponent = components[parseInt(providerId) - 1];
262+
importContext += `import ${providerComponent.name}Context from './${providerComponent.name}.tsx'\n \t\t` ;
263+
}
262264
}
263-
}
264265

265266
if (currComponent.useContext) {
266267
for (const providerId of Object.keys(currComponent.useContext)) {
@@ -271,20 +272,9 @@ const generateUnformattedCode = (
271272
for (let i = 0; i < providerComponent.stateProps.length; i++) {
272273
if(statesFromProvider.has(providerComponent.stateProps[i].id)) {
273274
context +=
274-
275-
// if (currComponent.useContext) {
276-
277-
// for (const providerId of Object.keys(currComponent.useContext)) {
278-
// const attributesAndStateIds = currComponent.useContext[String(providerId)]; //currently just from App
279-
// const providerComponent = components[providerId - 1];
280-
// providers += 'const ' + providerComponent.name.toLowerCase() + 'Context = useContext(' + providerComponent.name + 'Context);\n';
281-
282-
// for (const stateId of Object.values(attributesAndStateIds)) {
283-
// context +=
284-
285275
'const ' +
286276
providerComponent.stateProps[i].key +
287-
'Value = ' +
277+
' = ' +
288278
providerComponent.name.toLowerCase() +
289279
'Context.' +
290280
providerComponent.stateProps[i].key +
@@ -310,22 +300,22 @@ const generateUnformattedCode = (
310300
? ` const ${currComponent.name}Context = createContext(${createState(currComponent.stateProps)});`
311301
: ``
312302
}
313-
${!importReactRouter
303+
${!importReactRouter
314304
? ` return (
315305
<${currComponent.name}Context.Provider value="">
316306
<div className="${currComponent.name}" ${formatStyles(currComponent)}>
317307
\t${writeNestedElements(enrichedChildren)}
318308
</div>
319-
</${currComponent.name}Context.Provider>
320-
);`
309+
</${currComponent.name}Context.Provider>
310+
);`
321311
: ` return (
322312
<${currComponent.name}Context.Provider value="">
323313
<Router>
324314
<div className="${currComponent.name}" ${formatStyles(currComponent)}>
325315
\t${writeNestedElements(enrichedChildren)}
326316
</div>
327317
</Router>
328-
</${currComponent.name}Context.Provider>
318+
</${currComponent.name}Context.Provider>
329319
);`}
330320
${`}\n`}
331321
export default ${currComponent.name};

app/src/helperFunctions/localStorage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
// };
77
// export const loadState = () =>
88
// localforage.getItem('state-v1.0.1').then(value => {
9-
// // console.log('The value stored in local storage: ', value);
9+
// // ('The value stored in local storage: ', value);
1010
// });

0 commit comments

Comments
 (0)