Hello World
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello World</title>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<!-- Don't use this in production: -->
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script src="https://unpkg.com/@mui/material@5.13.0/umd/material-ui.development.js"></script>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
/>
<!-- Icons to support Material Design -->
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
</head>
<body>
<div id="root"></div>
<script type="text/babel">
const {useState, useEffect, useReducer } = React;
const {
colors,
CssBaseline,
ThemeProvider,
Typography,
Container,
createTheme,
Box,
SvgIcon,
Link,
Switch,
Button,
Select,
Input,
TextField,
MenuItem
} = MaterialUI;
const theme = createTheme({
palette: {
primary: {
main: '#556cd6',
},
secondary: {
main: '#19857b',
},
error: {
main: colors.red.A400,
},
},
});
function mapSentenceToPickers(sentence, pickers, dispatch, formState) {
console.log(formState);
return sentence.split(' ').map((word) => {
if (word.includes('$')) {
const replacedWord = word.replace('$', '');
const picker = pickers[replacedWord];
switch(picker.type) {
case('text'):
return <><Input value={formState[replacedWord]} onChange={(e) => dispatch({ type: replacedWord, value: e.target.value })}/> </>;
case('multipleSelect'):
return <><Select multiple onChange={(e) => dispatch({ type: replacedWord, value: e.target.value })} value={formState[replacedWord]}>{Object.entries(picker.default).map(([key, value]) => <MenuItem key={key} value={value}>{value}</MenuItem>)}</Select> </>;
case('select'):
return <><Select onChange={(e) => dispatch({ type: replacedWord, value: e.target.value })} value={formState[replacedWord]}>{Object.entries(picker.default).map(([key, value]) => <MenuItem key={key} value={value}>{value}</MenuItem>)}</Select> </>;
case('switch'):
return <Switch onChange={(e) => dispatch({ type: replacedWord, value: e.target.checked })} label={Object.keys(picker.default)[0]} defaultChecked={formState[replacedWord]} />;
}
}
return word + ' ';
});
}
function formStateReducer(state, action) {
return {
...state,
[action.type]: action.value
}
};
function mapPickersToDefaultReducer(pickers) {
return Object.entries(pickers).reduce((prev, [key, value]) => {
switch(value.type) {
case('select'):
prev[key] = Object.values(value.default)[0];
break;
case('text'):
prev[key] = value.default.value;
break;
case('switch'):
prev[key] = Object.values(value.default)[0];
break; case('multipleSelect'):
prev[key] = [Object.values(value.default)[0]];
break;
}
return prev;
}, {});
}
function SentencePicker({ sentence, pickers, renderButton }) {
const [formState, dispatch] = useReducer(formStateReducer, mapPickersToDefaultReducer(pickers));
return <Typography variant="body2">
<form>
{mapSentenceToPickers(sentence, pickers, dispatch, formState)}
{ renderButton() }
</form>
</Typography>;
}
function MyApp() {
const data = {
multipleSelectEurovisionQuery: {
pickers: {
contestants: {
type: 'multipleSelect',
default: {
portugal: 'Red bejba',
poland: 'Polish Bejba',
finaland: 'Cha Cha Bejba',
sweden: 'Not funny looser Bejba'
}
}
},
sentence: 'Visualize me connections between contestants $contestants'
},
eurovisionQuery: {
pickers: {
said: {
type: 'select',
default: {
booty: 'Booty',
bejba: 'Bejba',
hejba: 'Hejba',
lejba: 'Lejba'
}
}
},
sentence: 'Polish eurovision contestant said $said'
},
hereAnotherQuery: {
pickers: {
skirtOn: {
type: 'switch',
default: {
gnuUser: true
}
}
},
sentence: 'Visualize all contestants with skirt $skirtOn'
},
queryBackendQuery: {
pickers: {
user: {
type: 'text',
default: {
value: 'Artur'
}
},
name: {
type: 'select',
default: {
dziedziczak: 'Dziedziczak',
nawoj: 'Nawój',
}
},
gnu: {
type: 'switch',
default: {
gnuUser: true
}
}
},
sentence: 'Visualize an $user user with $name name thas $gnu power user'
}
};
const [queryFilter, setQuerFilter] = useState('');
const [selectedQuery, setSelectedQuery] = useState(null);
return <>
{ !selectedQuery ? <TextField value={queryFilter} onChange={(e) => setQuerFilter(e.target.value)} label="Search" /> : <SentencePicker sentence={data[selectedQuery].sentence} pickers={data[selectedQuery].pickers} renderButton={() => <><Button>Search</Button><Button onClick={() => setSelectedQuery(null)}>Clear</Button></> } /> }
{ !selectedQuery ? Object.entries(data).filter(([key, data]) => {
const splittedQueryFilter = queryFilter.split(' ');
return splittedQueryFilter.some((word) => data.sentence.includes(word));
}).map(([key, value]) => {
return <SentencePicker sentence={value.sentence} pickers={value.pickers} renderButton={(selectedItem) => <Button onClick={() => setSelectedQuery(key)}>Use</Button>} />
}) : null}
</>;
}
const container = document.getElementById('root');
const root = ReactDOM.createRoot(container);
root.render(<MyApp />);
</script>
</body>
</html>