aboutsummaryrefslogtreecommitdiff
path: root/modern/src/reports
diff options
context:
space:
mode:
authorAnton Tananaev <anton.tananaev@gmail.com>2020-11-14 23:10:22 -0800
committerAnton Tananaev <anton.tananaev@gmail.com>2020-11-14 23:10:22 -0800
commit604eabcd97c6e7ddb42316a5a1fb0abc24e8dc7f (patch)
tree79a1ad01487fa95ac8ba6257d5b423011cba7873 /modern/src/reports
parentcfb788f1f8738b0b29ffb6d27ca8790f1ef7b49a (diff)
downloadetbsa-traccar-web-604eabcd97c6e7ddb42316a5a1fb0abc24e8dc7f.tar.gz
etbsa-traccar-web-604eabcd97c6e7ddb42316a5a1fb0abc24e8dc7f.tar.bz2
etbsa-traccar-web-604eabcd97c6e7ddb42316a5a1fb0abc24e8dc7f.zip
Support excel reports
Diffstat (limited to 'modern/src/reports')
-rw-r--r--modern/src/reports/EventReportPage.js23
-rw-r--r--modern/src/reports/ReplayPage.js6
-rw-r--r--modern/src/reports/ReportFilter.js23
-rw-r--r--modern/src/reports/ReportLayoutPage.js6
-rw-r--r--modern/src/reports/RouteReportPage.js18
-rw-r--r--modern/src/reports/StopReportPage.js18
-rw-r--r--modern/src/reports/SummaryReportPage.js18
-rw-r--r--modern/src/reports/TripReportPage.js18
8 files changed, 87 insertions, 43 deletions
diff --git a/modern/src/reports/EventReportPage.js b/modern/src/reports/EventReportPage.js
index b11933a..13e081e 100644
--- a/modern/src/reports/EventReportPage.js
+++ b/modern/src/reports/EventReportPage.js
@@ -6,16 +6,23 @@ import { formatPosition } from '../common/formatter';
import ReportFilter from './ReportFilter';
import ReportLayoutPage from './ReportLayoutPage';
-const ReportFilterForm = ({ onResult }) => {
+const ReportFilterForm = ({ setItems }) => {
- const [eventType, setEventType] = useState(['allEvents']);
+ const [eventTypes, setEventTypes] = useState(['allEvents']);
- const handleSubmit = async (deviceId, from, to) => {
- const query = new URLSearchParams({ deviceId, from, to });
- eventType.forEach(it => query.append('type', it));
- const response = await fetch(`/api/reports/events?${query.toString()}`, { headers: { Accept: 'application/json' } });
+ const handleSubmit = async (deviceId, from, to, mail, headers) => {
+ const query = new URLSearchParams({ deviceId, from, to, mail });
+ eventTypes.forEach(it => query.append('type', it));
+ const response = await fetch(`/api/reports/events?${query.toString()}`, { headers });
if (response.ok) {
- onResult(await response.json());
+ const contentType = response.headers.get('content-type');
+ if (contentType) {
+ if (contentType === 'application/json') {
+ setItems(await response.json());
+ } else {
+ window.location.assign(window.URL.createObjectURL(await response.blob()));
+ }
+ }
}
};
@@ -23,7 +30,7 @@ const ReportFilterForm = ({ onResult }) => {
<ReportFilter handleSubmit={handleSubmit}>
<FormControl variant="filled" margin="normal" fullWidth>
<InputLabel>{t('reportEventTypes')}</InputLabel>
- <Select value={eventType} onChange={e => setEventType(e.target.value)} multiple>
+ <Select value={eventTypes} onChange={e => setEventTypes(e.target.value)} multiple>
<MenuItem value="allEvents">{t('eventAll')}</MenuItem>
<MenuItem value="deviceOnline">{t('eventDeviceOnline')}</MenuItem>
<MenuItem value="deviceUnknown">{t('eventDeviceUnknown')}</MenuItem>
diff --git a/modern/src/reports/ReplayPage.js b/modern/src/reports/ReplayPage.js
index 5c27cb5..dfa9999 100644
--- a/modern/src/reports/ReplayPage.js
+++ b/modern/src/reports/ReplayPage.js
@@ -46,9 +46,9 @@ const ReplayPage = () => {
const [positions, setPositions] = useState([]);
const [index, setIndex] = useState(0);
- const handleSubmit = async (deviceId, from, to) => {
+ const handleSubmit = async (deviceId, from, to, _, headers) => {
const query = new URLSearchParams({ deviceId, from, to });
- const response = await fetch(`/api/positions?${query.toString()}`, { headers: { 'Accept': 'application/json' } });
+ const response = await fetch(`/api/positions?${query.toString()}`, { headers });
if (response.ok) {
setIndex(0);
setPositions(await response.json());
@@ -88,7 +88,7 @@ const ReplayPage = () => {
</Typography>
</AccordionSummary>
<AccordionDetails className={classes.configForm}>
- <ReportFilter handleSubmit={handleSubmit} />;
+ <ReportFilter handleSubmit={handleSubmit} showOnly />
</AccordionDetails>
</Accordion>
</div>
diff --git a/modern/src/reports/ReportFilter.js b/modern/src/reports/ReportFilter.js
index 9bc88bb..164dbf9 100644
--- a/modern/src/reports/ReportFilter.js
+++ b/modern/src/reports/ReportFilter.js
@@ -1,17 +1,17 @@
import React, { useState } from 'react';
-import { FormControl, InputLabel, Select, MenuItem, Button, TextField } from '@material-ui/core';
+import { FormControl, InputLabel, Select, MenuItem, Button, TextField, ButtonGroup } from '@material-ui/core';
import t from '../common/localization';
import { useSelector } from 'react-redux';
import moment from 'moment';
-const ReportFilter = ({ children, handleSubmit }) => {
+const ReportFilter = ({ children, handleSubmit, showOnly }) => {
const devices = useSelector(state => Object.values(state.devices.items));
const [deviceId, setDeviceId] = useState();
const [period, setPeriod] = useState('today');
const [from, setFrom] = useState(moment().subtract(1, 'hour'));
const [to, setTo] = useState(moment());
- const handleShow = () => {
+ const handleClick = (mail, json) => {
let selectedFrom;
let selectedTo;
switch (period) {
@@ -45,7 +45,14 @@ const ReportFilter = ({ children, handleSubmit }) => {
break;
}
- handleSubmit(deviceId, selectedFrom.toISOString(), selectedTo.toISOString());
+ const accept = json ? 'application/json' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
+ handleSubmit(
+ deviceId,
+ selectedFrom.toISOString(),
+ selectedTo.toISOString(),
+ mail,
+ { Accept: accept }
+ );
}
return (
@@ -92,9 +99,11 @@ const ReportFilter = ({ children, handleSubmit }) => {
)}
{children}
<FormControl margin="normal" fullWidth>
- <Button type="button" color="primary" variant="contained" disabled={!deviceId} onClick={handleShow}>
- {t('reportShow')}
- </Button>
+ <ButtonGroup color="primary" orientation="vertical" disabled={!deviceId}>
+ <Button onClick={() => handleClick(false, true)}>{t('reportShow')}</Button>
+ {!showOnly && <Button onClick={() => handleClick(false, false)}>{t('reportExport')}</Button>}
+ {!showOnly && <Button onClick={() => handleClick(true, false)}>{t('reportEmail')}</Button>}
+ </ButtonGroup>
</FormControl>
</>
);
diff --git a/modern/src/reports/ReportLayoutPage.js b/modern/src/reports/ReportLayoutPage.js
index 296b7c6..ddc7325 100644
--- a/modern/src/reports/ReportLayoutPage.js
+++ b/modern/src/reports/ReportLayoutPage.js
@@ -20,10 +20,6 @@ const useStyles = makeStyles(theme => ({
const ReportLayoutPage = ({ reportFilterForm:ReportFilterForm, setItems, children }) => {
const classes = useStyles();
-
- const onResult = (data) => {
- setItems(data);
- }
return (
<div className={classes.root}>
<MainToolbar />
@@ -31,7 +27,7 @@ const ReportLayoutPage = ({ reportFilterForm:ReportFilterForm, setItems, childre
<Grid container spacing={2}>
<Grid item xs={12} md={3} lg={2}>
<Paper className={classes.form}>
- <ReportFilterForm onResult={ onResult } />
+ <ReportFilterForm setItems={ setItems } />
</Paper>
</Grid>
<Grid item xs={12} md={9} lg={10}>
diff --git a/modern/src/reports/RouteReportPage.js b/modern/src/reports/RouteReportPage.js
index 7ff5d40..43d310b 100644
--- a/modern/src/reports/RouteReportPage.js
+++ b/modern/src/reports/RouteReportPage.js
@@ -5,15 +5,23 @@ import { formatPosition } from '../common/formatter';
import ReportFilter from './ReportFilter';
import ReportLayoutPage from './ReportLayoutPage';
-const ReportFilterForm = ({ onResult }) => {
+const ReportFilterForm = ({ setItems }) => {
- const handleSubmit = async (deviceId, from, to) => {
- const query = new URLSearchParams({ deviceId, from, to });
- const response = await fetch(`/api/reports/route?${query.toString()}`, { headers: { Accept: 'application/json' } });
+ const handleSubmit = async (deviceId, from, to, mail, headers) => {
+ const query = new URLSearchParams({ deviceId, from, to, mail });
+ const response = await fetch(`/api/reports/route?${query.toString()}`, { headers });
if (response.ok) {
- onResult(await response.json());
+ const contentType = response.headers.get('content-type');
+ if (contentType) {
+ if (contentType === 'application/json') {
+ setItems(await response.json());
+ } else {
+ window.location.assign(window.URL.createObjectURL(await response.blob()));
+ }
+ }
}
}
+
return <ReportFilter handleSubmit={handleSubmit} />;
};
diff --git a/modern/src/reports/StopReportPage.js b/modern/src/reports/StopReportPage.js
index ec4c199..77d3dfa 100644
--- a/modern/src/reports/StopReportPage.js
+++ b/modern/src/reports/StopReportPage.js
@@ -6,15 +6,23 @@ import ReportFilter from './ReportFilter';
import ReportLayoutPage from './ReportLayoutPage';
import { useAttributePreference } from '../common/preferences';
-const ReportFilterForm = ({ onResult }) => {
+const ReportFilterForm = ({ setItems }) => {
- const handleSubmit = async (deviceId, from, to) => {
- const query = new URLSearchParams({ deviceId, from, to });
- const response = await fetch(`/api/reports/stops?${query.toString()}`, { headers: { Accept: 'application/json' } });
+ const handleSubmit = async (deviceId, from, to, mail, headers) => {
+ const query = new URLSearchParams({ deviceId, from, to, mail });
+ const response = await fetch(`/api/reports/stops?${query.toString()}`, { headers });
if (response.ok) {
- onResult(await response.json());
+ const contentType = response.headers.get('content-type');
+ if (contentType) {
+ if (contentType === 'application/json') {
+ setItems(await response.json());
+ } else {
+ window.location.assign(window.URL.createObjectURL(await response.blob()));
+ }
+ }
}
}
+
return <ReportFilter handleSubmit={handleSubmit} />;
};
diff --git a/modern/src/reports/SummaryReportPage.js b/modern/src/reports/SummaryReportPage.js
index 4cb37aa..dcd3323 100644
--- a/modern/src/reports/SummaryReportPage.js
+++ b/modern/src/reports/SummaryReportPage.js
@@ -6,17 +6,25 @@ import ReportFilter from './ReportFilter';
import ReportLayoutPage from './ReportLayoutPage';
import { useAttributePreference } from '../common/preferences';
-const ReportFilterForm = ({ onResult }) => {
+const ReportFilterForm = ({ setItems }) => {
const [daily, setDaily] = useState(false);
- const handleSubmit = async (deviceId, from, to) => {
- const query = new URLSearchParams({ deviceId, from, to, daily });
- const response = await fetch(`/api/reports/summary?${query.toString()}`, { headers: { Accept: 'application/json' } });
+ const handleSubmit = async (deviceId, from, to, mail, headers) => {
+ const query = new URLSearchParams({ deviceId, from, to, daily, mail });
+ const response = await fetch(`/api/reports/summary?${query.toString()}`, { headers });
if (response.ok) {
- onResult(await response.json());
+ const contentType = response.headers.get('content-type');
+ if (contentType) {
+ if (contentType === 'application/json') {
+ setItems(await response.json());
+ } else {
+ window.location.assign(window.URL.createObjectURL(await response.blob()));
+ }
+ }
}
}
+
return (
<ReportFilter handleSubmit={handleSubmit}>
<FormControlLabel
diff --git a/modern/src/reports/TripReportPage.js b/modern/src/reports/TripReportPage.js
index bb987e1..10f1c46 100644
--- a/modern/src/reports/TripReportPage.js
+++ b/modern/src/reports/TripReportPage.js
@@ -6,15 +6,23 @@ import ReportFilter from './ReportFilter';
import ReportLayoutPage from './ReportLayoutPage';
import { useAttributePreference } from '../common/preferences';
-const ReportFilterForm = ({ onResult }) => {
+const ReportFilterForm = ({ setItems }) => {
- const handleSubmit = async (deviceId, from, to) => {
- const query = new URLSearchParams({ deviceId, from, to });
- const response = await fetch(`/api/reports/trips?${query.toString()}`, { headers: { Accept: 'application/json' } });
+ const handleSubmit = async (deviceId, from, to, mail, headers) => {
+ const query = new URLSearchParams({ deviceId, from, to, mail });
+ const response = await fetch(`/api/reports/trips?${query.toString()}`, { headers });
if (response.ok) {
- onResult(await response.json());
+ const contentType = response.headers.get('content-type');
+ if (contentType) {
+ if (contentType === 'application/json') {
+ setItems(await response.json());
+ } else {
+ window.location.assign(window.URL.createObjectURL(await response.blob()));
+ }
+ }
}
}
+
return <ReportFilter handleSubmit={handleSubmit} />;
}