Skip to content

Commit 7eff29d

Browse files
authored
Merge pull request #31 from oslabs-beta/context-ui
Context UI
2 parents 7da192e + e9b0dee commit 7eff29d

File tree

11 files changed

+151
-123
lines changed

11 files changed

+151
-123
lines changed

__tests__/BottomTabs.test.tsx

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,15 +122,24 @@ describe('Creation Panel', () => {
122122
});
123123

124124
describe('Context Manager', () => {
125-
test('Create/Edit Tab should contain all buttons and input fields', () => {
125+
test('should render Create/Edit, Assign, and Display tabs', () => {
126126
render(
127127
<Provider store={store}>
128128
<ContextManager />
129129
</Provider>
130130
);
131-
expect(screen.getAllByRole('textbox')).toHaveLength(2);
132-
expect(screen.getAllByRole('button')).toHaveLength(3);
131+
expect(screen.getAllByRole('tab')).toHaveLength(3);
132+
});
133+
test('Create/Edit Tab should contain all buttons, inputs field, and a data table', () => {
134+
render(
135+
<Provider store={store}>
136+
<ContextManager />
137+
</Provider>
138+
);
139+
expect(screen.getAllByRole('textbox')).toHaveLength(3);
140+
expect(screen.getAllByRole('button')).toHaveLength(4);
133141
expect(screen.getByText('Context Name')).toBeInTheDocument();
142+
expect(screen.getByRole('table')).toBeInTheDocument();
134143
});
135144
test('Assign Tab should contain all buttons and input fields', () => {
136145
render(
@@ -141,6 +150,11 @@ describe('Context Manager', () => {
141150

142151
fireEvent.click(screen.getByText('Assign'));
143152
expect(screen.getByText('Contexts Consumed')).toBeInTheDocument();
153+
const dropdown = screen.getByLabelText('Select Component');
154+
expect(dropdown).toBeInTheDocument();
155+
expect(screen.getAllByRole('button')).toHaveLength(1);
156+
expect(screen.getAllByRole('combobox')).toHaveLength(2);
157+
expect(screen.getAllByRole('table')).toHaveLength(2);
144158
});
145159
});
146160

@@ -156,6 +170,19 @@ describe('State Manager', () => {
156170
expect(screen.getAllByRole('grid')).toHaveLength(3);
157171
expect(screen.getAllByRole('columnheader')).toHaveLength(9);
158172
});
173+
174+
test('Display tab should render correct elements', () => {
175+
render(
176+
<Provider store={store}>
177+
<StateManager isThemeLight={null} />
178+
</Provider>
179+
);
180+
fireEvent.click(screen.getByText('Display'));
181+
expect(screen.getByRole('table')).toBeInTheDocument();
182+
expect(
183+
screen.getByText('State Initialized in Current Component:')
184+
).toBeInTheDocument();
185+
});
159186
});
160187

161188
describe('Customization Panel', () => {

__tests__/helper.test.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import randomPassword from '../app/src/helperFunctions/randomPassword';
2+
3+
describe('Random Password', () => {
4+
test('should generate password with 18 characters', () => {
5+
expect(randomPassword()).toHaveLength(18);
6+
});
7+
});

app/src/components/ContextAPIManager/AssignTab/components/ComponentDropDrown.tsx

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { Fragment, useState, useEffect, useContext } from 'react';
1+
import React, { Fragment } from 'react';
22
import TextField from '@mui/material/TextField';
33
import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete';
44
import Box from '@mui/material/Box';
@@ -14,13 +14,11 @@ const ComponentDropDown = ({
1414
componentInput,
1515
setComponentInput
1616
}) => {
17-
const { allContext } = contextStore;
18-
// const [componentList] = useContext(StateContext);
19-
const {state, isDarkMode} = useSelector((store:RootState) =>({
20-
state: store.appState,
17+
const { state, isDarkMode } = useSelector((store: RootState) => ({
18+
state: store.appState,
2119
isDarkMode: store.darkMode.isDarkMode
22-
} ))
23-
const color = isDarkMode ? "white":"black"
20+
}));
21+
const color = isDarkMode ? 'white' : 'black';
2422
const onChange = (event, newValue) => {
2523
if (typeof newValue === 'string') {
2624
setComponentInput({
@@ -44,7 +42,7 @@ const ComponentDropDown = ({
4442
const filtered = filter(options, params);
4543
const { inputValue } = params;
4644
// Suggest the creation of a new contextInput
47-
const isExisting = options.some(option => inputValue === option.name);
45+
const isExisting = options.some((option) => inputValue === option.name);
4846
if (inputValue !== '' && !isExisting) {
4947
filtered.push({
5048
inputValue,
@@ -57,7 +55,7 @@ const ComponentDropDown = ({
5755
return filtered;
5856
};
5957

60-
const getOptionLabel = option => {
58+
const getOptionLabel = (option) => {
6159
// Value selected with enter, right from the input
6260
if (typeof option === 'string') {
6361
return option;
@@ -70,11 +68,15 @@ const ComponentDropDown = ({
7068
return option.name;
7169
};
7270

73-
const renderOption = (props, option) => <li style={{ color: "black", border: "1px solid black" }} {...props}>{option.name}</li>;
71+
const renderOption = (props, option) => (
72+
<li style={{ color: 'black', border: '1px solid black' }} {...props}>
73+
{option.name}
74+
</li>
75+
);
7476

7577
return (
7678
<Fragment>
77-
<Box sx={{ display: 'flex', gap: 2, mb: 4}}>
79+
<Box sx={{ display: 'flex', gap: 2, mb: 4, border: '1px solid black' }}>
7880
<Autocomplete
7981
id="autoCompleteContextField"
8082
value={componentInput}
@@ -86,18 +88,23 @@ const ComponentDropDown = ({
8688
options={state.components || []}
8789
getOptionLabel={getOptionLabel}
8890
renderOption={renderOption}
89-
sx={{ width: 425, border: "1px solid black" }}
91+
sx={{ width: 425 }}
9092
freeSolo
91-
renderInput={params => (
92-
<TextField {...params} InputProps={{
93-
...params.InputProps,
94-
style: { color: color },
95-
}} label="Select Component" helperText='Select a component for your selected context to consume' />
93+
renderInput={(params) => (
94+
<TextField
95+
{...params}
96+
InputProps={{
97+
...params.InputProps,
98+
style: { color: color }
99+
}}
100+
variant="filled"
101+
label="Select Component"
102+
/>
96103
)}
97104
/>
98105
</Box>
99106
</Fragment>
100107
);
101108
};
102109

103-
export default ComponentDropDown;
110+
export default ComponentDropDown;

app/src/components/ContextAPIManager/AssignTab/components/ContextDropDown.tsx

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ const ContextDropDown = ({
1515
}) => {
1616
const { allContext } = contextStore;
1717

18-
const isDarkMode = useSelector((store:RootState) => store.darkMode.isDarkMode)
19-
const color = isDarkMode ? "white":"black"
18+
const isDarkMode = useSelector(
19+
(store: RootState) => store.darkMode.isDarkMode
20+
);
21+
const color = isDarkMode ? 'white' : 'black';
2022
const onChange = (event, newValue) => {
2123
if (typeof newValue === 'string') {
2224
setContextInput({
@@ -40,7 +42,7 @@ const color = isDarkMode ? "white":"black"
4042
const filtered = filter(options, params);
4143
const { inputValue } = params;
4244
// Suggest the creation of a new contextInput
43-
const isExisting = options.some(option => inputValue === option.name);
45+
const isExisting = options.some((option) => inputValue === option.name);
4446
if (inputValue !== '' && !isExisting) {
4547
filtered.push({
4648
inputValue,
@@ -53,7 +55,7 @@ const color = isDarkMode ? "white":"black"
5355
return filtered;
5456
};
5557

56-
const getOptionLabel = option => {
58+
const getOptionLabel = (option) => {
5759
// Value selected with enter, right from the input
5860
if (typeof option === 'string') {
5961
return option;
@@ -66,11 +68,15 @@ const color = isDarkMode ? "white":"black"
6668
return option.name;
6769
};
6870

69-
const renderOption = (props, option) => <li style={{ color:"black", border: "1px solid black" }} {...props}>{option.name}</li>;
71+
const renderOption = (props, option) => (
72+
<li style={{ color: 'black', border: '1px solid black' }} {...props}>
73+
{option.name}
74+
</li>
75+
);
7076

7177
return (
7278
<Fragment>
73-
<Box sx={{ display: 'flex', gap: 2, mb: 4, border:"1px black solid" }}>
79+
<Box sx={{ display: 'flex', gap: 2, mb: 4, border: '1px black solid' }}>
7480
<Autocomplete
7581
id="autoCompleteContextField"
7682
value={contextInput}
@@ -84,18 +90,21 @@ const color = isDarkMode ? "white":"black"
8490
renderOption={renderOption}
8591
sx={{ width: 425 }}
8692
freeSolo
87-
renderInput={params => (
88-
<TextField {...params}
89-
InputProps={{
90-
...params.InputProps,
91-
style: { color },
92-
}}
93-
label="Select Context" helperText='Select a context you would like to assign'/>
93+
renderInput={(params) => (
94+
<TextField
95+
{...params}
96+
InputProps={{
97+
...params.InputProps,
98+
style: { color }
99+
}}
100+
label="Select Context"
101+
variant="filled"
102+
/>
94103
)}
95104
/>
96105
</Box>
97106
</Fragment>
98107
);
99108
};
100109

101-
export default ContextDropDown;
110+
export default ContextDropDown;

app/src/components/ContextAPIManager/CreateTab/components/AddContextForm.tsx

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ import Select from '@mui/material/Select';
44
import Snackbar from '@mui/material/Snackbar';
55
import Button from '@mui/material/Button';
66
import Box from '@mui/material/Box';
7-
import IconButton from '@mui/material/IconButton';
8-
import CloseIcon from '@mui/icons-material/Close';
7+
import FormControl from '@mui/material/FormControl';
98
import MuiAlert, { AlertProps } from '@mui/material/Alert';
10-
import { MenuItem, Typography } from '@mui/material';
9+
import { InputLabel, MenuItem, Typography } from '@mui/material';
1110
import { useSelector } from 'react-redux';
1211
import { RootState } from '../../../../redux/store';
1312

@@ -62,13 +61,17 @@ const AddContextForm = ({
6261
return <MuiAlert elevation={6} ref={ref} variant="filled" {...props} />;
6362
});
6463

65-
const contexts = allContext.map((context) => {
66-
return (
67-
<MenuItem style={{ color: 'black' }} value={context.name}>
68-
{context.name}
69-
</MenuItem>
70-
);
71-
});
64+
const contexts = allContext.length ? (
65+
allContext.map((context) => {
66+
return (
67+
<MenuItem style={{ color: color }} value={context.name}>
68+
{context.name}
69+
</MenuItem>
70+
);
71+
})
72+
) : (
73+
<MenuItem disabled>No Contexts Created</MenuItem>
74+
);
7275

7376
return (
7477
<Fragment>
@@ -78,18 +81,18 @@ const AddContextForm = ({
7881
<Box sx={{ display: 'flex', gap: 2, mb: 4 }}>
7982
<TextField
8083
InputProps={{
81-
style: { color: 'black' }
84+
style: { color: color }
8285
}}
8386
onChange={handleChange}
8487
sx={{
8588
width: 425,
86-
border: '1px solid black'
89+
border: `1px solid ${color}`
8790
}}
88-
variant="filled"
8991
label="Create Context"
9092
value={contextInput}
9193
helperText={errorStatus ? errorMsg : null}
9294
error={errorStatus}
95+
variant="filled"
9396
/>
9497
<Snackbar
9598
open={open && !errorStatus}
@@ -116,19 +119,22 @@ const AddContextForm = ({
116119
Select Context
117120
</Typography>
118121
<Box sx={{ display: 'flex', gap: 2, mb: 4 }}>
119-
<Select
120-
sx={{ width: 425 }}
121-
style={{ border: '1px solid #0099e6', color: 'black' }}
122-
value={currentContext}
123-
label="Select Context"
124-
MenuProps={{ disablePortal: true }}
125-
onChange={(e) => {
126-
console.log(e);
127-
setCurrentContext(e.target.value);
128-
}}
129-
>
130-
{contexts}
131-
</Select>
122+
<FormControl variant="filled">
123+
<InputLabel style={{ color: color }}>Select Context</InputLabel>
124+
<Select
125+
required
126+
sx={{ width: 425 }}
127+
style={{ border: '1px solid #0099e6', color: color }}
128+
value={currentContext}
129+
label="Select Context"
130+
MenuProps={{ disablePortal: true }}
131+
onChange={(e) => {
132+
setCurrentContext(e.target.value);
133+
}}
134+
>
135+
{contexts}
136+
</Select>
137+
</FormControl>
132138
<Button
133139
color="error"
134140
variant="contained"

app/src/components/ContextAPIManager/CreateTab/components/AddDataForm.tsx

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
1-
import React, { Fragment, useState, useEffect } from 'react';
1+
import React from 'react';
22
import TextField from '@mui/material/TextField';
33
import Button from '@mui/material/Button';
44
import Box from '@mui/material/Box';
55
import { Typography } from '@mui/material';
66
import { useSelector } from 'react-redux';
77
import { RootState } from '../../../../redux/store';
88

9-
const AddDataForm = ({
10-
handleClickInputData,
11-
currentContext
12-
}) => {
9+
const AddDataForm = ({ handleClickInputData, currentContext }) => {
1310
//const [contextInput, setContextInput] = React.useState(null);
1411
const defaultInputData = { inputKey: '', inputValue: '' };
1512
const [dataContext, setDataContext] = React.useState(defaultInputData);
@@ -34,15 +31,15 @@ const AddDataForm = ({
3431
};
3532

3633
return (
37-
<Fragment>
34+
<>
3835
<Typography style={{ color: color }} variant="h6" gutterBottom={true}>
3936
Add context data
4037
</Typography>
4138
<Box sx={{ display: 'flex', gap: 2, color: 'black' }}>
4239
<TextField
4340
id="outlined-basic"
4441
label="Key"
45-
variant="outlined"
42+
variant="filled"
4643
value={dataContext.inputKey}
4744
name="inputKey"
4845
onChange={(e) => handleChange(e)}
@@ -52,7 +49,7 @@ const AddDataForm = ({
5249
<TextField
5350
id="outlined-basic"
5451
label="Value"
55-
variant="outlined"
52+
variant="filled"
5653
value={dataContext.inputValue}
5754
name="inputValue"
5855
onChange={(e) => handleChange(e)}
@@ -63,7 +60,7 @@ const AddDataForm = ({
6360
Save
6461
</Button>
6562
</Box>
66-
</Fragment>
63+
</>
6764
);
6865
};
6966

app/src/components/StateManagement/CreateTab/components/StatePropsPanel.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ const StatePropsPanel = ({ isThemeLight, data }): JSX.Element => {
227227
Type
228228
</InputLabel>
229229
<Select
230+
data-testid="type-select"
230231
labelId="select-required-label"
231232
id="type-input"
232233
className={

0 commit comments

Comments
 (0)