aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDeterminant <ted.sybil@gmail.com>2019-02-06 23:33:05 -0500
committerDeterminant <ted.sybil@gmail.com>2019-02-06 23:33:05 -0500
commit840b8f32b157c3bf9f0ffa4c300ac44c82dffc1e (patch)
tree45f60063c8f94aba2fa841c24140040075aea57f /src
parentd88b873c63d8ad5b5336b509f8a4ee35a583e279 (diff)
...
Diffstat (limited to 'src')
-rw-r--r--src/App.js81
-rw-r--r--src/CustomAnalyzer.js56
2 files changed, 91 insertions, 46 deletions
diff --git a/src/App.js b/src/App.js
index 6988105..bd17cec 100644
--- a/src/App.js
+++ b/src/App.js
@@ -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>