Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handled YAML Errors on dashboard #21

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion dashboard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ Exposure Time [ms]:
path: devices/cmv12000/computed/exposure_time_ms
min: 100
max: 10000

- widget: spacing
px: 30
- widget: buttons
Expand Down
171 changes: 142 additions & 29 deletions frontend/routes/Dashboard.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import * as React from 'react';
import {
Box,
Button,
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
Fab,
Grid,
Link,
makeStyles,
Paper,
TextField,
Expand All @@ -19,6 +22,11 @@ import { usePromiseGenerator } from '../util/usePromiseGenerator';
import { NctrlValueWidgets } from '../components/*.jsx';
import Typography from '@material-ui/core/Typography';
import { NCTRL_BASE_PATH } from '../util/nctrl';
import { Player } from '@lottiefiles/react-lottie-player';
import ErrorTwoToneIcon from '@material-ui/icons/ErrorTwoTone';

// This animation is taken from : https://lottiefiles.com/624-camera-aperture and comes under creative commons license 4.0
const apertus_animation = require('../util/animations/aperture.json');

export const title = 'Dashboard';
export const route = '/dashboard';
Expand All @@ -27,6 +35,12 @@ export const explanation = `
**set-compatible** way. Here you can set the ISO, exposure time and related parameters.`;

const YAML_PATH = 'dashboard.yml';
const validYAML = new Set([
'- widget: spacing',
'- widget: slider',
'- widget: textfield',
'- widget: buttons',
]);

const useStyles = makeStyles(theme => ({
add: {
Expand All @@ -35,6 +49,25 @@ const useStyles = makeStyles(theme => ({
right: 0,
margin: '50px',
},
error_message: {
padding: theme.spacing(2),
},
error_wrapper: {
textAlign: 'left',
width: '100%',
},
error_player: {
height: '10px',
width: '10px',
alignItems: 'center',
display: 'flex',
},
load_player: {
height: '10px',
width: '10px',
alignItems: 'center',
display: 'flex',
},
ul: {
listStyle: 'none',
padding: 0,
Expand All @@ -49,6 +82,10 @@ const useStyles = makeStyles(theme => ({
paper: {
padding: '10px 5px',
},
attribution: {
fontFamily: theme.typography.fontFamily,
padding: theme.spacing(1),
},
}));

export function Component(props) {
Expand All @@ -62,13 +99,12 @@ export function Component(props) {
}
}, [file_yml]);

const parsed = useYaml(yaml) || [];

const parsed = useYaml(yaml);
const [rerenderDep, setRerenderDep] = useState(0);
const rerender = () => setRerenderDep(rerenderDep + 1);

return (
<div>
<Box>
{
<EditDashboard
current_yml={yaml}
Expand All @@ -78,33 +114,75 @@ export function Component(props) {
}}
/>
}
<div className={classes.ul}>
{Object.keys(parsed).map((heading, i) => {
return (
<div className={classes.notWide} key={i}>
<Typography variant="h6">{heading}:</Typography>
<Paper className={classes.paper}>
{parsed[heading].map((x, i) => {
const InputWidget =
NctrlValueWidgets[
`NctrlValue${x.widget.replace(/^(.)/, v => v.toUpperCase())}`
];
return (
<InputWidget
key={i}
rerender={rerender}
rerenderDep={rerenderDep}
{...x}
path={`${NCTRL_BASE_PATH}${x.path}`}
/>
);
})}
</Paper>
<div>
{!parsed ? (
<Player
src={apertus_animation}
autoplay={true}
loop={true}
controls={false}
style={{ height: '500px', width: '500px' }}
speed={3}
/>
) : parsed.error_message ? (
<div className={classes.error_wrapper}>
<Grid item style={{ textAlign: 'center' }}>
<ErrorTwoToneIcon
color="error"
fontSize="large"
style={{ height: '100px', width: '100px', padding: '0.5rem' }}
/>
</Grid>

<Typography color="error" className={classes.error_message}>
An Error has Occured : <br />
<br />
<b>Name</b> : {parsed.error_name} <br />
<br />
<b>Message</b> : {parsed.error_message} <br />
<br />
<b>Stack</b> : {parsed.error_stack}
</Typography>
</div>
) : (
<div>
<div className={classes.ul}>
{Object.keys(parsed).map((heading, i) => {
return (
<div className={classes.notWide} key={i}>
<Typography variant="h6">{heading}:</Typography>
<Paper className={classes.paper}>
{parsed[heading].map((x, i) => {
const InputWidget =
NctrlValueWidgets[
`NctrlValue${x.widget.replace(/^(.)/, v => v.toUpperCase())}`
];
return (
<InputWidget
key={i}
rerender={rerender}
rerenderDep={rerenderDep}
{...x}
path={`${NCTRL_BASE_PATH}${x.path}`}
/>
);
})}
</Paper>
</div>
);
})}
</div>
);
})}
<Link
target="_blank"
className={classes.attribution}
href="https://lottiefiles.com/624-camera-aperture"
>
aperture animation
</Link>
</div>
)}
</div>
</div>
</Box>
);
}

Expand Down Expand Up @@ -163,10 +241,45 @@ function EditDashboard({ current_yml: currentYaml, setYaml }) {
);
}

function validateWidgets(yamlString) {
var idx = 0,
curWidget = '';
while (idx < yamlString.length) {
while (idx < yamlString.length && yamlString[idx] == ' ') idx++;
if (idx == yamlString.length) return null;
if (yamlString[idx] == '-' && idx < yamlString.length - 1 && yamlString[idx + 1] == ' ') {
while (idx < yamlString.length && yamlString[idx] != '\n') curWidget += yamlString[idx++];
if (!validYAML.has(curWidget)) {
return curWidget;
}
curWidget = '';
} else {
while (idx < yamlString.length && yamlString[idx] != '\n') idx++;
}
idx++;
}
return null;
}

function useYaml(yamlString) {
const [deserialized, setDeserialized] = useState(null);
useEffect(() => {
setDeserialized(safeLoad(yamlString));
try {
const res = validateWidgets(yamlString);
if (yamlString != null && res)
throw {
name: 'Invalid widget',
message: `Cannot find widget`,
stack: `Error : ---${res}---; ${yamlString}`,
};
setDeserialized(safeLoad(yamlString));
} catch (error) {
return setDeserialized({
error_name: error.name,
error_message: error.message,
error_stack: error.stack,
});
}
}, [yamlString]);
return deserialized;
}
Expand Down
1 change: 1 addition & 0 deletions frontend/util/animations/aperture.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"last 10 Firefox versions"
],
"dependencies": {
"@lottiefiles/react-lottie-player": "^3.1.2",
"express": "~4.17.1",
"socketio": "^1.0.0"
},
Expand Down
12 changes: 12 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,13 @@
resolved "https://registry.yarnpkg.com/@iarna/toml/-/toml-2.2.3.tgz#f060bf6eaafae4d56a7dac618980838b0696e2ab"
integrity sha512-FmuxfCuolpLl0AnQ2NHSzoUKWEJDFl63qXjzdoWBVyFCXzMGm1spBzk7LeHNoVCiWCF7mRVms9e6jEV9+MoPbg==

"@lottiefiles/react-lottie-player@^3.1.2":
version "3.1.2"
resolved "https://registry.yarnpkg.com/@lottiefiles/react-lottie-player/-/react-lottie-player-3.1.2.tgz#077e581ffa0469d6499bf9dae21b758334143c01"
integrity sha512-u8ApmkpV4bpiQ2hqHyZGy9mmsTKxFvrQBgIJC1epPjs8NdYuAyN//33UXMFzddmvmrVCMzM4WdJb8sPoN+bIIg==
dependencies:
lottie-web "^5.7.8"

"@material-ui/core@^4.8.0":
version "4.8.0"
resolved "https://registry.yarnpkg.com/@material-ui/core/-/core-4.8.0.tgz#8fb4f4df2b35e3e781b1eec17d4aaf388edf3099"
Expand Down Expand Up @@ -3577,6 +3584,11 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3
dependencies:
js-tokens "^3.0.0 || ^4.0.0"

lottie-web@^5.7.8:
version "5.7.8"
resolved "https://registry.yarnpkg.com/lottie-web/-/lottie-web-5.7.8.tgz#c7a2e42983bcb42093590a03ccdde8741d3f960e"
integrity sha512-VxKCZk33GwZac6mVHvT3grUFR/zrMsW85M7vxQPrgpJOP2IhcnjMbuD0h7muBkXgw84K9KmGulmcyzvhpzSMAg==

magic-string@^0.22.4:
version "0.22.5"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.22.5.tgz#8e9cf5afddf44385c1da5bc2a6a0dbd10b03657e"
Expand Down