aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Analyze.js3
-rw-r--r--src/Chart.js17
-rw-r--r--src/Dashboard.js2
-rw-r--r--src/PatternTable.js88
-rw-r--r--src/RegexField.js4
-rw-r--r--src/Settings.js34
-rw-r--r--src/pattern.js11
-rw-r--r--src/popup.js3
-rw-r--r--src/theme.js6
9 files changed, 133 insertions, 35 deletions
diff --git a/src/Analyze.js b/src/Analyze.js
index 0d01210..0985b2d 100644
--- a/src/Analyze.js
+++ b/src/Analyze.js
@@ -5,6 +5,7 @@ import 'react-dates/lib/css/_datepicker.css';
import { DateRangePicker } from 'react-dates';
import { withStyles } from '@material-ui/core/styles';
import cyan from '@material-ui/core/colors/cyan';
+import deepOrange from '@material-ui/core/colors/deepOrange';
import CssBaseline from '@material-ui/core/CssBaseline';
import Typography from '@material-ui/core/Typography';
import Button from '@material-ui/core/Button';
@@ -23,7 +24,7 @@ import AlertDialog from './Dialog';
const default_chart_data = [
{name: 'Work', value: 10, color: cyan[300]},
- {name: 'Wasted', value: 10, color: cyan[300]}];
+ {name: 'Wasted', value: 10, color: deepOrange[300]}];
const styles = theme => ({
buttonSpacer: {
diff --git a/src/Chart.js b/src/Chart.js
index 983436a..b1c36ed 100644
--- a/src/Chart.js
+++ b/src/Chart.js
@@ -2,9 +2,9 @@ import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import Grid from '@material-ui/core/Grid';
-import deepOrange from '@material-ui/core/colors/deepOrange';
import cyan from '@material-ui/core/colors/cyan';
import { PieChart, Pie, Cell, Tooltip } from 'recharts';
+import { defaultChartColor } from './theme';
export function getChartData(start, end, patterns, calendars, calEventsGetter) {
if (start >= end) return Promise.resolve({ patternGraphData: [], calendarGraphData: [] });
@@ -57,12 +57,15 @@ export function getChartData(start, end, patterns, calendars, calEventsGetter) {
majorParts.push({
name: 'Other',
value: minorSum,
- color: '#fff',
+ color: defaultChartColor,
});
return majorParts;
};
for (let i = 0; i < patterns.length; i++) {
- patternGraphData.push({ name: patterns[i].name, value: results[i] / 60.0 });
+ patternGraphData.push({
+ name: patterns[i].name,
+ value: results[i] / 60.0,
+ color: patterns[i].color.background});
}
for (let id in cal_results) {
calendarGraphData.push({
@@ -115,9 +118,11 @@ function PatternPieChart(props) {
cx={200}
cy={125}
outerRadius={60}
- fill={deepOrange[300]}
+ fill={defaultChartColor}
isAnimationActive={false}
- label={customizedLabel}/>
+ label={customizedLabel}>
+ {props.data.map((d, i) => <Cell key={i} fill={d.color ? d.color: defaultChartColor}/>)}
+ </Pie>
<Tooltip formatter={(value) => `${value.toFixed(2)} hr`}/>
</PieChart>
</div>
@@ -143,7 +148,7 @@ function DoublePieChart(props) {
fill={cyan[300]}
isAnimationActive={false}
label={customizedLabel}>
- {props.calendarGraphData.map((d, i) => <Cell key={i} fill={d.color}/>)}
+ {props.calendarGraphData.map((d, i) => <Cell key={i} fill={d.color ? d.color : cyan[300]}/>)}
</Pie>
<Tooltip formatter={(value) => `${value.toFixed(2)} hr`}/>
</PieChart>
diff --git a/src/Dashboard.js b/src/Dashboard.js
index 6c17d2c..04ced46 100644
--- a/src/Dashboard.js
+++ b/src/Dashboard.js
@@ -13,7 +13,7 @@ import Grid from '@material-ui/core/Grid';
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';
+import { theme } from './theme';
import Analyze from './Analyze';
import Settings from './Settings';
diff --git a/src/PatternTable.js b/src/PatternTable.js
index e054f9e..49fec21 100644
--- a/src/PatternTable.js
+++ b/src/PatternTable.js
@@ -9,12 +9,14 @@ import TableCell from '@material-ui/core/TableCell';
import TableHead from '@material-ui/core/TableHead';
import TablePagination from '@material-ui/core/TablePagination';
import DeleteOutlinedIcon from '@material-ui/icons/DeleteOutlined';
+import Popover from '@material-ui/core/Popover';
+import MaterialColorPicker from 'react-material-color-picker';
import { CalendarField, EventField } from './RegexField';
-import theme from './theme';
+import { theme, defaultChartColor } from './theme';
const styles = theme => ({
deleteButton: {
- width: '100%',
+ width: 0,
position: 'absolute',
marginRight: '2em',
right: 0,
@@ -38,16 +40,44 @@ const styles = theme => ({
}
});
+let nameFieldstyles = {
+ colorSample: {
+ display: 'inline-block',
+ height: 30,
+ width: 30,
+ marginRight: 10,
+ cursor: 'pointer'
+ }
+};
+
+function NameField(props) {
+ let color = props.value.color.background;
+ return (
+ <span>
+ <div
+ className={props.classes.colorSample}
+ style={{backgroundColor: color ? color : defaultChartColor}}
+ onClick={props.colorOnClick}>
+ </div>
+ <TextField
+ value={props.value.name}
+ onChange={props.onChange} />
+ </span>);
+}
+
const patternHead = [
- {label: "Name", field: "name", elem: TextField},
- {label: "Calendar", field: "cal", elem: withTheme(theme)(CalendarField)},
- {label: "Event", field: 'event', elem: withTheme(theme)(EventField)}];
+ {label: "Name", elem: withStyles(nameFieldstyles)(NameField)},
+ {label: "Calendar", elem: withTheme(theme)(CalendarField)},
+ {label: "Event", elem: withTheme(theme)(EventField)}];
class PatternTable extends React.Component {
state = {
page: 0,
rowsPerPage: 5,
- activePattern: null
+ activePattern: null,
+ anchorEl: null,
+ colorPickerOpen: false,
+ colorPickerDefault: defaultChartColor
};
handleChangePage = (event, page) => {
@@ -58,6 +88,14 @@ class PatternTable extends React.Component {
this.setState({ rowsPerPage: event.target.value });
}
+ handleColorPickerClose = () => {
+ this.setState({ colorPickerOpen: false });
+ this.activeColorPattern !== null &&
+ this.chosenColor &&
+ this.props.onUpdatePattern('color', this.activeColorPattern,
+ {background: this.chosenColor.target.value})
+ }
+
render() {
const { classes, calendars, patterns } = this.props;
const { rowsPerPage, page } = this.state;
@@ -83,9 +121,17 @@ class PatternTable extends React.Component {
return (
<TableCell key={i}>
<CustomText
- value={p[s.field]}
+ value={p}
calendars={calendars}
- onChange={event => this.props.onUpdatePattern(s.field, p.idx, event.target.value)}/>
+ onChange={event => this.props.onUpdatePattern(s.field, p.idx, event.target.value)}
+ colorOnClick={event => {
+ this.activeColorPattern = p.idx;
+ this.setState({
+ anchorEl: event.currentTarget,
+ colorPickerDefault: p.color.background,
+ colorPickerOpen: true
+ });
+ }}/>
</TableCell>)})
}
</TableRow>]
@@ -94,6 +140,32 @@ class PatternTable extends React.Component {
return (
<div>
+ <Popover
+ id="colorPicker"
+ open={this.state.colorPickerOpen}
+ anchorEl={this.state.anchorEl}
+ onClose={this.handleColorPickerClose}
+ anchorOrigin={{
+ vertical: 'bottom',
+ horizontal: 'center',
+ }}
+ transformOrigin={{
+ vertical: 'top',
+ horizontal: 'center',
+ }}>
+ <MaterialColorPicker
+ initColor={this.state.colorPickerDefault}
+ onSelect={color => {
+ console.log("select");
+ this.chosenColor = color;
+ }}
+ onSubmit={this.handleColorPickerClose}
+ onReset={() => {}}
+ style={{width: 400, backgroundColor: '#c7c7c7'}}
+ submitLabel='Apply'
+ resetLabel='Undo'
+ />
+ </Popover>
<div className={classes.patternTableWrapper}>
<Table className={classes.patternTable}>
<TableHead>
diff --git a/src/RegexField.js b/src/RegexField.js
index d4080a1..f1bc2e8 100644
--- a/src/RegexField.js
+++ b/src/RegexField.js
@@ -79,7 +79,7 @@ export function CalendarField(props) {
}
return (
<RegexFieldWithStyles
- value={props.value}
+ value={props.value.cal}
options={options}
onChange={props.onChange}
theme={props.theme} />);
@@ -91,7 +91,7 @@ export function EventField(props) {
options[any.id] = any;
return (
<RegexFieldWithStyles
- value={props.value}
+ value={props.value.event}
options={options}
onChange={props.onChange}
theme={props.theme} />);
diff --git a/src/Settings.js b/src/Settings.js
index 9358eee..40f4839 100644
--- a/src/Settings.js
+++ b/src/Settings.js
@@ -196,7 +196,7 @@ class Settings extends React.Component {
}).then(() => this.setState({ calendars }));
}
- async loadAll(loadDefaultPatterns) {
+ async loadAll(loadPatterns = false) {
await new Promise(resolver => (this.setState({ calendarsLoading: true }, resolver)));
let colors = gapi.getAuthToken().then(gapi.getColors).then(color => {
@@ -213,18 +213,27 @@ class Settings extends React.Component {
//cal: new gapi.GCalendar(item.id, item.summary)
}});
this.loadCalendars(cals);
- if (loadDefaultPatterns)
- {
- this.loadPatterns(items.map((item, idx) => {
- return new PatternEntry(item.summary, idx,
- new Pattern(item.id, false, item.summary, item.summary),
- Pattern.anyPattern());
- }), 'main');
- }
+ if (loadPatterns)
+ this.loadDefaultPatterns();
});
this.setState({ calendarsLoading: false });
};
+ loadDefaultPatterns() {
+ let patterns = [];
+ let idx = 0;
+ for (let id in this.state.calendars) {
+ let cal = this.state.calendars[id];
+ if (!cal.enabled) continue;
+ patterns.push(new PatternEntry(cal.name, idx++,
+ new Pattern(id, false, cal.name, cal.name),
+ Pattern.anyPattern(),
+ cal.color));
+ }
+ console.log(patterns);
+ this.loadPatterns(patterns, 'main');
+ }
+
loadCalendars = calendars => {
for (let id in this.state.calendars) {
if (calendars.hasOwnProperty(id))
@@ -246,6 +255,7 @@ class Settings extends React.Component {
updatePattern = (field, idx, value) => {
let patterns = this.state.patterns;
patterns[idx][field] = value;
+ console.log(patterns[idx]);
this.loadPatterns(patterns);
};
@@ -378,6 +388,12 @@ class Settings extends React.Component {
onClick={() => this.newPattern()}
disabled={!this.state.isLoggedIn}><AddCircleIcon /></IconButton>
Tracked Events
+ <div>
+ <Button
+ variant="contained"
+ color="primary"
+ onClick={() => this.loadDefaultPatterns()}>Load Default</Button>
+ </div>
</STableCell>
<STableCell className={classes.tableContent}>
{(this.state.isLoggedIn &&
diff --git a/src/pattern.js b/src/pattern.js
index b4100e2..858f2a3 100644
--- a/src/pattern.js
+++ b/src/pattern.js
@@ -22,11 +22,12 @@ export class Pattern {
}
export class PatternEntry {
- constructor(name, idx, calPattern, eventPattern) {
+ constructor(name, idx, calPattern, eventPattern, color) {
this.name = name;
this.idx = idx;
this.cal = calPattern;
this.event = eventPattern;
+ this.color = color;
}
deflate() {
@@ -34,12 +35,14 @@ export class PatternEntry {
name: this.name,
idx: this.idx,
cal: this.cal.deflate(),
- event: this.event.deflate()
+ event: this.event.deflate(),
+ color: this.color
};
}
- static defaultPatternEntry = (idx) => new PatternEntry('', idx, Pattern.emptyPattern(), Pattern.anyPattern());
+ static defaultPatternEntry = (idx) => new PatternEntry('', idx, Pattern.emptyPattern(), Pattern.anyPattern(), {background: null});
static inflate = obj => new PatternEntry(
obj.name, obj.idx,
- Pattern.inflate(obj.cal), Pattern.inflate(obj.event));
+ Pattern.inflate(obj.cal), Pattern.inflate(obj.event),
+ obj.color);
}
diff --git a/src/popup.js b/src/popup.js
index f13688c..c93ce91 100644
--- a/src/popup.js
+++ b/src/popup.js
@@ -7,7 +7,7 @@ import IconButton from '@material-ui/core/IconButton';
import RefreshIcon from '@material-ui/icons/Refresh';
import Logo from './Logo';
import Typography from '@material-ui/core/Typography';
-import theme from './theme';
+import { theme } from './theme';
import CssBaseline from '@material-ui/core/CssBaseline';
import { PatternEntry } from './pattern';
import { Duration } from './duration';
@@ -26,6 +26,7 @@ const styles = theme => ({
overflow: 'auto',
},
buttons: {
+ width: 400,
height: 48,
lineHeight: '48px'
},
diff --git a/src/theme.js b/src/theme.js
index 3773e6e..0269fd3 100644
--- a/src/theme.js
+++ b/src/theme.js
@@ -1,7 +1,9 @@
import { createMuiTheme } from '@material-ui/core/styles';
import orange from '@material-ui/core/colors/orange';
+import deepOrange from '@material-ui/core/colors/deepOrange';
-const theme = createMuiTheme({
+export const defaultChartColor = deepOrange[300];
+export const theme = createMuiTheme({
palette: {
primary: {
light: orange[300],
@@ -14,5 +16,3 @@ const theme = createMuiTheme({
useNextVariants: true,
}
});
-
-export default theme;