diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/App.js | 81 | ||||
-rw-r--r-- | src/CustomAnalyzer.js | 56 |
2 files changed, 91 insertions, 46 deletions
@@ -11,7 +11,7 @@ import Paper from '@material-ui/core/Paper'; import Tabs from '@material-ui/core/Tabs'; import Tab from '@material-ui/core/Tab'; import Grid from '@material-ui/core/Grid'; -import { HashRouter as Router, Route, Link, Redirect, Switch } from "react-router-dom"; +import { HashRouter as Router, withRouter, Route, Link, Redirect, Switch } from "react-router-dom"; import { hashHistory } from 'react-router'; import Logo from './Logo'; import theme from './theme'; @@ -45,52 +45,55 @@ const styles = theme => ({ } }); -class Dashboard extends React.Component { - state = { - currentTab: 0 - }; - +class DashboardTabs extends React.Component { handleChangeTab = (event, currentTab) => { - this.setState({ currentTab }); + this.props.history.push(currentTab); } - render() { const { classes } = this.props; - return ( - <MuiThemeProvider theme={theme}> - <Router> - <div className={classes.root}> - <AppBar - position="absolute" - className={classes.appBar}> - <Toolbar className={classes.toolbar}> - <Typography component="h1" variant="h6" color="inherit" noWrap className={classes.title}> - <Logo style={{width: '2em', verticalAlign: 'bottom', marginRight: '0.2em'}}/>Chromicle - </Typography> - <Tabs styles={{ display: 'inline-block '}} - classes={{ indicator: classes.indicator }} - value={this.state.currentTab} - onChange={this.handleChangeTab}> - <Tab label="Settings" component={Link} to="/settings" /> - <Tab label="Analyze" component={Link} to="/analyze" /> - </Tabs> - </Toolbar> - </AppBar> - <CssBaseline /> - <main className={classes.content}> - <div className={classes.appBarSpacer} /> - <Route exact path="/settings" component={Settings} /> - <Route exact path="/analyze" component={CustomAnalyzer} /> - </main> - </div> - </Router> - </MuiThemeProvider>); + <div className={classes.root}> + <AppBar + position="absolute" + className={classes.appBar}> + <Toolbar className={classes.toolbar}> + <Typography component="h1" variant="h6" color="inherit" noWrap className={classes.title}> + <Logo style={{width: '2em', verticalAlign: 'bottom', marginRight: '0.2em'}}/>Chromicle + </Typography> + <Tabs styles={{ display: 'inline-block '}} + classes={{ indicator: classes.indicator }} + value={this.props.history.location.pathname} + onChange={this.handleChangeTab}> + <Tab label="Settings" component={Link} to="/settings" value="/settings" /> + <Tab label="Analyze" component={Link} to="/analyze" value="/analyze" /> + </Tabs> + </Toolbar> + </AppBar> + <CssBaseline /> + <main className={classes.content}> + <div className={classes.appBarSpacer} /> + <Route exact path="/settings" component={Settings} /> + <Route exact path="/analyze" component={CustomAnalyzer} /> + <Route exact path="/" render={() => <Redirect to="/settings" />}/> + </main> + </div> + ); } } -Dashboard.propTypes = { +DashboardTabs.propTypes = { classes: PropTypes.object.isRequired, }; -export default withStyles(styles)(Dashboard); +class Dashboard extends React.Component { + render() { + const { classes } = this.props; + let Tabs = withRouter(withStyles(styles)(DashboardTabs)); + return ( + <MuiThemeProvider theme={theme}> + <Router><Tabs /></Router> + </MuiThemeProvider>); + } +} + +export default Dashboard; diff --git a/src/CustomAnalyzer.js b/src/CustomAnalyzer.js index 62a8e39..53fa7ba 100644 --- a/src/CustomAnalyzer.js +++ b/src/CustomAnalyzer.js @@ -19,6 +19,7 @@ import { Pattern, PatternEntry } from './pattern'; import PieChart from './Chart'; import PatternTable from './PatternTable'; import Snackbar from './Snackbar'; +import AlertDialog from './Dialog'; const default_chart_data = [ {name: 'Work', value: 10, color: cyan[300]}, @@ -46,7 +47,9 @@ class CustomAnalyzer extends React.Component { calendarGraphData: default_chart_data, snackBarOpen: false, snackBarMsg: 'unknown', - snackBarVariant: 'error' + snackBarVariant: 'error', + dialogOpen: false, + dialogMsg: {title: '', message: ''}, }; constructor(props) { @@ -63,6 +66,7 @@ class CustomAnalyzer extends React.Component { }); gapi.getLoggedIn().then(b => !b && this.handleSnackbarOpen('Not logged in. Operating in offline mode.', 'warning')); + this.dialogPromiseResolver = null; } updatePattern = (field, idx, value) => { @@ -116,7 +120,7 @@ class CustomAnalyzer extends React.Component { analyze = () => { if (!(this.state.startDate && this.state.endDate)) { - alert("Please choose a valid time range."); + this.handleSnackbarOpen('Please choose a valid time range.', 'error'); return; } let start = this.state.startDate.startOf('day').toDate(); @@ -173,8 +177,23 @@ class CustomAnalyzer extends React.Component { }; reset = () => { - this.loadPatterns([]); - this.setState({ startDate: null, endDate: null }); + this.handleDialogOpen("Reset", "Are you sure to reset the patterns?").then(ans => { + if (!ans) return; + this.loadPatterns([]); + this.setState({ startDate: null, endDate: null }); + }); + } + + default = () => { + this.handleDialogOpen("Load Default", "Load the calendars as patterns?").then(ans => { + if (!ans) return; + this.loadPatterns(Object.keys(this.state.calendars).map((id, idx) => { + let item = this.state.calendars[id]; + return new PatternEntry(item.name, idx, + new Pattern(id, false, item.name, item.name), + Pattern.anyPattern()); + })); + }); } handleSnackbarClose = (event, reason) => { @@ -186,11 +205,29 @@ class CustomAnalyzer extends React.Component { this.setState({ snackBarOpen: true, snackBarMsg: msg, snackBarVariant: variant }); } + handleDialogOpen = (title, message) => { + let pm = new Promise(resolver => { + this.dialogPromiseResolver = resolver + }); + this.setState({ dialogOpen: true, dialogMsg: {title, message} }); + return pm; + } + + handleDialogClose = result => { + this.dialogPromiseResolver(result); + this.setState({ dialogOpen: false }); + } + render() { const { classes } = this.props; return ( <Grid container spacing={16}> + <AlertDialog + title={this.state.dialogMsg.title} + message={this.state.dialogMsg.message} + open={this.state.dialogOpen} + handleClose={this.handleDialogClose}/> <Snackbar message={this.state.snackBarMsg} open={this.state.snackBarOpen} @@ -231,16 +268,21 @@ class CustomAnalyzer extends React.Component { </FormGroup> <div className={classes.buttonSpacer} /> <Grid container spacing={16}> - <Grid item md={6} xs={12}> + <Grid item md={4} xs={12}> <FormGroup> - <Button variant="contained" color="primary" onClick={this.analyze}>Analyze</Button> + <Button variant="contained" color="primary" onClick={this.default}>Load Default</Button> </FormGroup> </Grid> - <Grid item md={6} xs={12}> + <Grid item md={4} xs={12}> <FormGroup> <Button variant="contained" color="primary" onClick={this.reset}>Reset</Button> </FormGroup> </Grid> + <Grid item md={4} xs={12}> + <FormGroup> + <Button variant="contained" color="primary" onClick={this.analyze}>Analyze</Button> + </FormGroup> + </Grid> </Grid> </FormControl> </Grid> |