aboutsummaryrefslogtreecommitdiff
path: root/web/app
diff options
context:
space:
mode:
authorAbyss777 <abyss@fox5.ru>2017-03-22 16:15:53 +0500
committerAbyss777 <abyss@fox5.ru>2017-03-22 16:15:53 +0500
commit7e95b0a294d99360ab728fd9ba3c82a472d87c7d (patch)
tree7c4e4521ccf9830b216996774081b061042af2e2 /web/app
parent0df9dc40451708f3f3904ba4c69a7e34ecc8e5be (diff)
downloadtrackermap-web-7e95b0a294d99360ab728fd9ba3c82a472d87c7d.tar.gz
trackermap-web-7e95b0a294d99360ab728fd9ba3c82a472d87c7d.tar.bz2
trackermap-web-7e95b0a294d99360ab728fd9ba3c82a472d87c7d.zip
Implement extended device filtering
Diffstat (limited to 'web/app')
-rw-r--r--web/app/Application.js4
-rw-r--r--web/app/Style.js2
-rw-r--r--web/app/controller/Root.js4
-rw-r--r--web/app/store/DeviceStatuses.js35
-rw-r--r--web/app/store/VisibleDevices.js22
-rw-r--r--web/app/view/Devices.js136
-rw-r--r--web/app/view/MapMarkerController.js67
7 files changed, 180 insertions, 90 deletions
diff --git a/web/app/Application.js b/web/app/Application.js
index f2baa0c5..9b450466 100644
--- a/web/app/Application.js
+++ b/web/app/Application.js
@@ -75,7 +75,9 @@ Ext.define('Traccar.Application', {
'DeviceImages',
'Calendars',
'AllCalendars',
- 'AllTimezones'
+ 'AllTimezones',
+ 'VisibleDevices',
+ 'DeviceStatuses'
],
controllers: [
diff --git a/web/app/Style.js b/web/app/Style.js
index d7f01f29..c594d92e 100644
--- a/web/app/Style.js
+++ b/web/app/Style.js
@@ -34,7 +34,7 @@ Ext.define('Traccar.Style', {
dateFormat: 'Y-m-d',
weekStartDay: 1,
- deviceWidth: 350,
+ deviceWidth: 400,
reportHeight: 250,
diff --git a/web/app/controller/Root.js b/web/app/controller/Root.js
index b858b20c..e8d4f0ff 100644
--- a/web/app/controller/Root.js
+++ b/web/app/controller/Root.js
@@ -25,6 +25,10 @@ Ext.define('Traccar.controller.Root', {
'Traccar.model.Position'
],
+ init: function () {
+ Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
+ },
+
onLaunch: function () {
Ext.Ajax.request({
scope: this,
diff --git a/web/app/store/DeviceStatuses.js b/web/app/store/DeviceStatuses.js
new file mode 100644
index 00000000..14c1f950
--- /dev/null
+++ b/web/app/store/DeviceStatuses.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+Ext.define('Traccar.store.DeviceStatuses', {
+ extend: 'Ext.data.Store',
+ fields: ['id', 'name', 'tdCls'],
+
+ data: [{
+ id: 'online',
+ name: Strings.deviceStatusOnline,
+ tdCls: 'view-color-green'
+ }, {
+ id: 'offline',
+ name: Strings.deviceStatusOffline,
+ tdCls: 'view-color-red'
+ }, {
+ id: 'unknown',
+ name: Strings.deviceStatusUnknown,
+ tdCls: 'view-color-yellow'
+ }]
+});
diff --git a/web/app/store/VisibleDevices.js b/web/app/store/VisibleDevices.js
new file mode 100644
index 00000000..db1ca7da
--- /dev/null
+++ b/web/app/store/VisibleDevices.js
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+Ext.define('Traccar.store.VisibleDevices', {
+ extend: 'Ext.data.ChainedStore',
+ source: 'Devices'
+});
diff --git a/web/app/view/Devices.js b/web/app/view/Devices.js
index 645b8e7f..165fd032 100644
--- a/web/app/view/Devices.js
+++ b/web/app/view/Devices.js
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,20 +20,19 @@ Ext.define('Traccar.view.Devices', {
xtype: 'devicesView',
requires: [
+ 'Ext.grid.filters.Filters',
'Traccar.view.DevicesController',
'Traccar.view.EditToolbar'
],
controller: 'devices',
- rootVisible: false,
- initComponent: function () {
- this.store = Ext.create('Ext.data.ChainedStore', {
- source: 'Devices',
- groupField: 'groupId'
- });
- this.callParent();
- },
+ plugins: 'gridfilters',
+
+ store: 'VisibleDevices',
+
+ stateful: true,
+ stateId: 'devices-grid',
tbar: {
componentCls: 'toolbar-header-style',
@@ -85,79 +84,30 @@ Ext.define('Traccar.view.Devices', {
}]
},
- bbar: [{
- xtype: 'tbtext',
- html: Strings.groupParent
- }, {
- xtype: 'combobox',
- store: 'Groups',
- queryMode: 'local',
- displayField: 'name',
- valueField: 'id',
- flex: 1,
- listeners: {
- change: function () {
- if (Ext.isNumber(this.getValue())) {
- this.up('grid').store.filter({
- id: 'groupFilter',
- filterFn: function (item) {
- var groupId, group, groupStore, filter = true;
- groupId = item.get('groupId');
- groupStore = Ext.getStore('Groups');
-
- while (groupId) {
- group = groupStore.getById(groupId);
- if (group) {
- if (group.get('id') === this.getValue()) {
- filter = false;
- break;
- }
- groupId = group.get('groupId');
- } else {
- groupId = 0;
- }
- }
-
- return !filter;
- },
- scope: this
- });
- } else {
- this.up('grid').store.removeFilter('groupFilter');
- }
- }
- }
- }, {
- xtype: 'tbtext',
- html: Strings.sharedSearch
- }, {
- xtype: 'textfield',
- flex: 1,
- listeners: {
- change: function () {
- this.up('grid').store.filter('name', this.getValue());
- }
- }
- }],
-
listeners: {
selectionchange: 'onSelectionChange'
},
columns: {
defaults: {
- flex: 1,
+ flex: 2,
minWidth: Traccar.Style.columnWidthNormal
},
items: [{
text: Strings.sharedName,
- dataIndex: 'name'
+ dataIndex: 'name',
+ filter: {
+ type: 'string',
+ itemDefaults: {
+ emptyText: Strings.deviceSearchFor
+ }
+ }
}, {
text: Strings.deviceIdentifier,
dataIndex: 'uniqueId',
hidden: true
}, {
- text: Strings.devicePhone,
+ text: Strings.sharedPhone,
dataIndex: 'phone',
hidden: true
}, {
@@ -169,26 +119,46 @@ Ext.define('Traccar.view.Devices', {
dataIndex: 'contact',
hidden: true
}, {
+ text: Strings.groupDialog,
+ dataIndex: 'groupId',
+ hidden: true,
+ filter: {
+ type: 'list',
+ labelField: 'name',
+ store: 'Groups'
+ },
+ renderer: function (value) {
+ var group;
+ if (value !== 0) {
+ group = Ext.getStore('Groups').getById(value);
+ return group ? group.get('name') : value;
+ }
+ }
+ }, {
text: Strings.deviceLastUpdate,
dataIndex: 'lastUpdate',
- renderer: function (value, metaData, record) {
- switch (record.get('status')) {
- case 'online':
- metaData.tdCls = 'view-color-green';
- break;
- case 'offline':
- metaData.tdCls = 'view-color-red';
- break;
- default:
- metaData.tdCls = 'view-color-yellow';
- break;
- }
- if (Traccar.app.getPreference('twelveHourFormat', false)) {
- return Ext.Date.format(value, Traccar.Style.dateTimeFormat12);
- } else {
- return Ext.Date.format(value, Traccar.Style.dateTimeFormat24);
+ renderer: function (value) {
+ if (value) {
+ if (Traccar.app.getPreference('twelveHourFormat', false)) {
+ return Ext.Date.format(value, Traccar.Style.dateTimeFormat12);
+ } else {
+ return Ext.Date.format(value, Traccar.Style.dateTimeFormat24);
+ }
}
}
+ }, {
+ text: Strings.deviceStatus,
+ dataIndex: 'status',
+ flex: 1,
+ filter: {
+ type: 'list',
+ labelField: 'name',
+ store: 'DeviceStatuses'
+ },
+ renderer: function (value, metaData) {
+ metaData.tdCls = Ext.getStore('DeviceStatuses').getById(value).get('tdCls');
+ return Ext.getStore('DeviceStatuses').getById(value).get('name');
+ }
}]
}
});
diff --git a/web/app/view/MapMarkerController.js b/web/app/view/MapMarkerController.js
index bb418704..bf3a2c0d 100644
--- a/web/app/view/MapMarkerController.js
+++ b/web/app/view/MapMarkerController.js
@@ -40,6 +40,12 @@ Ext.define('Traccar.view.MapMarkerController', {
update: 'updateDevice',
remove: 'removeDevice'
},
+ '#VisibleDevices': {
+ add: 'updateVisibleDevice',
+ update: 'updateVisibleDevice',
+ remove: 'updateVisibleDevice',
+ refresh: 'filterDevices'
+ },
'#LatestPositions': {
add: 'updateLatest',
update: 'updateLatest'
@@ -198,11 +204,11 @@ Ext.define('Traccar.view.MapMarkerController', {
} else {
feature = new ol.Feature(new ol.geom.Circle(center, radius));
feature.setStyle(this.getAreaStyle(null, Traccar.Style.mapAccuracyColor));
- this.getView().getAccuracySource().addFeature(feature);
+ feature.setId(position.get('deviceId'));
this.accuracyCircles[position.get('deviceId')] = feature;
}
} else {
- if (feature) {
+ if (feature && this.getView().getAccuracySource().getFeatureById(feature.getId())) {
this.getView().getAccuracySource().removeFeature(feature);
}
delete this.accuracyCircles[position.get('deviceId')];
@@ -232,9 +238,9 @@ Ext.define('Traccar.view.MapMarkerController', {
device.get('category'));
style.getText().setText(device.get('name'));
marker.setStyle(style);
+ marker.setId(device.get('id'));
this.latestMarkers[deviceId] = marker;
- this.getView().getMarkersSource().addFeature(marker);
-
+ this.checkDeviceVisibility(device);
}
if (marker === this.selectedMarker && this.lookupReference('deviceFollowButton').pressed) {
@@ -268,8 +274,8 @@ Ext.define('Traccar.view.MapMarkerController', {
])
});
liveLine.setStyle(this.getRouteStyle(deviceId));
+ liveLine.setId(position.get('deviceId'));
this.liveRoutes[deviceId] = liveLine;
- this.getView().getLiveRouteSource().addFeature(liveLine);
}
},
@@ -488,5 +494,56 @@ Ext.define('Traccar.view.MapMarkerController', {
} else if (point) {
this.getView().getMapView().fit(new ol.geom.Point(point));
}
+ },
+
+ updateVisibleDevice: function (store, data) {
+ var i, device;
+
+ if (!Ext.isArray(data)) {
+ data = [data];
+ }
+
+ for (i = 0; i < data.length; i++) {
+ device = data[i];
+ if (device.get('id') in this.latestMarkers) {
+ this.checkDeviceVisibility(device);
+ }
+ }
+ },
+
+ checkDeviceVisibility: function (device) {
+ var deviceId, accuracy, liveLine, marker;
+ deviceId = device.get('id');
+ marker = this.latestMarkers[deviceId];
+ accuracy = this.accuracyCircles[deviceId];
+ liveLine = this.liveRoutes[deviceId];
+ if (Ext.getStore('VisibleDevices').contains(device)) {
+ if (marker && !this.getView().getMarkersSource().getFeatureById(marker.getId())) {
+ this.getView().getMarkersSource().addFeature(marker);
+ }
+ if (accuracy && !this.getView().getAccuracySource().getFeatureById(accuracy.getId())) {
+ this.getView().getAccuracySource().addFeature(accuracy);
+ }
+ if (liveLine && !this.getView().getLiveRouteSource().getFeatureById(liveLine.getId())) {
+ this.getView().getLiveRouteSource().addFeature(liveLine);
+ }
+ } else {
+ if (marker && this.getView().getMarkersSource().getFeatureById(marker.getId())) {
+ this.getView().getMarkersSource().removeFeature(marker);
+ }
+ if (this.selectedMarker && marker && marker.getId() === this.selectedMarker.getId()) {
+ this.deselectFeature();
+ }
+ if (accuracy && this.getView().getAccuracySource().getFeatureById(accuracy.getId())) {
+ this.getView().getAccuracySource().removeFeature(accuracy);
+ }
+ if (liveLine && this.getView().getLiveRouteSource().getFeatureById(liveLine.getId())) {
+ this.getView().getLiveRouteSource().removeFeature(liveLine);
+ }
+ }
+ },
+
+ filterDevices: function (store) {
+ Ext.getStore('Devices').each(this.checkDeviceVisibility, this, false);
}
});