Skip to content

Commit 681852b

Browse files
authored
Merge pull request #99 from mikecao/dev
v0.21.0
2 parents a5c3429 + 405205f commit 681852b

File tree

14 files changed

+471
-602
lines changed

14 files changed

+471
-602
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,16 @@ To build the umami container and start up a Postgres database, run:
8282
docker-compose up
8383
```
8484

85+
### Getting updates
86+
87+
To get the latest features, simply do a pull, install any new dependencies, and rebuild:
88+
89+
```
90+
git pull
91+
npm install
92+
npm run build
93+
```
94+
8595
## License
8696

8797
MIT

components/common/RefreshButton.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,28 @@
1-
import React from 'react';
2-
import { useDispatch } from 'react-redux';
1+
import React, { useState, useEffect } from 'react';
2+
import { useDispatch, useSelector } from 'react-redux';
33
import { setDateRange } from 'redux/actions/websites';
44
import Button from './Button';
55
import Refresh from 'assets/redo.svg';
6+
import Dots from 'assets/ellipsis-h.svg';
67
import { useDateRange } from 'hooks/useDateRange';
8+
import { getDateRange } from '../../lib/date';
79

810
export default function RefreshButton({ websiteId }) {
911
const dispatch = useDispatch();
1012
const dateRange = useDateRange(websiteId);
13+
const [loading, setLoading] = useState(false);
14+
const completed = useSelector(state => state.queries[`/api/website/${websiteId}/metrics`]);
1115

1216
function handleClick() {
1317
if (dateRange) {
14-
dispatch(setDateRange(websiteId, dateRange));
18+
setLoading(true);
19+
dispatch(setDateRange(websiteId, getDateRange(dateRange.value)));
1520
}
1621
}
1722

18-
return <Button icon={<Refresh />} size="small" onClick={handleClick} />;
23+
useEffect(() => {
24+
setLoading(false);
25+
}, [completed]);
26+
27+
return <Button icon={loading ? <Dots /> : <Refresh />} size="small" onClick={handleClick} />;
1928
}

components/metrics/BarChart.js

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import classNames from 'classnames';
44
import ChartJS from 'chart.js';
55
import styles from './BarChart.module.css';
66
import { format } from 'date-fns';
7-
import { formatLongNumber } from '../../lib/format';
7+
import { formatLongNumber } from 'lib/format';
88

99
export default function BarChart({
1010
chartId,
@@ -22,30 +22,39 @@ export default function BarChart({
2222
const chart = useRef();
2323
const [tooltip, setTooltip] = useState({});
2424

25-
const renderXLabel = (label, index, values) => {
25+
function renderXLabel(label, index, values) {
2626
const d = new Date(values[index].value);
27-
const n = records;
27+
const w = canvas.current.width;
2828

2929
switch (unit) {
3030
case 'hour':
3131
return format(d, 'ha');
3232
case 'day':
33-
if (n >= 15) {
34-
return index % ~~(n / 15) === 0 ? format(d, 'MMM d') : '';
33+
if (records > 31) {
34+
if (w <= 500) {
35+
return index % 10 === 0 ? format(d, 'M/d') : '';
36+
}
37+
return index % 5 === 0 ? format(d, 'M/d') : '';
38+
}
39+
if (w <= 500) {
40+
return index % 2 === 0 ? format(d, 'MMM d') : '';
3541
}
3642
return format(d, 'EEE M/d');
3743
case 'month':
44+
if (w <= 660) {
45+
return format(d, 'MMM');
46+
}
3847
return format(d, 'MMMM');
3948
default:
4049
return label;
4150
}
42-
};
51+
}
4352

44-
const renderYLabel = label => {
53+
function renderYLabel(label) {
4554
return +label > 1 ? formatLongNumber(label) : label;
46-
};
55+
}
4756

48-
const renderTooltip = model => {
57+
function renderTooltip(model) {
4958
const { opacity, title, body, labelColors } = model;
5059

5160
if (!opacity) {
@@ -60,9 +69,9 @@ export default function BarChart({
6069
labelColor: labelColors[0].backgroundColor,
6170
});
6271
}
63-
};
72+
}
6473

65-
const createChart = () => {
74+
function createChart() {
6675
const options = {
6776
animation: {
6877
duration: animationDuration,
@@ -119,17 +128,17 @@ export default function BarChart({
119128
},
120129
options,
121130
});
122-
};
131+
}
123132

124-
const updateChart = () => {
133+
function updateChart() {
125134
const { options } = chart.current;
126135

127136
options.scales.xAxes[0].time.unit = unit;
128137
options.scales.xAxes[0].ticks.callback = renderXLabel;
129138
options.animation.duration = animationDuration;
130139

131140
onUpdate(chart.current);
132-
};
141+
}
133142

134143
useEffect(() => {
135144
if (datasets) {

components/metrics/WebsiteHeader.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export default function WebsiteHeader({ websiteId, title, showLink = false }) {
2121
<Button
2222
icon={<Arrow />}
2323
onClick={() =>
24-
router.push('/website/[...id]', `/website/${websiteId}/${name}`, {
24+
router.push('/website/[...id]', `/website/${websiteId}/${title}`, {
2525
shallow: true,
2626
})
2727
}

hooks/useFetch.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { useState, useEffect } from 'react';
2+
import { useDispatch } from 'react-redux';
23
import { get } from 'lib/web';
4+
import { updateQuery } from 'redux/actions/queries';
35

46
export default function useFetch(url, params = {}, options = {}) {
7+
const dispatch = useDispatch();
58
const [data, setData] = useState();
69
const [error, setError] = useState();
710
const keys = Object.keys(params)
@@ -12,7 +15,11 @@ export default function useFetch(url, params = {}, options = {}) {
1215
async function loadData() {
1316
try {
1417
setError(null);
18+
const time = performance.now();
1519
const data = await get(url, params);
20+
21+
dispatch(updateQuery({ url, time: performance.now() - time, completed: Date.now() }));
22+
1623
setData(data);
1724
onDataLoad(data);
1825
} catch (e) {

lib/db.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ export default prisma;
3434

3535
export async function runQuery(query) {
3636
return query.catch(e => {
37-
console.error(e);
3837
throw e;
3938
});
4039
}

lib/filters.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ export const urlFilter = (data, { raw }) => {
1313

1414
const cleanUrl = url => {
1515
try {
16-
const { pathname, searchParams } = new URL(url);
16+
const { pathname, search, searchParams } = new URL(url);
17+
18+
if (search.startsWith('?/')) {
19+
return `${pathname}${search}`;
20+
}
1721

1822
const path = removeTrailingSlash(pathname);
1923
const ref = searchParams.get('ref');

0 commit comments

Comments
 (0)