mirror of
https://github.com/qlik-oss/nebula.js.git
synced 2026-05-26 04:00:15 -04:00
166 lines
3.9 KiB
JavaScript
166 lines
3.9 KiB
JavaScript
/* eslint no-param-reassign:0 */
|
|
/* eslint no-use-before-define:0 */
|
|
|
|
import React, { useState } from 'react';
|
|
|
|
import {
|
|
Typography,
|
|
Grid,
|
|
Checkbox,
|
|
FormControlLabel,
|
|
TextField,
|
|
ExpansionPanel,
|
|
ExpansionPanelSummary,
|
|
ExpansionPanelDetails,
|
|
} from '@material-ui/core';
|
|
|
|
import { ExpandMore } from '@nebula.js/ui/icons';
|
|
|
|
import { makeStyles } from '@nebula.js/ui/theme';
|
|
|
|
const useStyles = makeStyles((theme) => ({
|
|
summary: {
|
|
padding: theme.spacing(0, 1),
|
|
backgroundColor: theme.palette.background.lighter,
|
|
borderBottom: `1px solid ${theme.palette.divider}`,
|
|
},
|
|
details: {
|
|
padding: theme.spacing(1),
|
|
},
|
|
}));
|
|
|
|
const usePanelStyles = makeStyles((theme) => ({
|
|
root: {
|
|
boxShadow: 'none',
|
|
marginLeft: -theme.spacing(1),
|
|
marginRight: -theme.spacing(1),
|
|
'&$expanded': {
|
|
marginLeft: -theme.spacing(1),
|
|
marginRight: -theme.spacing(1),
|
|
},
|
|
},
|
|
expanded: {},
|
|
}));
|
|
|
|
const getType = (value) => {
|
|
if (Array.isArray(value)) {
|
|
return 'array';
|
|
}
|
|
if (typeof value === 'boolean') {
|
|
return 'boolean';
|
|
}
|
|
if (typeof value === 'string') {
|
|
return 'string';
|
|
}
|
|
if (typeof value === 'number') {
|
|
return 'number';
|
|
}
|
|
if (value && typeof value === 'object') {
|
|
return 'object';
|
|
}
|
|
return 'unknown';
|
|
};
|
|
|
|
const Bool = ({ property, value, target, changed }) => {
|
|
const handleChange = (e) => {
|
|
target[property] = e.target.checked;
|
|
changed();
|
|
};
|
|
return (
|
|
<FormControlLabel
|
|
control={<Checkbox checked={value} onChange={handleChange} />}
|
|
label={property}
|
|
labelPlacement="end"
|
|
/>
|
|
);
|
|
};
|
|
|
|
const Str = ({ property, value, target, changed }) => {
|
|
const [s, setS] = useState(value);
|
|
const handleChange = (e) => {
|
|
setS(e.target.value);
|
|
};
|
|
const onBlur = () => {
|
|
if (s !== value) {
|
|
target[property] = s;
|
|
changed();
|
|
}
|
|
};
|
|
|
|
return <TextField fullWidth onChange={handleChange} onBlur={onBlur} label={property} value={s} />;
|
|
};
|
|
|
|
const Num = ({ property, value, target, changed }) => {
|
|
const [s, setS] = useState(+value);
|
|
const handleChange = (e) => {
|
|
setS(e.target.value);
|
|
};
|
|
const onBlur = () => {
|
|
if (s !== value) {
|
|
target[property] = +s;
|
|
changed();
|
|
}
|
|
};
|
|
|
|
return <TextField fullWidth onChange={handleChange} onBlur={onBlur} label={property} value={s} />;
|
|
};
|
|
|
|
const Obj = ({ property, value, changed }) => {
|
|
const classes = useStyles();
|
|
const panelClasses = usePanelStyles();
|
|
return (
|
|
<ExpansionPanel square className={[panelClasses.root, panelClasses.expanded].join(' ')}>
|
|
<ExpansionPanelSummary expandIcon={<ExpandMore />} className={classes.summary}>
|
|
<Typography>{property}</Typography>
|
|
</ExpansionPanelSummary>
|
|
<ExpansionPanelDetails className={classes.details}>{generateComponents(value, changed)}</ExpansionPanelDetails>
|
|
</ExpansionPanel>
|
|
);
|
|
};
|
|
|
|
const registeredComponents = {
|
|
boolean: Bool,
|
|
string: Str,
|
|
object: Obj,
|
|
number: Num,
|
|
};
|
|
|
|
const QRX = /^q[A-Z]/;
|
|
|
|
function generateComponents(properties, changed) {
|
|
const components = Object.keys(properties)
|
|
.map((key) => {
|
|
if (['visualization', 'version'].indexOf(key) !== -1) {
|
|
return false;
|
|
}
|
|
if (QRX.test(key)) {
|
|
// skip q properties for now
|
|
return false;
|
|
}
|
|
const type = getType(properties[key]);
|
|
if (!registeredComponents[type]) {
|
|
return false;
|
|
}
|
|
return {
|
|
Component: registeredComponents[type],
|
|
property: key,
|
|
target: properties,
|
|
value: properties[key],
|
|
key: `${key}:${properties[key]}`,
|
|
};
|
|
})
|
|
.filter(Boolean);
|
|
|
|
return (
|
|
<Grid container direction="column" spacing={0} alignItems="stretch">
|
|
{components.map((c) => (
|
|
<Grid item xs key={c.key} style={{ width: '100%' }}>
|
|
<c.Component key={c.key} property={c.property} value={c.value} target={properties} changed={changed} />
|
|
</Grid>
|
|
))}
|
|
</Grid>
|
|
);
|
|
}
|
|
|
|
export { generateComponents as default };
|