diff options
86 files changed, 1758 insertions, 651 deletions
diff --git a/tools/minify.bat b/tools/minify.bat index 6ab8fd94..bb350bf5 100644 --- a/tools/minify.bat +++ b/tools/minify.bat @@ -1,5 +1,5 @@ @echo off cd C:\[traccar path]\traccar\web -set SDK=C:\[sencha path]\ext-6.0.0 +set SDK=C:\[sencha path]\ext-6.2.0 sencha -sdk %SDK% compile -classpath=app.js,app,%SDK%\packages\core\src,%SDK%\packages\core\overrides,%SDK%\classic\classic\src,%SDK%\classic\classic\overrides exclude -all and include -recursive -file app.js and exclude -namespace=Ext and concatenate -closure app.min.js diff --git a/tools/minify.sh b/tools/minify.sh index 0b86320b..24abde32 100755 --- a/tools/minify.sh +++ b/tools/minify.sh @@ -2,7 +2,7 @@ cd $(dirname $0)/../web -SDK="../../../ext-6.0.1" +SDK="../../../ext-6.2.0" sencha compile --classpath=app.js,app,$SDK/packages/core/src,$SDK/packages/core/overrides,$SDK/classic/classic/src,$SDK/classic/classic/overrides \ exclude -all \ diff --git a/web/.jscsrc b/web/.jscsrc index 7d924ab9..70c9dc48 100644 --- a/web/.jscsrc +++ b/web/.jscsrc @@ -1,4 +1,5 @@ { "preset": "crockford", - "maxErrors": 100 + "maxErrors": 100, + "excludeFiles": ["simple/app.js"] } diff --git a/web/.jshintignore b/web/.jshintignore index 52da2c02..0a20d51b 100644 --- a/web/.jshintignore +++ b/web/.jshintignore @@ -1 +1,2 @@ locale.js +simple/app.js diff --git a/web/app/Application.js b/web/app/Application.js index 6f4cb1dd..daa25b85 100644 --- a/web/app/Application.js +++ b/web/app/Application.js @@ -37,7 +37,8 @@ Ext.define('Traccar.Application', { 'Notification', 'AttributeAlias', 'ReportSummary', - 'ReportTrip' + 'ReportTrip', + 'Calendar' ], stores: [ @@ -70,7 +71,9 @@ Ext.define('Traccar.Application', { 'ReportTypes', 'ReportEventTypes', 'Statistics', - 'DeviceImages' + 'DeviceImages', + 'Calendars', + 'AllCalendars' ], controllers: [ @@ -81,6 +84,11 @@ Ext.define('Traccar.Application', { return window.matchMedia && window.matchMedia('(max-width: 768px)').matches; }, + getEventString: function (eventType) { + var key = 'event' + eventType.charAt(0).toUpperCase() + eventType.slice(1); + return Strings[key] || key; + }, + showReports: function (show) { var rootPanel = Ext.getCmp('rootPanel'); if (rootPanel) { diff --git a/web/app/DeviceImages.js b/web/app/DeviceImages.js index a05a8153..b31f3ed3 100644 --- a/web/app/DeviceImages.js +++ b/web/app/DeviceImages.js @@ -98,15 +98,8 @@ Ext.define('Traccar.DeviceImages', { }, rotateImageIcon: function (image, angle) { - var svg = Traccar.DeviceImages.getImageSvg(image.fill, image.zoom, angle, image.category); + var svg = this.getImageSvg(image.fill, image.zoom, angle, image.category); image.getImage().src = this.formatSrc(svg); image.angle = angle; - }, - - changeImageColor: function (image, color, category) { - var svg = Traccar.DeviceImages.getImageSvg(color, image.zoom, image.angle, category); - image.getImage().src = this.formatSrc(svg); - image.fill = color; - image.category = category; } }); diff --git a/web/app/GeofenceConverter.js b/web/app/GeofenceConverter.js index f0e28b3f..9e3c1327 100644 --- a/web/app/GeofenceConverter.js +++ b/web/app/GeofenceConverter.js @@ -49,6 +49,20 @@ Ext.define('Traccar.GeofenceConverter', { geometry = new ol.geom.Circle(center, radius); } } + } else if (wkt.lastIndexOf('LINESTRING', 0) === 0) { + content = wkt.match(/\([^\(\)]+\)/); + if (content !== null) { + coordinates = content[0].match(/-?\d+\.?\d*/g); + if (coordinates !== null) { + projection = mapView.getProjection(); + for (i = 0; i < coordinates.length; i += 2) { + lat = Number(coordinates[i]); + lon = Number(coordinates[i + 1]); + points.push(ol.proj.transform([lon, lat], 'EPSG:4326', projection)); + } + geometry = new ol.geom.LineString(points); + } + } } return geometry; }, @@ -74,6 +88,14 @@ Ext.define('Traccar.GeofenceConverter', { result += points[0][i][1] + ' ' + points[0][i][0] + ', '; } result = result.substring(0, result.length - 2) + '))'; + } else if (geometry instanceof ol.geom.LineString) { + geometry.transform(projection, 'EPSG:4326'); + points = geometry.getCoordinates(); + result = 'LINESTRING ('; + for (i = 0; i < points.length; i += 1) { + result += points[i][1] + ' ' + points[i][0] + ', '; + } + result = result.substring(0, result.length - 2) + ')'; } return result; } diff --git a/web/app/Style.js b/web/app/Style.js index 4960aefa..c5fce9b6 100644 --- a/web/app/Style.js +++ b/web/app/Style.js @@ -18,6 +18,8 @@ Ext.define('Traccar.Style', { singleton: true, + reconnectTimeout: 60 * 1000, + normalPadding: 10, windowWidth: 640, @@ -76,7 +78,5 @@ Ext.define('Traccar.Style', { coordinatePrecision: 6, numberPrecision: 2, - reportTagfieldWidth: 375, - - headerButtonsMargin: '0 5' + reportTagfieldWidth: 375 }); diff --git a/web/app/controller/Root.js b/web/app/controller/Root.js index e30446c9..0cc2a148 100644 --- a/web/app/controller/Root.js +++ b/web/app/controller/Root.js @@ -75,7 +75,7 @@ Ext.define('Traccar.controller.Root', { }, loadApp: function () { - var attribution; + var attribution, eventId; Ext.getStore('Groups').load(); Ext.getStore('Geofences').load(); Ext.getStore('AttributeAliases').load(); @@ -94,6 +94,11 @@ Ext.define('Traccar.controller.Root', { } else { Ext.create('widget.main'); } + eventId = Ext.Object.fromQueryString(window.location.search).eventId; + if (eventId) { + this.fireEvent('showsingleevent', eventId); + this.removeUrlParameter('eventId'); + } }, beep: function () { @@ -108,103 +113,117 @@ Ext.define('Traccar.controller.Root', { return muteButton && !muteButton.pressed; }, + removeUrlParameter: function (param) { + var params = Ext.Object.fromQueryString(window.location.search); + delete params[param]; + if (Ext.Object.isEmpty(params)) { + window.history.pushState(null, null, window.location.pathname); + } else { + window.history.pushState(null, null, window.location.pathname + '?' + Ext.Object.toQueryString(params)); + } + }, + asyncUpdate: function (first) { - var protocol, pathname, socket, self = this; + var self = this, protocol, pathname, socket; protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; pathname = window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/') + 1); socket = new WebSocket(protocol + '//' + window.location.host + pathname + 'api/socket'); socket.onclose = function (event) { - self.asyncUpdate(false); + Ext.toast(Strings.errorSocket, Strings.errorTitle, 'br'); + + Ext.Ajax.request({ + url: 'api/devices', + success: function(response) { + self.updateDevices(Ext.decode(response.responseText)); + } + }); + + Ext.Ajax.request({ + url: 'api/positions', + headers: { + Accept: 'application/json' + }, + success: function(response) { + self.updatePositions(Ext.decode(response.responseText)); + } + }); + + setTimeout(function() { + self.asyncUpdate(false); + }, Traccar.Style.reconnectTimeout); }; socket.onmessage = function (event) { - var i, j, store, data, array, entity, device, typeKey, alarmKey, text, geofence; - - data = Ext.decode(event.data); + var data = Ext.decode(event.data); if (data.devices) { - array = data.devices; - store = Ext.getStore('Devices'); - for (i = 0; i < array.length; i++) { - entity = store.getById(array[i].id); - if (entity) { - entity.set({ - status: array[i].status, - lastUpdate: array[i].lastUpdate - }, { - dirty: false - }); - } - } + self.updateDevices(data.devices); + } + if (data.positions) { + self.updatePositions(data.positions); } + if (data.events) { + self.updateEvents(data.events); + } + }; + }, - if (data.positions && !data.events) { - array = data.positions; - store = Ext.getStore('LatestPositions'); - for (i = 0; i < array.length; i++) { - entity = store.findRecord('deviceId', array[i].deviceId, 0, false, false, true); - if (entity) { - entity.set(array[i]); - } else { - store.add(Ext.create('Traccar.model.Position', array[i])); - } - } + updateDevices: function (array) { + var i, store, entity; + store = Ext.getStore('Devices'); + for (i = 0; i < array.length; i++) { + entity = store.getById(array[i].id); + if (entity) { + entity.set({ + status: array[i].status, + lastUpdate: array[i].lastUpdate + }, { + dirty: false + }); } + } + }, - if (data.events) { - array = data.events; - store = Ext.getStore('Events'); - for (i = 0; i < array.length; i++) { - store.add(array[i]); - if (array[i].type === 'commandResult' && data.positions) { - for (j = 0; j < data.positions.length; j++) { - if (data.positions[j].id === array[i].positionId) { - text = data.positions[j].attributes.result; - break; - } - } - text = Strings.eventCommandResult + ': ' + text; - } else if (array[i].type === 'alarm' && data.positions) { - alarmKey = 'alarm'; - text = Strings[alarmKey]; - if (!text) { - text = alarmKey; - } - for (j = 0; j < data.positions.length; j++) { - if (data.positions[j].id === array[i].positionId && data.positions[j].attributes.alarm !== null) { - if (typeof data.positions[j].attributes.alarm === 'string' && data.positions[j].attributes.alarm.length >= 2) { - alarmKey = 'alarm' + data.positions[j].attributes.alarm.charAt(0).toUpperCase() + data.positions[j].attributes.alarm.slice(1); - text = Strings[alarmKey]; - if (!text) { - text = alarmKey; - } - } - break; - } - } - } else { - typeKey = 'event' + array[i].type.charAt(0).toUpperCase() + array[i].type.slice(1); - text = Strings[typeKey]; - if (!text) { - text = typeKey; - } - } - if (array[i].geofenceId !== 0) { - geofence = Ext.getStore('Geofences').getById(array[i].geofenceId); - if (typeof geofence !== 'undefined') { - text += ' \"' + geofence.get('name') + '"'; - } - } - device = Ext.getStore('Devices').getById(array[i].deviceId); - if (typeof device !== 'undefined') { - if (self.mutePressed()) { - self.beep(); - } - Ext.toast(text, device.get('name')); - } + updatePositions: function (array) { + var i, store, data, entity; + store = Ext.getStore('LatestPositions'); + for (i = 0; i < array.length; i++) { + entity = store.findRecord('deviceId', array[i].deviceId, 0, false, false, true); + if (entity) { + entity.set(array[i]); + } else { + store.add(Ext.create('Traccar.model.Position', array[i])); + } + } + }, + + updateEvents: function (array) { + var i, store, device, alarmKey, text, geofence; + store = Ext.getStore('Events'); + for (i = 0; i < array.length; i++) { + store.add(array[i]); + if (array[i].type === 'commandResult') { + text = Strings.eventCommandResult + ': ' + array[i].attributes.result; + } else if (array[i].type === 'alarm') { + alarmKey = 'alarm' + array[i].attributes.alarm.charAt(0).toUpperCase() + array[i].attributes.alarm.slice(1); + text = Strings[alarmKey] || alarmKey; + } else { + text = Traccar.app.getEventString(array[i].type); + } + if (array[i].geofenceId !== 0) { + geofence = Ext.getStore('Geofences').getById(array[i].geofenceId); + if (geofence) { + text += ' \"' + geofence.get('name') + '"'; } } - }; + device = Ext.getStore('Devices').getById(array[i].deviceId); + if (device) { + if (this.mutePressed()) { + this.beep(); + } + Ext.toast(text, device.get('name'), 'br'); + } + } } }); diff --git a/web/app/model/Calendar.js b/web/app/model/Calendar.js new file mode 100644 index 00000000..00b076b3 --- /dev/null +++ b/web/app/model/Calendar.js @@ -0,0 +1,34 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 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.model.Calendar', { + extend: 'Ext.data.Model', + identifier: 'negative', + + fields: [{ + name: 'id', + type: 'int' + }, { + name: 'name', + type: 'string' + }, { + name: 'calendarData' + }, { + name: 'attributes' + }] +}); diff --git a/web/app/model/Geofence.js b/web/app/model/Geofence.js index 63c8e8e2..12a9f878 100644 --- a/web/app/model/Geofence.js +++ b/web/app/model/Geofence.js @@ -32,6 +32,9 @@ Ext.define('Traccar.model.Geofence', { name: 'area', type: 'string' }, { + name: 'calendarId', + type: 'int' + }, { name: 'attributes' }] }); diff --git a/web/app/model/Notification.js b/web/app/model/Notification.js index 1e6c36c5..54f6674c 100644 --- a/web/app/model/Notification.js +++ b/web/app/model/Notification.js @@ -17,7 +17,7 @@ Ext.define('Traccar.model.Notification', { extend: 'Ext.data.Model', - identifier: 'negative', + idProperty: 'type', fields: [{ name: 'id', @@ -30,5 +30,11 @@ Ext.define('Traccar.model.Notification', { type: 'int' }, { name: 'attributes' + }, { + name: 'web', + type: 'bool' + }, { + name: 'mail', + type: 'bool' }] }); diff --git a/web/app/store/AllCalendars.js b/web/app/store/AllCalendars.js new file mode 100644 index 00000000..26557287 --- /dev/null +++ b/web/app/store/AllCalendars.js @@ -0,0 +1,30 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 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.AllCalendars', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Calendar', + + proxy: { + type: 'rest', + url: 'api/calendars', + extraParams: { + all: true + } + } +}); diff --git a/web/app/store/Calendars.js b/web/app/store/Calendars.js new file mode 100644 index 00000000..fa8e5c66 --- /dev/null +++ b/web/app/store/Calendars.js @@ -0,0 +1,30 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 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.Calendars', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Calendar', + + proxy: { + type: 'rest', + url: 'api/calendars', + writer: { + writeAllFields: true + } + } +}); diff --git a/web/app/store/GeofenceTypes.js b/web/app/store/GeofenceTypes.js index c102de69..45b79897 100644 --- a/web/app/store/GeofenceTypes.js +++ b/web/app/store/GeofenceTypes.js @@ -25,5 +25,8 @@ Ext.define('Traccar.store.GeofenceTypes', { }, { key: 'Circle', name: Strings.mapShapeCircle + }, { + key: 'LineString', + name: Strings.mapShapePolyline }] }); diff --git a/web/app/store/Notifications.js b/web/app/store/Notifications.js index e4d2991a..d79702fc 100644 --- a/web/app/store/Notifications.js +++ b/web/app/store/Notifications.js @@ -22,5 +22,7 @@ Ext.define('Traccar.store.Notifications', { proxy: { type: 'rest', url: 'api/users/notifications' - } + }, + sortOnLoad: true, + sorters: { property: 'type', direction : 'ASC' } }); diff --git a/web/app/store/Positions.js b/web/app/store/Positions.js index 8f185af1..388a3320 100644 --- a/web/app/store/Positions.js +++ b/web/app/store/Positions.js @@ -21,6 +21,9 @@ Ext.define('Traccar.store.Positions', { proxy: { type: 'rest', - url: 'api/positions' + url: 'api/positions', + headers: { + 'Accept': 'application/json' + } } }); diff --git a/web/app/view/CalendarDialog.js b/web/app/view/CalendarDialog.js new file mode 100644 index 00000000..2609a6da --- /dev/null +++ b/web/app/view/CalendarDialog.js @@ -0,0 +1,58 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 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.view.CalendarDialog', { + extend: 'Traccar.view.BaseEditDialog', + + requires: [ + 'Traccar.view.CalendarDialogController' + ], + + controller: 'calendarDialog', + title: Strings.sharedCalendar, + + items: { + xtype: 'form', + items: [{ + xtype: 'textfield', + name: 'name', + fieldLabel: Strings.sharedName, + allowBlank: false + }, { + xtype: 'filefield', + name: 'file', + fieldLabel: Strings.sharedFile, + allowBlank: false, + buttonConfig: { + glyph: 'xf093@FontAwesome', + text: '', + tooltip: Strings.sharedSelectFile, + tooltipType: 'title', + minWidth: 0 + }, + listeners: { + change: 'onFileChange' + } + }, { + xtype: 'hiddenfield', + name: 'calendarData', + allowBlank: false, + reference: 'calendarDataField' + }] + } +}); diff --git a/web/app/view/CalendarDialogController.js b/web/app/view/CalendarDialogController.js new file mode 100644 index 00000000..48400bc5 --- /dev/null +++ b/web/app/view/CalendarDialogController.js @@ -0,0 +1,37 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 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.view.CalendarDialogController', { + extend: 'Traccar.view.BaseEditDialogController', + alias: 'controller.calendarDialog', + + onFileChange: function (fileField) { + var reader; + if (fileField.fileInputEl.dom.files.length > 0) { + reader = new FileReader(); + reader.onload = function (event) { + fileField.up('window').lookupReference('calendarDataField').setValue( + btoa(String.fromCharCode.apply(null, new Uint8Array(event.target.result)))); + }; + reader.onerror = function (event) { + Traccar.app.showError(event.target.error); + }; + reader.readAsArrayBuffer(fileField.fileInputEl.dom.files[0]); + } + } +}); diff --git a/web/app/view/Calendars.js b/web/app/view/Calendars.js new file mode 100644 index 00000000..a905a5ba --- /dev/null +++ b/web/app/view/Calendars.js @@ -0,0 +1,52 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 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.view.Calendars', { + extend: 'Ext.grid.Panel', + xtype: 'calendarsView', + + requires: [ + 'Traccar.view.CalendarsController', + 'Traccar.view.EditToolbar' + ], + + controller: 'calendars', + store: 'Calendars', + + selType: 'rowmodel', + + tbar: { + xtype: 'editToolbar' + }, + + listeners: { + selectionchange: 'onSelectionChange' + }, + + forceFit: true, + + columns: { + defaults: { + minWidth: Traccar.Style.columnWidthNormal + }, + items: [{ + text: Strings.sharedName, + dataIndex: 'name' + }] + } +}); diff --git a/web/app/view/CalendarsController.js b/web/app/view/CalendarsController.js new file mode 100644 index 00000000..d5ab57a5 --- /dev/null +++ b/web/app/view/CalendarsController.js @@ -0,0 +1,74 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 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.view.CalendarsController', { + extend: 'Ext.app.ViewController', + alias: 'controller.calendars', + + requires: [ + 'Traccar.view.CalendarDialog', + 'Traccar.model.Calendar' + ], + + init: function () { + Ext.getStore('Calendars').load(); + }, + + onAddClick: function () { + var calendar, dialog; + calendar = Ext.create('Traccar.model.Calendar'); + calendar.store = this.getView().getStore(); + dialog = Ext.create('Traccar.view.CalendarDialog'); + dialog.down('form').loadRecord(calendar); + dialog.show(); + }, + + onEditClick: function () { + var calendar, dialog; + calendar = this.getView().getSelectionModel().getSelection()[0]; + dialog = Ext.create('Traccar.view.CalendarDialog'); + dialog.down('form').loadRecord(calendar); + dialog.show(); + }, + + onRemoveClick: function () { + var calendar = this.getView().getSelectionModel().getSelection()[0]; + Ext.Msg.show({ + title: Strings.sharedCalendar, + message: Strings.sharedRemoveConfirm, + buttons: Ext.Msg.YESNO, + buttonText: { + yes: Strings.sharedRemove, + no: Strings.sharedCancel + }, + fn: function (btn) { + var store = Ext.getStore('Calendars'); + if (btn === 'yes') { + store.remove(calendar); + store.sync(); + } + } + }); + }, + + onSelectionChange: function (selected) { + var disabled = selected.length > 0; + this.lookupReference('toolbarEditButton').setDisabled(disabled); + this.lookupReference('toolbarRemoveButton').setDisabled(disabled); + } +}); diff --git a/web/app/view/GeofenceDialog.js b/web/app/view/GeofenceDialog.js index 9f5bdbf7..7b2112b3 100644 --- a/web/app/view/GeofenceDialog.js +++ b/web/app/view/GeofenceDialog.js @@ -36,6 +36,14 @@ Ext.define('Traccar.view.GeofenceDialog', { name: 'description', fieldLabel: Strings.sharedDescription }, { + xtype: 'combobox', + name: 'calendarId', + store: 'Calendars', + queryMode: 'local', + displayField: 'name', + valueField: 'id', + fieldLabel: Strings.sharedCalendar + }, { xtype: 'hiddenfield', name: 'area', allowBlank: false, diff --git a/web/app/view/GeofencesController.js b/web/app/view/GeofencesController.js index 032ba7fa..78389066 100644 --- a/web/app/view/GeofencesController.js +++ b/web/app/view/GeofencesController.js @@ -26,6 +26,7 @@ Ext.define('Traccar.view.GeofencesController', { init: function () { Ext.getStore('Geofences').load(); + Ext.getStore('Calendars').load(); }, onAddClick: function () { diff --git a/web/app/view/Login.js b/web/app/view/Login.js index d71fed8b..5d0da0f5 100644 --- a/web/app/view/Login.js +++ b/web/app/view/Login.js @@ -25,7 +25,7 @@ Ext.define('Traccar.view.Login', { controller: 'login', - title: Strings.loginTitle, + header: false, closable: false, modal: false, @@ -41,6 +41,16 @@ Ext.define('Traccar.view.Login', { }, items: [{ + xtype: 'image', + src: 'logo.svg', + alt: Strings.loginLogo, + width: 180, + height: 48, + style: { + display: 'block', + margin: '10px auto 25px' + } + }, { xtype: 'combobox', name: 'language', fieldLabel: Strings.loginLanguage, @@ -79,6 +89,8 @@ Ext.define('Traccar.view.Login', { inputAttrTpl: ['autocomplete="on"'] }, { xtype: 'checkboxfield', + inputValue: true, + uncheckedValue: false, reference: 'rememberField', fieldLabel: Strings.userRemember }, { diff --git a/web/app/view/MapController.js b/web/app/view/MapController.js index 9fcd4939..c52fdd5f 100644 --- a/web/app/view/MapController.js +++ b/web/app/view/MapController.js @@ -16,59 +16,33 @@ */ Ext.define('Traccar.view.MapController', { - extend: 'Ext.app.ViewController', + extend: 'Traccar.view.MapMarkerController', alias: 'controller.map', requires: [ - 'Traccar.model.Position', - 'Traccar.model.Device', - 'Traccar.GeofenceConverter', - 'Traccar.DeviceImages' + 'Traccar.GeofenceConverter' ], config: { listen: { controller: { '*': { - selectdevice: 'selectDevice', - selectreport: 'selectReport', mapstaterequest: 'getMapState' } }, store: { - '#Devices': { - add: 'updateDevice', - update: 'updateDevice', - remove: 'removeDevice' - }, - '#LatestPositions': { - add: 'updateLatest', - update: 'updateLatest' - }, - '#ReportRoute': { - load: 'loadReport', - clear: 'clearReport' - }, '#Geofences': { load: 'showGeofences', add: 'updateGeofences', update: 'updateGeofences', remove: 'updateGeofences' } - }, - component: { - '#': { - selectfeature: 'selectFeature' - } } } }, init: function () { - this.latestMarkers = {}; - this.reportMarkers = {}; - this.liveRoutes = {}; - this.liveRouteLength = Traccar.app.getAttributePreference('web.liveRouteLength', 10); + this.callParent(); this.lookupReference('showReportsButton').setVisible(Traccar.app.isMobile()); }, @@ -76,58 +50,6 @@ Ext.define('Traccar.view.MapController', { Traccar.app.showReports(true); }, - getDeviceColor: function (device) { - switch (device.get('status')) { - case 'online': - return Traccar.Style.mapColorOnline; - case 'offline': - return Traccar.Style.mapColorOffline; - default: - return Traccar.Style.mapColorUnknown; - } - }, - - updateDevice: function (store, data) { - var i, device, deviceId, marker, style; - - 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]; - style = marker.getStyle(); - if (style.getImage().fill !== this.getDeviceColor(device) || - style.getImage().category !== device.get('category')) { - Traccar.DeviceImages.changeImageColor(style.getImage(), - this.getDeviceColor(device), device.get('category')); - marker.changed(); - } - if (style.getText().getText() !== device.get('name')) { - style.getText().setText(device.get('name')); - marker.changed(); - } - } - } - }, - - removeDevice: function (store, data) { - var i, deviceId; - if (!Ext.isArray(data)) { - data = [data]; - } - for (i = 0; i < data.length; i++) { - deviceId = data[i].get('id'); - if (this.latestMarkers[deviceId]) { - this.getView().getLatestSource().removeFeature(this.latestMarkers[deviceId]); - } - } - }, - onFollowClick: function (button, pressed) { if (pressed && this.selectedMarker) { this.getView().getMapView().setCenter(this.selectedMarker.getGeometry().getCoordinates()); @@ -138,245 +60,6 @@ Ext.define('Traccar.view.MapController', { this.getView().getLiveRouteLayer().setVisible(button.pressed); }, - updateLatest: function (store, data) { - var i, position, device; - - if (!Ext.isArray(data)) { - data = [data]; - } - - for (i = 0; i < data.length; i++) { - position = data[i]; - device = Ext.getStore('Devices').findRecord('id', position.get('deviceId'), 0, false, false, true); - - if (device) { - this.updateLatestMarker(position, device); - this.updateLiveRoute(position); - } - } - }, - - updateLatestMarker: function (position, device) { - var geometry, deviceId, marker, style; - geometry = new ol.geom.Point(ol.proj.fromLonLat([ - position.get('longitude'), - position.get('latitude') - ])); - deviceId = position.get('deviceId'); - if (deviceId in this.latestMarkers) { - marker = this.latestMarkers[deviceId]; - style = marker.getStyle(); - if (style.getImage().angle !== position.get('course')) { - Traccar.DeviceImages.rotateImageIcon(style.getImage(), position.get('course')); - } - marker.setGeometry(geometry); - } else { - marker = new ol.Feature(geometry); - marker.set('record', device); - - style = this.getLatestMarker(this.getDeviceColor(device), - position.get('course'), - device.get('category')); - style.getText().setText(device.get('name')); - marker.setStyle(style); - this.latestMarkers[deviceId] = marker; - this.getView().getLatestSource().addFeature(marker); - - } - - if (marker === this.selectedMarker && this.lookupReference('deviceFollowButton').pressed) { - this.getView().getMapView().setCenter(marker.getGeometry().getCoordinates()); - } - }, - - updateLiveRoute: function (position) { - var deviceId, liveLine, liveCoordinates, lastLiveCoordinates, newCoordinates; - deviceId = position.get('deviceId'); - if (deviceId in this.liveRoutes) { - liveCoordinates = this.liveRoutes[deviceId].getGeometry().getCoordinates(); - lastLiveCoordinates = liveCoordinates[liveCoordinates.length - 1]; - newCoordinates = ol.proj.fromLonLat([position.get('longitude'), position.get('latitude')]); - if (lastLiveCoordinates[0] === newCoordinates[0] && - lastLiveCoordinates[1] === newCoordinates[1]) { - return; - } - if (liveCoordinates.length >= this.liveRouteLength) { - liveCoordinates.shift(); - } - liveCoordinates.push(newCoordinates); - this.liveRoutes[deviceId].getGeometry().setCoordinates(liveCoordinates); - } else { - liveLine = new ol.Feature({ - geometry: new ol.geom.LineString([ - ol.proj.fromLonLat([ - position.get('longitude'), - position.get('latitude') - ]) - ]) - }); - liveLine.setStyle(this.getRouteStyle(deviceId)); - this.liveRoutes[deviceId] = liveLine; - this.getView().getLiveRouteSource().addFeature(liveLine); - } - }, - - loadReport: function (store, data) { - var i, position, point, geometry, marker, style; - - this.clearReport(store); - - if (data.length > 0) { - this.reportRoute = []; - for (i = 0; i < data.length; i++) { - if (i === 0 || data[i].get('deviceId') !== data[i - 1].get('deviceId')) { - this.reportRoute.push(new ol.Feature({ - geometry: new ol.geom.LineString([]) - })); - this.reportRoute[this.reportRoute.length - 1].setStyle(this.getRouteStyle(data[i].get('deviceId'))); - this.getView().getRouteSource().addFeature(this.reportRoute[this.reportRoute.length - 1]); - } - position = data[i]; - - point = ol.proj.fromLonLat([ - position.get('longitude'), - position.get('latitude') - ]); - geometry = new ol.geom.Point(point); - - marker = new ol.Feature(geometry); - marker.set('record', position); - this.reportMarkers[position.get('id')] = marker; - this.getView().getReportSource().addFeature(marker); - - style = this.getReportMarker(position.get('deviceId'), position.get('course')); - /*style.getText().setText( - Ext.Date.format(position.get('fixTime'), Traccar.Style.dateTimeFormat24));*/ - - marker.setStyle(style); - - this.reportRoute[this.reportRoute.length - 1].getGeometry().appendCoordinate(point); - } - - this.getView().getMapView().fit(this.reportRoute[0].getGeometry(), this.getView().getMap().getSize()); - } - }, - - clearReport: function (store) { - var key, i; - - if (this.reportRoute) { - for (i = 0; i < this.reportRoute.length; i++) { - this.getView().getRouteSource().removeFeature(this.reportRoute[i]); - } - this.reportRoute = null; - } - - if (this.reportMarkers) { - for (key in this.reportMarkers) { - if (this.reportMarkers.hasOwnProperty(key)) { - this.getView().getReportSource().removeFeature(this.reportMarkers[key]); - } - } - this.reportMarkers = {}; - } - }, - - getRouteStyle: function (deviceId) { - var index = 0; - if (deviceId !== undefined) { - index = deviceId % Traccar.Style.mapRouteColor.length; - } - return new ol.style.Style({ - stroke: new ol.style.Stroke({ - color: Traccar.Style.mapRouteColor[index], - width: Traccar.Style.mapRouteWidth - }) - }); - }, - - getMarkerStyle: function (zoom, color, angle, category) { - var image = Traccar.DeviceImages.getImageIcon(color, zoom, angle, category); - return new ol.style.Style({ - image: image, - text: new ol.style.Text({ - textBaseline: 'bottom', - fill: new ol.style.Fill({ - color: Traccar.Style.mapTextColor - }), - stroke: new ol.style.Stroke({ - color: Traccar.Style.mapTextStrokeColor, - width: Traccar.Style.mapTextStrokeWidth - }), - offsetY: -image.getSize()[1] / 2 - Traccar.Style.mapTextOffset, - font : Traccar.Style.mapTextFont - }) - }); - }, - - getLatestMarker: function (color, angle, category) { - return this.getMarkerStyle(false, color, angle, category); - }, - - getReportMarker: function (deviceId, angle) { - var index = 0; - if (deviceId !== undefined) { - index = deviceId % Traccar.Style.mapRouteColor.length; - } - return this.getMarkerStyle(false, Traccar.Style.mapRouteColor[index], angle, 'arrow'); - }, - - resizeMarker: function (style, zoom) { - var image, text; - image = Traccar.DeviceImages.getImageIcon(style.getImage().fill, - zoom, - style.getImage().angle, - style.getImage().category); - text = style.getText(); - text.setOffsetY(-image.getSize()[1] / 2 - Traccar.Style.mapTextOffset); - return new ol.style.Style({ - image: image, - text: text - }); - }, - - selectMarker: function (marker, center) { - if (this.selectedMarker) { - this.selectedMarker.setStyle( - this.resizeMarker(this.selectedMarker.getStyle(), false)); - } - - if (marker) { - marker.setStyle( - this.resizeMarker(marker.getStyle(), true)); - if (center) { - this.getView().getMapView().setCenter(marker.getGeometry().getCoordinates()); - } - } - - this.selectedMarker = marker; - }, - - selectDevice: function (device, center) { - this.selectMarker(this.latestMarkers[device.get('id')], center); - }, - - selectReport: function (position, center) { - if (position instanceof Traccar.model.Position) { - this.selectMarker(this.reportMarkers[position.get('id')], center); - } - }, - - selectFeature: function (feature) { - var record = feature.get('record'); - if (record) { - if (record instanceof Traccar.model.Device) { - this.fireEvent('selectdevice', record, false); - } else { - this.fireEvent('selectreport', record, false); - } - } - }, - getMapState: function () { var zoom, center, projection; projection = this.getView().getMapView().getProjection(); diff --git a/web/app/view/MapMarkerController.js b/web/app/view/MapMarkerController.js new file mode 100644 index 00000000..5fa9f4ca --- /dev/null +++ b/web/app/view/MapMarkerController.js @@ -0,0 +1,387 @@ +/* + * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 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.view.MapMarkerController', { + extend: 'Ext.app.ViewController', + alias: 'controller.mapMarker', + + requires: [ + 'Traccar.model.Position', + 'Traccar.model.Device', + 'Traccar.DeviceImages' + ], + + config: { + listen: { + controller: { + '*': { + selectdevice: 'selectDevice', + selectreport: 'selectReport' + } + }, + store: { + '#Devices': { + add: 'updateDevice', + update: 'updateDevice', + remove: 'removeDevice' + }, + '#LatestPositions': { + add: 'updateLatest', + update: 'updateLatest' + }, + '#ReportRoute': { + add: 'addReportMarkers', + load: 'loadReport', + clear: 'clearReport' + } + }, + component: { + '#': { + selectfeature: 'selectFeature' + } + } + } + }, + + init: function () { + this.latestMarkers = {}; + this.reportMarkers = {}; + this.liveRoutes = {}; + this.liveRouteLength = Traccar.app.getAttributePreference('web.liveRouteLength', 10); + }, + + getDeviceColor: function (device) { + switch (device.get('status')) { + case 'online': + return Traccar.Style.mapColorOnline; + case 'offline': + return Traccar.Style.mapColorOffline; + default: + return Traccar.Style.mapColorUnknown; + } + }, + + updateDevice: function (store, data) { + var i, device, deviceId, marker, style; + + 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]; + style = marker.getStyle(); + if (style.getImage().fill !== this.getDeviceColor(device) || + style.getImage().category !== device.get('category')) { + marker.setStyle(this.updateDeviceMarker(style, this.getDeviceColor(device), device.get('category'))); + } + if (style.getText().getText() !== device.get('name')) { + style.getText().setText(device.get('name')); + marker.changed(); + } + } + } + }, + + removeDevice: function (store, data) { + var i, deviceId; + if (!Ext.isArray(data)) { + data = [data]; + } + for (i = 0; i < data.length; i++) { + deviceId = data[i].get('id'); + if (this.latestMarkers[deviceId]) { + this.getView().getLatestSource().removeFeature(this.latestMarkers[deviceId]); + } + } + }, + + updateLatest: function (store, data) { + var i, position, device; + + if (!Ext.isArray(data)) { + data = [data]; + } + + for (i = 0; i < data.length; i++) { + position = data[i]; + device = Ext.getStore('Devices').findRecord('id', position.get('deviceId'), 0, false, false, true); + + if (device) { + this.updateLatestMarker(position, device); + this.updateLiveRoute(position); + } + } + }, + + updateLatestMarker: function (position, device) { + var geometry, deviceId, marker, style; + geometry = new ol.geom.Point(ol.proj.fromLonLat([ + position.get('longitude'), + position.get('latitude') + ])); + deviceId = position.get('deviceId'); + if (deviceId in this.latestMarkers) { + marker = this.latestMarkers[deviceId]; + style = marker.getStyle(); + if (style.getImage().angle !== position.get('course')) { + Traccar.DeviceImages.rotateImageIcon(style.getImage(), position.get('course')); + } + marker.setGeometry(geometry); + } else { + marker = new ol.Feature(geometry); + marker.set('record', device); + + style = this.getLatestMarker(this.getDeviceColor(device), + position.get('course'), + device.get('category')); + style.getText().setText(device.get('name')); + marker.setStyle(style); + this.latestMarkers[deviceId] = marker; + this.getView().getLatestSource().addFeature(marker); + + } + + if (marker === this.selectedMarker && this.lookupReference('deviceFollowButton').pressed) { + this.getView().getMapView().setCenter(marker.getGeometry().getCoordinates()); + } + }, + + updateLiveRoute: function (position) { + var deviceId, liveLine, liveCoordinates, lastLiveCoordinates, newCoordinates; + deviceId = position.get('deviceId'); + if (deviceId in this.liveRoutes) { + liveCoordinates = this.liveRoutes[deviceId].getGeometry().getCoordinates(); + lastLiveCoordinates = liveCoordinates[liveCoordinates.length - 1]; + newCoordinates = ol.proj.fromLonLat([position.get('longitude'), position.get('latitude')]); + if (lastLiveCoordinates[0] === newCoordinates[0] && + lastLiveCoordinates[1] === newCoordinates[1]) { + return; + } + if (liveCoordinates.length >= this.liveRouteLength) { + liveCoordinates.shift(); + } + liveCoordinates.push(newCoordinates); + this.liveRoutes[deviceId].getGeometry().setCoordinates(liveCoordinates); + } else { + liveLine = new ol.Feature({ + geometry: new ol.geom.LineString([ + ol.proj.fromLonLat([ + position.get('longitude'), + position.get('latitude') + ]) + ]) + }); + liveLine.setStyle(this.getRouteStyle(deviceId)); + this.liveRoutes[deviceId] = liveLine; + this.getView().getLiveRouteSource().addFeature(liveLine); + } + }, + + loadReport: function (store, data) { + var i, position, point; + + this.addReportMarkers(store, data); + + this.reportRoute = []; + for (i = 0; i < data.length; i++) { + position = data[i]; + point = ol.proj.fromLonLat([ + position.get('longitude'), + position.get('latitude') + ]); + if (i === 0 || data[i].get('deviceId') !== data[i - 1].get('deviceId')) { + this.reportRoute.push(new ol.Feature({ + geometry: new ol.geom.LineString([]) + })); + this.reportRoute[this.reportRoute.length - 1].setStyle(this.getRouteStyle(data[i].get('deviceId'))); + this.getView().getRouteSource().addFeature(this.reportRoute[this.reportRoute.length - 1]); + } + this.reportRoute[this.reportRoute.length - 1].getGeometry().appendCoordinate(point); + } + }, + + addReportMarkers: function (store, data) { + var i, position, point, geometry, marker, style, minx, miny, maxx, maxy; + this.clearReport(); + for (i = 0; i < data.length; i++) { + position = data[i]; + point = ol.proj.fromLonLat([ + position.get('longitude'), + position.get('latitude') + ]); + if (i === 0) { + minx = maxx = point[0]; + miny = maxy = point[1]; + } else { + minx = Math.min(point[0], minx); + miny = Math.min(point[1], miny); + maxx = Math.max(point[0], maxx); + maxy = Math.max(point[1], maxy); + } + geometry = new ol.geom.Point(point); + marker = new ol.Feature(geometry); + marker.set('record', position); + style = this.getReportMarker(position.get('deviceId'), position.get('course')); + /*style.getText().setText( + Ext.Date.format(position.get('fixTime'), Traccar.Style.dateTimeFormat24));*/ + marker.setStyle(style); + this.reportMarkers[position.get('id')] = marker; + this.getView().getReportSource().addFeature(marker); + } + if (minx !== maxx || miny !== maxy) { + this.getView().getMapView().fit([minx, miny, maxx, maxy], this.getView().getMap().getSize()); + } else if (geometry) { + this.getView().getMapView().fit(geometry, this.getView().getMap().getSize()); + } + }, + + clearReport: function () { + var key, i; + + if (this.reportRoute) { + for (i = 0; i < this.reportRoute.length; i++) { + this.getView().getRouteSource().removeFeature(this.reportRoute[i]); + } + this.reportRoute = null; + } + + if (this.reportMarkers) { + for (key in this.reportMarkers) { + if (this.reportMarkers.hasOwnProperty(key)) { + this.getView().getReportSource().removeFeature(this.reportMarkers[key]); + } + } + this.reportMarkers = {}; + } + }, + + getRouteStyle: function (deviceId) { + var index = 0; + if (deviceId !== undefined) { + index = deviceId % Traccar.Style.mapRouteColor.length; + } + return new ol.style.Style({ + stroke: new ol.style.Stroke({ + color: Traccar.Style.mapRouteColor[index], + width: Traccar.Style.mapRouteWidth + }) + }); + }, + + getMarkerStyle: function (zoom, color, angle, category) { + var image = Traccar.DeviceImages.getImageIcon(color, zoom, angle, category); + return new ol.style.Style({ + image: image, + text: new ol.style.Text({ + textBaseline: 'bottom', + fill: new ol.style.Fill({ + color: Traccar.Style.mapTextColor + }), + stroke: new ol.style.Stroke({ + color: Traccar.Style.mapTextStrokeColor, + width: Traccar.Style.mapTextStrokeWidth + }), + offsetY: -image.getSize()[1] / 2 - Traccar.Style.mapTextOffset, + font : Traccar.Style.mapTextFont + }) + }); + }, + + getLatestMarker: function (color, angle, category) { + return this.getMarkerStyle(false, color, angle, category); + }, + + getReportMarker: function (deviceId, angle) { + var index = 0; + if (deviceId !== undefined) { + index = deviceId % Traccar.Style.mapRouteColor.length; + } + return this.getMarkerStyle(false, Traccar.Style.mapRouteColor[index], angle, 'arrow'); + }, + + resizeMarker: function (style, zoom) { + var image, text; + image = Traccar.DeviceImages.getImageIcon(style.getImage().fill, + zoom, + style.getImage().angle, + style.getImage().category); + text = style.getText(); + text.setOffsetY(-image.getSize()[1] / 2 - Traccar.Style.mapTextOffset); + return new ol.style.Style({ + image: image, + text: text + }); + }, + + updateDeviceMarker: function (style, color, category) { + var image, text; + image = Traccar.DeviceImages.getImageIcon(color, + style.getImage().zoom, + style.getImage().angle, + category); + text = style.getText(); + text.setOffsetY(-image.getSize()[1] / 2 - Traccar.Style.mapTextOffset); + return new ol.style.Style({ + image: image, + text: text + }); + }, + + selectMarker: function (marker, center) { + if (this.selectedMarker) { + this.selectedMarker.setStyle( + this.resizeMarker(this.selectedMarker.getStyle(), false)); + } + + if (marker) { + marker.setStyle( + this.resizeMarker(marker.getStyle(), true)); + if (center) { + this.getView().getMapView().setCenter(marker.getGeometry().getCoordinates()); + } + } + + this.selectedMarker = marker; + }, + + selectDevice: function (device, center) { + this.selectMarker(this.latestMarkers[device.get('id')], center); + }, + + selectReport: function (position, center) { + if (position instanceof Traccar.model.Position) { + this.selectMarker(this.reportMarkers[position.get('id')], center); + } + }, + + selectFeature: function (feature) { + var record = feature.get('record'); + if (record) { + if (record instanceof Traccar.model.Device) { + this.fireEvent('selectdevice', record, false); + } else { + this.fireEvent('selectreport', record, false); + } + } + } +}); diff --git a/web/app/view/Notifications.js b/web/app/view/Notifications.js index 900ebe3f..419d9616 100644 --- a/web/app/view/Notifications.js +++ b/web/app/view/Notifications.js @@ -24,7 +24,7 @@ Ext.define('Traccar.view.Notifications', { ], controller: 'notificationsController', - store: 'AllNotifications', + store: 'Notifications', selModel: { selType: 'cellmodel' @@ -44,32 +44,21 @@ Ext.define('Traccar.view.Notifications', { text: Strings.notificationType, dataIndex: 'type', renderer: function (value) { - var typeKey = 'event' + value.charAt(0).toUpperCase() + value.slice(1); - return Strings[typeKey]; + return Traccar.app.getEventString(value); } }, { text: Strings.notificationWeb, - dataIndex: 'attributes.web', + dataIndex: 'web', xtype: 'checkcolumn', listeners: { - beforeCheckChange: 'onBeforeCheckChange', checkChange: 'onCheckChange' - }, - renderer: function (value, metaData, record) { - var fields = this.dataIndex.split('\.', 2); - return (new Ext.ux.CheckColumn()).renderer(record.get(fields[0])[fields[1]], metaData); } }, { text: Strings.notificationMail, - dataIndex: 'attributes.mail', + dataIndex: 'mail', xtype: 'checkcolumn', listeners: { - beforeCheckChange: 'onBeforeCheckChange', checkChange: 'onCheckChange' - }, - renderer: function (value, metaData, record) { - var fields = this.dataIndex.split('\.', 2); - return (new Ext.ux.CheckColumn()).renderer(record.get(fields[0])[fields[1]], metaData); } }] } diff --git a/web/app/view/NotificationsController.js b/web/app/view/NotificationsController.js index 70b99f1b..4c83b145 100644 --- a/web/app/view/NotificationsController.js +++ b/web/app/view/NotificationsController.js @@ -24,57 +24,19 @@ Ext.define('Traccar.view.NotificationsController', { ], init: function () { - this.userId = this.getView().user.getId(); this.getView().getStore().load({ - scope: this, - callback: function (records, operation, success) { - var notificationsStore = Ext.create('Traccar.store.Notifications'); - notificationsStore.load({ - params: { - userId: this.userId - }, - scope: this, - callback: function (records, operation, success) { - var i, index, attributes, storeRecord; - if (success) { - for (i = 0; i < records.length; i++) { - index = this.getView().getStore().findExact('type', records[i].get('type')); - attributes = records[i].get('attributes'); - storeRecord = this.getView().getStore().getAt(index); - storeRecord.set('attributes', attributes); - storeRecord.commit(); - } - } - } - }); + params: { + userId: this.getView().user.getId() } }); }, - onBeforeCheckChange: function (column, rowIndex, checked, eOpts) { - var fields, record, data; - fields = column.dataIndex.split('\.', 2); - record = this.getView().getStore().getAt(rowIndex); - data = record.get(fields[0]); - if (!data[fields[1]]) { - data[fields[1]] = 'true'; - } else { - delete data[fields[1]]; - } - record.set(fields[0], data); - record.commit(); - }, - onCheckChange: function (column, rowIndex, checked, eOpts) { var record = this.getView().getStore().getAt(rowIndex); Ext.Ajax.request({ scope: this, url: 'api/users/notifications', - jsonData: { - userId: this.userId, - type: record.get('type'), - attributes: record.get('attributes') - }, + jsonData: record.data, callback: function (options, success, response) { if (!success) { Traccar.app.showError(response); diff --git a/web/app/view/ReportConfigController.js b/web/app/view/ReportConfigController.js index c121c654..0ae7c0a4 100644 --- a/web/app/view/ReportConfigController.js +++ b/web/app/view/ReportConfigController.js @@ -35,13 +35,11 @@ Ext.define('Traccar.view.ReportConfigController', { Ext.create('Traccar.store.AllNotifications').load({ scope: this, callback: function (records, operation, success) { - var i, value, name, typeKey; + var i, value; if (success) { for (i = 0; i < records.length; i++) { value = records[i].get('type'); - typeKey = 'event' + value.charAt(0).toUpperCase() + value.slice(1); - name = Strings[typeKey]; - store.add({type: value, name: name}); + store.add({type: value, name: Traccar.app.getEventString(value)}); } } } diff --git a/web/app/view/ReportController.js b/web/app/view/ReportController.js index 775394d0..1f3f3a2a 100644 --- a/web/app/view/ReportController.js +++ b/web/app/view/ReportController.js @@ -32,11 +32,18 @@ Ext.define('Traccar.view.ReportController', { listen: { controller: { '*': { - selectdevice: 'selectDevice' + selectdevice: 'selectDevice', + showsingleevent: 'showSingleEvent' }, 'map': { selectreport: 'selectReport' } + }, + store: { + '#ReportEvents': { + add: 'loadEvents', + load: 'loadEvents' + } } } }, @@ -112,8 +119,8 @@ Ext.define('Traccar.view.ReportController', { deviceId: this.deviceId, groupId: this.groupId, type: this.eventType, - from: from.toISOString(), - to: to.toISOString() + from: Ext.Date.format(from, 'c'), + to: Ext.Date.format(to, 'c') }); } } @@ -126,7 +133,7 @@ Ext.define('Traccar.view.ReportController', { clearReport: function (reportType) { this.getView().getStore().removeAll(); - if (reportType === 'trips') { + if (reportType === 'trips' || reportType === 'events') { Ext.getStore('ReportRoute').removeAll(); } }, @@ -139,6 +146,9 @@ Ext.define('Traccar.view.ReportController', { if (report instanceof Traccar.model.ReportTrip) { this.selectTrip(report); } + if (report instanceof Traccar.model.Event) { + this.selectEvent(report); + } } }, @@ -149,10 +159,16 @@ Ext.define('Traccar.view.ReportController', { }, selectReport: function (object, center) { - var reportType = this.lookupReference('reportTypeField').getValue(); - if (object instanceof Traccar.model.Position && reportType === 'route') { - this.getView().getSelectionModel().select([object], false, true); - this.getView().getView().focusRow(object); + var positionEvent, reportType = this.lookupReference('reportTypeField').getValue(); + if (object instanceof Traccar.model.Position) { + if (reportType === 'route') { + this.getView().getSelectionModel().select([object], false, true); + this.getView().getView().focusRow(object); + } else if (reportType === 'events') { + positionEvent = this.getView().getStore().findRecord('positionId', object.get('id'), 0, false, true, true); + this.getView().getSelectionModel().select([positionEvent], false, true); + this.getView().getView().focusRow(positionEvent); + } } }, @@ -170,6 +186,67 @@ Ext.define('Traccar.view.ReportController', { }); }, + selectEvent: function (event) { + var position; + if (event.get('positionId')) { + position = Ext.getStore('ReportRoute').getById(event.get('positionId')); + if (position) { + this.fireEvent('selectreport', position, true); + } + } + }, + + loadEvents: function (store, data) { + var i, eventObject, positionIds = []; + Ext.getStore('ReportRoute').removeAll(); + for (i = 0; i < data.length; i++) { + eventObject = data[i]; + if (eventObject.get('positionId')) { + positionIds.push(eventObject.get('positionId')); + } + } + if (positionIds.length > 0) { + Ext.getStore('Positions').load({ + params: { + id: positionIds + }, + scope: this, + callback: function (records, operation, success) { + if (success) { + Ext.getStore('ReportRoute').add(records); + if (records.length === 1) { + this.fireEvent('selectreport', records[0], false); + } + } + } + }); + } + }, + + showSingleEvent: function (eventId) { + this.lookupReference('reportTypeField').setValue('events'); + Ext.getStore('Events').load({ + id: eventId, + scope: this, + callback: function (records, operation, success) { + if (success) { + Ext.getStore('ReportEvents').add(records); + if (records.length > 0) { + if (!records[0].get('positionId')) { + if (Traccar.app.isMobile()) { + Traccar.app.showReports(true); + } else { + this.getView().expand(); + } + } + this.getView().getSelectionModel().select([records[0]], false, true); + this.getView().getView().focusRow(records[0]); + } + } + } + }); + }, + downloadFile: function (requestUrl, requestParams) { Ext.Ajax.request({ url: requestUrl, @@ -272,8 +349,7 @@ Ext.define('Traccar.view.ReportController', { text: Strings.sharedType, dataIndex: 'type', renderer: function (value) { - var typeKey = 'event' + value.charAt(0).toUpperCase() + value.slice(1); - return Strings[typeKey]; + return Traccar.app.getEventString(value); } }, { text: Strings.sharedGeofence, diff --git a/web/app/view/ServerDialog.js b/web/app/view/ServerDialog.js index 0f965885..0a05876e 100644 --- a/web/app/view/ServerDialog.js +++ b/web/app/view/ServerDialog.js @@ -29,11 +29,15 @@ Ext.define('Traccar.view.ServerDialog', { xtype: 'form', items: [{ xtype: 'checkboxfield', + inputValue: true, + uncheckedValue: false, name: 'registration', fieldLabel: Strings.serverRegistration, allowBlank: false }, { xtype: 'checkboxfield', + inputValue: true, + uncheckedValue: false, name: 'readonly', fieldLabel: Strings.serverReadonly, allowBlank: false @@ -88,11 +92,15 @@ Ext.define('Traccar.view.ServerDialog', { fieldLabel: Strings.serverZoom }, { xtype: 'checkboxfield', + inputValue: true, + uncheckedValue: false, name: 'twelveHourFormat', fieldLabel: Strings.settingsTwelveHourFormat, allowBlank: false }, { xtype: 'checkboxfield', + inputValue: true, + uncheckedValue: false, name: 'forceSettings', fieldLabel: Strings.serverForceSettings, allowBlank: false diff --git a/web/app/view/SettingsMenu.js b/web/app/view/SettingsMenu.js index db436b33..c71c8372 100644 --- a/web/app/view/SettingsMenu.js +++ b/web/app/view/SettingsMenu.js @@ -82,6 +82,12 @@ Ext.define('Traccar.view.SettingsMenu', { handler: 'onStatisticsClick', reference: 'settingsStatisticsButton' }, { + hidden: true, + text: Strings.sharedCalendars, + glyph: 'xf073@FontAwesome', + handler: 'onCalendarsClick', + reference: 'settingsCalendarsButton' + }, { text: Strings.loginLogout, glyph: 'xf08b@FontAwesome', handler: 'onLogoutClick' diff --git a/web/app/view/SettingsMenuController.js b/web/app/view/SettingsMenuController.js index 0ec2a781..2f1685f0 100644 --- a/web/app/view/SettingsMenuController.js +++ b/web/app/view/SettingsMenuController.js @@ -30,6 +30,7 @@ Ext.define('Traccar.view.SettingsMenuController', { 'Traccar.view.AttributeAliases', 'Traccar.view.Statistics', 'Traccar.view.DeviceDistanceDialog', + 'Traccar.view.Calendars', 'Traccar.view.BaseWindow' ], @@ -47,12 +48,14 @@ Ext.define('Traccar.view.SettingsMenuController', { this.lookupReference('settingsGroupsButton').setHidden(false); this.lookupReference('settingsGeofencesButton').setHidden(false); this.lookupReference('settingsAttributeAliasesButton').setHidden(false); + this.lookupReference('settingsCalendarsButton').setHidden(false); } }, onUserClick: function () { var dialog = Ext.create('Traccar.view.UserDialog'); dialog.down('form').loadRecord(Traccar.app.getUser()); + dialog.lookupReference('testMailButton').setHidden(false); dialog.show(); }, @@ -129,6 +132,16 @@ Ext.define('Traccar.view.SettingsMenuController', { dialog.show(); }, + onCalendarsClick: function () { + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedCalendars, + modal: false, + items: { + xtype: 'calendarsView' + } + }).show(); + }, + onLogoutClick: function () { Ext.create('Traccar.view.LoginController').logout(); } diff --git a/web/app/view/State.js b/web/app/view/State.js index 3356fd72..2dc466f1 100644 --- a/web/app/view/State.js +++ b/web/app/view/State.js @@ -49,11 +49,10 @@ Ext.define('Traccar.view.State', { selectionchange: 'onSelectionChange' }, - forceFit: true, - columns: { defaults: { - minWidth: Traccar.Style.columnWidthNormal + minWidth: Traccar.Style.columnWidthNormal, + flex: 1 }, items: [{ text: Strings.stateName, diff --git a/web/app/view/UserCalendars.js b/web/app/view/UserCalendars.js new file mode 100644 index 00000000..29bb99cb --- /dev/null +++ b/web/app/view/UserCalendars.js @@ -0,0 +1,49 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 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.view.UserCalendars', { + extend: 'Ext.grid.Panel', + xtype: 'userCalendarsView', + + requires: [ + 'Traccar.view.BasePermissionsController' + ], + + controller: 'basePermissionsController', + + selModel: { + selType: 'checkboxmodel', + checkOnly: true, + showHeaderCheckbox: false + }, + + listeners: { + beforedeselect: 'onBeforeDeselect', + beforeselect: 'onBeforeSelect' + }, + + forceFit: true, + + columns: { + items: [{ + text: Strings.sharedName, + minWidth: Traccar.Style.columnWidthNormal, + dataIndex: 'name' + }] + } +}); diff --git a/web/app/view/UserDialog.js b/web/app/view/UserDialog.js index 52ec933c..8ee12437 100644 --- a/web/app/view/UserDialog.js +++ b/web/app/view/UserDialog.js @@ -44,6 +44,8 @@ Ext.define('Traccar.view.UserDialog', { allowBlank: false }, { xtype: 'checkboxfield', + inputValue: true, + uncheckedValue: false, name: 'readonly', fieldLabel: Strings.serverReadonly, allowBlank: false, @@ -51,6 +53,8 @@ Ext.define('Traccar.view.UserDialog', { reference: 'readonlyField' }, { xtype: 'checkboxfield', + inputValue: true, + uncheckedValue: false, name: 'admin', fieldLabel: Strings.userAdmin, allowBlank: false, @@ -99,6 +103,8 @@ Ext.define('Traccar.view.UserDialog', { fieldLabel: Strings.serverZoom }, { xtype: 'checkboxfield', + inputValue: true, + uncheckedValue: false, name: 'twelveHourFormat', fieldLabel: Strings.settingsTwelveHourFormat, allowBlank: false @@ -112,6 +118,8 @@ Ext.define('Traccar.view.UserDialog', { editable: false }, { xtype: 'checkboxfield', + inputValue: true, + uncheckedValue: false, name: 'disabled', fieldLabel: Strings.userDisabled, hidden: true, @@ -155,6 +163,14 @@ Ext.define('Traccar.view.UserDialog', { tooltip: Strings.sharedGetMapState, tooltipType: 'title' }, { + glyph: 'xf003@FontAwesome', + minWidth: 0, + handler: 'testMail', + hidden: true, + reference: 'testMailButton', + tooltip: Strings.sharedTestMail, + tooltipType: 'title' + }, { xtype: 'tbfill' }, { glyph: 'xf00c@FontAwesome', diff --git a/web/app/view/UserDialogController.js b/web/app/view/UserDialogController.js index 0f1c022b..f07031e3 100644 --- a/web/app/view/UserDialogController.js +++ b/web/app/view/UserDialogController.js @@ -42,6 +42,16 @@ Ext.define('Traccar.view.UserDialogController', { this.lookupReference('tokenField').setValue(newToken); }, + testMail: function () { + Ext.Ajax.request({ + url: 'api/users/notifications/test', + method: 'POST', + failure: function (response) { + Traccar.app.showError(response); + } + }); + }, + onSaveClick: function (button) { var dialog, record, store; dialog = button.up('window').down('form'); diff --git a/web/app/view/Users.js b/web/app/view/Users.js index 4259c4c1..09a03cc2 100644 --- a/web/app/view/Users.js +++ b/web/app/view/Users.js @@ -1,5 +1,6 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 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 @@ -59,6 +60,13 @@ Ext.define('Traccar.view.Users', { glyph: 'xf003@FontAwesome', tooltip: Strings.sharedNotifications, tooltipType: 'title' + }, { + disabled: true, + handler: 'onCalendarsClick', + reference: 'userCalendarsButton', + glyph: 'xf073@FontAwesome', + tooltip: Strings.sharedCalendars, + tooltipType: 'title' }] }, diff --git a/web/app/view/UsersController.js b/web/app/view/UsersController.js index 9b7076e6..af9d47b2 100644 --- a/web/app/view/UsersController.js +++ b/web/app/view/UsersController.js @@ -1,5 +1,6 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 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 @@ -24,6 +25,7 @@ Ext.define('Traccar.view.UsersController', { 'Traccar.view.UserDevices', 'Traccar.view.UserGroups', 'Traccar.view.UserGeofences', + 'Traccar.view.UserCalendars', 'Traccar.view.Notifications', 'Traccar.view.BaseWindow', 'Traccar.model.User' @@ -129,6 +131,22 @@ Ext.define('Traccar.view.UsersController', { }).show(); }, + onCalendarsClick: function () { + var user = this.getView().getSelectionModel().getSelection()[0]; + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedCalendars, + items: { + xtype: 'userCalendarsView', + baseObjectName: 'userId', + linkObjectName: 'calendarId', + storeName: 'AllCalendars', + linkStoreName: 'Calendars', + urlApi: 'api/permissions/calendars', + baseObject: user.getId() + } + }).show(); + }, + onSelectionChange: function (selected) { var disabled = selected.length > 0; this.lookupReference('toolbarEditButton').setDisabled(disabled); @@ -137,5 +155,6 @@ Ext.define('Traccar.view.UsersController', { this.lookupReference('userGroupsButton').setDisabled(disabled); this.lookupReference('userGeofencesButton').setDisabled(disabled); this.lookupReference('userNotificationsButton').setDisabled(disabled); + this.lookupReference('userCalendarsButton').setDisabled(disabled); } }); diff --git a/web/debug.html b/web/debug.html index bafdd3c4..5e47ee65 100644 --- a/web/debug.html +++ b/web/debug.html @@ -4,6 +4,7 @@ <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <title>Traccar</title> +<link rel="stylesheet" href="app.css"> </head> <body> <div id="spinner"></div> diff --git a/web/l10n/ar.json b/web/l10n/ar.json index 0c72c8ee..f70fe04f 100644 --- a/web/l10n/ar.json +++ b/web/l10n/ar.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "خطأ", "errorUnknown": "خطأ غير معروف", "errorConnection": "خطأ في الاتصال", @@ -58,6 +59,7 @@ "loginFailed": "كلمة مرور او بريد خاطئ", "loginCreated": "تم تسجيل مستخدم جديد", "loginLogout": "خروج", + "loginLogo": "Logo", "devicesAndState": "الأجهزة والحالة", "deviceTitle": "أجهزة", "deviceIdentifier": "المعرف", @@ -111,6 +113,7 @@ "mapBingAerial": "خرائط جوية Bing", "mapShapePolygon": "مضلع", "mapShapeCircle": "دائرة", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "حالة", "stateName": "عنصر", @@ -146,6 +149,7 @@ "commandMessage": "Message", "eventAll": "All Events", "eventDeviceOnline": "الجهاز متصل", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "الجهاز غير متصل", "eventDeviceMoving": "الجهاز يتحرك", "eventDeviceStopped": "Device has stopped", @@ -156,6 +160,7 @@ "eventAlarm": "Alarms", "eventIgnitionOn": "Ignition is ON", "eventIgnitionOff": "Ignition is OFF", + "eventMaintenance": "Maintenance required", "alarm": "Alarm", "alarmSos": "SOS Alarm", "alarmVibration": "Vibration Alarm", diff --git a/web/l10n/bg.json b/web/l10n/bg.json index 7ccd4211..80d2d67e 100644 --- a/web/l10n/bg.json +++ b/web/l10n/bg.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "Грешка", "errorUnknown": "Непозната Грешка", "errorConnection": "Грешка във връзката", @@ -58,6 +59,7 @@ "loginFailed": "Грешен потребител или парола", "loginCreated": "Регистриран Нов Потребител", "loginLogout": "Изход", + "loginLogo": "Logo", "devicesAndState": "Устройства и състояние", "deviceTitle": "Устройства", "deviceIdentifier": "Идентификатор", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps Aerial", "mapShapePolygon": "Многоъгълник", "mapShapeCircle": "Кръг", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "Състояние", "stateName": "Параметър", @@ -146,6 +149,7 @@ "commandMessage": "Съобщение", "eventAll": "Всички събития", "eventDeviceOnline": "Устройството е онлайн", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Устройството е офлайн", "eventDeviceMoving": "Устройството е в движение", "eventDeviceStopped": "Device has stopped", @@ -156,6 +160,7 @@ "eventAlarm": "Аларми", "eventIgnitionOn": "Запалването е включено", "eventIgnitionOff": "Запалването е изключено", + "eventMaintenance": "Maintenance required", "alarm": "Аларма", "alarmSos": "SOS Аларма", "alarmVibration": "Аларма Вибрация", diff --git a/web/l10n/cs.json b/web/l10n/cs.json index 229febdb..8741fb97 100644 --- a/web/l10n/cs.json +++ b/web/l10n/cs.json @@ -40,6 +40,7 @@ "sharedAlias": "Přezdívka", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "Chyba", "errorUnknown": "Neznámá chyba", "errorConnection": "Chyba spojení", @@ -58,6 +59,7 @@ "loginFailed": "Nesprávný email nebo heslo", "loginCreated": "Nový uživatel byl zaregistrován", "loginLogout": "Odhlášení", + "loginLogo": "Logo", "devicesAndState": "Zařízení a stav", "deviceTitle": "Zařízení", "deviceIdentifier": "Identifikace", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps anténa", "mapShapePolygon": "Mnohoúhelník", "mapShapeCircle": "Kruh", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "Stav", "stateName": "Atribut", @@ -146,6 +149,7 @@ "commandMessage": "Zpráva", "eventAll": "Všechny události", "eventDeviceOnline": "Zařízení je online", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Zařízení je offline", "eventDeviceMoving": "Zařízení s pohybuje", "eventDeviceStopped": "Zařízení se zastavilo", @@ -156,6 +160,7 @@ "eventAlarm": "Alarmy", "eventIgnitionOn": "Zažehnutí je ZAPNUTO", "eventIgnitionOff": "Zažehnutí je VYPNUTO", + "eventMaintenance": "Maintenance required", "alarm": "Alarm", "alarmSos": "SOS alarm", "alarmVibration": "Vibrační alarm", diff --git a/web/l10n/da.json b/web/l10n/da.json index ad61ff55..491b1374 100644 --- a/web/l10n/da.json +++ b/web/l10n/da.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "Fejl", "errorUnknown": "Ukendt Fejl", "errorConnection": "Tilslutning fejl", @@ -58,6 +59,7 @@ "loginFailed": "Fejl i email adresse eller kodeord", "loginCreated": "Ny bruger er registreret", "loginLogout": "Log af", + "loginLogo": "Logo", "devicesAndState": "Enheder og status", "deviceTitle": "Enheder", "deviceIdentifier": "Imei nr", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps Aerial", "mapShapePolygon": "Polygon", "mapShapeCircle": "Cirkel", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "Status", "stateName": "Parameter", @@ -146,6 +149,7 @@ "commandMessage": "Meddelelse", "eventAll": "Alle begivenheder", "eventDeviceOnline": "Enhed online", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Enhed offline", "eventDeviceMoving": "Enhed i bevægelse", "eventDeviceStopped": "Device has stopped", @@ -156,6 +160,7 @@ "eventAlarm": "Alarmer", "eventIgnitionOn": "Tænding slået til", "eventIgnitionOff": "Tænding slået fra", + "eventMaintenance": "Maintenance required", "alarm": "Alarm", "alarmSos": "SOS alarm", "alarmVibration": "Vibrations alarm", diff --git a/web/l10n/de.json b/web/l10n/de.json index 1379c394..ba22a2f4 100644 --- a/web/l10n/de.json +++ b/web/l10n/de.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Gerätedistanz", "sharedDevice": "Gerät", + "sharedTestMail": "Send Test Email", "errorTitle": "Fehler", "errorUnknown": "Unbekannter Fehler", "errorConnection": "Verbindungsfehler", @@ -49,8 +50,8 @@ "userRemember": "Erinnern", "userDisabled": "Deaktiviert", "userExpirationTime": "Ablaufdatum", - "userDeviceLimit": "Device Limit", - "userToken": "Token", + "userDeviceLimit": "Gerätelimit", + "userToken": "Zeichen", "loginTitle": "Anmeldung", "loginLanguage": "Sprache", "loginRegister": "Registrieren", @@ -58,13 +59,14 @@ "loginFailed": "Falsche Emailadresse oder Passwort", "loginCreated": "Neuer Benutzer wurde registriert", "loginLogout": "Abmelden", + "loginLogo": "Logo", "devicesAndState": "Geräte und Status", "deviceTitle": "Geräte", "deviceIdentifier": "Kennung", "devicePhone": "Telefon", "deviceModel": "Modell", "deviceContact": "Kontakt", - "deviceCategory": "Kategorie", + "deviceCategory": "Symbol", "deviceLastUpdate": "Letzte Aktualisierung", "deviceCommand": "Befehl", "deviceFollow": "Folgen", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Luftbilder", "mapShapePolygon": "Polygon", "mapShapeCircle": "Kreis", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Route", "stateTitle": "Status", "stateName": "Parameter", @@ -146,6 +149,7 @@ "commandMessage": "Nachricht", "eventAll": "Alle Ereignisse", "eventDeviceOnline": "Gerät ist online", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Gerät ist offline", "eventDeviceMoving": "Gerät ist in Bewegung", "eventDeviceStopped": "Gerät hat angehalten", @@ -156,6 +160,7 @@ "eventAlarm": "Alarme", "eventIgnitionOn": "Zünding an", "eventIgnitionOff": "Zündung aus", + "eventMaintenance": "Maintenance required", "alarm": "Alarm", "alarmSos": "SOS Alarm", "alarmVibration": "Erschütterungsalarm", diff --git a/web/l10n/el.json b/web/l10n/el.json index 0c7b8c69..1abac4dc 100644 --- a/web/l10n/el.json +++ b/web/l10n/el.json @@ -40,6 +40,7 @@ "sharedAlias": "Ψευδώνυμο", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "Σφάλμα", "errorUnknown": "Άγνωστο σφάλμα", "errorConnection": "Σφάλμα σύνδεσης", @@ -58,6 +59,7 @@ "loginFailed": "Εσφαλμένη διεύθυνση ή εσφαλμένο συνθηματικό", "loginCreated": "Ο νέος χρήστης καταχωρήθηκε.", "loginLogout": "Αποσύνδεση", + "loginLogo": "Logo", "devicesAndState": "Κατάσταση συσκευών", "deviceTitle": "Συσκευές", "deviceIdentifier": "Αναγνωριστικό", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps Aerial", "mapShapePolygon": "Πολύγωνο", "mapShapeCircle": "Κύκλος", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "Κατάσταση", "stateName": "Παράμετρος", @@ -146,6 +149,7 @@ "commandMessage": "Μήνυμα", "eventAll": "Όλα τα γεγονότα", "eventDeviceOnline": "Η συσκευή είναι συνδεδεμένη", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Η συσκευή είναι αποσυνδεδεμένη", "eventDeviceMoving": "Η συσκευή βρίσκεται σε κίνηση", "eventDeviceStopped": "Η συσκευή είναι σταματημένη", @@ -156,6 +160,7 @@ "eventAlarm": "Προειδοποιήσεις", "eventIgnitionOn": "Ignition is ON", "eventIgnitionOff": "Ignition is OFF", + "eventMaintenance": "Maintenance required", "alarm": "Προειδοποίηση", "alarmSos": "Προειδοποίηση SOS", "alarmVibration": "Προειδοποίηση δόνησης", diff --git a/web/l10n/en.json b/web/l10n/en.json index 220c1d68..39376bea 100644 --- a/web/l10n/en.json +++ b/web/l10n/en.json @@ -40,9 +40,15 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", + "sharedCalendar": "Calendar", + "sharedCalendars": "Calendars", + "sharedFile": "File", + "sharedSelectFile": "Select File", "errorTitle": "Error", "errorUnknown": "Unknown error", "errorConnection": "Connection error", + "errorSocket": "Web socket connection error", "userEmail": "Email", "userPassword": "Password", "userAdmin": "Admin", @@ -58,6 +64,7 @@ "loginFailed": "Incorrect email address or password", "loginCreated": "New user has been registered", "loginLogout": "Logout", + "loginLogo": "Logo", "devicesAndState": "Devices and State", "deviceTitle": "Devices", "deviceIdentifier": "Identifier", @@ -111,6 +118,7 @@ "mapBingAerial": "Bing Maps Aerial", "mapShapePolygon": "Polygon", "mapShapeCircle": "Circle", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "State", "stateName": "Attribute", @@ -148,6 +156,7 @@ "commandTimezone": "Timezone Offset", "eventAll": "All Events", "eventDeviceOnline": "Device is online", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Device is offline", "eventDeviceMoving": "Device is moving", "eventDeviceStopped": "Device has stopped", @@ -158,6 +167,7 @@ "eventAlarm": "Alarms", "eventIgnitionOn": "Ignition is ON", "eventIgnitionOff": "Ignition is OFF", + "eventMaintenance": "Maintenance required", "alarm": "Alarm", "alarmSos": "SOS Alarm", "alarmVibration": "Vibration Alarm", diff --git a/web/l10n/es.json b/web/l10n/es.json index e660c775..ce65fe49 100644 --- a/web/l10n/es.json +++ b/web/l10n/es.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "Error", "errorUnknown": "Error Desconocido", "errorConnection": "Error de Conexión", @@ -58,6 +59,7 @@ "loginFailed": "Dirección de Correo o Contraseña Incorrecta", "loginCreated": "Nuevo Usuario ha sido registrado", "loginLogout": "Salir", + "loginLogo": "Logo", "devicesAndState": "Dispositivos y Estado", "deviceTitle": "Dispositivos", "deviceIdentifier": "Identificador", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps - Aéreo", "mapShapePolygon": "Polígono", "mapShapeCircle": "Círculo", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "Estado", "stateName": "Parámetro", @@ -146,6 +149,7 @@ "commandMessage": "Mensaje", "eventAll": "Todos los Eventos", "eventDeviceOnline": "El dispositivo está en linea", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "El dispositivo está fuera de linea", "eventDeviceMoving": "El dispositivo se está moviendo", "eventDeviceStopped": "El dispositivo se ha detenido", @@ -156,6 +160,7 @@ "eventAlarm": "Alarmas", "eventIgnitionOn": "Encendido ON", "eventIgnitionOff": "Encendido OFF", + "eventMaintenance": "Maintenance required", "alarm": "Alarma", "alarmSos": "Alarma de SOS", "alarmVibration": "Alarma de vibración", diff --git a/web/l10n/fa.json b/web/l10n/fa.json index b3e68e94..0d7e0dab 100644 --- a/web/l10n/fa.json +++ b/web/l10n/fa.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "خطا", "errorUnknown": "خطا ناشناخته", "errorConnection": "خطا در اتصال", @@ -58,6 +59,7 @@ "loginFailed": "نام كاربرى يا گذرواژه اشتباه است", "loginCreated": "ثبت نام با موفقيت انجام شد", "loginLogout": "خروج", + "loginLogo": "Logo", "devicesAndState": "دستگاه ها و وضعیت", "deviceTitle": "دستگاه ها", "deviceIdentifier": "سريال دستگاه", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps Aerial", "mapShapePolygon": "چند ضلعی", "mapShapeCircle": "دایره ", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "وضعیت", "stateName": "ویژگی", @@ -146,6 +149,7 @@ "commandMessage": "Message", "eventAll": "All Events", "eventDeviceOnline": "دستگاه آنلاین است ", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "دستگاه آفلاین است ", "eventDeviceMoving": "خودرو در حال حرکت است", "eventDeviceStopped": "Device has stopped", @@ -156,6 +160,7 @@ "eventAlarm": "هشدار ها", "eventIgnitionOn": "خودرو روشن هست ", "eventIgnitionOff": "خودرو خاموش است ", + "eventMaintenance": "Maintenance required", "alarm": "هشدار", "alarmSos": "هشدار کمک اضطراری", "alarmVibration": "هشدار ضربه", diff --git a/web/l10n/fi.json b/web/l10n/fi.json index 12691f0d..beccd687 100644 --- a/web/l10n/fi.json +++ b/web/l10n/fi.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "Virhe", "errorUnknown": "Tuntematon virhe", "errorConnection": "Yhteysvirhe", @@ -58,6 +59,7 @@ "loginFailed": "Virheellinen email tai salasana", "loginCreated": "Uusi käyttäjä on rekisteröitynyt", "loginLogout": "Kirjaudu ulos", + "loginLogo": "Logo", "devicesAndState": "Laitteet ja Tilat", "deviceTitle": "Laitteet", "deviceIdentifier": "Tunniste", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps ilmakuva", "mapShapePolygon": "Polygon", "mapShapeCircle": "Circle", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "Tila", "stateName": "Ominaisuus", @@ -146,6 +149,7 @@ "commandMessage": "Message", "eventAll": "All Events", "eventDeviceOnline": "Device is online", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Device is offline", "eventDeviceMoving": "Device is moving", "eventDeviceStopped": "Device has stopped", @@ -156,6 +160,7 @@ "eventAlarm": "Alarms", "eventIgnitionOn": "Ignition is ON", "eventIgnitionOff": "Ignition is OFF", + "eventMaintenance": "Maintenance required", "alarm": "Alarm", "alarmSos": "SOS Alarm", "alarmVibration": "Vibration Alarm", diff --git a/web/l10n/fr.json b/web/l10n/fr.json index 85ed03f0..ec042e58 100644 --- a/web/l10n/fr.json +++ b/web/l10n/fr.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "Erreur", "errorUnknown": "Erreur inconnue", "errorConnection": "Erreur de connexion", @@ -58,6 +59,7 @@ "loginFailed": "Adresse email ou mot de passe incorrect", "loginCreated": "Nouvel utilisateur enregistré", "loginLogout": "Déconnexion", + "loginLogo": "Logo", "devicesAndState": "Dispositifs et Etat", "deviceTitle": "Dispositifs", "deviceIdentifier": "Identifiant", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps Aerial", "mapShapePolygon": "Polygone", "mapShapeCircle": "Cercle", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "Etat", "stateName": "Paramètre", @@ -146,6 +149,7 @@ "commandMessage": "Message", "eventAll": "Tous les événements", "eventDeviceOnline": "L'appareil est en ligne", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "L'appareil est hors-ligne", "eventDeviceMoving": "L'appareil est en mouvement", "eventDeviceStopped": "Le dispositif s'est arrêté", @@ -156,6 +160,7 @@ "eventAlarm": "Alarmes", "eventIgnitionOn": "Contact mis", "eventIgnitionOff": "Contact coupé", + "eventMaintenance": "Maintenance required", "alarm": "Alarme", "alarmSos": "Alarme SOS", "alarmVibration": "Alarme vibration", diff --git a/web/l10n/he.json b/web/l10n/he.json index 79712ef9..5bfa1160 100644 --- a/web/l10n/he.json +++ b/web/l10n/he.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "שגיאה", "errorUnknown": "שגיאה לא ידועה", "errorConnection": "בעייה בחיבור", @@ -58,6 +59,7 @@ "loginFailed": "אימייל או סיסמה שגויים", "loginCreated": "משתמש חדש נרשם", "loginLogout": "יציאה", + "loginLogo": "Logo", "devicesAndState": "מכשירים וסטטוס", "deviceTitle": "מכשירים", "deviceIdentifier": "מזהה", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps Aerial", "mapShapePolygon": "פוליגון", "mapShapeCircle": "מעגל", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "מצב", "stateName": "תכונה", @@ -146,6 +149,7 @@ "commandMessage": "Message", "eventAll": "All Events", "eventDeviceOnline": "המכשיר און לין", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "המכשיר מנותק", "eventDeviceMoving": "המכשיר בתזוזה", "eventDeviceStopped": "Device has stopped", @@ -156,6 +160,7 @@ "eventAlarm": "אזעקות", "eventIgnitionOn": "Ignition is ON", "eventIgnitionOff": "Ignition is OFF", + "eventMaintenance": "Maintenance required", "alarm": "אזעקה", "alarmSos": "אתרעת SOS", "alarmVibration": "אזעקת רטט", diff --git a/web/l10n/hi.json b/web/l10n/hi.json index d8e10931..4ca52215 100644 --- a/web/l10n/hi.json +++ b/web/l10n/hi.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "त्रुटि", "errorUnknown": "अज्ञात त्रुटि", "errorConnection": "कनेक्शन त्रुटि", @@ -58,6 +59,7 @@ "loginFailed": "ई-मेल पता या पासवर्ड गलत है", "loginCreated": "नया उपयोगकर्ता पंजीकृत हो गया है", "loginLogout": "लॉगआउट / निष्कासन करें", + "loginLogo": "Logo", "devicesAndState": "उपकरण एवम स्तिति", "deviceTitle": "उपकरण", "deviceIdentifier": "पहचानकर्ता", @@ -111,6 +113,7 @@ "mapBingAerial": "बिंग मैप्स एरियल", "mapShapePolygon": "बहुभुज", "mapShapeCircle": "वृत्त", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "स्थिति / अवस्ता", "stateName": "गुण", @@ -146,6 +149,7 @@ "commandMessage": "संदेश / मेसेज", "eventAll": "सभी घटनाएँ / इवेंट्स", "eventDeviceOnline": "उपकरण / डिवाइस ऑनलाइन है", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "उपकरण / डिवाइस ऑफ़लाइन है", "eventDeviceMoving": "उपकरण / डिवाइस गतिमान है", "eventDeviceStopped": "उपकरण / डिवाइस रुक गया है", @@ -156,6 +160,7 @@ "eventAlarm": " एक से अधिक अलार्म", "eventIgnitionOn": "इग्निशन ऑन / चालू है", "eventIgnitionOff": "इग्निशन ऑफ / बंद है", + "eventMaintenance": "Maintenance required", "alarm": "अलार्म", "alarmSos": "एसओएस / एमर्जेन्सी अलार्म", "alarmVibration": "कंपन होने का अलार्म", diff --git a/web/l10n/hu.json b/web/l10n/hu.json index d1a5fcb4..a598be1a 100644 --- a/web/l10n/hu.json +++ b/web/l10n/hu.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "Hiba", "errorUnknown": "Ismeretlen hiba", "errorConnection": "Kapcsolódási hiba", @@ -58,6 +59,7 @@ "loginFailed": "Hibás email vagy jelszó", "loginCreated": "Az új felhasználó sikeresen létrehozva", "loginLogout": "Kilépés", + "loginLogo": "Logo", "devicesAndState": "Eszközök és állapotuk", "deviceTitle": "Eszközök", "deviceIdentifier": "Azonosító", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps Aerial", "mapShapePolygon": "Poligon", "mapShapeCircle": "Kör", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "Helyzet", "stateName": "Paraméter", @@ -146,6 +149,7 @@ "commandMessage": "Üzenet", "eventAll": "Minden esemény", "eventDeviceOnline": "Eszköz online", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Eszköz offline", "eventDeviceMoving": "Eszköz mozog", "eventDeviceStopped": "Eszköz megállt", @@ -156,6 +160,7 @@ "eventAlarm": "Riasztások", "eventIgnitionOn": "Gyújtás BE", "eventIgnitionOff": "Gyújtás KI", + "eventMaintenance": "Maintenance required", "alarm": "Riasztás", "alarmSos": "SOS Riasztás", "alarmVibration": "Rezgés riasztás", diff --git a/web/l10n/id.json b/web/l10n/id.json index 424f9796..03a3c3c7 100644 --- a/web/l10n/id.json +++ b/web/l10n/id.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "Error", "errorUnknown": "Error tidak diketahui", "errorConnection": "Koneksi error", @@ -58,6 +59,7 @@ "loginFailed": "Email atau password salah", "loginCreated": "Pengguna baru telah terdaftar", "loginLogout": "Keluar", + "loginLogo": "Logo", "devicesAndState": "Perangkat dan Status", "deviceTitle": "Perangkat", "deviceIdentifier": "Identifikasi", @@ -111,6 +113,7 @@ "mapBingAerial": "Peta Udara Bing", "mapShapePolygon": "Polygon", "mapShapeCircle": "Circle", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "Status", "stateName": "atribut", @@ -146,6 +149,7 @@ "commandMessage": "Message", "eventAll": "All Events", "eventDeviceOnline": "Device is online", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Device is offline", "eventDeviceMoving": "Device is moving", "eventDeviceStopped": "Device has stopped", @@ -156,6 +160,7 @@ "eventAlarm": "Alarms", "eventIgnitionOn": "Ignition is ON", "eventIgnitionOff": "Ignition is OFF", + "eventMaintenance": "Maintenance required", "alarm": "Alarm", "alarmSos": "SOS Alarm", "alarmVibration": "Vibration Alarm", diff --git a/web/l10n/it.json b/web/l10n/it.json index 2f83e0ed..a6ffe655 100644 --- a/web/l10n/it.json +++ b/web/l10n/it.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "Errore", "errorUnknown": "Errore sconosciuto", "errorConnection": "Errore di connessione", @@ -58,6 +59,7 @@ "loginFailed": "Indirizzo email o password errati", "loginCreated": "Un nuovo utente si e` registrato", "loginLogout": "Logout", + "loginLogo": "Logo", "devicesAndState": "Dispositivi e stato", "deviceTitle": "Dispositivi", "deviceIdentifier": "Identificativo", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps Aerial", "mapShapePolygon": "Poligono", "mapShapeCircle": "Cerchio", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "Stato", "stateName": "Attributo", @@ -146,6 +149,7 @@ "commandMessage": "Messaggio", "eventAll": "Tutti gli Eventi", "eventDeviceOnline": "Dispositivo online", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Dispositivo offline", "eventDeviceMoving": "Dispositivo in movimento", "eventDeviceStopped": "Il dispositivo si è feramto", @@ -156,6 +160,7 @@ "eventAlarm": "Allarmi", "eventIgnitionOn": "Accensione è inserita", "eventIgnitionOff": "Accensione è disinserita", + "eventMaintenance": "Maintenance required", "alarm": "Allarme", "alarmSos": "Allarme SOS", "alarmVibration": "Allarme Vibrazione", diff --git a/web/l10n/ka.json b/web/l10n/ka.json index 765c2a9e..da5f00d6 100644 --- a/web/l10n/ka.json +++ b/web/l10n/ka.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "შეცდომა", "errorUnknown": "უცნობი შეცდომა", "errorConnection": "კავშირის შეცდომა", @@ -58,6 +59,7 @@ "loginFailed": "არასწორი ელ-ფოსტა ან პაროლი", "loginCreated": "ახალი მომხარებელი დარეგისტრირდა", "loginLogout": "გამოსვლა", + "loginLogo": "Logo", "devicesAndState": "მოწყობილობები და სტატუსი", "deviceTitle": "მოწყობილობები", "deviceIdentifier": "იდენტიფიკატორი", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps Aerial", "mapShapePolygon": "Polygon", "mapShapeCircle": "Circle", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "სტატუსი", "stateName": "ატრიბუტი", @@ -146,6 +149,7 @@ "commandMessage": "Message", "eventAll": "All Events", "eventDeviceOnline": "Device is online", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Device is offline", "eventDeviceMoving": "Device is moving", "eventDeviceStopped": "Device has stopped", @@ -156,6 +160,7 @@ "eventAlarm": "Alarms", "eventIgnitionOn": "Ignition is ON", "eventIgnitionOff": "Ignition is OFF", + "eventMaintenance": "Maintenance required", "alarm": "Alarm", "alarmSos": "SOS Alarm", "alarmVibration": "Vibration Alarm", diff --git a/web/l10n/lo.json b/web/l10n/lo.json index 3d3e4b96..74c11a53 100644 --- a/web/l10n/lo.json +++ b/web/l10n/lo.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "ຜິດພາດ", "errorUnknown": "ຂໍ້ຜິດພາດທີ່ບໍ່ຮູ້ຈັກ", "errorConnection": "ການເຊື່ອມຕໍ່ຜິດພາດ", @@ -58,6 +59,7 @@ "loginFailed": "ທີ່ຢູ່ອີເມວຫລືລະຫັດຜ່ານບໍ່ຖືກຕ້ອງ", "loginCreated": "ຜູ້ໃຊ້ໃຫມ່ ໄດ້ຮັບການລົງທະບຽນ", "loginLogout": "ອອກຈາກລະບົບ", + "loginLogo": "Logo", "devicesAndState": "ອຸປະກອນແລະສະຖານະ", "deviceTitle": "ເຄື່ອງ/ອຸປະກອນ", "deviceIdentifier": "ລະບຸເລກອຸປະກອນ", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps ທາງອາກາດ", "mapShapePolygon": "ໂພລີກອນ", "mapShapeCircle": "ວົງກົມ", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "ສະຖານະ", "stateName": "ຄຸນລັກສະນະ", @@ -146,6 +149,7 @@ "commandMessage": "Message", "eventAll": "All Events", "eventDeviceOnline": "ອຸປະກອນເຊື່ອມຕໍ່ແລ້ວ", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "ອຸປະກອນບໍ່ໄດ້ເຊື່ອມຕໍ່", "eventDeviceMoving": "ອຸປະກອນກຳລັງເຄື່ອນທີ່", "eventDeviceStopped": "Device has stopped", @@ -156,6 +160,7 @@ "eventAlarm": "ລາຍການແຈ້ງເຕືອນ", "eventIgnitionOn": "Ignition is ON", "eventIgnitionOff": "Ignition is OFF", + "eventMaintenance": "Maintenance required", "alarm": "ແຈ້ງເຕືອນ", "alarmSos": "ແຈ້ງເຕືອນ SOS", "alarmVibration": "ແຈ້ງເຕືອນແບບສັ່ນ", diff --git a/web/l10n/lt.json b/web/l10n/lt.json index 43c804a4..6d3da8fc 100644 --- a/web/l10n/lt.json +++ b/web/l10n/lt.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "Klaida", "errorUnknown": "Nenumatyta klaida", "errorConnection": "Ryšio klaida", @@ -58,6 +59,7 @@ "loginFailed": "Neteisingas el.paštas ir/ar slaptažodis", "loginCreated": "Registracija sėkminga", "loginLogout": "Atsijungti", + "loginLogo": "Logo", "devicesAndState": "Prietaisai ir Statusas", "deviceTitle": "Prietaisai", "deviceIdentifier": "Identifikacinis kodas", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps Aerial", "mapShapePolygon": "Polygon", "mapShapeCircle": "Circle", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "Būklė", "stateName": "Parametras", @@ -146,6 +149,7 @@ "commandMessage": "Message", "eventAll": "All Events", "eventDeviceOnline": "Device is online", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Device is offline", "eventDeviceMoving": "Device is moving", "eventDeviceStopped": "Device has stopped", @@ -156,6 +160,7 @@ "eventAlarm": "Alarms", "eventIgnitionOn": "Ignition is ON", "eventIgnitionOff": "Ignition is OFF", + "eventMaintenance": "Maintenance required", "alarm": "Alarm", "alarmSos": "SOS Alarm", "alarmVibration": "Vibration Alarm", diff --git a/web/l10n/ml.json b/web/l10n/ml.json index 0aedf6ca..ab4037e6 100644 --- a/web/l10n/ml.json +++ b/web/l10n/ml.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "പിശക്", "errorUnknown": "അജ്ഞാത പിശക്", "errorConnection": "കണക്ഷൻ പിശക്", @@ -58,6 +59,7 @@ "loginFailed": "തെറ്റായ ഇമെയിൽ വിലാസവും പാസ്വേഡും", "loginCreated": "പുതിയ ഉപയോക്താവ് രജിസ്റ്റർ ചെയ്തു", "loginLogout": "പുറത്തുകടക്കുക", + "loginLogo": "Logo", "devicesAndState": "സാധനങ്ങളിന് നില ", "deviceTitle": "സാധനങ്ങളിന് ", "deviceIdentifier": "ഐഡന്റിഫയർ", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps Aerial", "mapShapePolygon": "Polygon", "mapShapeCircle": "Circle", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "State", "stateName": "Attribute", @@ -146,6 +149,7 @@ "commandMessage": "Message", "eventAll": "All Events", "eventDeviceOnline": "Device is online", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Device is offline", "eventDeviceMoving": "Device is moving", "eventDeviceStopped": "Device has stopped", @@ -156,6 +160,7 @@ "eventAlarm": "Alarms", "eventIgnitionOn": "Ignition is ON", "eventIgnitionOff": "Ignition is OFF", + "eventMaintenance": "Maintenance required", "alarm": "Alarm", "alarmSos": "SOS Alarm", "alarmVibration": "Vibration Alarm", diff --git a/web/l10n/ms.json b/web/l10n/ms.json index a1c90970..6a9f3c4a 100644 --- a/web/l10n/ms.json +++ b/web/l10n/ms.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "Ralat", "errorUnknown": "Ralat tidak diketahui", "errorConnection": "Ralat penyambungan", @@ -58,6 +59,7 @@ "loginFailed": "Kesalahan emel atau katalaluan", "loginCreated": "Pengguna baru telah didaftarkan", "loginLogout": "Keluar", + "loginLogo": "Logo", "devicesAndState": "Peranti dan State", "deviceTitle": "Peranti", "deviceIdentifier": "IMEI/ID", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps Aerial", "mapShapePolygon": "Polygon", "mapShapeCircle": "Circle", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "Negeri", "stateName": "Atribut", @@ -146,6 +149,7 @@ "commandMessage": "Message", "eventAll": "All Events", "eventDeviceOnline": "Device is online", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Device is offline", "eventDeviceMoving": "Device is moving", "eventDeviceStopped": "Device has stopped", @@ -156,6 +160,7 @@ "eventAlarm": "Alarms", "eventIgnitionOn": "Ignition is ON", "eventIgnitionOff": "Ignition is OFF", + "eventMaintenance": "Maintenance required", "alarm": "Alarm", "alarmSos": "SOS Alarm", "alarmVibration": "Vibration Alarm", diff --git a/web/l10n/nb.json b/web/l10n/nb.json index f4afa0e7..fee18de2 100644 --- a/web/l10n/nb.json +++ b/web/l10n/nb.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "Feil", "errorUnknown": "Ukjent feil", "errorConnection": "Forbindelse feilet", @@ -58,6 +59,7 @@ "loginFailed": "Feil e-post eller passord", "loginCreated": "Ny bruker har blitt registrert", "loginLogout": "Logg ut", + "loginLogo": "Logo", "devicesAndState": "Enheter og status", "deviceTitle": "Enheter", "deviceIdentifier": "Identifikator", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps-flyfoto", "mapShapePolygon": "Mangekant", "mapShapeCircle": "Sirkel", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "Status", "stateName": "Egenskap", @@ -146,6 +149,7 @@ "commandMessage": "Melding", "eventAll": "Alle hendelser", "eventDeviceOnline": "Enhet er tilkoblet", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Enhet er frakoblet", "eventDeviceMoving": "Enheten beveger seg", "eventDeviceStopped": "Enheten har stoppet", @@ -156,6 +160,7 @@ "eventAlarm": "Alarmer", "eventIgnitionOn": "Tenning er PÅ", "eventIgnitionOff": "Tenning er AV", + "eventMaintenance": "Maintenance required", "alarm": "Alarm", "alarmSos": "SOS-alarm", "alarmVibration": "Vibrasjonsalarm", diff --git a/web/l10n/ne.json b/web/l10n/ne.json index 1ccbcbec..744153b3 100644 --- a/web/l10n/ne.json +++ b/web/l10n/ne.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "त्रुटी", "errorUnknown": "अज्ञात त्रुटी ", "errorConnection": "जडान मा त्रुटी भयो ", @@ -58,6 +59,7 @@ "loginFailed": "इ मेल वा गोप्य शब्द गलत भयो ", "loginCreated": "नया प्रयोगकर्ता दर्ता भयो ", "loginLogout": "बाहिरिने ", + "loginLogo": "Logo", "devicesAndState": "यन्त्रहरू तथा अवस्था ", "deviceTitle": "यन्त्रहरू ", "deviceIdentifier": "परिचायक ", @@ -111,6 +113,7 @@ "mapBingAerial": "बिंग नक्शा (एरियल)", "mapShapePolygon": "Polygon", "mapShapeCircle": "Circle", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "अवस्था ", "stateName": "गुण ", @@ -146,6 +149,7 @@ "commandMessage": "Message", "eventAll": "All Events", "eventDeviceOnline": "Device is online", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Device is offline", "eventDeviceMoving": "Device is moving", "eventDeviceStopped": "Device has stopped", @@ -156,6 +160,7 @@ "eventAlarm": "Alarms", "eventIgnitionOn": "Ignition is ON", "eventIgnitionOff": "Ignition is OFF", + "eventMaintenance": "Maintenance required", "alarm": "Alarm", "alarmSos": "SOS Alarm", "alarmVibration": "Vibration Alarm", diff --git a/web/l10n/nl.json b/web/l10n/nl.json index d8d40381..8e2d3b5f 100644 --- a/web/l10n/nl.json +++ b/web/l10n/nl.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Afstand apparaat", "sharedDevice": "Apparaat", + "sharedTestMail": "Verstuur test-e-mail", "errorTitle": "Fout", "errorUnknown": "Onbekende fout", "errorConnection": "Verbindingsfout", @@ -58,6 +59,7 @@ "loginFailed": "Onjuist e-mailadres of wachtwoord", "loginCreated": "De nieuwe gebruiker is geregistreerd", "loginLogout": "Afmelden", + "loginLogo": "Logo", "devicesAndState": "Apparaten en status", "deviceTitle": "Apparaten", "deviceIdentifier": "Identifier", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps Luchtfoto", "mapShapePolygon": "Polygoon", "mapShapeCircle": "Cirkel", + "mapShapePolyline": "Polylijn", "mapLiveRoutes": "Live routes", "stateTitle": "Status", "stateName": "Parameter", @@ -146,6 +149,7 @@ "commandMessage": "Bericht", "eventAll": "Alle gebeurtenissen", "eventDeviceOnline": "Apparaat is online", + "eventDeviceUnknown": "Apparaatstatus is onbekend", "eventDeviceOffline": "Apparaat is offline", "eventDeviceMoving": "Apparaat beweegt", "eventDeviceStopped": "Apparaat is gestopt", @@ -156,6 +160,7 @@ "eventAlarm": "Alarmen", "eventIgnitionOn": "Contact aan", "eventIgnitionOff": "Contact uit", + "eventMaintenance": "Onderhoud vereist", "alarm": "Alarm", "alarmSos": "SOS alarm", "alarmVibration": "Vibratiealarm", diff --git a/web/l10n/nn.json b/web/l10n/nn.json index 82e59dc5..40e037f9 100644 --- a/web/l10n/nn.json +++ b/web/l10n/nn.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "Feil", "errorUnknown": "Ukjent feil", "errorConnection": "Forbindelse feila", @@ -58,6 +59,7 @@ "loginFailed": "Feil e-post eller passord", "loginCreated": "Ny brukar har blitt registrert", "loginLogout": "Logg ut", + "loginLogo": "Logo", "devicesAndState": "Einingar og status", "deviceTitle": "Einingar", "deviceIdentifier": "Identifikator", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps-flyfoto", "mapShapePolygon": "Mangekant", "mapShapeCircle": "Sirkel", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "Status", "stateName": "Eigenskap", @@ -146,6 +149,7 @@ "commandMessage": "Melding", "eventAll": "Alle hendingar", "eventDeviceOnline": "Eining er tilkopla", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Eininga er fråkopla", "eventDeviceMoving": "Eininga rører seg", "eventDeviceStopped": "Eininga har stoppa", @@ -156,6 +160,7 @@ "eventAlarm": "Alarmar", "eventIgnitionOn": "Tenninga er PÅ", "eventIgnitionOff": "Tenninga er AV", + "eventMaintenance": "Maintenance required", "alarm": "Alarm", "alarmSos": "SOS-alarm", "alarmVibration": "Vibrasjonsalarm", diff --git a/web/l10n/pl.json b/web/l10n/pl.json index 28262aeb..b857a72e 100644 --- a/web/l10n/pl.json +++ b/web/l10n/pl.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Dystans urządzenia", "sharedDevice": "Urządzenie", + "sharedTestMail": "Send Test Email", "errorTitle": "Bląd", "errorUnknown": "Nieznany błąd", "errorConnection": "Błąd przy połączeniu", @@ -58,6 +59,7 @@ "loginFailed": "Nieprawidłowy adres e-mail lub hasło", "loginCreated": "Nowy użytkownik został zarejestrowany", "loginLogout": "Wyloguj", + "loginLogo": "Logo", "devicesAndState": "Urządzenia i stan", "deviceTitle": "Urządzenia", "deviceIdentifier": "Identyfikator", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps Aerial", "mapShapePolygon": "Wielokąt", "mapShapeCircle": "Okrąg", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Ścieżki na żywo", "stateTitle": "Stan i lokalizacja", "stateName": "Właściwość", @@ -146,6 +149,7 @@ "commandMessage": "Wiadomość", "eventAll": "Wszystkie zdarzenia", "eventDeviceOnline": "Urządzenie jest online", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Urządzenie jest offline", "eventDeviceMoving": "Urządzenie przemieszcza się", "eventDeviceStopped": "Urządzenie się zatrzymało", @@ -156,6 +160,7 @@ "eventAlarm": "Alarmy", "eventIgnitionOn": "Zapłon włączony", "eventIgnitionOff": "Zapłon wyłączony", + "eventMaintenance": "Maintenance required", "alarm": "Alarm", "alarmSos": "Alarm SOS", "alarmVibration": "Alarm wibracyjny", diff --git a/web/l10n/pt.json b/web/l10n/pt.json index 4a63cc55..c516cce4 100644 --- a/web/l10n/pt.json +++ b/web/l10n/pt.json @@ -1,8 +1,8 @@ { "sharedLoading": "Carregando...", - "sharedHide": "Hide", + "sharedHide": "Ocultar", "sharedSave": "Salvar", - "sharedSet": "Set", + "sharedSet": "Conjunto", "sharedCancel": "Cancelar", "sharedAdd": "Adicionar", "sharedEdit": "Editar", @@ -17,72 +17,74 @@ "sharedHour": "Hora", "sharedMinute": "Minuto", "sharedSecond": "Segundo", - "sharedDecimalDegrees": "Decimal Degrees", - "sharedDegreesDecimalMinutes": "Degrees Decimal Minutes", - "sharedDegreesMinutesSeconds": "Degrees Minutes Seconds", - "sharedName": "Name", - "sharedDescription": "Description", - "sharedSearch": "Search", - "sharedGeofence": "Geofence", - "sharedGeofences": "Geofences", - "sharedNotifications": "Notifications", - "sharedAttributes": "Attributes", - "sharedAttribute": "Attribute", - "sharedArea": "Area", - "sharedMute": "Mute", - "sharedType": "Type", - "sharedDistance": "Distance", - "sharedHourAbbreviation": "h", - "sharedMinuteAbbreviation": "m", - "sharedGetMapState": "Get Map State", - "sharedAttributeAlias": "Attribute Alias", - "sharedAttributeAliases": "Attribute Aliases", + "sharedDecimalDegrees": "Graus Decimais", + "sharedDegreesDecimalMinutes": "Graus Decimais Minutos", + "sharedDegreesMinutesSeconds": "Graus Decimais Segundos", + "sharedName": "Nome", + "sharedDescription": "Descrição", + "sharedSearch": "Pesquisar", + "sharedGeofence": "Cerca Geográfica", + "sharedGeofences": "Cercas Geográficas", + "sharedNotifications": "Notificações", + "sharedAttributes": "Atributos", + "sharedAttribute": "Atributo", + "sharedArea": "Área", + "sharedMute": "Mudo", + "sharedType": "Tipo", + "sharedDistance": "Distância", + "sharedHourAbbreviation": "H", + "sharedMinuteAbbreviation": "M", + "sharedGetMapState": "Obter Estado do Mapa", + "sharedAttributeAlias": "Alias de Atributo", + "sharedAttributeAliases": "Alias de Atributos", "sharedAlias": "Alias", - "sharedDeviceDistance": "Device Distance", - "sharedDevice": "Device", + "sharedDeviceDistance": "Distancia do Dispositivo", + "sharedDevice": "Dispositivo", + "sharedTestMail": "Enviar Email de Teste", "errorTitle": "Erro", "errorUnknown": "Erro desconhecido", "errorConnection": "Erro de conexão", - "userEmail": "E-mail", + "userEmail": "Email", "userPassword": "Senha", - "userAdmin": "Admin", - "userRemember": "Remember", - "userDisabled": "Disabled", - "userExpirationTime": "Expiration", - "userDeviceLimit": "Device Limit", - "userToken": "Token", + "userAdmin": "Administrador", + "userRemember": "Relembrar", + "userDisabled": "Desactivado", + "userExpirationTime": "Expiração", + "userDeviceLimit": "Limite do Dipositivo", + "userToken": "Símbolo", "loginTitle": "Entrar", "loginLanguage": "Idioma", - "loginRegister": "Registrar", + "loginRegister": "Registar", "loginLogin": "Entrar", - "loginFailed": "Endereço de e-mail ou senha incorreta", - "loginCreated": "Novo usuário foi registrado", + "loginFailed": "Endereço de e-mail ou senha incorrectos", + "loginCreated": "Novo utilizador foi registado", "loginLogout": "Sair", - "devicesAndState": "Devices and State", - "deviceTitle": "Devices", + "loginLogo": "Logótipo", + "devicesAndState": "Dispositivos e Estados", + "deviceTitle": "Dispositivos", "deviceIdentifier": "Identificador", - "devicePhone": "Phone", - "deviceModel": "Model", - "deviceContact": "Contact", - "deviceCategory": "Category", - "deviceLastUpdate": "Last Update", + "devicePhone": "Telefone", + "deviceModel": "Modelo", + "deviceContact": "Contacto", + "deviceCategory": "Categoria", + "deviceLastUpdate": "Ultima Actualização", "deviceCommand": "Comando", - "deviceFollow": "Follow", - "deviceTotalDistance": "Total Distance", - "groupDialog": "Group", - "groupParent": "Group", - "groupNoGroup": "No Group", + "deviceFollow": "Seguir", + "deviceTotalDistance": "Distancia Total", + "groupDialog": "Grupo", + "groupParent": "Grupo", + "groupNoGroup": "Sem Grupo", "settingsTitle": "Configurações", "settingsUser": "Conta", - "settingsGroups": "Groups", + "settingsGroups": "Grupos", "settingsServer": "Servidor", - "settingsUsers": "Usuário", + "settingsUsers": "Utilizadores", "settingsSpeedUnit": "Velocidade", - "settingsTwelveHourFormat": "12-hour Format", - "settingsCoordinateFormat": "Coordinates Format", + "settingsTwelveHourFormat": "Formato 12 Horas", + "settingsCoordinateFormat": "Formato das Coordenadas", "reportTitle": "Relatórios", "reportDevice": "Dispositivo", - "reportGroup": "Group", + "reportGroup": "Grupo", "reportFrom": "De", "reportTo": "Para", "reportShow": "Mostrar", @@ -95,110 +97,113 @@ "positionSpeed": "Velocidade", "positionCourse": "Curso", "positionAddress": "Endereço", - "positionProtocol": "protocolo", + "positionProtocol": "Protocolo", "serverTitle": "Configurações do Servidor", "serverZoom": "Zoom", - "serverRegistration": "Registro", - "serverReadonly": "Readonly", - "serverForceSettings": "Force Settings", + "serverRegistration": "Registo", + "serverReadonly": "Apenas Leitura", + "serverForceSettings": "Forçar Configurações", "mapTitle": "Mapa", "mapLayer": "Camada Mapa", "mapCustom": "Mapa personalizado", - "mapCarto": "Carto Basemaps", - "mapOsm": "Open Street Mapa", - "mapBingKey": "Bing Maps Key", - "mapBingRoad": "Bing Mapas Estrada", - "mapBingAerial": "Bing Mapas Aérea", - "mapShapePolygon": "Polygon", - "mapShapeCircle": "Circle", - "mapLiveRoutes": "Live Routes", + "mapCarto": "Mapa Carto", + "mapOsm": "Mapa Open Street", + "mapBingKey": "Mapa Bing Key", + "mapBingRoad": "Mapa Bing Road", + "mapBingAerial": "Mapa Bing Aéreo", + "mapShapePolygon": "Polígono", + "mapShapeCircle": "Circulo", + "mapShapePolyline": "Linha Poligono", + "mapLiveRoutes": "Rotas ao Vivo", "stateTitle": "Estado", "stateName": "Parâmetro", "stateValue": "Valor", "commandTitle": "Comando", "commandSend": "Enviar", "commandSent": "Comando foi enviado", - "commandPositionPeriodic": "Posição Tempo", + "commandPositionPeriodic": "Relatório Periódico", "commandPositionStop": "Parar Posição", - "commandEngineStop": "Bloqueio Veículo", - "commandEngineResume": "Desbloqueio Veículo", + "commandEngineStop": "Parar Motor", + "commandEngineResume": "Desbloqueio do Motor", "commandFrequency": "Frequência", "commandUnit": "Unidade", - "commandCustom": "Custom command", - "commandPositionSingle": "Single Reporting", - "commandAlarmArm": "Arm Alarm", - "commandAlarmDisarm": "Disarm Alarm", - "commandSetTimezone": "Set Timezone", - "commandRequestPhoto": "Request Photo", - "commandRebootDevice": "Reboot Device", - "commandSendSms": "Send SMS", - "commandSendUssd": "Send USSD", - "commandSosNumber": "Set SOS Number", - "commandSilenceTime": "Set Silence Time", - "commandSetPhonebook": "Set Phonebook", - "commandVoiceMessage": "Voice Message", - "commandOutputControl": "Output Control", - "commandAlarmSpeed": "Overspeed Alarm", - "commandDeviceIdentification": "Device Identification", - "commandIndex": "Index", - "commandData": "Data", - "commandPhone": "Phone Number", - "commandMessage": "Message", - "eventAll": "All Events", - "eventDeviceOnline": "Device is online", - "eventDeviceOffline": "Device is offline", - "eventDeviceMoving": "Device is moving", - "eventDeviceStopped": "Device has stopped", - "eventDeviceOverspeed": "Device exceeds the speed", - "eventCommandResult": "Command result", - "eventGeofenceEnter": "Device has entered geofence", - "eventGeofenceExit": "Device has exited geofence", - "eventAlarm": "Alarms", - "eventIgnitionOn": "Ignition is ON", - "eventIgnitionOff": "Ignition is OFF", - "alarm": "Alarm", - "alarmSos": "SOS Alarm", - "alarmVibration": "Vibration Alarm", - "alarmMovement": "Movement Alarm", - "alarmOverspeed": "Overspeed Alarm", - "alarmFallDown": "FallDown Alarm", - "alarmLowBattery": "LowBattery Alarm", - "alarmFault": "Fault Alarm", - "notificationType": "Type of Notification", - "notificationWeb": "Send via Web", - "notificationMail": "Send via Mail", - "reportRoute": "Route", - "reportEvents": "Events", - "reportTrips": "Trips", - "reportSummary": "Summary", - "reportConfigure": "Configure", - "reportEventTypes": "Event Types", - "reportExport": "Export", - "reportDeviceName": "Device Name", - "reportAverageSpeed": "Average Speed", - "reportMaximumSpeed": "Maximum Speed", - "reportEngineHours": "Engine Hours", - "reportDuration": "Duration", - "reportStartTime": "Start Time", - "reportStartAddress": "Start Address", - "reportEndTime": "End Time", - "reportEndAddress": "End Address", - "reportSpentFuel": "Spent Fuel", - "statisticsTitle": "Statistics", - "statisticsCaptureTime": "Capture Time", - "statisticsActiveUsers": "Active Users", - "statisticsActiveDevices": "Active Devices", - "statisticsRequests": "Requests", - "statisticsMessagesReceived": "Messages Received", - "statisticsMessagesStored": "Messages Stored", - "categoryArrow": "Arrow", - "categoryDefault": "Default", - "categoryCar": "Car", - "categoryBus": "Bus", - "categoryTruck": "Truck", - "categoryShip": "Ship", - "categoryPlane": "Plane", - "categoryMotorcycle": "Motorcycle", - "categoryBicycle": "Bicycle", - "categoryPerson": "Person" + "commandCustom": "Comando Personalizado", + "commandPositionSingle": "Relatórios Únicos", + "commandAlarmArm": "Armar Alarme", + "commandAlarmDisarm": "Desarmar Alarme", + "commandSetTimezone": "Definir Fuso Horário", + "commandRequestPhoto": "Solicitar Foto", + "commandRebootDevice": "Reiniciar Dispositivo", + "commandSendSms": "Enviar SMS", + "commandSendUssd": "Enviar USSD", + "commandSosNumber": "Definir Numero SOS", + "commandSilenceTime": "Definir Tempo de Silencio", + "commandSetPhonebook": "Definir Agenda", + "commandVoiceMessage": "Mensagem de Voz", + "commandOutputControl": "Controlo de Saída ", + "commandAlarmSpeed": "Alarme de Excesso de Velocidade", + "commandDeviceIdentification": "Identificação do Dispositivo", + "commandIndex": "Inicio", + "commandData": "Dados", + "commandPhone": "Número de Telefone", + "commandMessage": "Mensagem", + "eventAll": "Todos os Eventos", + "eventDeviceOnline": "Dispositivo Conectado", + "eventDeviceUnknown": "Estado do dispositivo desconhecido", + "eventDeviceOffline": "Dispositivo Desconectado", + "eventDeviceMoving": "Dispositivo em Movimento", + "eventDeviceStopped": "Dispositivo Parado", + "eventDeviceOverspeed": "Dispositivo em Excesso de Velocidade", + "eventCommandResult": "Resultado do Comando", + "eventGeofenceEnter": "Dispositivo Entrou na Cerca Geográfica", + "eventGeofenceExit": "Dispositivo Saiu da Cerca Geográfica", + "eventAlarm": "Alarmes", + "eventIgnitionOn": "Ignição Ligada", + "eventIgnitionOff": "Ignição Desligada", + "eventMaintenance": "Necessária manutenção", + "alarm": "Alarme", + "alarmSos": "Alarme SOS", + "alarmVibration": "Alarme de Vibração", + "alarmMovement": "Alarme de Movimento", + "alarmOverspeed": "Alarme de Excesso de Velocidade", + "alarmFallDown": "Alarme de Queda", + "alarmLowBattery": "Alarme de Bateria Baixa", + "alarmFault": "Alarme de Falha", + "notificationType": "Tipo de Notificação", + "notificationWeb": "Enviar por Web", + "notificationMail": "Enviar por Email", + "reportRoute": "Rota", + "reportEvents": "Eventos", + "reportTrips": "Viagens", + "reportSummary": "Resumo", + "reportConfigure": "Configurar", + "reportEventTypes": "Tipos de Eventos", + "reportExport": "Exportar", + "reportDeviceName": "Nome do Dispositivo", + "reportAverageSpeed": "Velocidade Média", + "reportMaximumSpeed": "Velocidade Máxima", + "reportEngineHours": "Horas do Motor", + "reportDuration": "Duração", + "reportStartTime": "Iniciar Hora", + "reportStartAddress": "Iniciar Morada", + "reportEndTime": "Terminar Hora", + "reportEndAddress": "Terminar Morada", + "reportSpentFuel": "Combustível Gasto", + "statisticsTitle": "Estatísticas", + "statisticsCaptureTime": "Hora da Captura", + "statisticsActiveUsers": "Activar Utilizadores", + "statisticsActiveDevices": "Activar Dispositivos", + "statisticsRequests": "Pedidos", + "statisticsMessagesReceived": "Mensagens Recebidas", + "statisticsMessagesStored": "Mensagens Armazenadas", + "categoryArrow": "Seta", + "categoryDefault": "Padrão", + "categoryCar": "Carro", + "categoryBus": "Autocarro", + "categoryTruck": "Camião", + "categoryShip": "Barco", + "categoryPlane": "Avião", + "categoryMotorcycle": "Mota", + "categoryBicycle": "Bicicleta", + "categoryPerson": "Pessoa" }
\ No newline at end of file diff --git a/web/l10n/pt_BR.json b/web/l10n/pt_BR.json index c29b3548..3baeda89 100644 --- a/web/l10n/pt_BR.json +++ b/web/l10n/pt_BR.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Distância do dispositivo", "sharedDevice": "Dispositivo", + "sharedTestMail": "Enviar e-mail de teste", "errorTitle": "Erro", "errorUnknown": "Erro desconhecido", "errorConnection": "Erro de conexão", @@ -58,6 +59,7 @@ "loginFailed": "Endereço de email ou senha incorretos", "loginCreated": "O novo usuário foi registrado", "loginLogout": "Sair", + "loginLogo": "Logo", "devicesAndState": "Dispositivo e Estado", "deviceTitle": "Dispositivos", "deviceIdentifier": "Identificador", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps Aéreo", "mapShapePolygon": "Polígono", "mapShapeCircle": "Círculo", + "mapShapePolyline": "Polilinha", "mapLiveRoutes": "Rotas ao Vivo", "stateTitle": "Estado", "stateName": "Atributo", @@ -146,6 +149,7 @@ "commandMessage": "Mensagem", "eventAll": "Todos Eventos", "eventDeviceOnline": "Dispositivo está on-line", + "eventDeviceUnknown": "Estado do dispositivo desconhecido", "eventDeviceOffline": "Dispositivo está offline", "eventDeviceMoving": "Dispositivo está se movendo", "eventDeviceStopped": "Dispositivo parou", @@ -156,6 +160,7 @@ "eventAlarm": "Alarmes", "eventIgnitionOn": "Ignição está ON", "eventIgnitionOff": "Ignição está OFF", + "eventMaintenance": "Manutenção necessária", "alarm": "Alarme", "alarmSos": "Alarme SOS", "alarmVibration": "Alarme de Vibração", diff --git a/web/l10n/ro.json b/web/l10n/ro.json index ed066efd..191b76e9 100644 --- a/web/l10n/ro.json +++ b/web/l10n/ro.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "Eroare", "errorUnknown": "Eroare necunoscută", "errorConnection": "Eroare de conexiune", @@ -58,6 +59,7 @@ "loginFailed": "E-mail sau parolă incorectă", "loginCreated": "Un utilizator nou a fost înregistrat", "loginLogout": "Deconectare", + "loginLogo": "Logo", "devicesAndState": "Stare dispozitive", "deviceTitle": "Dispozitive", "deviceIdentifier": "Identificator", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Hartă Aeriană", "mapShapePolygon": "Poligon", "mapShapeCircle": "Cerc", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "Stare", "stateName": "Atribut", @@ -146,6 +149,7 @@ "commandMessage": "Message", "eventAll": "All Events", "eventDeviceOnline": "Dispozitivul este pornit", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Dispozitivul este oprit", "eventDeviceMoving": "Dispozitivul este în mişcare", "eventDeviceStopped": "Device has stopped", @@ -156,6 +160,7 @@ "eventAlarm": "Alarme", "eventIgnitionOn": "Contact pornit", "eventIgnitionOff": "Contact oprit", + "eventMaintenance": "Maintenance required", "alarm": "Alarmă", "alarmSos": "Alarmă SOS", "alarmVibration": "Alarmă vibraţii", diff --git a/web/l10n/ru.json b/web/l10n/ru.json index 371a6382..bd871cd0 100644 --- a/web/l10n/ru.json +++ b/web/l10n/ru.json @@ -40,6 +40,7 @@ "sharedAlias": "Псевдоним", "sharedDeviceDistance": "Пробег Устройства", "sharedDevice": "Устройство", + "sharedTestMail": "Отправить Тестовое Сообщение", "errorTitle": "Ошибка", "errorUnknown": "Неизвестная ошибка", "errorConnection": "Ошибка соединения", @@ -47,10 +48,10 @@ "userPassword": "Пароль", "userAdmin": "Администратор", "userRemember": "Запомнить", - "userDisabled": "Disabled", - "userExpirationTime": "Expiration", - "userDeviceLimit": "Device Limit", - "userToken": "Token", + "userDisabled": "Оключен", + "userExpirationTime": "Срок Действия", + "userDeviceLimit": "Ограничение Устройств", + "userToken": "Ключ", "loginTitle": "Вход", "loginLanguage": "Язык", "loginRegister": "Регистрация", @@ -58,6 +59,7 @@ "loginFailed": "Неправильный email адрес или пароль", "loginCreated": "Новый пользователь зарегистрирован", "loginLogout": "Выход", + "loginLogo": "Логотип", "devicesAndState": "Устройства и Состояния", "deviceTitle": "Устройства", "deviceIdentifier": "Идентификатор", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps Спутник", "mapShapePolygon": "Многоугольник", "mapShapeCircle": "Круг", + "mapShapePolyline": "Линия", "mapLiveRoutes": " Живые Маршруты", "stateTitle": "Состояние", "stateName": "Параметр", @@ -146,6 +149,7 @@ "commandMessage": "Сообщение", "eventAll": "Все События", "eventDeviceOnline": "Устройство в сети", + "eventDeviceUnknown": "Статус устройства неизвестен", "eventDeviceOffline": "Устройство не в сети", "eventDeviceMoving": "Устройство движется", "eventDeviceStopped": "Устройство остановилось", @@ -156,6 +160,7 @@ "eventAlarm": "Тревоги", "eventIgnitionOn": "Зажигание ВКЛ", "eventIgnitionOff": "Зажигание ВЫКЛ", + "eventMaintenance": "Требуется обслуживание", "alarm": "Тревога", "alarmSos": "Тревога SOS", "alarmVibration": "Тревога Вибрации", diff --git a/web/l10n/si.json b/web/l10n/si.json index 7758637e..73d10cf0 100644 --- a/web/l10n/si.json +++ b/web/l10n/si.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "දෝෂයක් ", "errorUnknown": "නොදන්නා දෝෂයක් !", "errorConnection": "සම්බන්ධතා දෝෂයක් !", @@ -58,6 +59,7 @@ "loginFailed": "ඊ-මේල් ලිපිනය හෝ මුරපදය වැරදිය !", "loginCreated": "නව පරිශීලක ලියාපදිංචි කරන ලදි !", "loginLogout": "ඉවත්වන්න", + "loginLogo": "Logo", "devicesAndState": "උපාංග සහ ස්වභාවය", "deviceTitle": "උපාංග", "deviceIdentifier": "හඳුනාගැනීමේ කේතය", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps Aerial", "mapShapePolygon": "බහුඅශ්රය", "mapShapeCircle": "වෘත්තය", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "තත්වය", "stateName": "පරාමිතිය", @@ -146,6 +149,7 @@ "commandMessage": "පණිවිඩය", "eventAll": "All Events", "eventDeviceOnline": "Device is online", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Device is offline", "eventDeviceMoving": "Device is moving", "eventDeviceStopped": "Device has stopped", @@ -156,6 +160,7 @@ "eventAlarm": "නිවේදන", "eventIgnitionOn": "Ignition is ON", "eventIgnitionOff": "Ignition is OFF", + "eventMaintenance": "Maintenance required", "alarm": "අනතුරු ඇඟවීම්", "alarmSos": "SOS Alarm", "alarmVibration": "Vibration Alarm", diff --git a/web/l10n/sk.json b/web/l10n/sk.json index e0caa5c7..36025bda 100644 --- a/web/l10n/sk.json +++ b/web/l10n/sk.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "Chyba", "errorUnknown": "Neznáma chyba", "errorConnection": "Chyba pripojenia", @@ -58,6 +59,7 @@ "loginFailed": "Nesprávna e-mailová adresa alebo heslo", "loginCreated": "Nový užívateľ sa zaregistroval", "loginLogout": "Odhlásiť", + "loginLogo": "Logo", "devicesAndState": "Zariadenia a Status", "deviceTitle": "Zariadena", "deviceIdentifier": "Identifikátor", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps Arial", "mapShapePolygon": "Polygón", "mapShapeCircle": "Kruh", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "Štát", "stateName": "Parameter", @@ -146,6 +149,7 @@ "commandMessage": "Správa", "eventAll": "Všetky akcie", "eventDeviceOnline": "Zariadenie je online", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Zariadenie je offline", "eventDeviceMoving": "Zariadenie je v pohybe", "eventDeviceStopped": "Device has stopped", @@ -156,6 +160,7 @@ "eventAlarm": "Upozornenia", "eventIgnitionOn": "Zapaľovanie je ZAPNUTÉ", "eventIgnitionOff": "Zapaľovanie je VYPNUTÉ", + "eventMaintenance": "Maintenance required", "alarm": "Upozornenie", "alarmSos": "SOS upozornenie", "alarmVibration": "Vibračné upozornenie", diff --git a/web/l10n/sl.json b/web/l10n/sl.json index 2140046f..dd3ee53e 100644 --- a/web/l10n/sl.json +++ b/web/l10n/sl.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Razdalja naprave", "sharedDevice": "Naprava", + "sharedTestMail": "Send Test Email", "errorTitle": "Napaka", "errorUnknown": "Neznana napaka", "errorConnection": "Napaka v povezavi", @@ -58,6 +59,7 @@ "loginFailed": "Nepravilna e-pošta ali geslo", "loginCreated": "Nov uporabnik je registriran", "loginLogout": "Odjava", + "loginLogo": "Logo", "devicesAndState": "Naprava in stanje", "deviceTitle": "Naprave", "deviceIdentifier": "Identifikacija", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps Satelit", "mapShapePolygon": "Poligon", "mapShapeCircle": "Krog", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "Stanje", "stateName": "Parameter", @@ -146,6 +149,7 @@ "commandMessage": "Sporočilo", "eventAll": "Vsi dogodki", "eventDeviceOnline": "Naprava je povezana", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Naprava ni povezana", "eventDeviceMoving": "Naprava se premika", "eventDeviceStopped": "Naprava se je ustavila", @@ -156,6 +160,7 @@ "eventAlarm": "Alarms", "eventIgnitionOn": "Ignition is ON", "eventIgnitionOff": "Ignition is OFF", + "eventMaintenance": "Maintenance required", "alarm": "Alaram", "alarmSos": "SOS Alarm", "alarmVibration": "Vibration Alarm", diff --git a/web/l10n/sq.json b/web/l10n/sq.json index 80f86aa9..822a0b38 100644 --- a/web/l10n/sq.json +++ b/web/l10n/sq.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "Gabim", "errorUnknown": "Gabim i panjohur", "errorConnection": "Gabim lidhjeje", @@ -58,6 +59,7 @@ "loginFailed": "Adresë Email-i ose fjalëkalim i gabuar", "loginCreated": "Përdoruesi i ri u regjistrua", "loginLogout": "Shkëputu", + "loginLogo": "Logo", "devicesAndState": "Gjendja e pajisjeve", "deviceTitle": "Pajisjet", "deviceIdentifier": "Identifikues", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps Aerial", "mapShapePolygon": "Polygon", "mapShapeCircle": "Circle", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "Gjëndja", "stateName": "Atribut", @@ -146,6 +149,7 @@ "commandMessage": "Message", "eventAll": "All Events", "eventDeviceOnline": "Device is online", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Device is offline", "eventDeviceMoving": "Device is moving", "eventDeviceStopped": "Device has stopped", @@ -156,6 +160,7 @@ "eventAlarm": "Alarms", "eventIgnitionOn": "Ignition is ON", "eventIgnitionOff": "Ignition is OFF", + "eventMaintenance": "Maintenance required", "alarm": "Alarm", "alarmSos": "SOS Alarm", "alarmVibration": "Vibration Alarm", diff --git a/web/l10n/sr.json b/web/l10n/sr.json index e003473c..3cce2f6b 100644 --- a/web/l10n/sr.json +++ b/web/l10n/sr.json @@ -40,6 +40,7 @@ "sharedAlias": "Pseudonim", "sharedDeviceDistance": "Odstojanje uređaja", "sharedDevice": "Uređaj", + "sharedTestMail": "Pošalji test email", "errorTitle": "Greška", "errorUnknown": "Nepoznata greška", "errorConnection": "Greška u konekciji", @@ -50,7 +51,7 @@ "userDisabled": "Onemogućen", "userExpirationTime": "Ističe", "userDeviceLimit": "Limit uređaja", - "userToken": "Token", + "userToken": "Znak", "loginTitle": "Prijava", "loginLanguage": "Jezik", "loginRegister": "Registruj se", @@ -58,6 +59,7 @@ "loginFailed": "Neispravna email adresa ili lozinka", "loginCreated": "Novi korisnik je registrovan", "loginLogout": "Odjava", + "loginLogo": "Logo", "devicesAndState": "Uređaji i Stanje ", "deviceTitle": "Uređaji", "deviceIdentifier": "Identifikator", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps Aerial", "mapShapePolygon": "Višeugao", "mapShapeCircle": "Krug", + "mapShapePolyline": "Višelinijski", "mapLiveRoutes": "Validne rute", "stateTitle": "Stanje", "stateName": "Parametar", @@ -146,6 +149,7 @@ "commandMessage": "Poruka", "eventAll": "Svi događaji", "eventDeviceOnline": "Uređaj je na mreži", + "eventDeviceUnknown": "Status uređaja je nepoznat", "eventDeviceOffline": "Uređaj je van mreže", "eventDeviceMoving": "Uređaj se kreće", "eventDeviceStopped": "Uređaj se zaustavio", @@ -156,6 +160,7 @@ "eventAlarm": "Alarmi", "eventIgnitionOn": "Kontakt uklj.", "eventIgnitionOff": "Kontakt isklj.", + "eventMaintenance": "Potrebno održavanje", "alarm": "Alarm", "alarmSos": "SOS alarm", "alarmVibration": "Alarm vibracija", diff --git a/web/l10n/ta.json b/web/l10n/ta.json index 51db30d6..cd67a359 100644 --- a/web/l10n/ta.json +++ b/web/l10n/ta.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "பிழை", "errorUnknown": "அறியப்படாத பிழை", "errorConnection": "இணைப்புப் பிழை", @@ -58,6 +59,7 @@ "loginFailed": "தவறான மின்னஞ்சல் முகவரி அல்லது கடவுச்சொல்", "loginCreated": "புதிய பயனர் பதிவு செய்யப்பட்டுள்ளது", "loginLogout": "வெளியேறு", + "loginLogo": "Logo", "devicesAndState": "கருவிகள் மற்றும் அதன் நிலை", "deviceTitle": "சாதனம்", "deviceIdentifier": "அடையாளங்காட்டி", @@ -111,6 +113,7 @@ "mapBingAerial": "பிங் வான்வழி வரைபடம்", "mapShapePolygon": "பலகோணம்", "mapShapeCircle": "வட்டம்", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "நிலை", "stateName": "சாட்டு", @@ -146,6 +149,7 @@ "commandMessage": "குறுஞ்செய்தி", "eventAll": "All Events", "eventDeviceOnline": "சாதனம் இணைப்பில் உள்ளது", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "சாதன இணைப்பு துண்டிக்கபட்டது", "eventDeviceMoving": "சாதனம் நகருகிறது", "eventDeviceStopped": "Device has stopped", @@ -156,6 +160,7 @@ "eventAlarm": "Alarms", "eventIgnitionOn": "Ignition is ON", "eventIgnitionOff": "Ignition is OFF", + "eventMaintenance": "Maintenance required", "alarm": "Alarm", "alarmSos": "SOS Alarm", "alarmVibration": "Vibration Alarm", diff --git a/web/l10n/th.json b/web/l10n/th.json index 20d7826e..a3c1e4d5 100644 --- a/web/l10n/th.json +++ b/web/l10n/th.json @@ -40,6 +40,7 @@ "sharedAlias": "นามแฝง", "sharedDeviceDistance": "ระยะทาง อุปกรณ์", "sharedDevice": "อุปกรณ์", + "sharedTestMail": "ทดสอบ ส่งอีเมล", "errorTitle": "ผิดพลาด", "errorUnknown": "ข้อผิดพลาดที่ไม่รู้จัก", "errorConnection": "การเชื่อมต่อผิดพลาด", @@ -58,6 +59,7 @@ "loginFailed": "ที่อยู่อีเมลหรือรหัสผ่านไม่ถูกต้อง", "loginCreated": "ผู้ใช้ใหม่ ได้รับการลงทะเบียน", "loginLogout": "ออกจากระบบ", + "loginLogo": "Logo", "devicesAndState": "อุปกรณ์และสถานะ", "deviceTitle": "เครื่อง/อุปกรณ์", "deviceIdentifier": "ระบุเลขอุปกรณ์", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps ทางอากาศ", "mapShapePolygon": "โพลิกอน", "mapShapeCircle": "วงกลม", + "mapShapePolyline": "โพลีไลน์", "mapLiveRoutes": "เส้นทาง Live", "stateTitle": "สถานะ", "stateName": "พารามิเตอร์", @@ -146,6 +149,7 @@ "commandMessage": "ข้อความ", "eventAll": "เหตุการณ์ทั้งหมด", "eventDeviceOnline": "อุปกรณ์เชื่อมต่อแล้ว", + "eventDeviceUnknown": "สถานะของอุปกรณ์ไม่เป็นที่รู้จัก", "eventDeviceOffline": "อุปกรณ์ไม่ได้เชื่อมต่อ", "eventDeviceMoving": "อุปกรณ์กำลังเคลื่อนที่", "eventDeviceStopped": "อุปกรณ์กำลังหยุด", @@ -156,6 +160,7 @@ "eventAlarm": "แจ้งเตือน", "eventIgnitionOn": "สวิทย์กุญแจ เปิด", "eventIgnitionOff": "สวิทย์กุญแจ ปิด", + "eventMaintenance": "จำเป็นต้อง บำรุงรักษา", "alarm": "แจ้งเตือน", "alarmSos": "แจ้งเตือนฉุกเฉิน SOS", "alarmVibration": "แจ้งเตือนการสั่นสะเทือน", diff --git a/web/l10n/tr.json b/web/l10n/tr.json index d3aab3a6..6b57cc62 100644 --- a/web/l10n/tr.json +++ b/web/l10n/tr.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "Hata", "errorUnknown": "Bilinmeyen hata ", "errorConnection": "Bağlantı Hatası", @@ -58,6 +59,7 @@ "loginFailed": "Geçersiz eposta veya şifre", "loginCreated": "Yeni kullanıcı kaydedildi", "loginLogout": "Oturumu sonlandır", + "loginLogo": "Logo", "devicesAndState": "Cihazlar ve Bölge", "deviceTitle": "Cihazlar", "deviceIdentifier": "Kimlik", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps Aerial", "mapShapePolygon": "Çokgen", "mapShapeCircle": "Çember", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "Bölge", "stateName": "Özellik", @@ -146,6 +149,7 @@ "commandMessage": "Mesaj", "eventAll": "Tüm Olaylar", "eventDeviceOnline": "Cihaz çevrimiçi", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Cihaz çevrimdışı", "eventDeviceMoving": "Cihaz hareket halinde", "eventDeviceStopped": "Cihaz çalışmıyor", @@ -156,6 +160,7 @@ "eventAlarm": "Alarmlar", "eventIgnitionOn": "Kontak Açık", "eventIgnitionOff": "Kontak Kapalı", + "eventMaintenance": "Maintenance required", "alarm": "Alarm", "alarmSos": "İmdat Alarmı", "alarmVibration": "Darbe Alarmı", diff --git a/web/l10n/uk.json b/web/l10n/uk.json index e3add330..c6da05d3 100644 --- a/web/l10n/uk.json +++ b/web/l10n/uk.json @@ -40,6 +40,7 @@ "sharedAlias": "Алиас", "sharedDeviceDistance": "Відстань пристроїв", "sharedDevice": "Пристрій", + "sharedTestMail": "Send Test Email", "errorTitle": "Помилка", "errorUnknown": "Невiдома помилка", "errorConnection": "Помилка з'єднання", @@ -58,6 +59,7 @@ "loginFailed": "Неправильне адреса електронної пошти або пароль", "loginCreated": "Новий користувач був зареєстрований", "loginLogout": "Вийти", + "loginLogo": "Logo", "devicesAndState": "Пристрої та стан", "deviceTitle": " Прилади", "deviceIdentifier": "Iдентифікатор", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps Супутник", "mapShapePolygon": "Багатокутник", "mapShapeCircle": "Коло", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Поточні маршрути", "stateTitle": "Стан", "stateName": "Атрибут", @@ -146,6 +149,7 @@ "commandMessage": "Повідомлення", "eventAll": "Всі події", "eventDeviceOnline": "Пристрій з'єднався", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Пристрій від'єднався", "eventDeviceMoving": "Пристрій в русі", "eventDeviceStopped": "Пристрій зупинився", @@ -156,6 +160,7 @@ "eventAlarm": "Тревоги", "eventIgnitionOn": "Запалення УВІМК", "eventIgnitionOff": "Запалення ВИМК", + "eventMaintenance": "Maintenance required", "alarm": "Тревога", "alarmSos": "Тривога SOS", "alarmVibration": "Тривога вібрації", diff --git a/web/l10n/vi.json b/web/l10n/vi.json index 57791944..c831f691 100644 --- a/web/l10n/vi.json +++ b/web/l10n/vi.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "Lỗi", "errorUnknown": "Lỗi không xác định", "errorConnection": "Lỗi kết nối", @@ -58,6 +59,7 @@ "loginFailed": "Sai mật khẩu hoặc địa chỉ email", "loginCreated": "Người dùng mới đã được đăng ký", "loginLogout": "Đăng xuất", + "loginLogo": "Logo", "devicesAndState": "Các thiết bị và trạng thái", "deviceTitle": "Các thiết bị", "deviceIdentifier": "Định danh", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing Maps Aerial", "mapShapePolygon": "Đa giác", "mapShapeCircle": "Vòng tròn", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "Trạng thái", "stateName": "Thuộc tính", @@ -146,6 +149,7 @@ "commandMessage": "Message", "eventAll": "All Events", "eventDeviceOnline": "Thiết bị trực tuyến", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Thiết bị ngoại tuyến", "eventDeviceMoving": "Thiết bị đang di chuyển", "eventDeviceStopped": "Device has stopped", @@ -156,6 +160,7 @@ "eventAlarm": "Alarms", "eventIgnitionOn": "Ignition is ON", "eventIgnitionOff": "Ignition is OFF", + "eventMaintenance": "Maintenance required", "alarm": "Alarm", "alarmSos": "SOS Alarm", "alarmVibration": "Vibration Alarm", diff --git a/web/l10n/zh.json b/web/l10n/zh.json index 053da280..dd058384 100644 --- a/web/l10n/zh.json +++ b/web/l10n/zh.json @@ -40,6 +40,7 @@ "sharedAlias": "Alias", "sharedDeviceDistance": "Device Distance", "sharedDevice": "Device", + "sharedTestMail": "Send Test Email", "errorTitle": "错误", "errorUnknown": "未知错误", "errorConnection": "连接错误", @@ -58,6 +59,7 @@ "loginFailed": "邮箱地址或密码不对", "loginCreated": "新用户已经被注册了", "loginLogout": "登出", + "loginLogo": "Logo", "devicesAndState": "设备和状态", "deviceTitle": "设备", "deviceIdentifier": "标识符", @@ -111,6 +113,7 @@ "mapBingAerial": "Bing 航测地图", "mapShapePolygon": "Polygon", "mapShapeCircle": "Circle", + "mapShapePolyline": "Polyline", "mapLiveRoutes": "Live Routes", "stateTitle": "状态", "stateName": "参数", @@ -146,6 +149,7 @@ "commandMessage": "Message", "eventAll": "All Events", "eventDeviceOnline": "Device is online", + "eventDeviceUnknown": "Device status is unknown", "eventDeviceOffline": "Device is offline", "eventDeviceMoving": "Device is moving", "eventDeviceStopped": "Device has stopped", @@ -156,6 +160,7 @@ "eventAlarm": "Alarms", "eventIgnitionOn": "Ignition is ON", "eventIgnitionOff": "Ignition is OFF", + "eventMaintenance": "Maintenance required", "alarm": "Alarm", "alarmSos": "SOS Alarm", "alarmVibration": "Vibration Alarm", diff --git a/web/load.js b/web/load.js index fe5c2805..0fe7ce54 100644 --- a/web/load.js +++ b/web/load.js @@ -109,7 +109,7 @@ }); - extjsVersion = '6.0.1'; + extjsVersion = '6.2.0'; fontAwesomeVersion = '4.7.0'; olVersion = '3.19.1'; @@ -128,8 +128,6 @@ addStyleFile('//cdnjs.cloudflare.com/ajax/libs/ol3/' + olVersion + '/ol.css'); addScriptFile('//cdnjs.cloudflare.com/ajax/libs/ol3/' + olVersion + '/ol-debug.js'); - addStyleFile('app.css'); - addSvgFile('images/default.svg', 'defaultSvg'); addSvgFile('images/arrow.svg', 'arrowSvg'); addSvgFile('images/car.svg', 'carSvg'); diff --git a/web/logo.svg b/web/logo.svg new file mode 100644 index 00000000..55da0dcd --- /dev/null +++ b/web/logo.svg @@ -0,0 +1,166 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="240" + height="64" + id="svg2985" + version="1.1" + inkscape:version="0.91+devel+osxmenu r12922" + sodipodi:docname="logo.svg" + inkscape:export-filename="/home/user/Documents/website/logo2x.png" + inkscape:export-xdpi="123.75" + inkscape:export-ydpi="123.75" + viewBox="0 0 240 64"> + <defs + id="defs2987" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="2.49" + inkscape:cx="19.718102" + inkscape:cy="19.948184" + inkscape:current-layer="layer1" + showgrid="true" + inkscape:document-units="px" + inkscape:grid-bbox="true" + inkscape:snap-bbox="true" + inkscape:bbox-paths="true" + inkscape:bbox-nodes="true" + inkscape:snap-bbox-edge-midpoints="true" + inkscape:snap-bbox-midpoints="true" + inkscape:object-paths="true" + inkscape:object-nodes="true" + inkscape:snap-intersection-paths="true" + inkscape:snap-smooth-nodes="true" + inkscape:snap-midpoints="true" + inkscape:snap-center="true" + inkscape:snap-object-midpoints="true" + inkscape:window-width="1633" + inkscape:window-height="798" + inkscape:window-x="108" + inkscape:window-y="80" + inkscape:window-maximized="0" + inkscape:snap-global="true" /> + <metadata + id="metadata2990"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + id="layer1" + inkscape:label="Layer 1" + inkscape:groupmode="layer"> + <rect + style="fill:none;stroke:none" + id="rect3778" + width="236.09605" + height="64" + x="0" + y="0" + inkscape:export-filename="/home/user/Documents/website/logo2x.png" + inkscape:export-xdpi="154.6875" + inkscape:export-ydpi="154.6875" /> + <g + id="g2995" + inkscape:export-filename="/home/user/Documents/website/logo2x.png" + inkscape:export-xdpi="154.6875" + inkscape:export-ydpi="154.6875" + transform="matrix(1.0095018,0,0,1.0095018,-0.30405898,-0.30405887)"> + <ellipse + transform="matrix(11.849785,-6.8414759,4.1048857,7.1098702,-141.6761,-453.06363)" + id="path3038" + style="fill:#ffffff" + cx="-6.7327504" + cy="61.745384" + rx="2.0991254" + ry="3.4985423" /> + <ellipse + transform="matrix(0.98000485,-0.56580602,0.76260819,1.3208761,-13.500496,-10.292296)" + id="path2993" + style="fill:#000000" + cx="14.142136" + cy="38.929852" + rx="1.9927555" + ry="1.478496" /> + <path + id="path3004" + d="m 36.965211,24.251054 -2.816072,3.57877 c 0.657208,0.517134 1.313001,1.146671 1.756681,1.915146 0.443679,0.768474 0.660975,1.651177 0.780224,2.478901 l 4.507342,-0.649405 C 41.001257,30.166972 40.565802,28.79619 39.81164,27.489944 39.057477,26.183697 38.088074,25.121191 36.965211,24.251054 Z" + style="fill:#000000" + inkscape:connector-curvature="0" /> + <path + id="path3014" + d="m 42.404828,17.041928 -2.816072,3.578769 c 1.591875,1.223919 3.062315,2.767181 4.128704,4.614221 1.066388,1.847038 1.667671,3.892108 1.931679,5.882671 l 4.507341,-0.649405 c -0.336471,-2.571017 -1.155959,-5.102841 -2.5332,-7.488294 -1.377241,-2.385452 -3.160122,-4.36106 -5.218452,-5.937962 z" + style="fill:#000000" + inkscape:connector-curvature="0" /> + <path + sodipodi:end="4.712389" + sodipodi:start="1.5707963" + transform="matrix(3.9507144,-2.2809459,1.4097023,2.4416757,-59.699972,-127.24372)" + d="m -2.0227272,68.375862 a 1.9772727,3.1992946 0 0 1 -1.7123685,-1.599648 1.9772727,3.1992946 0 0 1 0,-3.199294 1.9772727,3.1992946 0 0 1 1.7123685,-1.599647 l -1e-7,3.199294 z" + sodipodi:ry="3.1992946" + sodipodi:rx="1.9772727" + sodipodi:cy="65.176567" + sodipodi:cx="-2.0227273" + id="path3036" + style="fill:#000000" + sodipodi:type="arc" /> + <path + id="path3038-8" + d="M 17.638883,7.1258129 C 3.9012503,15.057239 -0.80560983,32.62348 7.1258152,46.361111 15.057241,60.098742 32.623482,64.805603 46.361115,56.874177 60.098748,48.942752 64.805608,31.37651 56.874183,17.63888 48.942758,3.9012493 31.376516,-0.80561226 17.638883,7.1258129 Z m 1.689543,2.9263741 C 31.449867,3.0538711 46.949491,7.2069826 53.947808,19.328422 60.946126,31.449863 56.793012,46.949488 44.671573,53.947803 32.550132,60.94612 17.050507,56.793009 10.05219,44.671568 3.0538724,32.550127 7.2069849,17.050503 19.328426,10.052187 Z" + style="fill:#000000" + inkscape:connector-curvature="0" /> + </g> + <g + style="font-style:normal;font-weight:normal;font-size:47.16480255px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none" + aria-label="Traccar" + id="text3003"> + <path + d="m 89.719355,48.670609 -3.915047,0 0,-30.191922 -10.662746,0 0,-3.477483 25.240538,0 0,3.477483 -10.662745,0 0,30.191922 z" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans'" + id="path4172" /> + <path + d="m 116.3647,22.969476 q 1.68117,0 3.01689,0.276356 l -0.52968,3.546572 q -1.56602,-0.345445 -2.76356,-0.345445 -3.06295,0 -5.25077,2.487206 -2.16479,2.487207 -2.16479,6.194987 l 0,13.541457 -3.82293,0 0,-25.240539 3.15507,0 0.43756,4.675026 0.18424,0 q 1.40481,-2.464176 3.38536,-3.799898 1.98056,-1.335722 4.35261,-1.335722 z" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans'" + id="path4174" /> + <path + d="m 139.62469,48.670609 -0.75998,-3.592632 -0.18424,0 q -1.88843,2.372058 -3.77687,3.224157 -1.8654,0.829068 -4.67502,0.829068 -3.75384,0 -5.8956,-1.934494 -2.11874,-1.934493 -2.11874,-5.504095 0,-7.645857 12.22877,-8.014332 l 4.28352,-0.138178 0,-1.566019 q 0,-2.97083 -1.28966,-4.375641 -1.26663,-1.42784 -4.07626,-1.42784 -3.15506,0 -7.1392,1.934493 l -1.17451,-2.92477 q 1.8654,-1.013306 4.07625,-1.589049 2.23388,-0.575742 4.46776,-0.575742 4.51382,0 6.67861,2.003583 2.18782,2.003583 2.18782,6.425283 l 0,17.226208 -2.83265,0 z m -8.63613,-2.694474 q 3.5696,0 5.59621,-1.957524 2.04964,-1.957523 2.04964,-5.481066 l 0,-2.279939 -3.82293,0.161208 q -4.55987,0.161208 -6.58649,1.427841 -2.00358,1.243603 -2.00358,3.892017 0,2.072672 1.2436,3.155068 1.26664,1.082395 3.52355,1.082395 z" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans'" + id="path4176" /> + <path + d="m 160.44353,49.131202 q -5.48107,0 -8.49796,-3.362334 -2.99386,-3.385365 -2.99386,-9.557321 0,-6.333164 3.03992,-9.787618 3.06295,-3.454453 8.70522,-3.454453 1.81935,0 3.6387,0.391505 1.81934,0.391504 2.85568,0.921187 l -1.17452,3.247186 q -1.26663,-0.506653 -2.76356,-0.829069 -1.49693,-0.345445 -2.64841,-0.345445 -7.69192,0 -7.69192,9.810648 0,4.651997 1.8654,7.139203 1.88844,2.487206 5.57319,2.487206 3.15507,0 6.47134,-1.358751 l 0,3.385364 q -2.53326,1.312692 -6.37922,1.312692 z" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans'" + id="path4178" /> + <path + d="m 182.9205,49.131202 q -5.48106,0 -8.49795,-3.362334 -2.99386,-3.385365 -2.99386,-9.557321 0,-6.333164 3.03992,-9.787618 3.06295,-3.454453 8.70522,-3.454453 1.81934,0 3.63869,0.391505 1.81935,0.391504 2.85568,0.921187 l -1.17451,3.247186 q -1.26664,-0.506653 -2.76357,-0.829069 -1.49693,-0.345445 -2.64841,-0.345445 -7.69192,0 -7.69192,9.810648 0,4.651997 1.86541,7.139203 1.88843,2.487206 5.57318,2.487206 3.15507,0 6.47135,-1.358751 l 0,3.385364 q -2.53327,1.312692 -6.37923,1.312692 z" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans'" + id="path4180" /> + <path + d="m 210.83249,48.670609 -0.75998,-3.592632 -0.18424,0 q -1.88843,2.372058 -3.77687,3.224157 -1.8654,0.829068 -4.67502,0.829068 -3.75384,0 -5.8956,-1.934494 -2.11873,-1.934493 -2.11873,-5.504095 0,-7.645857 12.22876,-8.014332 l 4.28352,-0.138178 0,-1.566019 q 0,-2.97083 -1.28966,-4.375641 -1.26663,-1.42784 -4.07625,-1.42784 -3.15507,0 -7.13921,1.934493 l -1.17451,-2.92477 q 1.8654,-1.013306 4.07625,-1.589049 2.23388,-0.575742 4.46776,-0.575742 4.51382,0 6.67861,2.003583 2.18782,2.003583 2.18782,6.425283 l 0,17.226208 -2.83265,0 z m -8.63613,-2.694474 q 3.5696,0 5.59621,-1.957524 2.04964,-1.957523 2.04964,-5.481066 l 0,-2.279939 -3.82292,0.161208 q -4.55988,0.161208 -6.58649,1.427841 -2.00359,1.243603 -2.00359,3.892017 0,2.072672 1.24361,3.155068 1.26663,1.082395 3.52354,1.082395 z" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans'" + id="path4182" /> + <path + d="m 233.07917,22.969476 q 1.68117,0 3.01689,0.276356 l -0.52968,3.546572 q -1.56602,-0.345445 -2.76357,-0.345445 -3.06294,0 -5.25076,2.487206 -2.1648,2.487207 -2.1648,6.194987 l 0,13.541457 -3.82292,0 0,-25.240539 3.15506,0 0.43757,4.675026 0.18423,0 q 1.40482,-2.464176 3.38537,-3.799898 1.98055,-1.335722 4.35261,-1.335722 z" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans'" + id="path4184" /> + </g> + </g> +</svg> diff --git a/web/release.html b/web/release.html index 3113f36c..cd02272b 100644 --- a/web/release.html +++ b/web/release.html @@ -4,6 +4,7 @@ <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <title>Traccar</title> +<link rel="stylesheet" href="app.css"> </head> <body> <div id="spinner"></div> diff --git a/web/simple/app.js b/web/simple/app.js new file mode 100644 index 00000000..5ae8ac2c --- /dev/null +++ b/web/simple/app.js @@ -0,0 +1,97 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * + * 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. + */ + +var url = 'http://localhost:8082'; +var token = 'TOKEN'; + +var style = new ol.style.Style({ + image: new ol.style.Circle({ + fill: new ol.style.Fill({ + color: 'teal' + }), + stroke: new ol.style.Stroke({ + color: 'navy', + width: 2 + }), + radius: 7 + }) +}); + +var source = new ol.source.Vector(); + +var markers = {}; + +var map = new ol.Map({ + layers: [ + new ol.layer.Tile({ + source: new ol.source.OSM() + }), + new ol.layer.Vector({ + source: source + }) + ], + target: 'map', + view: new ol.View({ + center: [0, 0], + zoom: 2 + }) +}); + +var ajax = function (method, url, callback) { + var xhr = new XMLHttpRequest(); + xhr.withCredentials = true; + xhr.open(method, url, true); + xhr.onreadystatechange = function () { + if (xhr.readyState == 4) { + callback(JSON.parse(xhr.responseText)); + } + }; + if (method == 'POST') { + xhr.setRequestHeader('Content-type', 'application/json'); + } + xhr.send() +}; + +ajax('GET', url + '/api/session?token=' + token, function(user) { + ajax('GET', url + '/api/devices', function(devices) { + + var socket = new WebSocket('ws' + url.substring(4) + '/api/socket'); + + socket.onclose = function (event) { + console.log('socket closed'); + }; + + socket.onmessage = function (event) { + var data = JSON.parse(event.data); + if (data.positions) { + for (i = 0; i < data.positions.length; i++) { + var position = data.positions[i]; + var marker = markers[position.deviceId]; + var point = new ol.geom.Point(ol.proj.fromLonLat([position.longitude, position.latitude])); + if (!marker) { + marker = new ol.Feature(point); + marker.setStyle(style); + markers[position.deviceId] = marker; + source.addFeature(marker); + } else { + marker.setGeometry(point); + } + } + } + }; + + }); +}); diff --git a/web/simple/index.html b/web/simple/index.html new file mode 100644 index 00000000..d4bfe504 --- /dev/null +++ b/web/simple/index.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="UTF-8"> +<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> +<title>Traccar</title> +<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ol3/3.19.1/ol.css" type="text/css"> +</head> +<body style="margin: 0; padding: 0;"> +<div id="map" style="width: 100%; height: 100%; position:fixed;"></div> +<script src="https://cdnjs.cloudflare.com/ajax/libs/ol3/3.19.1/ol.js" type="text/javascript"></script> +<script id="loadScript" src="app.js"></script> +</body> +</html> |