Skip to content

Commit

Permalink
[Editor] Removed materialize.css, use MUI for toolbar and dialog (#1001)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ahmetanakol authored and edgarmueller committed Jun 15, 2018
1 parent ade0da0 commit 6c8cfbf
Show file tree
Hide file tree
Showing 19 changed files with 1,359 additions and 5,317 deletions.
381 changes: 195 additions & 186 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"@types/jest": "^22.2.0",
"@types/lodash": "^4.14.104",
"@types/node": "^8.0.0",
"@types/react": "16.3.14",
"@types/react": "16.3.17",
"@types/react-dnd": "^2.0.36",
"ava": "^0.24.0",
"babel-loader": "^7.1.2",
Expand Down
29 changes: 29 additions & 0 deletions packages/editor/example/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import * as React from 'react';
import { Provider } from 'react-redux';
import EditorIde from '../src/EditorIde';
import EditorBar from './app-bar/EditorBar';
import {
getData,
getSchema,
getUiSchema
} from '@jsonforms/core';

const App = ({store, filterPredicate, labelProvider, imageProvider}) => (
<Provider store={store}>
<React.Fragment>
<EditorBar
schema={getSchema(store.getState())}
rootData={getData(store.getState())}
/>
<EditorIde
filterPredicate={filterPredicate}
labelProvider={labelProvider}
imageProvider={imageProvider}
schema={getSchema(store.getState())}
uischema={getUiSchema(store.getState())}
/>
</React.Fragment>
</Provider>
);

export default App;
182 changes: 182 additions & 0 deletions packages/editor/example/app-bar/EditorBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import * as React from 'react';
import { connect } from 'react-redux';
import { compose } from 'recompose';
import * as _ from 'lodash';
import { StyleRulesCallback, withStyles, WithStyles } from '@material-ui/core/styles';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
import Button from '@material-ui/core/Button';
import FileDownload from '@material-ui/icons/FileDownload';
import FolderOpen from '@material-ui/icons/FolderOpen';
import ImportExport from '@material-ui/icons/ImportExport';
import ModelSchemaDialog from './dialogs/ModelSchemaDialog';
import { Actions, getData, getSchema } from '@jsonforms/core';
import { createAjv } from '@jsonforms/core/lib/util/validator';

const ajv = createAjv();

const styles: StyleRulesCallback<'root' | 'flex' | 'rightIcon' | 'button'> = theme => ({
root: {
flexGrow: 1,
},
flex: {
flex: 1,
},
rightIcon: {
marginLeft: theme.spacing.unit,
},
button: {
margin: theme.spacing.unit,
}
});

interface EditorBarProps {
schema: any;
rootData: any;
updateRootData?: any;
}

interface EditorBarState {
exportDialog: {
open: boolean
};
}

class EditorBar extends
React.Component<EditorBarProps & WithStyles<'root' | 'flex' | 'rightIcon' | 'button'>,
EditorBarState> {
constructor(props) {
super(props);
this.state = {
exportDialog: {
open: false
}
};
}

handleExportDialogOpen = () => {
this.setState({
exportDialog: {
open: true
}
});
}

handleExportDialogClose = () => {
this.setState({
exportDialog: {
open: false
}
});
}

handleDownload = () => {
const a = document.createElement('a');
const file = new Blob([JSON.stringify(this.props.rootData, null, 2)],
{type: 'application/json'});
a.href = URL.createObjectURL(file);
a.download = 'download.json';
a.click();
}

handleFileUpload = event => {
// triggered after a file was selected
const schema = this.props.schema;
const target = event.target as HTMLInputElement;
const files = target.files;
if (_.isEmpty(files) || files.length > 1) {
return;
}
const file = files[0];
const reader = new FileReader();

// Callback when the file was loaded
reader.onload = () => {
if (reader.result === undefined || reader.result === null) {
console.error('Could not read data');
}
let readData;
try {
readData = JSON.parse(reader.result);
} catch (err) {
console.error('The loaded file did not contain valid JSON.', err);
alert(`The selected file '${file.name}' does not contain valid JSON`);

return;
}
if (!_.isEmpty(readData)) {
const valid = ajv.validate(schema, readData);
if (valid) {
this.props.updateRootData(readData);
} else {
alert('Loaded data does not adhere to the specified schema.');
console.error('Loaded data does not adhere to the specified schema.');

return;
}
}
};

reader.readAsText(file);
}

render() {
const { classes } = this.props;
return (
<div className={classes.root}>
<AppBar position='static'>
<Toolbar>
<Typography variant='title' color='inherit' className={classes.flex}>
User and Task Editor
</Typography>
<Button component='label' className={classes.button} color='inherit'>
Open Data File
<FolderOpen className={classes.rightIcon} />
<input
onChange={this.handleFileUpload}
style={{ display: 'none' }}
type='file'
/>
</Button>
<Button
className={classes.button}
color='inherit'
onClick={this.handleExportDialogOpen}
>
Export Model
<ImportExport className={classes.rightIcon} />
</Button>
<ModelSchemaDialog
open={this.state.exportDialog.open}
onClose={this.handleExportDialogClose}
/>
<Button className={classes.button} color='inherit' onClick={this.handleDownload}>
Download Model
<FileDownload className={classes.rightIcon} />
</Button>

</Toolbar>
</AppBar>
</div>
);
}
}

const mapStateToProps = state => {
return {
schema: getSchema(state),
rootData: getData(state)
};
};

const mapDispatchToProps = dispatch => ({
updateRootData(data: Object) {
dispatch(Actions.update('', () => data));
}
});

export default compose(
withStyles(styles, { name: 'EditorBar' }),
connect(mapStateToProps, mapDispatchToProps)
)(EditorBar);
98 changes: 98 additions & 0 deletions packages/editor/example/app-bar/dialogs/ModelSchemaDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import * as React from 'react';
import { connect } from 'react-redux';
import { compose } from 'recompose';
import { StyleRulesCallback, withStyles, WithStyles } from '@material-ui/core/styles';
import DialogTitle from '@material-ui/core/DialogTitle';
import DialogContent from '@material-ui/core/DialogContent';
import DialogActions from '@material-ui/core/DialogActions';
import Dialog from '@material-ui/core/Dialog';
import Button from '@material-ui/core/Button';
import TextField from '@material-ui/core/TextField';
import withMobileDialog from '@material-ui/core/withMobileDialog';
import { getData, getUiSchema } from '@jsonforms/core';

const styles: StyleRulesCallback<'textarea'> = () => ({
textarea: {
width: 400,
height: 600,
whiteSpace: 'pre-wrap',
overflowWrap: 'normal',
overflowX: 'scroll'
}
});

interface ModelSchemaDialogProps {
onClose: any;
readOnly: boolean;
open: boolean;
fullScreen?: boolean;
rootData?: any;
}

class ModelSchemaDialog extends
React.Component<ModelSchemaDialogProps & WithStyles<'textarea'>, {}> {
private textInput = React.createRef<HTMLInputElement>();

handleCancel = () => {
this.props.onClose();
}

handleCopy = () => {
this.textInput.current.select();
document.execCommand('copy');
}

render() {
const { classes, fullScreen, open, rootData } = this.props;
const textFieldData = JSON.stringify(rootData, null, 2);

return (
<Dialog open={open} fullScreen={fullScreen}>
<DialogTitle id='model-schema-dialog'>
Model Data
</DialogTitle>
<DialogContent>
<TextField
id='model-schema-textfield'
className={classes.textarea}
label='Model Data'
multiline
value={textFieldData}
margin='normal'
rowsMax={25}
inputProps={{
readOnly: true
}}
inputRef={this.textInput}
/>
</DialogContent>
<DialogActions>
<Button onClick={this.handleCancel} color='primary'>
Cancel
</Button>
<Button onClick={this.handleCopy} color='primary'>
Copy
</Button>
</DialogActions>
</Dialog>
);
}
}

const mapStateToProps = (state, ownProps) => {
const rootData = getData(state);

return {
rootData,
classes: ownProps.classes,
onClose: ownProps.onClose,
open: ownProps.open,
uischema: getUiSchema(state)
};
};

export default compose(
withStyles(styles, { name: 'ModelSchemaDialog' }),
withMobileDialog(),
connect(mapStateToProps)
)(ModelSchemaDialog);

0 comments on commit 6c8cfbf

Please sign in to comment.