diff options
author | Anton Tananaev <anton.tananaev@gmail.com> | 2016-08-10 14:06:39 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-08-10 14:06:39 +0300 |
commit | 40e26cbf38a236f3c92e50dff619b1a29bd413de (patch) | |
tree | 450026b9cda50c8cafdf3a15ce07ed3bbccfbc3c | |
parent | 78f8d278276f0826eb302a08213609b083570760 (diff) | |
parent | ee5af32f8a9bc1edd7af02dfe3f243ebfdfb8641 (diff) | |
download | traccar-server-40e26cbf38a236f3c92e50dff619b1a29bd413de.tar.gz traccar-server-40e26cbf38a236f3c92e50dff619b1a29bd413de.tar.bz2 traccar-server-40e26cbf38a236f3c92e50dff619b1a29bd413de.zip |
Merge pull request #2197 from Abyss777/reports_web
Initial implementation Report API for web
-rw-r--r-- | src/org/traccar/api/resource/ReportResource.java | 31 | ||||
-rw-r--r-- | src/org/traccar/reports/Events.java | 9 | ||||
-rw-r--r-- | src/org/traccar/reports/Route.java | 9 | ||||
-rw-r--r-- | src/org/traccar/reports/Summary.java | 9 | ||||
-rw-r--r-- | src/org/traccar/reports/model/SummaryReport.java | 8 | ||||
-rw-r--r-- | web/app/Application.js | 9 | ||||
-rw-r--r-- | web/app/controller/Root.js | 3 | ||||
-rw-r--r-- | web/app/model/ReportSummary.js | 37 | ||||
-rw-r--r-- | web/app/store/ReportEvents.js | 28 | ||||
-rw-r--r-- | web/app/store/ReportRoute.js | 28 | ||||
-rw-r--r-- | web/app/store/ReportSummary.js | 28 | ||||
-rw-r--r-- | web/app/store/ReportTypes.js | 31 | ||||
-rw-r--r-- | web/app/view/CommandDialog.js | 2 | ||||
-rw-r--r-- | web/app/view/MapController.js | 2 | ||||
-rw-r--r-- | web/app/view/Report.js | 63 | ||||
-rw-r--r-- | web/app/view/ReportController.js | 181 | ||||
-rw-r--r-- | web/app/view/ServerDialog.js | 2 | ||||
-rw-r--r-- | web/app/view/UserDialog.js | 2 | ||||
-rw-r--r-- | web/l10n/en.json | 13 |
19 files changed, 410 insertions, 85 deletions
diff --git a/src/org/traccar/api/resource/ReportResource.java b/src/org/traccar/api/resource/ReportResource.java index 8682070b1..e87d6401c 100644 --- a/src/org/traccar/api/resource/ReportResource.java +++ b/src/org/traccar/api/resource/ReportResource.java @@ -8,6 +8,8 @@ import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.traccar.api.BaseResource; @@ -17,12 +19,15 @@ import org.traccar.reports.Route; import org.traccar.web.JsonConverter; @Path("reports") -@Consumes("application/json") +@Consumes(MediaType.APPLICATION_JSON) public class ReportResource extends BaseResource { + public static final String TEXT_CSV = "text/csv"; + public static final String CONTENT_DISPOSITION_VALUE = "attachment; filename=report.csv"; + @Path("route") @GET - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public Response getRouteJson( @QueryParam("deviceId") final List<Long> deviceIds, @QueryParam("groupId") final List<Long> groupIds, @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException { @@ -32,17 +37,19 @@ public class ReportResource extends BaseResource { @Path("route") @GET - @Produces("application/ms-excel") + @Produces(TEXT_CSV) public Response getRouteCsv( @QueryParam("deviceId") final List<Long> deviceIds, @QueryParam("groupId") final List<Long> groupIds, @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException { return Response.ok(Route.getCsv(getUserId(), deviceIds, groupIds, - JsonConverter.parseDate(from), JsonConverter.parseDate(to))).build(); + JsonConverter.parseDate(from), JsonConverter.parseDate(to))) + .header(HttpHeaders.CONTENT_DISPOSITION, CONTENT_DISPOSITION_VALUE) + .build(); } @Path("events") @GET - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public Response getEventsJson( @QueryParam("deviceId") final List<Long> deviceIds, @QueryParam("groupId") final List<Long> groupIds, @QueryParam("type") final List<String> types, @@ -53,18 +60,20 @@ public class ReportResource extends BaseResource { @Path("events") @GET - @Produces("application/ms-excel") + @Produces(TEXT_CSV) public Response getEventsCsv( @QueryParam("deviceId") final List<Long> deviceIds, @QueryParam("groupId") final List<Long> groupIds, @QueryParam("type") final List<String> types, @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException { return Response.ok(Events.getCsv(getUserId(), deviceIds, groupIds, - types, JsonConverter.parseDate(from), JsonConverter.parseDate(to))).build(); + types, JsonConverter.parseDate(from), JsonConverter.parseDate(to))) + .header(HttpHeaders.CONTENT_DISPOSITION, CONTENT_DISPOSITION_VALUE) + .build(); } @Path("summary") @GET - @Produces("application/json") + @Produces(MediaType.APPLICATION_JSON) public Response getSummaryJson( @QueryParam("deviceId") final List<Long> deviceIds, @QueryParam("groupId") final List<Long> groupIds, @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException { @@ -74,12 +83,14 @@ public class ReportResource extends BaseResource { @Path("summary") @GET - @Produces("application/ms-excel") + @Produces(TEXT_CSV) public Response getSummaryCsv( @QueryParam("deviceId") final List<Long> deviceIds, @QueryParam("groupId") final List<Long> groupIds, @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException { return Response.ok(Summary.getCsv(getUserId(), deviceIds, groupIds, - JsonConverter.parseDate(from), JsonConverter.parseDate(to))).build(); + JsonConverter.parseDate(from), JsonConverter.parseDate(to))) + .header(HttpHeaders.CONTENT_DISPOSITION, CONTENT_DISPOSITION_VALUE) + .build(); } } diff --git a/src/org/traccar/reports/Events.java b/src/org/traccar/reports/Events.java index 9e14bd3db..fbbd3131b 100644 --- a/src/org/traccar/reports/Events.java +++ b/src/org/traccar/reports/Events.java @@ -5,7 +5,7 @@ import java.util.Collection; import java.util.Date; import javax.json.Json; -import javax.json.JsonObjectBuilder; +import javax.json.JsonArrayBuilder; import org.traccar.Context; import org.traccar.model.Event; @@ -19,12 +19,13 @@ public final class Events { public static String getJson(long userId, Collection<Long> deviceIds, Collection<Long> groupIds, Collection<String> types, Date from, Date to) throws SQLException { - JsonObjectBuilder json = Json.createObjectBuilder(); + JsonArrayBuilder json = Json.createArrayBuilder(); for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); for (String type : types) { - json.add(String.valueOf(deviceId), JsonConverter.arrayToJson(Context.getDataManager() - .getEvents(deviceId, type, from, to))); + for (Event event : Context.getDataManager().getEvents(deviceId, type, from, to)) { + json.add(JsonConverter.objectToJson(event)); + } } } return json.build().toString(); diff --git a/src/org/traccar/reports/Route.java b/src/org/traccar/reports/Route.java index 7abe5c194..9622151e7 100644 --- a/src/org/traccar/reports/Route.java +++ b/src/org/traccar/reports/Route.java @@ -5,7 +5,7 @@ import java.util.Collection; import java.util.Date; import javax.json.Json; -import javax.json.JsonObjectBuilder; +import javax.json.JsonArrayBuilder; import org.traccar.Context; import org.traccar.model.Position; @@ -19,11 +19,12 @@ public final class Route { public static String getJson(long userId, Collection<Long> deviceIds, Collection<Long> groupIds, Date from, Date to) throws SQLException { - JsonObjectBuilder json = Json.createObjectBuilder(); + JsonArrayBuilder json = Json.createArrayBuilder(); for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); - json.add(String.valueOf(deviceId), JsonConverter.arrayToJson(Context.getDataManager() - .getPositions(deviceId, from, to))); + for (Position position : Context.getDataManager().getPositions(deviceId, from, to)) { + json.add(JsonConverter.objectToJson(position)); + } } return json.build().toString(); } diff --git a/src/org/traccar/reports/Summary.java b/src/org/traccar/reports/Summary.java index 474562002..e0da1c87e 100644 --- a/src/org/traccar/reports/Summary.java +++ b/src/org/traccar/reports/Summary.java @@ -7,7 +7,7 @@ import java.util.Collection; import java.util.Date; import javax.json.Json; -import javax.json.JsonObjectBuilder; +import javax.json.JsonArrayBuilder; import org.traccar.Context; import org.traccar.helper.DistanceCalculator; @@ -23,9 +23,10 @@ public final class Summary { private static SummaryReport calculateGeneralResult(long deviceId, Date from, Date to) throws SQLException { SummaryReport result = new SummaryReport(); + result.setDeviceId(deviceId); + result.setDeviceName(Context.getDeviceManager().getDeviceById(deviceId).getName()); Collection<Position> positions = Context.getDataManager().getPositions(deviceId, from, to); if (positions != null && !positions.isEmpty()) { - result.setDeviceName(Context.getDeviceManager().getDeviceById(deviceId).getName()); Position previousPosition = null; double speedSum = 0; for (Position position : positions) { @@ -45,10 +46,10 @@ public final class Summary { public static String getJson(long userId, Collection<Long> deviceIds, Collection<Long> groupIds, Date from, Date to) throws SQLException { - JsonObjectBuilder json = Json.createObjectBuilder(); + JsonArrayBuilder json = Json.createArrayBuilder(); for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); - json.add(String.valueOf(deviceId), JsonConverter.objectToJson(calculateGeneralResult(deviceId, from, to))); + json.add(JsonConverter.objectToJson(calculateGeneralResult(deviceId, from, to))); } return json.build().toString(); } diff --git a/src/org/traccar/reports/model/SummaryReport.java b/src/org/traccar/reports/model/SummaryReport.java index aed3915f1..e42727eaf 100644 --- a/src/org/traccar/reports/model/SummaryReport.java +++ b/src/org/traccar/reports/model/SummaryReport.java @@ -2,6 +2,14 @@ package org.traccar.reports.model; public class SummaryReport { + private long deviceId; + public long getDeviceId() { + return deviceId; + } + public void setDeviceId(long deviceId) { + this.deviceId = deviceId; + } + private String deviceName; public String getDeviceName() { return deviceName; diff --git a/web/app/Application.js b/web/app/Application.js index ec942d21e..22102f74b 100644 --- a/web/app/Application.js +++ b/web/app/Application.js @@ -33,7 +33,8 @@ Ext.define('Traccar.Application', { 'Command', 'Event', 'Geofence', - 'Notification' + 'Notification', + 'ReportSummary' ], stores: [ @@ -56,7 +57,11 @@ Ext.define('Traccar.Application', { 'AllGeofences', 'Notifications', 'AllNotifications', - 'GeofenceTypes' + 'GeofenceTypes', + 'ReportRoute', + 'ReportEvents', + 'ReportSummary', + 'ReportTypes' ], controllers: [ diff --git a/web/app/controller/Root.js b/web/app/controller/Root.js index 2c565747b..6d18f4073 100644 --- a/web/app/controller/Root.js +++ b/web/app/controller/Root.js @@ -73,6 +73,7 @@ Ext.define('Traccar.controller.Root', { }, loadApp: function () { + var attribution; Ext.getStore('Groups').load(); Ext.getStore('Geofences').load(); Ext.getStore('Devices').load({ @@ -81,7 +82,7 @@ Ext.define('Traccar.controller.Root', { this.asyncUpdate(true); } }); - var attribution = Ext.get('attribution'); + attribution = Ext.get('attribution'); if (attribution) { attribution.remove(); } diff --git a/web/app/model/ReportSummary.js b/web/app/model/ReportSummary.js new file mode 100644 index 000000000..7821e1c00 --- /dev/null +++ b/web/app/model/ReportSummary.js @@ -0,0 +1,37 @@ +/* + * Copyright 2016 Anton Tananaev (anton.tananaev@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +Ext.define('Traccar.model.ReportSummary', { + extend: 'Ext.data.Model', + identifier: 'negative', + + fields: [{ + name: 'deviceId', + type: 'int' + }, { + name: 'deviceName', + type: 'string' + }, { + name: 'maxSpeed', + type: 'float' + }, { + name: 'averageSpeed', + type: 'float' + }, { + name: 'distance', + type: 'float' + }] +}); diff --git a/web/app/store/ReportEvents.js b/web/app/store/ReportEvents.js new file mode 100644 index 000000000..bdef7a170 --- /dev/null +++ b/web/app/store/ReportEvents.js @@ -0,0 +1,28 @@ +/* + * Copyright 2016 Anton Tananaev (anton.tananaev@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +Ext.define('Traccar.store.ReportEvents', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Event', + + proxy: { + type: 'rest', + url: '/api/reports/events', + headers: { + 'Accept': 'application/json' + } + } +}); diff --git a/web/app/store/ReportRoute.js b/web/app/store/ReportRoute.js new file mode 100644 index 000000000..fc96fc022 --- /dev/null +++ b/web/app/store/ReportRoute.js @@ -0,0 +1,28 @@ +/* + * Copyright 2016 Anton Tananaev (anton.tananaev@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +Ext.define('Traccar.store.ReportRoute', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Position', + + proxy: { + type: 'rest', + url: '/api/reports/route', + headers: { + 'Accept': 'application/json' + } + } +}); diff --git a/web/app/store/ReportSummary.js b/web/app/store/ReportSummary.js new file mode 100644 index 000000000..2e4a8750d --- /dev/null +++ b/web/app/store/ReportSummary.js @@ -0,0 +1,28 @@ +/* + * Copyright 2016 Anton Tananaev (anton.tananaev@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +Ext.define('Traccar.store.ReportSummary', { + extend: 'Ext.data.Store', + model: 'Traccar.model.ReportSummary', + + proxy: { + type: 'rest', + url: '/api/reports/summary', + headers: { + 'Accept': 'application/json' + } + } +}); diff --git a/web/app/store/ReportTypes.js b/web/app/store/ReportTypes.js new file mode 100644 index 000000000..d544a2fda --- /dev/null +++ b/web/app/store/ReportTypes.js @@ -0,0 +1,31 @@ +/* + * Copyright 2016 Anton Tananaev (anton.tananaev@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +Ext.define('Traccar.store.ReportTypes', { + extend: 'Ext.data.Store', + fields: ['key', 'name'], + + data: [{ + key: 'route', + name: Strings.reportRoute + }, { + key: 'events', + name: Strings.reportEvents + }, { + key: 'summary', + name: Strings.reportSummary + }] +}); diff --git a/web/app/view/CommandDialog.js b/web/app/view/CommandDialog.js index 031815273..8e9a80dbf 100644 --- a/web/app/view/CommandDialog.js +++ b/web/app/view/CommandDialog.js @@ -29,7 +29,7 @@ Ext.define('Traccar.view.CommandDialog', { items: [{ xtype: 'combobox', name: 'type', - fieldLabel: Strings.commandType, + fieldLabel: Strings.sharedType, store: 'CommandTypes', displayField: 'name', valueField: 'type', diff --git a/web/app/view/MapController.js b/web/app/view/MapController.js index 6ef9f91e6..ab7461cf0 100644 --- a/web/app/view/MapController.js +++ b/web/app/view/MapController.js @@ -35,7 +35,7 @@ Ext.define('Traccar.view.MapController', { add: 'updateLatest', update: 'updateLatest' }, - '#Positions': { + '#ReportRoute': { load: 'loadReport', clear: 'clearReport' } diff --git a/web/app/view/Report.js b/web/app/view/Report.js index 4261b9040..7bcfdcb52 100644 --- a/web/app/view/Report.js +++ b/web/app/view/Report.js @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2015 - 2016 Anton Tananaev (anton.tananaev@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,12 +24,24 @@ Ext.define('Traccar.view.Report', { ], controller: 'report', - store: 'Positions', title: Strings.reportTitle, tbar: [{ xtype: 'tbtext', + html: Strings.sharedType + }, { + xtype: 'combobox', + reference: 'reportTypeField', + store: 'ReportTypes', + displayField: 'name', + valueField: 'key', + typeAhead: true, + listeners: { + change: 'onTypeChange' + } + }, '-', { + xtype: 'tbtext', html: Strings.reportDevice }, { xtype: 'combobox', @@ -69,7 +81,12 @@ Ext.define('Traccar.view.Report', { value: new Date() }, '-', { text: Strings.reportShow, - handler: 'onShowClick' + reference: 'showButton', + handler: 'onReportClick' + }, { + text: Strings.reportCsv, + reference: 'csvButton', + handler: 'onReportClick' }, { text: Strings.reportClear, handler: 'onClearClick' @@ -77,43 +94,5 @@ Ext.define('Traccar.view.Report', { listeners: { selectionchange: 'onSelectionChange' - }, - - columns: [{ - text: Strings.positionValid, - dataIndex: 'valid', - flex: 1, - renderer: Traccar.AttributeFormatter.getFormatter('valid') - }, { - text: Strings.positionFixTime, - dataIndex: 'fixTime', - flex: 1, - xtype: 'datecolumn', - renderer: Traccar.AttributeFormatter.getFormatter('fixTime') - }, { - text: Strings.positionLatitude, - dataIndex: 'latitude', - flex: 1, - renderer: Traccar.AttributeFormatter.getFormatter('latitude') - }, { - text: Strings.positionLongitude, - dataIndex: 'longitude', - flex: 1, - renderer: Traccar.AttributeFormatter.getFormatter('latitude') - }, { - text: Strings.positionAltitude, - dataIndex: 'altitude', - flex: 1, - renderer: Traccar.AttributeFormatter.getFormatter('altitude') - }, { - text: Strings.positionSpeed, - dataIndex: 'speed', - flex: 1, - renderer: Traccar.AttributeFormatter.getFormatter('speed') - }, { - text: Strings.positionAddress, - dataIndex: 'address', - flex: 1, - renderer: Traccar.AttributeFormatter.getFormatter('address') - }] + } }); diff --git a/web/app/view/ReportController.js b/web/app/view/ReportController.js index 4fe7c62b8..ecc7b0f91 100644 --- a/web/app/view/ReportController.js +++ b/web/app/view/ReportController.js @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2015 - 2016 Anton Tananaev (anton.tananaev@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,15 +29,17 @@ Ext.define('Traccar.view.ReportController', { } }, - onShowClick: function () { - var deviceId, fromDate, fromTime, from, toDate, toTime, to, store; + onReportClick: function (button) { + var reportType, deviceId, fromDate, fromTime, from, toDate, toTime, to, store, url; + + reportType = this.lookupReference('reportTypeField').getValue(); deviceId = this.lookupReference('deviceField').getValue(); fromDate = this.lookupReference('fromDateField').getValue(); fromTime = this.lookupReference('fromTimeField').getValue(); - if (deviceId) { + if (reportType && deviceId) { from = new Date( fromDate.getFullYear(), fromDate.getMonth(), fromDate.getDate(), fromTime.getHours(), fromTime.getMinutes(), fromTime.getSeconds(), fromTime.getMilliseconds()); @@ -49,19 +51,30 @@ Ext.define('Traccar.view.ReportController', { toDate.getFullYear(), toDate.getMonth(), toDate.getDate(), toTime.getHours(), toTime.getMinutes(), toTime.getSeconds(), toTime.getMilliseconds()); - store = Ext.getStore('Positions'); - store.load({ - params: { + if (button.reference === "showButton") { + store = this.getView().getStore(); + store.load({ + params: { + deviceId: deviceId, + type: '%', + from: from.toISOString(), + to: to.toISOString() + } + }); + } else if (button.reference === "csvButton") { + url = this.getView().getStore().getProxy().url; + this.downloadCsv(url, { deviceId: deviceId, + type: '%', from: from.toISOString(), to: to.toISOString() - } - }); + }); + } } }, onClearClick: function () { - Ext.getStore('Positions').removeAll(); + this.getView().getStore().removeAll(); }, onSelectionChange: function (selected) { @@ -77,6 +90,152 @@ Ext.define('Traccar.view.ReportController', { }, selectReport: function (position, center) { - this.getView().getSelectionModel().select([position], false, true); + if (position instanceof Traccar.model.Position) { + this.getView().getSelectionModel().select([position], false, true); + } + }, + + downloadCsv: function (requestUrl, requestParams) { + Ext.Ajax.request({ + url: requestUrl, + method: 'GET', + params: requestParams, + headers: { + Accept: 'text/csv' + }, + success: function (response) { + var disposition, filename, type, blob, url, downloadUrl, elementA; + disposition = response.getResponseHeader('Content-Disposition'); + filename = disposition.slice(disposition.indexOf("=") + 1, disposition.length); + type = response.getResponseHeader('Content-Type'); + blob = new Blob([response.responseText], { type: type }); + if (typeof window.navigator.msSaveBlob !== 'undefined') { + // IE workaround + window.navigator.msSaveBlob(blob, filename); + } else { + url = window.URL || window.webkitURL; + downloadUrl = URL.createObjectURL(blob); + if (filename) { + elementA = document.createElement("a"); + elementA.href = downloadUrl; + elementA.download = filename; + document.body.appendChild(elementA); + elementA.click(); + } + setTimeout(function () { + url.revokeObjectURL(downloadUrl); + }, 100); + } + } + }); + }, + + onTypeChange: function (combobox, newValue, oldValue) { + var routeColumns, eventsColumns, summaryColumns; + if (oldValue !== null) { + this.onClearClick(); + } + routeColumns = [{ + text: Strings.positionValid, + dataIndex: 'valid', + flex: 1, + renderer: Traccar.AttributeFormatter.getFormatter('valid') + }, { + text: Strings.positionFixTime, + dataIndex: 'fixTime', + flex: 1, + xtype: 'datecolumn', + renderer: Traccar.AttributeFormatter.getFormatter('fixTime') + }, { + text: Strings.positionLatitude, + dataIndex: 'latitude', + flex: 1, + renderer: Traccar.AttributeFormatter.getFormatter('latitude') + }, { + text: Strings.positionLongitude, + dataIndex: 'longitude', + flex: 1, + renderer: Traccar.AttributeFormatter.getFormatter('latitude') + }, { + text: Strings.positionAltitude, + dataIndex: 'altitude', + flex: 1, + renderer: Traccar.AttributeFormatter.getFormatter('altitude') + }, { + text: Strings.positionSpeed, + dataIndex: 'speed', + flex: 1, + renderer: Traccar.AttributeFormatter.getFormatter('speed') + }, { + text: Strings.positionAddress, + dataIndex: 'address', + flex: 1, + renderer: Traccar.AttributeFormatter.getFormatter('address') + }]; + + eventsColumns = [{ + text: Strings.positionFixTime, + dataIndex: 'serverTime', + flex: 1, + xtype: 'datecolumn', + renderer: Traccar.AttributeFormatter.getFormatter('serverTime') + }, { + text: Strings.reportDeviceName, + dataIndex: 'deviceId', + flex: 1, + renderer: function (value) { + return Ext.getStore('Devices').findRecord('id', value).get('name'); + } + }, { + text: Strings.sharedType, + dataIndex: 'type', + flex: 1, + renderer: function (value) { + var typeKey = 'event' + value.charAt(0).toUpperCase() + value.slice(1); + return Strings[typeKey]; + } + }, { + text: Strings.sharedGeofence, + dataIndex: 'geofenceId', + flex: 1, + renderer: function (value) { + if (value !== 0) { + return Ext.getStore('Geofences').findRecord('id', value).get('name'); + } + } + }]; + + summaryColumns = [{ + text: Strings.reportDeviceName, + dataIndex: 'deviceId', + flex: 1, + renderer: function (value) { + return Ext.getStore('Devices').findRecord('id', value).get('name'); + } + }, { + text: Strings.sharedDistance, + dataIndex: 'distance', + flex: 1, + renderer: Traccar.AttributeFormatter.getFormatter('distance') + }, { + text: Strings.reportAverageSpeed, + dataIndex: 'averageSpeed', + flex: 1, + renderer: Traccar.AttributeFormatter.getFormatter('speed') + }, { + text: Strings.reportMaximumSpeed, + dataIndex: 'maxSpeed', + flex: 1, + renderer: Traccar.AttributeFormatter.getFormatter('speed') + }]; + + if (newValue === 'route') { + this.getView().reconfigure('ReportRoute', routeColumns); + } else if (newValue === 'events') { + this.getView().reconfigure('ReportEvents', eventsColumns); + } else if (newValue === 'summary') { + this.getView().reconfigure('ReportSummary', summaryColumns); + } } + }); diff --git a/web/app/view/ServerDialog.js b/web/app/view/ServerDialog.js index 1af000042..dd4579168 100644 --- a/web/app/view/ServerDialog.js +++ b/web/app/view/ServerDialog.js @@ -54,7 +54,7 @@ Ext.define('Traccar.view.ServerDialog', { }, { xtype: 'combobox', name: 'distanceUnit', - fieldLabel: Strings.settingsDistanceUnit, + fieldLabel: Strings.sharedDistance, store: 'DistanceUnits', displayField: 'name', valueField: 'key' diff --git a/web/app/view/UserDialog.js b/web/app/view/UserDialog.js index df8a26e7e..07fc1431f 100644 --- a/web/app/view/UserDialog.js +++ b/web/app/view/UserDialog.js @@ -58,7 +58,7 @@ Ext.define('Traccar.view.UserDialog', { }, { xtype: 'combobox', name: 'distanceUnit', - fieldLabel: Strings.settingsDistanceUnit, + fieldLabel: Strings.sharedDistance, store: 'DistanceUnits', displayField: 'name', valueField: 'key' diff --git a/web/l10n/en.json b/web/l10n/en.json index 37e4537f2..b98e6d127 100644 --- a/web/l10n/en.json +++ b/web/l10n/en.json @@ -24,6 +24,8 @@ "sharedAttribute": "Attribute", "sharedArea": "Area", "sharedMute": "Mute", + "sharedType": "Type", + "sharedDistance": "Distance", "errorTitle": "Error", "errorUnknown": "Unknown error", "errorConnection": "Connection error", @@ -53,7 +55,6 @@ "settingsGroups": "Groups", "settingsServer": "Server", "settingsUsers": "Users", - "settingsDistanceUnit": "Distance", "settingsSpeedUnit": "Speed", "settingsTwelveHourFormat": "12-hour Format", "reportTitle": "Reports", @@ -89,7 +90,6 @@ "stateValue": "Value", "commandTitle": "Command", "commandSend": "Send", - "commandType": "Type", "commandSent": "Command has been sent", "commandPositionPeriodic": "Periodic Reporting", "commandPositionStop": "Stop Reporting", @@ -132,5 +132,12 @@ "alarmFault": "Fault Alarm", "notificationType": "Type of Notification", "notificationWeb": "Send via Web", - "notificationMail": "Send via Mail" + "notificationMail": "Send via Mail", + "reportRoute": "Route", + "reportEvents": "Events", + "reportSummary": "Summary", + "reportCsv": "CSV", + "reportDeviceName": "Device Name", + "reportAverageSpeed": "Average Speed", + "reportMaximumSpeed": "Maximum Speed" }
\ No newline at end of file |