Skip to content

Commit d66a08d

Browse files
authored
Merge pull request #9 from oslabs-beta/ron-william-changes
Fixed delete state, indentation problems, context being replaced, link and switch separators in tree
2 parents f04de67 + 5ede225 commit d66a08d

File tree

7 files changed

+252
-191
lines changed

7 files changed

+252
-191
lines changed

app/src/components/bottom/UseStateModal.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,16 @@ import Modal from '@material-ui/core/Modal';
33
import StateContext from '../../context/context';
44
import TableStateProps from '../right/TableStateProps';
55

6-
76
function UseStateModal({ updateAttributeWithState, attributeToChange, childId }) {
87
const [state, dispatch] = useContext(StateContext);
98
const [open, setOpen] = useState(false);
109
const [displayObject, setDisplayObject] = useState(null)
1110
const [stateKey, setStateKey] = useState('');
1211
const [statePropsId, setStatePropsId] = useState(-1);
12+
const [componentProviderId, setComponentProviderId] = useState(1);
1313

14-
// make buttons to choose which component to get state from
15-
const [componentProviderId, setComponentProviderId] = useState(1) // for now set to App
16-
const components = [];
14+
// make tabs to choose which component to get state from
15+
const componentTabs = [];
1716
for (let i = 0; i < state.components.length; i ++) {
1817
components.push(<button
1918
onClick={() => {
@@ -43,11 +42,12 @@ function UseStateModal({ updateAttributeWithState, attributeToChange, childId })
4342
</div>
4443
<div className="useState-window">
4544
<div className="useState-dropdown">
46-
{components}
45+
{componentTabs}
4746
</div>
4847
<div className="useState-stateDisplay">
4948
<TableStateProps
5049
providerId = {componentProviderId}
50+
canDeleteState = {false}
5151
displayObject = {displayObject}
5252
selectHandler={(table) => {
5353
if (statePropsId < 0) setStatePropsId(table.row.id);
@@ -67,7 +67,6 @@ function UseStateModal({ updateAttributeWithState, attributeToChange, childId })
6767
setOpen(false);
6868
}
6969
}}
70-
deleteHandler={() => func()}
7170
isThemeLight={true}
7271
/>
7372
</div>

app/src/components/right/StatePropsPanel.tsx

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,8 @@ const StatePropsPanel = ({ isThemeLight }): JSX.Element => {
3636
const [inputKey, setInputKey] = useState("");
3737
const [inputValue, setInputValue] = useState("");
3838
const [inputType, setInputType] = useState("");
39-
40-
const [stateProps, setStateProps] = useState([]);
41-
39+
const [errorStatus, setErrorStatus] = useState(false);
40+
const [errorMsg, setErrorMsg] = useState('');
4241
// get currentComponent by using currently focused component's id
4342
const currentId = state.canvasFocus.componentId;
4443
const currentComponent = state.components[currentId - 1];
@@ -67,11 +66,25 @@ const StatePropsPanel = ({ isThemeLight }): JSX.Element => {
6766
setInputValue("");
6867
setInputType("");
6968
};
69+
//reset error warning
70+
const resetError = () => {
71+
setErrorStatus(false);
72+
};
7073

7174
// submit new stateProps entries to state context
75+
let currKey;
7276
const submitNewState = (e) => {
7377
e.preventDefault();
7478
const statesArray = currentComponent.stateProps;
79+
//loop though array, access each obj at key property
80+
let keyToInt = parseInt(inputKey[0]);
81+
if(!isNaN(keyToInt)) {
82+
setErrorStatus(true);
83+
setErrorMsg('Key name can not start with int.');
84+
return;
85+
}
86+
87+
//return alert('key can not start with number');
7588
const newState = {
7689
// check if array is not empty => true find last elem in array. get id and increment by 1 || else 1
7790
id: statesArray.length > 0 ? statesArray[statesArray.length-1].id + 1 : 1,
@@ -83,7 +96,8 @@ const StatePropsPanel = ({ isThemeLight }): JSX.Element => {
8396
dispatch({
8497
type: 'ADD STATE',
8598
payload: {newState: newState}
86-
});
99+
});
100+
resetError();
87101
clearForm();
88102
};
89103

@@ -102,20 +116,7 @@ const StatePropsPanel = ({ isThemeLight }): JSX.Element => {
102116
setInputValue(table.row.value);
103117
} else clearForm();
104118
};
105-
106-
// find & delete table row using its id
107-
const handlerRowDelete = (id:any) => {
108-
// iterate and filter out stateProps with matching row id
109-
const filtered = currentComponent.stateProps.filter(element => element.id !== id);
110-
111-
dispatch({
112-
type: 'DELETE STATE',
113-
payload: {stateProps: filtered}
114-
});
115-
116-
setStateProps(filtered);
117-
};
118-
119+
119120
return (
120121
<div className={'state-panel'}>
121122
<div>
@@ -126,6 +127,7 @@ const StatePropsPanel = ({ isThemeLight }): JSX.Element => {
126127
label="key:"
127128
variant="outlined"
128129
value={inputKey}
130+
error={errorStatus}
129131
onChange={(e) => setInputKey(e.target.value)}
130132
className={isThemeLight ? `${classes.rootLight} ${classes.inputTextLight}` : `${classes.rootDark} ${classes.inputTextDark}`}
131133
/>
@@ -196,7 +198,7 @@ const StatePropsPanel = ({ isThemeLight }): JSX.Element => {
196198
<h4 className={isThemeLight ? classes.lightThemeFontColor : classes.darkThemeFontColor}>
197199
Current State Name: {state.components[state.canvasFocus.componentId - 1].name}
198200
</h4>
199-
<TableStateProps selectHandler={handlerRowSelect} deleteHandler={handlerRowDelete} isThemeLight={isThemeLight} />
201+
<TableStateProps canDeleteState = {true} selectHandler={handlerRowSelect} isThemeLight={isThemeLight} />
200202
</div>
201203
</div>
202204
);

app/src/components/right/TableStateProps.tsx

Lines changed: 88 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -8,72 +8,63 @@ import Button from '@material-ui/core/Button';
88
import ClearIcon from '@material-ui/icons/Clear';
99
import StateContext from '../../context/context';
1010
import { makeStyles } from '@material-ui/core/styles';
11-
1211
import { StatePropsPanelProps } from '../../interfaces/Interfaces';
1312

14-
const getColumns = (props) => {
15-
const { deleteHandler } : StatePropsPanelProps = props;
16-
return [
17-
{
18-
field: 'id',
19-
headerName: 'ID',
20-
width: 70,
21-
editable: false,
22-
},
23-
{
24-
field: 'key',
25-
headerName: 'Key',
26-
width: 90,
27-
editable: true,
28-
},
29-
{
30-
field: 'value',
31-
headerName: 'Value',
32-
width: 90,
33-
editable: true,
34-
},
35-
{
36-
field: 'type',
37-
headerName: 'Type',
38-
width: 90,
39-
editable: false,
40-
},
41-
{
42-
field: 'delete',
43-
headerName: 'X',
44-
width: 70,
45-
editable: false,
46-
renderCell: function renderCell(params:any) {
47-
const getIdRow = () => {
48-
const { api } = params;
49-
return params.id;
50-
51-
// return params.getValue(fields[0]);
52-
};
53-
return (
54-
<Button style={{width:`${3}px`}}
55-
onClick={() => {
56-
deleteHandler(getIdRow());
57-
}}>
58-
<ClearIcon style={{width:`${15}px`}}/>
59-
</Button>
60-
);
61-
},
62-
},
63-
];
64-
};
65-
6613
const TableStateProps = (props) => {
14+
const [state, dispatch] = useContext(StateContext);
6715
const classes = useStyles();
68-
const [state] = useContext(StateContext);
6916
const [editRowsModel] = useState <GridEditRowsModel> ({});
7017
const [gridColumns, setGridColumns] = useState([]);
7118

19+
const [rows, setRows] = useState([]);
20+
21+
const columnTabs = [
22+
{
23+
field: 'id',
24+
headerName: 'ID',
25+
width: 70,
26+
editable: false,
27+
},
28+
{
29+
field: 'key',
30+
headerName: 'Key',
31+
width: 90,
32+
editable: true,
33+
},
34+
{
35+
field: 'value',
36+
headerName: 'Value',
37+
width: 90,
38+
editable: true,
39+
},
40+
{
41+
field: 'type',
42+
headerName: 'Type',
43+
width: 90,
44+
editable: false,
45+
},
46+
{
47+
field: 'delete',
48+
headerName: 'X',
49+
width: 70,
50+
editable: false,
51+
renderCell: function renderCell(params:any) {
52+
return (
53+
<Button style={{width:`${3}px`}} onClick={() => {
54+
deleteState(params.id)
55+
}}>
56+
<ClearIcon style={{width:`${15}px`}}/>
57+
</Button>
58+
);
59+
},
60+
},
61+
];
62+
7263

73-
useEffect(() => {
74-
setGridColumns(getColumns(props));
75-
}, [props.isThemeLight])
76-
// get currentComponent by using currently focused component's id
64+
const deleteState = (selectedId) => {
65+
// get the current focused component
66+
// remove the state that the button is clicked
67+
// send a dispatch to rerender the table
7768
const currentId = state.canvasFocus.componentId;
7869
const currentComponent = state.components[currentId - 1];
7970

@@ -97,13 +88,48 @@ const TableStateProps = (props) => {
9788
}
9889
}
9990

91+
const filtered = currentComponent.stateProps.filter(element => element.id !== selectedId);
92+
dispatch({
93+
type: 'DELETE STATE',
94+
payload: {stateProps: filtered, rowId: selectedId}
95+
});
96+
}
97+
98+
99+
useEffect(() => {
100+
setGridColumns(columnTabs);
101+
}, [props.isThemeLight])
102+
103+
100104
const { selectHandler } : StatePropsPanelProps = props;
101105

102-
// when component gets mounted, sets the gridColumn
106+
107+
// the delete button needs to be updated to remove
108+
// the states from the current focused component
103109
useEffect(() => {
104-
setGridColumns(getColumns(props));
105-
}, []);
110+
if(props.canDeleteState) {
111+
setGridColumns(columnTabs);
112+
}
113+
else {
114+
setGridColumns(columnTabs.slice(0, gridColumns.length - 1));
115+
}
116+
}, [state.canvasFocus.componentId]);
106117

118+
// when we switch between tabs in our modal or focus of our current
119+
// component, we need to update the states displayed in our table
120+
// we also need to update the table when the state is changed by
121+
// deleting and adding component state
122+
useEffect(() => {
123+
if (!props.providerId) {
124+
const currentId = state.canvasFocus.componentId;
125+
const currentComponent = state.components[currentId - 1];
126+
setRows(currentComponent.stateProps.slice());
127+
} else {
128+
const providerComponent = state.components[props.providerId - 1];
129+
setRows(providerComponent.stateProps.slice());
130+
}
131+
}, [props.providerId, state]);
132+
107133
return (
108134
<div className={'state-prop-grid'}>
109135
<DataGrid
@@ -119,6 +145,7 @@ const TableStateProps = (props) => {
119145
};
120146

121147

148+
122149
const useStyles = makeStyles({
123150
themeLight: {
124151
color: 'rgba(0,0,0,0.54)',

app/src/containers/CustomizationPanel.tsx

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -207,34 +207,52 @@ const CustomizationPanel = ({ isThemeLight }): JSX.Element => {
207207
};
208208

209209
// 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+
210229
const updateAttributeWithState = (attributeName, componentProviderId, statePropsId, statePropsRow, stateKey='') => {
211230
const newInput = statePropsRow.value;
212231

213232
if (attributeName === 'compText') {
214-
const newContextObj = useContextObj;
215-
if (!newContextObj[componentProviderId]) {
216-
newContextObj[componentProviderId] = {};
217-
}
218233
newContextObj[componentProviderId].compText = statePropsId;
219-
220234
// update/create stateUsed.compText
221235
setStateUsedObj(Object.assign(stateUsedObj, {compText: stateKey}));
222236
setCompText(newInput);
223-
setUseContextObj(newContextObj);
237+
dispatch({
238+
type: 'UPDATE USE CONTEXT',
239+
payload: { useContextObj: newContextObj}
240+
});
241+
// setUseContextObj(newContextObj);
224242
}
243+
225244
if (attributeName === 'compLink') {
226-
const newContextObj = useContextObj;
227-
if (!newContextObj[componentProviderId]) {
228-
newContextObj[componentProviderId] = {};
229-
}
230-
newContextObj[componentProviderId].compLink = statePropsId;
245+
newContextObj[componentProviderId].compLink = statePropsId;
231246

232247
// update/create stateUsed.compLink
233248
setStateUsedObj(Object.assign(stateUsedObj, {compLink: stateKey}));
234249
setCompLink(newInput);
235-
setUseContextObj(newContextObj);
250+
dispatch({
251+
type: 'UPDATE USE CONTEXT',
252+
payload: { useContextObj: newContextObj}
253+
});
254+
// setUseContextObj(newContextObj);
236255
}
237-
238256
}
239257

240258
const handleSave = (): Object => {
@@ -257,10 +275,11 @@ const CustomizationPanel = ({ isThemeLight }): JSX.Element => {
257275
payload: {stateUsedObj: stateUsedObj}
258276
})
259277

260-
dispatch({
261-
type: 'UPDATE USE CONTEXT',
262-
payload: { useContextObj: useContextObj}
263-
})
278+
// console.log("useContextObj to be dispatched", useContextObj);
279+
// dispatch({
280+
// type: 'UPDATE USE CONTEXT',
281+
// payload: { useContextObj: useContextObj}
282+
// })
264283

265284
dispatch({
266285
type: 'UPDATE CSS',

0 commit comments

Comments
 (0)