Skip to content

Commit ac24d84

Browse files
authored
Merge pull request #7 from oslabs-beta/rwc2
Merging RWC2 Branch to Dev-46
2 parents 949030c + 5ea14ce commit ac24d84

File tree

7 files changed

+137
-32
lines changed

7 files changed

+137
-32
lines changed

app/src/components/bottom/UseStateModal.tsx

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,41 +5,39 @@ import TableStateProps from '../right/TableStateProps';
55

66
// TODO: typescript interface or type check
77
function UseStateModal({ updateAttributeWithState, attributeToChange, childId }) {
8+
const [state, dispatch] = useContext(StateContext);
89
const [open, setOpen] = useState(false);
910

10-
// TODO: choose state source
11-
const componentProviderId = 1; // for now set to App
12-
13-
// selectHandler function to pass into TableStateProps
14-
// get id of selected component
15-
// access the ChildElement
11+
// make buttons to choose which component to get state from
12+
const [componentProviderId, setComponentProviderId] = useState(1) // for now set to App
13+
const components = [];
14+
for (let i = 0; i < state.components.length; i ++) {
15+
components.push(<button onClick={() => setComponentProviderId(i+1)}>{state.components[i].name}</button>)
16+
}
1617

1718
// return the selected state's ID back so the value of it can be updated in the customizationpanel. to the assign the value of selected state to attribute tied to useState button (currently just text)
18-
// attribute to change as parameter for UseStateModal
19+
// attribute to change as parameter for
1920
const body = (
2021
<div className="useState-position">
2122
<div className="useState-header">
2223
<span>Choose State Source</span>
2324
<button
24-
style={{ padding: '1px', float: 'right' }}
25+
style={{ margin: '5px 5px' ,padding: '1px', float: 'right' }}
2526
onClick={() => setOpen(false)}
2627
>
2728
X
2829
</button>
2930
</div>
3031
<div className="useState-window">
3132
<div className="useState-dropdown">
32-
<button>Choose Stateful Component</button>
33-
<div>
34-
<a href="#">component 1</a>
35-
<a href="#">component 2</a>
36-
</div>
33+
{components}
3734
</div>
3835
<div className="useState-stateDisplay">
3936
<TableStateProps
37+
providerId = {componentProviderId}
4038
selectHandler={(table) => {
41-
console.log('table.row.id',table.row.id);
42-
updateAttributeWithState(attributeToChange, componentProviderId, table.row.id)
39+
updateAttributeWithState(attributeToChange, componentProviderId, table.row.id);
40+
setOpen(false);
4341
}}
4442
deleteHandler={() => func()}
4543
isThemeLight={true}
@@ -51,7 +49,7 @@ function UseStateModal({ updateAttributeWithState, attributeToChange, childId })
5149

5250
return (
5351
<div>
54-
<button onClick={() => setOpen(true)}>Use State</button>
52+
<button className="useState-btn" onClick={() => setOpen(true)}>USE STATE</button>
5553
<Modal open={open}>{body}</Modal>
5654
</div>
5755
);

app/src/components/right/TableStateProps.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ const getColumns = (props) => {
6666
];
6767
};
6868

69+
//, providerId=1
6970
const TableStateProps = (props) => {
7071
const classes = useStyles();
7172
const [state] = useContext(StateContext);
@@ -80,7 +81,14 @@ const TableStateProps = (props) => {
8081
const currentId = state.canvasFocus.componentId;
8182
const currentComponent = state.components[currentId - 1];
8283

83-
const rows = currentComponent.stateProps.slice();
84+
// rows to show are either from current component or from a given provider
85+
let rows = [];
86+
if (!props.providerId) {
87+
rows = currentComponent.stateProps.slice();
88+
} else {
89+
const providerComponent = state.components[props.providerId - 1];
90+
rows = providerComponent.stateProps.slice();
91+
}
8492

8593
const { selectHandler } : StatePropsPanelProps = props;
8694

app/src/containers/CustomizationPanel.tsx

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ const CustomizationPanel = ({ isThemeLight }): JSX.Element => {
5050
const [deleteComponentError, setDeleteComponentError] = useState(false);
5151
const { style } = useContext(styleContext);
5252
const [modal, setModal] = useState(null);
53+
const [useContextObj, setUseContextObj] = useState({});
5354

5455
const resetFields = () => {
5556
const childrenArray = state.components[0].children;
@@ -212,12 +213,32 @@ const CustomizationPanel = ({ isThemeLight }): JSX.Element => {
212213
const currentComponentProps = currentComponent.stateProps;
213214
const newInput = currentComponentProps[statePropsId - 1].value;
214215

215-
if (attributeName === 'compText') setCompText(newInput);
216-
if (attributeName === 'compLink') setCompLink(newInput);
216+
if (attributeName === 'compText') {
217+
const newContextObj = useContextObj;
218+
if (!newContextObj[componentProviderId]) {
219+
newContextObj[componentProviderId] = {};
220+
}
221+
newContextObj[componentProviderId].compText = statePropsId;
222+
223+
setCompText(newInput);
224+
setUseContextObj(newContextObj);
225+
}
226+
if (attributeName === 'compLink') {
227+
const newContextObj = useContextObj;
228+
if (!newContextObj[componentProviderId]) {
229+
newContextObj[componentProviderId] = {};
230+
}
231+
newContextObj[componentProviderId].compLink = statePropsId;
232+
233+
setCompLink(newInput);
234+
setUseContextObj(newContextObj);
235+
}
217236

218237
// TODO: set something to signify that state was used
219238
// so it can be handled in generateCode
220239

240+
// update use context object
241+
221242
}
222243

223244
// dispatch to 'UPDATE CSS' called when save button is clicked,
@@ -237,6 +258,15 @@ const CustomizationPanel = ({ isThemeLight }): JSX.Element => {
237258
if (compLink !== '') attributesObj.compLink = compLink;
238259
if (cssClasses !== '') attributesObj.cssClasses = cssClasses;
239260

261+
// dispatch to update useContext
262+
// type: 'UPDATE USE CONTEXT'
263+
// payload: useContext object
264+
265+
dispatch({
266+
type: 'UPDATE USE CONTEXT',
267+
payload: { useContextObj: useContextObj}
268+
})
269+
240270
dispatch({
241271
type: 'UPDATE CSS',
242272
payload: { style: styleObj }

app/src/helperFunctions/generateCode.ts

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ const generateUnformattedCode = (
2626
const currentComponent = components.find(elem => elem.id === componentId);
2727
// find the unique components that we need to import into this component file
2828
let imports: any = [];
29+
let providers: string = '';
30+
let context: string = '';
2931
let links: boolean = false;
3032

3133
const isRoot = rootComponents.includes(componentId);
@@ -47,14 +49,14 @@ const generateUnformattedCode = (
4749
// check if imports array include the referenced component, if not, add its name to the imports array (e.g. the name/tag of the component/element)
4850
if (!imports.includes(referencedComponent.name))
4951
imports.push(referencedComponent.name);
50-
child['name'] = referencedComponent.name;
51-
return child;
52+
child['name'] = referencedComponent.name;
53+
return child;
5254
} else if (child.type === 'HTML Element') {
5355
const referencedHTML = HTMLTypes.find(elem => elem.id === child.typeId);
5456
child['tag'] = referencedHTML.tag;
5557
if (
5658
referencedHTML.tag === 'div' ||
57-
referencedHTML.tag === 'separator' ||
59+
referencedHTML.tag === 'separator' ||
5860
referencedHTML.tag === 'form' ||
5961
referencedHTML.tag === 'ul' ||
6062
referencedHTML.tag === 'ol' ||
@@ -67,15 +69,16 @@ const generateUnformattedCode = (
6769
child.children = getEnrichedChildren(child);
6870
}
6971
// when we see a Switch or LinkTo, import React Router
70-
if (referencedHTML.tag === 'Switch' || referencedHTML.tag === 'LinkTo') importReactRouter = true;
72+
if (referencedHTML.tag === 'Switch' || referencedHTML.tag === 'LinkTo')
73+
importReactRouter = true;
7174
return child;
7275
} else if (child.type === 'Route Link') {
7376
links = true;
7477
child.name = components.find(
7578
(comp: Component) => comp.id === child.typeId
76-
).name;
77-
return child;
78-
}
79+
).name;
80+
return child;
81+
}
7982
});
8083
return enrichedChildren;
8184
};
@@ -225,7 +228,26 @@ const generateUnformattedCode = (
225228

226229
return state;
227230
}
228-
231+
// check for context
232+
if (currentComponent.useContext) {
233+
234+
for (const providerId of Object.keys(currentComponent.useContext)) {
235+
const attributesAndStateIds = currentComponent.useContext[String(providerId)]; //currently just from App
236+
const providerComponent = components[providerId - 1];
237+
providers += 'const ' + providerComponent.name.toLowerCase() + 'Context = useContext(' + providerComponent.name + 'Context);\n';
238+
239+
for (const stateId of Object.values(attributesAndStateIds)) {
240+
context +=
241+
'const ' +
242+
providerComponent.stateProps[stateId - 1].key +
243+
' = ' +
244+
providerComponent.name.toLowerCase() +
245+
'Context.' +
246+
providerComponent.stateProps[stateId - 1].key +
247+
';\n';
248+
}
249+
}
250+
}
229251

230252
// create final component code. component code differs between classic react, next.js, gatsby.js
231253
// classic react code
@@ -236,6 +258,8 @@ const generateUnformattedCode = (
236258
${classBased ? `import React, { Component } from 'react';` : ''}
237259
${!stateful && !classBased ? `import React, { createContext, useContext } from 'react';` : ''}
238260
${importsMapped}
261+
${providers}
262+
${context}
239263
${
240264
classBased
241265
? `class ${currentComponent.name} extends Component {`

app/src/interfaces/Interfaces.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ export interface Component {
3939
stateProps: StateProp[]; // state: [ { id, key, value, type }, ...]
4040
annotations?: string;
4141
useStateCodes: string[];
42+
useContext?: object // structure --> {providerId: {attribute: stateId, ....}, ...}
43+
// example:
44+
// {1: {compText: 1, compLink: 2}}
45+
// {1: {compText: 1}, 2: {compLink: 1}, ....}
4246
}
4347

4448
export interface StateProp {

app/src/public/styles/style.css

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -609,16 +609,30 @@ a.nav_link:hover {
609609
z-index: 999;
610610
}
611611

612+
.useState-btn {
613+
color: rgb(241, 240, 240);
614+
background-color: #0099E6;
615+
font-family: Arial, Helvetica, sans-serif;
616+
}
617+
618+
.useState-btn {
619+
color: rgb(241, 240, 240);
620+
background-color: #0099E6;
621+
border: 1px solid #186BB4;
622+
border-radius: 3;
623+
box-shadow: "0 0px 0px 2px #1a1a1a";
624+
padding: 2px 2px 2px 2px;
625+
}
626+
612627
/* UseStateModal Styling */
613628

614629
.useState-position {
615630
display: flex;
616631
flex-direction: column;
617632
position: fixed;
618-
align-items:flex-start;
633+
align-items: center;
619634
top: 30%;
620635
left: 30%;
621-
622636
}
623637

624638
.useState-header {
@@ -633,16 +647,23 @@ a.nav_link:hover {
633647
border-radius: 15px 15px 0px 0px;
634648
}
635649

650+
.useState-dropdown {
651+
align-self: flex-start;
652+
}
653+
636654
.useState-window {
637655
width: 600px;
638-
height: 300px;
656+
height: 400px;
639657
resize: none;
640658
white-space: pre-line;
641659
font-size: 18px;
642-
border: 3px;
660+
border: 2px;
643661
border-style: solid;
644662
border-color: black;
645663
border-radius: 0px 0px 15px 15px;
646664
font-family: Arial, Helvetica, sans-serif;
647-
background-color: rgb(241, 240, 240);;
665+
background-color: rgb(241, 240, 240);
666+
display: flex;
667+
flex-direction: column;
668+
align-items: center;
648669
}

app/src/reducers/componentReducer.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,27 @@ const reducer = (state: State, action: Action) => {
450450
}
451451
return { ...state };
452452
}
453+
case 'UPDATE USE CONTEXT': {
454+
const { useContextObj } = action.payload;
453455

456+
const components = [...state.components];
457+
const component = findComponent(
458+
components,
459+
state.canvasFocus.componentId
460+
);
461+
component.useContext = useContextObj;
462+
463+
component.code = generateCode(
464+
components,
465+
state.canvasFocus.componentId,
466+
[...state.rootComponents],
467+
state.projectType,
468+
state.HTMLTypes
469+
);
470+
471+
return {...state, components }
472+
473+
}
454474
case 'UPDATE CSS': {
455475
const { style } = action.payload;
456476
const components = [...state.components];

0 commit comments

Comments
 (0)