From d3d4345a7ab82e9715b1cbf398d43206d43737f6 Mon Sep 17 00:00:00 2001 From: Determinant Date: Mon, 4 Feb 2019 02:06:59 -0500 Subject: add settings page --- build/static/js/main.f88964ab.chunk.js.map | 1 - 1 file changed, 1 deletion(-) delete mode 100644 build/static/js/main.f88964ab.chunk.js.map (limited to 'build/static/js/main.f88964ab.chunk.js.map') diff --git a/build/static/js/main.f88964ab.chunk.js.map b/build/static/js/main.f88964ab.chunk.js.map deleted file mode 100644 index 66bad0a..0000000 --- a/build/static/js/main.f88964ab.chunk.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["Logo.js","gapi.js","msg.js","pattern.js","Chart.js","RegexField.js","theme.js","PatternTable.js","App.js","serviceWorker.js","index.js"],"names":["Logo","props","react_default","a","createElement","xmlns","viewBox","version","style","id","transform","points","fill","fontStyle","fontVariant","fontWeight","fontStretch","fontSize","fontFamily","gapi_base","to_params","dict","Object","entries","filter","_ref","_ref2","slicedToArray","map","_ref3","_ref4","k","v","concat","encodeURIComponent","join","getAuthToken","Promise","resolver","chrome","identity","interactive","token","getCalendars","fetch","access_token","method","async","then","response","json","data","items","getColors","_updatePatterns","_getPatterns","_updateCalendars","_getCalendars","_getCalEvents","msgType","freeze","updatePatterns","Symbol","getPatterns","updateCalendars","getCalEvents","stringifyMsgType","mt","Msg","type","classCallCheck","this","createClass","key","value","inflate","obj","s","parseMsgType","MsgClient","channelName","_this","sendMsg","cb","rcb","requestCallback","pm","resolve","ids","length","pop","maxId","inFlight","port","postMessage","deflate","runtime","connect","name","onMessage","addListener","msg","console","log","assert","undefined","push","Pattern","isRegex","label","get","RegExp","emptyPattern","anyPattern","revive","PatternEntry","idx","calPattern","eventPattern","cal","event","defaultPatternEntry","customizedLabel","cx","cy","x","y","anchor","dx","dy","textAnchor","withStyles","theme","pieChart","margin","Grid_default","container","spacing","item","xs","lg","className","classes","patternTableWrapper","PieChart","width","height","Pie","patternGraphData","dataKey","outerRadius","deepOrange","Tooltip","formatter","toFixed","calendarGraphData","innerRadius","cyan","d","i","Cell","color","RegexField","pitems","options","p0","isEmpty","palette","primary","dark","MenuItem_default","fieldRegex","fieldNoRegex","FormControl_default","Select_default","onChange","target","TextField_default","React","Component","RegexFieldWithStyles","marginRight","createMuiTheme","light","orange","main","contrastText","typography","useNextVariants","patternHead","field","elem","TextField","withTheme","calendars","any","PatternTable","state","page","rowsPerPage","handleChangePage","setState","handleChangeRowsPerPage","_this2","_this$props","patterns","_this$state","nDummy","Math","min","rows","slice","p","TableRow_default","onMouseOver","activePattern","onMouseOut","CustomText","TableCell_default","onUpdatePattern","deleteButtonShow","deleteButtonHide","DeleteOutlined_default","deleteIcon","onClick","onRemovePattern","Table_default","patternTable","TableHead_default","TableBody_default","colSpan","TablePagination_default","rowsPerPageOptions","component","count","backIconButtonProps","aria-label","nextIconButtonProps","onChangePage","onChangeRowsPerPage","position","right","display","cursor","overflowX","overflowY","minWidth","default_chart_data","Dashboard","possibleConstructorReturn","getPrototypeOf","call","timeRange","gapi","updatePattern","msgClient","removePattern","splice","newPattern","toConsumableArray","loadPatterns","loadCalendars","start","end","getTime","e","Date","analyze","startDate","endDate","startOf","toDate","event_pms","cals","_loop","calName","regex","test","filterPatterns","r","events","all","all_events","results","cal_results","forEach","_loop2","summary","hasOwnProperty","duration","background","alert","load","colors","calendar","colorId","styles","root","AppBar_default","appBar","Toolbar_default","toolbar","Typography_default","variant","noWrap","title","verticalAlign","content","appBarSpacer","CssBaseline_default","md","fullWidth","FormGroup_default","gutterBottom","IconButton_default","marginBottom","marginLeft","AddCircle_default","src_PatternTable","textAlign","react_dates","startDateId","endDateId","onDatesChange","focusedInput","onFocusChange","isOutsideRange","buttonSpacer","Button_default","Chart","zIndex","drawer","transition","transitions","create","easing","sharp","leavingScreen","flexGrow","sectionTitle","flex","mixins","padding","unit","overflow","fab","Boolean","window","location","hostname","match","ReactDOM","render","App","document","getElementById","navigator","serviceWorker","ready","registration","unregister"],"mappings":"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","file":"static/js/main.f88964ab.chunk.js","sourcesContent":["import React from 'react';\nexport default (props) =>\n \n \n \n \n \n \n Cr\n \n \n \n \n \n","/* global chrome */\nimport LRU from \"lru-cache\";\nconst gapi_base = 'https://www.googleapis.com/calendar/v3';\n\nconst GApiError = {\n invalidSyncToken: 1,\n otherError: 2,\n};\n\nfunction to_params(dict) {\n return Object.entries(dict).filter(([k, v]) => v).map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join('&');\n}\n\nexport function getAuthToken() {\n return new Promise(resolver =>\n chrome.identity.getAuthToken(\n {interactive: true}, token => resolver(token)));\n}\n\nexport function getCalendars(token) {\n return fetch(`${gapi_base}/users/me/calendarList?${to_params({access_token: token})}`,\n { method: 'GET', async: true })\n .then(response => response.json())\n .then(data => data.items);\n}\n\nexport function getColors(token) {\n return fetch(`${gapi_base}/colors?${to_params({access_token: token})}`,\n { method: 'GET', async: true })\n .then(response => response.json());\n}\n\nfunction getEvent(calId, eventId, token) {\n return fetch(`${gapi_base}/calendars/${calId}/events/${eventId}?${to_params({access_token: token})}`,\n { method: 'GET', async: true })\n .then(response => response.json());\n}\n\nfunction getEvents(calId, token, syncToken=null, timeMin=null, timeMax=null, resultsPerRequest=100) {\n let results = [];\n const singleFetch = (pageToken, syncToken) => fetch(`${gapi_base}/calendars/${calId}/events?${to_params({\n access_token: token,\n pageToken,\n syncToken,\n timeMin,\n timeMax,\n maxResults: resultsPerRequest\n })}`, { method: 'GET', async: true })\n .then(response => {\n if (response.status === 200)\n return response.json();\n else if (response.status === 410)\n throw GApiError.invalidSyncToken;\n else throw GApiError.otherErrors;\n })\n .then(data => {\n results.push(...data.items);\n if (data.nextPageToken) {\n return singleFetch(data.nextPageToken, '');\n } else {\n return ({\n nextSyncToken: data.nextSyncToken,\n results\n });\n }\n })\n\n return singleFetch('', syncToken);\n}\n\nexport class GCalendar {\n constructor(calId, name, options={maxCachedItems: 100, nDaysPerSlot: 10, largeQuery: 10}) {\n this.calId = calId;\n this.name = name;\n this.token = getAuthToken();\n this.syncToken = '';\n this.cache = new LRU({\n max: options.maxCachedItems,\n dispose: (k, v) => this.onRemoveSlot(k, v)\n });\n this.eventMeta = {};\n this.options = options;\n this.divider = 8.64e7 * this.options.nDaysPerSlot;\n }\n\n dateToCacheKey(date) {\n return Math.floor(date / this.divider);\n }\n\n dateRangeToCacheKeys(range) {\n return {\n start: this.dateToCacheKey(range.start),\n end: this.dateToCacheKey(new Date(range.end.getTime() - 1))\n };\n }\n\n getSlot(k) {\n if (!this.cache.has(k))\n {\n let res = {};\n this.cache.set(k, res);\n return res;\n }\n else return this.cache.get(k);\n }\n\n onRemoveSlot(k, v) {\n for (let id in v) {\n console.assert(this.eventMeta[id]);\n let keys = this.eventMeta[id].keys;\n keys.delete(k);\n if (keys.size === 0)\n delete this.eventMeta[id];\n }\n }\n\n slotStartDate(k) { return new Date(k * this.divider); }\n slotEndDate(k) { return new Date((k + 1) * this.divider); }\n\n addEvent(e, evict = false) {\n //console.log('adding event', e);\n if (this.eventMeta.hasOwnProperty(e.id))\n this.removeEvent(e);\n let r = this.dateRangeToCacheKeys(e);\n let ks = r.start;\n let ke = r.end;\n let t = this.cache.length;\n let keys = new Set();\n for (let i = ks; i <= ke; i++)\n {\n keys.add(i);\n if (!this.cache.has(i)) t++;\n }\n this.eventMeta[e.id] = {\n keys,\n summary: e.summary,\n };\n if (!evict && t > this.options.maxCachedItems) return;\n if (ks === ke)\n this.getSlot(ks)[e.id] = {\n start: e.start,\n end: e.end,\n id: e.id };\n else\n {\n this.getSlot(ks)[e.id] = {\n start: e.start,\n end: this.slotEndDate(ks),\n id: e.id };\n this.getSlot(ke)[e.id] = {\n start: this.slotStartDate(ke),\n end: e.end,\n id: e.id };\n for (let k = ks + 1; k < ke; k++)\n this.getSlot(k)[e.id] = {\n start: this.slotStartDate(k),\n end: this.slotEndDate(k),\n id: e.id};\n }\n }\n\n removeEvent(e) {\n let keys = this.eventMeta[e.id].keys;\n console.assert(keys);\n keys.forEach(k => delete this.getSlot(k)[e.id]);\n delete this.eventMeta[e.id];\n }\n\n getSlotEvents(k, start, end) {\n let s = this.getSlot(k);\n //console.log(s);\n let results = [];\n for (let id in s) {\n if (!(s[id].start >= end || s[id].end <= start))\n {\n results.push({\n id,\n start: s[id].start < start ? start: s[id].start,\n end: s[id].end > end ? end: s[id].end,\n summary: this.eventMeta[id].summary\n });\n }\n }\n return results;\n }\n\n getCachedEvents(_r) {\n let r = this.dateRangeToCacheKeys(_r);\n let ks = r.start;\n let ke = r.end;\n let results = this.getSlotEvents(ks, _r.start, _r.end);\n for (let k = ks + 1; k < ke; k++)\n {\n let s = this.getSlot(k);\n for (let id in s)\n results.push(s[id]);\n }\n if (ke > ks)\n results.push(...this.getSlotEvents(ke, _r.start, _r.end));\n return results;\n }\n\n sync() {\n return this.token.then(token => getEvents(this.calId, token, this.syncToken).then(r => {\n let pms = r.results.map(e => e.start ? Promise.resolve(e) : getEvent(this.calId, e.id, token));\n return Promise.all(pms).then(results => {\n results.forEach(e => {\n e.start = new Date(e.start.dateTime);\n e.end = new Date(e.end.dateTime);\n if (e.status === 'confirmed')\n this.addEvent(e);\n else if (e.status === 'cancelled')\n this.removeEvent(e);\n });\n this.syncToken = r.nextSyncToken;\n });\n })).catch(e => {\n if (e === GApiError.invalidSyncToken) {\n this.syncToken = '';\n this.sync();\n } else throw e;\n });\n }\n\n getEvents(start, end) {\n let r = this.dateRangeToCacheKeys({ start, end });\n let query = {};\n for (let k = r.start; k <= r.end; k++)\n if (!this.cache.has(k))\n {\n if (!query.hasOwnProperty('start'))\n query.start = k;\n query.end = k;\n }\n console.log(`start: ${start} end: ${end}`);\n if (query.hasOwnProperty('start'))\n {\n console.assert(query.start <= query.end);\n if (query.end - query.start + 1 > this.options.largeQuery) {\n console.log(`encounter large query, use direct fetch`);\n return this.token.then(token => getEvents(this.calId, token, null,\n start.toISOString(), end.toISOString()).then(r => {\n let results = [];\n r.results.forEach(e => {\n console.assert(e.start);\n e.start = new Date(e.start.dateTime);\n e.end = new Date(e.end.dateTime);\n results.push(e);\n });\n return results.filter(e => !(e.start >= end || e.end <= start)).map(e => {\n return {\n id: e.id,\n start: e.start < start ? start: e.start,\n end: e.end > end ? end: e.end,\n summary: e.summary,\n };\n });\n }));\n }\n\n console.log(`fetching short event list`);\n return this.token.then(token => getEvents(this.calId, token, null,\n this.slotStartDate(query.start).toISOString(),\n this.slotEndDate(query.end).toISOString()).then(r => {\n r.results.forEach(e => {\n if (e.status === 'confirmed')\n {\n console.assert(e.start);\n e.start = new Date(e.start.dateTime);\n e.end = new Date(e.end.dateTime);\n this.addEvent(e, true);\n }\n });\n if (this.syncToken === '')\n this.syncToken = r.nextSyncToken;\n })).then(() => this.sync())\n .then(() => this.getCachedEvents({ start, end }));\n }\n else\n {\n console.log(`cache hit`);\n return this.sync().then(() => this.getCachedEvents({ start, end }));\n }\n }\n}\n","/* global chrome */\nconst _updatePatterns = \"updatePatterns\";\nconst _getPatterns = \"getPatterns\";\nconst _updateCalendars = \"updateCalendars\";\nconst _getCalendars = \"getCalendars\";\nconst _getCalEvents = \"getCalEvents\";\n\nexport const msgType = Object.freeze({\n updatePatterns: Symbol(_updatePatterns),\n getPatterns: Symbol(_getPatterns),\n updateCalendars: Symbol(_updateCalendars),\n getCalendars: Symbol(_getCalendars),\n getCalEvents: Symbol(_getCalEvents),\n});\n\nfunction stringifyMsgType(mt) {\n switch (mt) {\n case msgType.updatePatterns: return _updatePatterns;\n case msgType.getPatterns: return _getPatterns;\n case msgType.updateCalendars: return _updateCalendars;\n case msgType.getCalendars: return _getCalendars;\n case msgType.getCalEvents: return _getCalEvents;\n }\n}\n\nfunction parseMsgType(s) {\n switch(s) {\n case _updatePatterns: return msgType.updatePatterns;\n case _getPatterns: return msgType.getPatterns;\n case _updateCalendars: return msgType.updateCalendars;\n case _getCalendars: return msgType.getCalendars;\n case _getCalEvents: return msgType.getCalEvents;\n }\n}\n\nexport class Msg {\n constructor(id, type, data) {\n this.id = id;\n this.type = type;\n this.data = data;\n }\n genResp(data) { return new Msg(this.id, this.type, data); }\n deflate() {\n return {\n id: this.id,\n type: stringifyMsgType(this.type),\n data: this.data\n }\n }\n static inflate = obj => new Msg(obj.id, parseMsgType(obj.type), obj.data);\n}\n\nexport class MsgClient {\n constructor(channelName) {\n let port = chrome.runtime.connect({name: channelName});\n const getCallBack = rcb => this.requestCallback;\n port.onMessage.addListener(function(msg) {\n console.log(msg);\n let rcb = getCallBack(msg.type);\n let cb = rcb.inFlight[msg.id];\n console.assert(cb !== undefined);\n rcb.ids.push(msg.id);\n cb(msg);\n });\n this.port = port;\n this.requestCallback = {inFlight: {}, ids: [], maxId: 0};\n }\n\n sendMsg = ({ type, data }) => {\n let rcb = this.requestCallback;\n let cb;\n let pm = new Promise(resolve => { cb = resolve; });\n let id;\n if (rcb.ids.length > 0) {\n id = rcb.ids.pop();\n } else {\n id = rcb.maxId++;\n }\n rcb.inFlight[id] = cb;\n this.port.postMessage((new Msg(id, type, data)).deflate());\n return pm;\n }\n}\n","export class Pattern {\n constructor(id, isRegex, value, label) {\n this.id = id;\n this.isRegex = isRegex;\n this.value = value;\n this.label = label;\n }\n\n get regex() { return new RegExp(this.isRegex ? this.value : `^${this.value}$`); }\n get isEmpty() { return this.label === null; }\n static emptyPattern = () => new Pattern(0, true, '', null);\n static anyPattern = () => new Pattern('any', true, '.*', 'Any');\n static revive = obj => new Pattern(obj.id, obj.isRegex, obj.value, obj.label);\n}\n\nexport class PatternEntry {\n constructor(name, idx, calPattern, eventPattern) {\n this.name = name;\n this.idx = idx;\n this.cal = calPattern;\n this.event = eventPattern;\n }\n\n static defaultPatternEntry = (idx) => new PatternEntry('', idx, Pattern.emptyPattern(), Pattern.anyPattern());\n static revive = obj => new PatternEntry(\n obj.name, obj.idx,\n Pattern.revive(obj.cal), Pattern.revive(obj.event));\n}\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { withStyles } from '@material-ui/core/styles';\nimport Grid from '@material-ui/core/Grid';\nimport deepOrange from '@material-ui/core/colors/deepOrange';\nimport cyan from '@material-ui/core/colors/cyan';\nimport { PieChart, Pie, Cell, Tooltip } from 'recharts';\n\nconst styles = theme => ({\n pieChart: {\n margin: '0 auto',\n }\n});\n\nfunction customizedLabel(props) {\n const {cx, cy, x, y, fill, name} = props;\n let anchor = \"middle\";\n const EPS = 2;\n let dx = 0;\n let dy = 0;\n if (x < cx - EPS) {\n dx = -5;\n anchor = \"end\"\n } else if (x > cx + EPS) {\n dx = 5;\n anchor = \"start\";\n }\n\n if (y < cy - EPS) {\n dy = -5;\n } else if (y > cy + EPS) {\n dy = 10;\n }\n\n return ({`${name}`});\n}\n\nfunction ChromiclePieChart(props) {\n return (\n \n \n
\n \n \n `${value.toFixed(2)} hr`}/>\n \n
\n
\n \n
\n \n \n {props.calendarGraphData.map((d, i) => )}\n \n `${value.toFixed(2)} hr`}/>\n \n
\n
\n
);\n}\n\nChromiclePieChart.propTypes = {\n patternGraphData: PropTypes.array.isRequired,\n calendarGraphData: PropTypes.array.isRequired,\n};\n\nexport default withStyles(styles)(ChromiclePieChart);\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { withStyles } from '@material-ui/core/styles';\nimport Select from '@material-ui/core/Select';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport TextField from '@material-ui/core/TextField';\nimport FormControl from '@material-ui/core/FormControl';\nimport { Pattern } from './pattern';\n\nconst styles = theme => ({\n fieldNoRegex: {\n width: 200\n },\n fieldRegex: {\n marginRight: '0.5em'\n }\n});\n\nclass RegexField extends React.Component {\n render() {\n const { classes } = this.props;\n let items = [];\n var pitems = this.props.options;\n const p0 = new Pattern.emptyPattern();\n pitems[p0.id] = p0;\n for (let id in pitems)\n {\n const label = !pitems[id].isEmpty ? pitems[id].label :\n Custom;\n items.push({label});\n }\n const selectOnClick = event => {\n let value;\n if (pitems[event.target.value].label == null) {\n value = new Pattern(0, true,\n this.props.value.isRegex ?\n this.props.value.value :\n `^${this.props.value.value}$`, null);\n } else {\n value = pitems[event.target.value];\n }\n this.props.onChange({target: {value}});\n };\n\n const regexTextOnChange = event => this.props.onChange({\n target: { value: new Pattern(0, true, event.target.value, null)}});\n\n const className = this.props.value.isRegex ? classes.fieldRegex: classes.fieldNoRegex;\n return (\n \n \n {items}\n \n {this.props.value.label == null && (\n \n )}\n \n );\n }\n}\n\nRegexField.propTypes = {\n classes: PropTypes.object.isRequired,\n};\n\nconst RegexFieldWithStyles = withStyles(styles)(RegexField);\n\nexport function CalendarField(props) {\n let options = {};\n for (let id in props.calendars) {\n options[id] = new Pattern(id, false,\n props.calendars[id].name,\n props.calendars[id].name);\n }\n return (\n );\n}\n\nexport function EventField(props) {\n let any = Pattern.anyPattern();\n let options = {};\n options[any.id] = any;\n return (\n );\n}\n","import { createMuiTheme } from '@material-ui/core/styles';\nimport orange from '@material-ui/core/colors/orange';\n\nconst theme = createMuiTheme({\n palette: {\n primary: {\n light: orange[300],\n main: orange[500],\n dark: orange[700],\n contrastText: \"#fff\"\n }\n },\n typography: {\n useNextVariants: true,\n }\n});\n\nexport default theme;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { withStyles, withTheme } from '@material-ui/core/styles';\nimport TextField from '@material-ui/core/TextField';\nimport Table from '@material-ui/core/Table';\nimport TableBody from '@material-ui/core/TableBody';\nimport TableRow from '@material-ui/core/TableRow';\nimport TableCell from '@material-ui/core/TableCell';\nimport TableHead from '@material-ui/core/TableHead';\nimport TablePagination from '@material-ui/core/TablePagination';\nimport DeleteOutlinedIcon from '@material-ui/icons/DeleteOutlined';\nimport { CalendarField, EventField } from './RegexField';\nimport theme from './theme';\n\nconst styles = theme => ({\n deleteButtonShow: {\n position: 'absolute',\n right: 0,\n height: 48\n },\n deleteButtonHide: {\n display: 'none'\n },\n deleteIcon: {\n height: '100%',\n cursor: 'pointer'\n },\n patternTableWrapper: {\n overflowX: 'auto',\n overflowY: 'hidden'\n },\n patternTable: {\n minWidth: 600\n }\n});\n\nconst patternHead = [\n {label: \"Name\", field: \"name\", elem: TextField},\n {label: \"Calendar\", field: \"cal\", elem: withTheme(theme)(CalendarField)},\n {label: \"Event\", field: 'event', elem: withTheme(theme)(EventField)}];\n\nclass PatternTable extends React.Component {\n state = {\n page: 0,\n rowsPerPage: 5,\n };\n\n handleChangePage = (event, page) => {\n this.setState({ page });\n }\n\n handleChangeRowsPerPage = event => {\n this.setState({ rowsPerPage: event.target.value });\n }\n\n render() {\n const { classes, calendars, patterns } = this.props;\n const { rowsPerPage, page } = this.state;\n const nDummy = rowsPerPage - Math.min(rowsPerPage, patterns.length - page * rowsPerPage);\n let rows = patterns.slice(page * rowsPerPage, (page + 1) * rowsPerPage).map(p => (\n this.setState({ activePattern: p.idx })}\n onMouseOut={() => this.setState({ activePattern: null })}>\n {\n patternHead.map(s => {\n const CustomText = s.elem;\n return (\n \n this.props.onUpdatePattern(s.field, p.idx, event.target.value)}/>\n )})\n }\n \n this.props.onRemovePattern(p.idx)} />\n \n ));\n\n return (\n
\n
\n \n \n {patternHead.map((s, i) => ({s.label}))}\n \n \n {rows}\n {\n nDummy > 0 && (\n \n \n )\n }\n \n
\n
\n \n
);\n }\n}\n\n\nPatternTable.propTypes = {\n classes: PropTypes.object.isRequired,\n patterns: PropTypes.array.isRequired,\n calendars: PropTypes.object.isRequired,\n onRemovePattern: PropTypes.func.isRequired,\n onUpdatePattern: PropTypes.func.isRequired,\n};\n\nexport default withStyles(styles)(PatternTable);\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport 'typeface-roboto';\nimport 'react-dates/initialize';\nimport 'react-dates/lib/css/_datepicker.css';\nimport { DateRangePicker } from 'react-dates';\nimport { withStyles } from '@material-ui/core/styles';\nimport { MuiThemeProvider } from '@material-ui/core/styles';\nimport cyan from '@material-ui/core/colors/cyan';\nimport CssBaseline from '@material-ui/core/CssBaseline';\nimport AppBar from '@material-ui/core/AppBar';\nimport Toolbar from '@material-ui/core/Toolbar';\nimport Typography from '@material-ui/core/Typography';\nimport Button from '@material-ui/core/Button';\nimport FormControl from '@material-ui/core/FormControl';\nimport FormGroup from '@material-ui/core/FormGroup';\nimport Grid from '@material-ui/core/Grid';\nimport AddCircleIcon from '@material-ui/icons/AddCircle';\nimport IconButton from '@material-ui/core/IconButton';\nimport Logo from './Logo';\nimport * as gapi from './gapi';\nimport { msgType, Msg, MsgClient } from './msg';\nimport { Pattern, PatternEntry } from './pattern';\nimport PieChart from './Chart';\nimport PatternTable from './PatternTable';\nimport theme from './theme';\n\nconst default_chart_data = [\n {name: 'Work', value: 10, color: cyan[300]},\n {name: 'Wasted', value: 10, color: cyan[300]}];\n\nfunction filterPatterns(patterns, calName) {\n return patterns.filter(p => {\n return p.cal.regex.test(calName);\n });\n}\n\nconst styles = theme => ({\n root: {\n display: 'flex',\n height: '100vh',\n },\n appBar: {\n zIndex: theme.zIndex.drawer + 1,\n transition: theme.transitions.create(['width', 'margin'], {\n easing: theme.transitions.easing.sharp,\n duration: theme.transitions.duration.leavingScreen,\n }),\n },\n title: {\n flexGrow: 1,\n },\n sectionTitle: {\n flex: '0 0 auto'\n },\n appBarSpacer: theme.mixins.toolbar,\n content: {\n flexGrow: 1,\n padding: theme.spacing.unit * 3,\n overflow: 'auto',\n },\n buttonSpacer: {\n marginBottom: theme.spacing.unit * 4,\n },\n fab: {\n margin: theme.spacing.unit,\n },\n});\n\nclass Dashboard extends React.Component {\n state = {\n patterns: [],\n calendars: [],\n timeRange: null,\n token: gapi.getAuthToken(),\n patternGraphData: default_chart_data,\n calendarGraphData: default_chart_data,\n activePattern: null\n };\n\n constructor(props) {\n super(props);\n this.msgClient = new MsgClient('main');\n this.msgClient.sendMsg({ type: msgType.getPatterns }).then(msg => {\n this.setState({ patterns: msg.data.map(p => PatternEntry.revive(p)) });\n });\n this.msgClient.sendMsg({ type: msgType.getCalendars }).then(msg => {\n this.setState({ calendars: msg.data });\n });\n }\n\n updatePattern = (field, idx, value) => {\n let patterns = this.state.patterns;\n patterns[idx][field] = value;\n this.setState({ patterns });\n this.msgClient.sendMsg({ type: msgType.updatePatterns, data: patterns });\n };\n\n removePattern = idx => {\n let patterns = this.state.patterns;\n patterns.splice(idx, 1);\n for (let i = 0; i < patterns.length; i++)\n patterns[i].idx = i;\n this.setState({ patterns });\n this.msgClient.sendMsg({ type: msgType.updatePatterns, data: patterns });\n };\n\n newPattern = () => {\n let patterns = [PatternEntry.defaultPatternEntry(0), ...this.state.patterns];\n for (let i = 1; i < patterns.length; i++)\n patterns[i].idx = i;\n this.setState({ patterns });\n this.msgClient.sendMsg({ type: msgType.updatePatterns, data: patterns });\n };\n\n loadPatterns = patterns => {\n this.setState({ patterns });\n this.msgClient.sendMsg({ type: msgType.updatePatterns, data: patterns });\n };\n\n loadCalendars = calendars => {\n this.setState({ calendars });\n this.msgClient.sendMsg({ type: msgType.updateCalendars, data: calendars });\n };\n\n getCalEvents = (id, start, end) => {\n return this.msgClient.sendMsg({ type: msgType.getCalEvents, data: { id,\n start: start.getTime(),\n end: end.getTime() } })\n .then(({ data }) => data.map(e => {\n return {\n id: e.id,\n start: new Date(e.start),\n end: new Date(e.end) }\n }));\n }\n\n analyze = () => {\n if (!(this.state.startDate && this.state.endDate)) {\n alert(\"Please choose a valid time range.\");\n return;\n }\n let start = this.state.startDate.startOf('day').toDate();\n let end = this.state.endDate.startOf('day').toDate();\n let event_pms = [];\n let cals = this.state.calendars;\n for (let id in cals)\n {\n let patterns = filterPatterns(this.state.patterns, cals[id].name);\n if (patterns.length > 0)\n event_pms.push(this.getCalEvents(id, start, end)\n .then(r => { return { id, events: r, patterns }; }));\n }\n Promise.all(event_pms).then(all_events => {\n console.log(all_events);\n let events = {};\n let patterns = {};\n let results = {}; // pattern idx => time\n let cal_results = {}; // cal id => time\n all_events.forEach(e => {\n events[e.id] = e.events;\n patterns[e.id] = e.patterns;\n });\n for (let i = 0; i < this.state.patterns.length; i++)\n results[i] = 0;\n for (let id in cals) {\n if (!events[id]) continue;\n events[id].forEach(event => {\n patterns[id].forEach(p => {\n if (!p.event.regex.test(event.summary)) return;\n if (!cal_results.hasOwnProperty(id)) {\n cal_results[id] = 0;\n }\n let duration = (event.end - event.start) / 60000;\n results[p.idx] += duration;\n cal_results[id] += duration;\n });\n });\n }\n let patternGraphData = [];\n let calendarGraphData = [];\n for (let i = 0; i < this.state.patterns.length; i++) {\n patternGraphData.push({ name: this.state.patterns[i].name, value: results[i] / 60.0 });\n }\n for (let id in cal_results) {\n calendarGraphData.push({\n name: cals[id].name,\n value: (cal_results[id] / 60.0),\n color: cals[id].color.background});\n }\n console.log(patternGraphData, calendarGraphData);\n this.setState({ patternGraphData, calendarGraphData });\n });\n };\n\n load = () => {\n let token = this.state.token;\n let colors = token.then(gapi.getColors).then(color => {\n return color.calendar;\n });\n let cals = token.then(gapi.getCalendars);\n Promise.all([colors, cals]).then(([colors, items]) => {\n var cals = {};\n items.forEach(item => {\n cals[item.id] = {\n name: item.summary,\n color: colors[item.colorId],\n //cal: new gapi.GCalendar(item.id, item.summary)\n }});\n this.loadCalendars(cals);\n this.loadPatterns(items.map((item, idx) => {\n return new PatternEntry(item.summary, idx,\n new Pattern(item.id, false, item.summary, item.summary),\n Pattern.anyPattern());\n }));\n });\n };\n\n render() {\n const { classes } = this.props;\n\n return (\n \n
\n \n \n \n Chromicle\n \n \n \n
\n
\n \n \n \n \n \n \n Event Patterns\n this.newPattern()}>\n \n \n \n \n \n Time Range\n \n
\n {\n this.setState({ startDate, endDate });\n }} \n focusedInput={this.state.focusedInput}\n onFocusChange={focusedInput => this.setState({ focusedInput })}\n isOutsideRange={() => false}/>\n
\n
\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n Graph\n \n \n \n \n
\n
\n
);\n }\n}\n\nDashboard.propTypes = {\n classes: PropTypes.object.isRequired,\n};\n\nexport default withStyles(styles)(Dashboard);\n","// This optional code is used to register a service worker.\n// register() is not called by default.\n\n// This lets the app load faster on subsequent visits in production, and gives\n// it offline capabilities. However, it also means that developers (and users)\n// will only see deployed updates on subsequent visits to a page, after all the\n// existing tabs open on the page have been closed, since previously cached\n// resources are updated in the background.\n\n// To learn more about the benefits of this model and instructions on how to\n// opt-in, read http://bit.ly/CRA-PWA\n\nconst isLocalhost = Boolean(\n window.location.hostname === 'localhost' ||\n // [::1] is the IPv6 localhost address.\n window.location.hostname === '[::1]' ||\n // 127.0.0.1/8 is considered localhost for IPv4.\n window.location.hostname.match(\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\n )\n);\n\nexport function register(config) {\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\n // The URL constructor is available in all browsers that support SW.\n const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);\n if (publicUrl.origin !== window.location.origin) {\n // Our service worker won't work if PUBLIC_URL is on a different origin\n // from what our page is served on. This might happen if a CDN is used to\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\n return;\n }\n\n window.addEventListener('load', () => {\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\n\n if (isLocalhost) {\n // This is running on localhost. Let's check if a service worker still exists or not.\n checkValidServiceWorker(swUrl, config);\n\n // Add some additional logging to localhost, pointing developers to the\n // service worker/PWA documentation.\n navigator.serviceWorker.ready.then(() => {\n console.log(\n 'This web app is being served cache-first by a service ' +\n 'worker. To learn more, visit http://bit.ly/CRA-PWA'\n );\n });\n } else {\n // Is not localhost. Just register service worker\n registerValidSW(swUrl, config);\n }\n });\n }\n}\n\nfunction registerValidSW(swUrl, config) {\n navigator.serviceWorker\n .register(swUrl)\n .then(registration => {\n registration.onupdatefound = () => {\n const installingWorker = registration.installing;\n if (installingWorker == null) {\n return;\n }\n installingWorker.onstatechange = () => {\n if (installingWorker.state === 'installed') {\n if (navigator.serviceWorker.controller) {\n // At this point, the updated precached content has been fetched,\n // but the previous service worker will still serve the older\n // content until all client tabs are closed.\n console.log(\n 'New content is available and will be used when all ' +\n 'tabs for this page are closed. See http://bit.ly/CRA-PWA.'\n );\n\n // Execute callback\n if (config && config.onUpdate) {\n config.onUpdate(registration);\n }\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a\n // \"Content is cached for offline use.\" message.\n console.log('Content is cached for offline use.');\n\n // Execute callback\n if (config && config.onSuccess) {\n config.onSuccess(registration);\n }\n }\n }\n };\n };\n })\n .catch(error => {\n console.error('Error during service worker registration:', error);\n });\n}\n\nfunction checkValidServiceWorker(swUrl, config) {\n // Check if the service worker can be found. If it can't reload the page.\n fetch(swUrl)\n .then(response => {\n // Ensure service worker exists, and that we really are getting a JS file.\n const contentType = response.headers.get('content-type');\n if (\n response.status === 404 ||\n (contentType != null && contentType.indexOf('javascript') === -1)\n ) {\n // No service worker found. Probably a different app. Reload the page.\n navigator.serviceWorker.ready.then(registration => {\n registr