aboutsummaryrefslogtreecommitdiff
path: root/web/app
diff options
context:
space:
mode:
Diffstat (limited to 'web/app')
-rw-r--r--web/app/Style.js10
-rw-r--r--web/app/controller/Root.js29
-rw-r--r--web/app/model/Device.js6
-rw-r--r--web/app/view/Devices.js29
-rw-r--r--web/app/view/Login.js2
-rw-r--r--web/app/view/Main.js5
-rw-r--r--web/app/view/Map.js32
-rw-r--r--web/app/view/MapController.js79
8 files changed, 157 insertions, 35 deletions
diff --git a/web/app/Style.js b/web/app/Style.js
index 58ab059ad..5202a3fb2 100644
--- a/web/app/Style.js
+++ b/web/app/Style.js
@@ -48,13 +48,13 @@ Ext.define('Traccar.Style', {
mapTextOffset: 10,
mapTextFont: 'bold 12px sans-serif',
- mapColorOnline: '#4DFA90',
- mapColorUnknown: '#FABE4D',
- mapColorOffline: '#FF5468',
+ mapColorOnline: 'rgba(77, 250, 144, 1.0)',
+ mapColorUnknown: 'rgba(250, 190, 77, 1.0)',
+ mapColorOffline: 'rgba(255, 84, 104, 1.0)',
mapColorReport: 'rgba(21, 127, 204, 1.0)',
- mapRadiusNormal: 10,
- mapRadiusSelected: 15,
+ mapRadiusNormal: 9,
+ mapRadiusSelected: 14,
mapMaxZoom: 19,
mapDelay: 500
diff --git a/web/app/controller/Root.js b/web/app/controller/Root.js
index 79827b8a6..733055cdf 100644
--- a/web/app/controller/Root.js
+++ b/web/app/controller/Root.js
@@ -40,6 +40,7 @@ Ext.define('Traccar.controller.Root', {
onServerReturn: function (options, success, response) {
var result;
+ Ext.get('spinner').remove();
if (Traccar.ErrorManager.check(success, response)) {
result = Ext.decode(response.responseText);
if (result.success) {
@@ -96,19 +97,35 @@ Ext.define('Traccar.controller.Root', {
first: first
},
callback: Traccar.app.getErrorHandler(this, function (options, success, response) {
- var i, store, data, position;
+ var i, deviceStore, positionStore, data, devices, positions, device, position;
if (success) {
- store = Ext.getStore('LatestPositions');
+ deviceStore = Ext.getStore('Devices');
+ positionStore = Ext.getStore('LatestPositions');
data = Ext.decode(response.responseText).data;
+ devices = data.devices;
+ positions = data.positions;
- for (i = 0; i < data.length; i++) {
- position = store.findRecord('deviceId', data[i].deviceId, 0, false, false, true);
+ for (i = 0; i < devices.length; i++) {
+ device = deviceStore.findRecord('id', devices[i].id, 0, false, false, true);
+ if (device) {
+ device.set({
+ status: devices[i].status,
+ lastUpdate: devices[i].lastUpdate
+ }, {
+ dirty: false
+ });
+ }
+ }
+
+ for (i = 0; i < positions.length; i++) {
+ position = positionStore.findRecord('deviceId', positions[i].deviceId, 0, false, false, true);
if (position) {
- position.set(data[i]);
+ position.set(positions[i]);
} else {
- store.add(Ext.create('Traccar.model.Position', data[i]));
+ positionStore.add(Ext.create('Traccar.model.Position', positions[i]));
}
}
+
this.asyncUpdate(false);
}
})
diff --git a/web/app/model/Device.js b/web/app/model/Device.js
index e9ed1f680..983e3e62e 100644
--- a/web/app/model/Device.js
+++ b/web/app/model/Device.js
@@ -27,5 +27,11 @@ Ext.define('Traccar.model.Device', {
}, {
name: 'uniqueId',
type: 'string'
+ }, {
+ name: 'status',
+ type: 'string'
+ }, {
+ name: 'lastUpdate',
+ type: 'date'
}]
});
diff --git a/web/app/view/Devices.js b/web/app/view/Devices.js
index 9dcd76a55..21bea6980 100644
--- a/web/app/view/Devices.js
+++ b/web/app/view/Devices.js
@@ -42,6 +42,12 @@ Ext.define('Traccar.view.Devices', {
}, {
xtype: 'tbfill'
}, {
+ id:'deviceFollowButton',
+ glyph: 'xf05b@FontAwesome',
+ tooltip: Strings.deviceFollow,
+ tooltipType: 'title',
+ enableToggle: true
+ }, {
xtype: 'settingsMenu'
}]
},
@@ -52,10 +58,27 @@ Ext.define('Traccar.view.Devices', {
columns: [{
text: Strings.deviceName,
- dataIndex: 'name', flex: 1
+ dataIndex: 'name',
+ flex: 1
}, {
- text: Strings.deviceIdentifier,
- dataIndex: 'uniqueId', flex: 1
+ text: Strings.deviceLastUpdate,
+ dataIndex: 'lastUpdate',
+ flex: 1,
+ renderer: function (value, metaData, record) {
+ var status = record.get('status');
+ switch (status) {
+ case 'online':
+ metaData.tdCls = 'status-color-online';
+ break;
+ case 'offline':
+ metaData.tdCls = 'status-color-offline';
+ break;
+ default:
+ metaData.tdCls = 'status-color-unknown';
+ break;
+ }
+ return Ext.Date.format(value, Traccar.Style.dateTimeFormat);
+ }
}]
});
diff --git a/web/app/view/Login.js b/web/app/view/Login.js
index 14a3fa41f..9c8187ed6 100644
--- a/web/app/view/Login.js
+++ b/web/app/view/Login.js
@@ -35,7 +35,7 @@ Ext.define('Traccar.view.Login', {
autoEl: {
tag: 'form',
method: 'GET',
- action: 'favicon.ico',
+ action: 'blank.html',
target: 'submitTarget'
},
diff --git a/web/app/view/Main.js b/web/app/view/Main.js
index 3bd7256f7..6b4daf138 100644
--- a/web/app/view/Main.js
+++ b/web/app/view/Main.js
@@ -54,7 +54,10 @@ Ext.define('Traccar.view.Main', {
}, {
region: 'south',
xtype: 'reportView',
- height: Traccar.Style.reportHeight
+ height: Traccar.Style.reportHeight,
+ collapsed: true,
+ titleCollapse: true,
+ floatable: false
}, {
region: 'center',
xtype: 'mapView',
diff --git a/web/app/view/Map.js b/web/app/view/Map.js
index 7d81699a3..b8c0d8dc5 100644
--- a/web/app/view/Map.js
+++ b/web/app/view/Map.js
@@ -35,13 +35,21 @@ Ext.define('Traccar.view.Map', {
return this.mapView;
},
- getVectorSource: function () {
- return this.vectorSource;
+ getLatestSource: function () {
+ return this.latestSource;
+ },
+
+ getRouteSource: function () {
+ return this.routeSource;
+ },
+
+ getReportSource: function () {
+ return this.reportSource;
},
listeners: {
afterrender: function () {
- var user, server, layer, type, bingKey, vectorLayer, lat, lon, zoom, target;
+ var user, server, layer, type, bingKey, latestLayer, routeLayer, reportLayer, lat, lon, zoom, target;
user = Traccar.app.getUser();
server = Traccar.app.getServer();
@@ -78,9 +86,19 @@ Ext.define('Traccar.view.Map', {
});
}
- this.vectorSource = new ol.source.Vector({});
- vectorLayer = new ol.layer.Vector({
- source: this.vectorSource
+ this.latestSource = new ol.source.Vector({});
+ latestLayer = new ol.layer.Vector({
+ source: this.latestSource
+ });
+
+ this.routeSource = new ol.source.Vector({});
+ routeLayer = new ol.layer.Vector({
+ source: this.routeSource
+ });
+
+ this.reportSource = new ol.source.Vector({});
+ reportLayer = new ol.layer.Vector({
+ source: this.reportSource
});
lat = user.get('latitude') || server.get('latitude') || Traccar.Style.mapDefaultLat;
@@ -95,7 +113,7 @@ Ext.define('Traccar.view.Map', {
this.map = new ol.Map({
target: this.body.dom.id,
- layers: [layer, vectorLayer],
+ layers: [layer, routeLayer, reportLayer, latestLayer],
view: this.mapView
});
diff --git a/web/app/view/MapController.js b/web/app/view/MapController.js
index c153ebd45..e4ce53b57 100644
--- a/web/app/view/MapController.js
+++ b/web/app/view/MapController.js
@@ -27,6 +27,10 @@ Ext.define('Traccar.view.MapController', {
}
},
store: {
+ '#Devices': {
+ add: 'updateDevice',
+ update: 'updateDevice'
+ },
'#LatestPositions': {
add: 'updateLatest',
update: 'updateLatest'
@@ -49,6 +53,54 @@ Ext.define('Traccar.view.MapController', {
this.reportMarkers = {};
},
+ getDeviceColor: function (device) {
+ switch (device.get('status')) {
+ case 'online':
+ return Traccar.Style.mapColorOnline;
+ case 'offline':
+ return Traccar.Style.mapColorOffline;
+ default:
+ return Traccar.Style.mapColorUnknown;
+ }
+ },
+
+ changeMarkerColor: function (style, color) {
+ return new ol.style.Style({
+ image: new ol.style.Arrow({
+ radius: style.getImage().getRadius(),
+ fill: new ol.style.Fill({
+ color: color
+ }),
+ stroke: style.getImage().getStroke(),
+ rotation: style.getImage().getRotation()
+ }),
+ text: style.getText()
+ });
+ },
+
+ updateDevice: function (store, data) {
+ var i, device, deviceId;
+
+ if (!Ext.isArray(data)) {
+ data = [data];
+ }
+
+ for (i = 0; i < data.length; i++) {
+ device = data[i];
+ deviceId = device.get('id');
+
+ if (deviceId in this.latestMarkers) {
+ marker = this.latestMarkers[deviceId];
+ marker.setStyle(
+ this.changeMarkerColor(marker.getStyle(), this.getDeviceColor(device)));
+ }
+ }
+ },
+
+ followSelected: function () {
+ return Ext.getCmp('deviceFollowButton') && Ext.getCmp('deviceFollowButton').pressed;
+ },
+
updateLatest: function (store, data) {
var i, position, geometry, device, deviceId, marker, style;
@@ -73,14 +125,18 @@ Ext.define('Traccar.view.MapController', {
marker = new ol.Feature(geometry);
marker.set('record', device);
this.latestMarkers[deviceId] = marker;
- this.getView().getVectorSource().addFeature(marker);
+ this.getView().getLatestSource().addFeature(marker);
- style = this.getLatestMarker();
+ style = this.getLatestMarker(this.getDeviceColor(device));
style.getText().setText(device.get('name'));
marker.setStyle(style);
}
marker.getStyle().getImage().setRotation(position.get('course') * Math.PI / 180);
+
+ if (marker === this.selectedMarker && this.followSelected()) {
+ this.getView().getMapView().setCenter(marker.getGeometry().getCoordinates());
+ }
}
},
@@ -93,7 +149,7 @@ Ext.define('Traccar.view.MapController', {
geometry: new ol.geom.LineString([])
});
this.reportRoute.setStyle(this.getRouteStyle());
- this.getView().getVectorSource().addFeature(this.reportRoute);
+ this.getView().getRouteSource().addFeature(this.reportRoute);
for (i = 0; i < data.length; i++) {
position = data[i];
@@ -107,12 +163,12 @@ Ext.define('Traccar.view.MapController', {
marker = new ol.Feature(geometry);
marker.set('record', position);
this.reportMarkers[position.get('id')] = marker;
- this.getView().getVectorSource().addFeature(marker);
+ this.getView().getReportSource().addFeature(marker);
style = this.getReportMarker();
style.getImage().setRotation(position.get('course') * Math.PI / 180);
- style.getText().setText(
- Ext.Date.format(position.get('fixTime'), Traccar.Style.dateTimeFormat));
+ /*style.getText().setText(
+ Ext.Date.format(position.get('fixTime'), Traccar.Style.dateTimeFormat));*/
marker.setStyle(style);
@@ -121,18 +177,17 @@ Ext.define('Traccar.view.MapController', {
},
clearReport: function (store) {
- var vectorSource, key;
- vectorSource = this.getView().getVectorSource();
+ var key;
if (this.reportRoute) {
- vectorSource.removeFeature(this.reportRoute);
+ this.getView().getRouteSource().removeFeature(this.reportRoute);
this.reportRoute = null;
}
if (this.reportMarkers) {
for (key in this.reportMarkers) {
if (this.reportMarkers.hasOwnProperty(key)) {
- vectorSource.removeFeature(this.reportMarkers[key]);
+ this.getView().getReportSource().removeFeature(this.reportMarkers[key]);
}
}
this.reportMarkers = {};
@@ -175,9 +230,9 @@ Ext.define('Traccar.view.MapController', {
});
},
- getLatestMarker: function () {
+ getLatestMarker: function (color) {
return this.getMarkerStyle(
- Traccar.Style.mapRadiusNormal, Traccar.Style.mapColorUnknown);
+ Traccar.Style.mapRadiusNormal, color);
},
getReportMarker: function () {