diff options
Diffstat (limited to 'legacy/web/app')
196 files changed, 15308 insertions, 0 deletions
diff --git a/legacy/web/app/Application.js b/legacy/web/app/Application.js new file mode 100644 index 00000000..dd9210dc --- /dev/null +++ b/legacy/web/app/Application.js @@ -0,0 +1,246 @@ +/* + * Copyright 2015 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.Application', { + extend: 'Ext.app.Application', + name: 'Traccar', + + requires: [ + 'Traccar.Style', + 'Traccar.AttributeFormatter', + 'Traccar.view.TouchFix62' + ], + + models: [ + 'Server', + 'User', + 'Group', + 'Device', + 'Position', + 'Attribute', + 'Command', + 'Event', + 'Geofence', + 'Notification', + 'ReportSummary', + 'ReportTrip', + 'ReportStop', + 'Calendar', + 'KnownAttribute', + 'Driver', + 'KnownCommand', + 'KnownNotification', + 'Maintenance' + ], + + stores: [ + 'Groups', + 'Devices', + 'AllGroups', + 'AllDevices', + 'AlarmTypes', + 'Positions', + 'LatestPositions', + 'EventPositions', + 'Users', + 'Attributes', + 'MapTypes', + 'DistanceUnits', + 'SpeedUnits', + 'CoordinateFormats', + 'CommandTypes', + 'TimeUnits', + 'Languages', + 'Events', + 'Geofences', + 'AllGeofences', + 'Notifications', + 'AllNotifications', + 'GeofenceTypes', + 'ReportRoute', + 'ReportEvents', + 'ReportTrips', + 'ReportStops', + 'ReportSummary', + 'ReportTypes', + 'ReportEventTypes', + 'ReportChartTypes', + 'ReportPeriods', + 'Statistics', + 'DeviceImages', + 'Calendars', + 'AllCalendars', + 'AllTimezones', + 'VisibleDevices', + 'DeviceStatuses', + 'CommonDeviceAttributes', + 'DeviceAttributes', + 'GeofenceAttributes', + 'GroupAttributes', + 'ServerAttributes', + 'CommonUserAttributes', + 'UserAttributes', + 'ComputedAttributes', + 'AllComputedAttributes', + 'PositionAttributes', + 'AttributeValueTypes', + 'Drivers', + 'AllDrivers', + 'KnownCommands', + 'VolumeUnits', + 'AllCommandTypes', + 'Commands', + 'AllCommands', + 'DeviceCommands', + 'AllNotificationTypes', + 'Maintenances', + 'AllMaintenances', + 'MaintenanceTypes', + 'HoursUnits', + 'AllNotificators' + ], + + controllers: [ + 'Root' + ], + + isMobile: function () { + return window.matchMedia && window.matchMedia('(max-width: 768px)').matches; + }, + + getVehicleFeaturesDisabled: function () { + return this.getBooleanAttributePreference('ui.disableVehicleFeatures'); + }, + + getEventString: function (eventType) { + var key = 'event' + eventType.charAt(0).toUpperCase() + eventType.slice(1); + return Strings[key] || key; + }, + + getNotificatorString: function (eventType) { + var key = 'notificator' + eventType.charAt(0).toUpperCase() + eventType.slice(1); + return Strings[key] || key; + }, + + showReports: function (show) { + var rootPanel = Ext.getCmp('rootPanel'); + if (rootPanel) { + rootPanel.setActiveItem(show ? 1 : 0); + } + }, + + showEvents: function (show) { + var rootPanel = Ext.getCmp('rootPanel'); + if (rootPanel) { + rootPanel.setActiveItem(show ? 2 : 0); + } + }, + + updateNotificationToken: function (token) { + var attributes = Ext.clone(this.user.get('attributes')); + if (!attributes.notificationTokens || attributes.notificationTokens.indexOf(token) < 0) { + if (!attributes.notificationTokens) { + attributes.notificationTokens = token; + } else { + attributes.notificationTokens += ',' + token; + } + this.user.set('attributes', attributes); + this.user.save(); + } + }, + + setUser: function (data) { + var reader = Ext.create('Ext.data.reader.Json', { + model: 'Traccar.model.User' + }); + this.user = reader.readRecords(data).getRecords()[0]; + }, + + getUser: function () { + return this.user; + }, + + setServer: function (data) { + var reader = Ext.create('Ext.data.reader.Json', { + model: 'Traccar.model.Server' + }); + this.server = reader.readRecords(data).getRecords()[0]; + }, + + getServer: function () { + return this.server; + }, + + getPreference: function (key, defaultValue) { + if (this.getServer().get('forceSettings')) { + return this.getServer().get(key) || this.getUser().get(key) || defaultValue; + } else { + return this.getUser().get(key) || this.getServer().get(key) || defaultValue; + } + }, + + getAttributePreference: function (key, defaultValue) { + if (this.getServer().get('forceSettings')) { + return this.getServer().get('attributes')[key] || this.getUser().get('attributes')[key] || defaultValue; + } else { + return this.getUser().get('attributes')[key] || this.getServer().get('attributes')[key] || defaultValue; + } + }, + + getBooleanAttributePreference: function (key) { + return this.getAttributePreference(key, false).toString() === 'true'; + }, + + getReportColor: function (deviceId) { + var index, reportColor, device = Ext.getStore('Devices').getById(deviceId); + if (device) { + reportColor = device.get('attributes')['web.reportColor']; + } + if (reportColor) { + return reportColor; + } else { + index = 0; + if (deviceId !== undefined) { + index = deviceId % Traccar.Style.mapRouteColor.length; + } + return Traccar.Style.mapRouteColor[index]; + } + }, + + showError: function (error) { + if (Ext.isString(error)) { + Ext.Msg.alert(Strings.errorTitle, error); + } else if (error.responseText) { + Ext.Msg.alert(Strings.errorTitle, Strings.errorGeneral + + '<br><br><textarea readonly rows="5" style="resize: none; width: 100%;">' + + error.responseText + '</textarea>'); + } else if (error.statusText) { + Ext.Msg.alert(Strings.errorTitle, error.statusText); + } else { + Ext.Msg.alert(Strings.errorTitle, Strings.errorConnection); + } + }, + + showToast: function (message, title) { + Ext.toast({ + html: message, + title: title, + width: Traccar.Style.toastWidth, + align: 'br' + }); + } +}); diff --git a/legacy/web/app/AttributeFormatter.js b/legacy/web/app/AttributeFormatter.js new file mode 100644 index 00000000..d207ef1e --- /dev/null +++ b/legacy/web/app/AttributeFormatter.js @@ -0,0 +1,311 @@ +/* + * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.AttributeFormatter', { + singleton: true, + + numberFormatterFactory: function (precision, suffix) { + return function (value) { + if (value !== undefined) { + return Number(value.toFixed(precision)) + ' ' + suffix; + } + return null; + }; + }, + + coordinateFormatter: function (key, value) { + return Ext.getStore('CoordinateFormats').formatValue(key, value, Traccar.app.getPreference('coordinateFormat')); + }, + + speedFormatter: function (value) { + return Ext.getStore('SpeedUnits').formatValue(value, Traccar.app.getAttributePreference('speedUnit')); + }, + + speedConverter: function (value) { + return Ext.getStore('SpeedUnits').convertValue(value, Traccar.app.getAttributePreference('speedUnit')); + }, + + courseFormatter: function (value) { + var courseValues = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW']; + return courseValues[Math.floor(value / 45)]; + }, + + distanceFormatter: function (value) { + return Ext.getStore('DistanceUnits').formatValue(value, Traccar.app.getAttributePreference('distanceUnit')); + }, + + distanceConverter: function (value) { + return Ext.getStore('DistanceUnits').convertValue(value, Traccar.app.getAttributePreference('distanceUnit')); + }, + + volumeFormatter: function (value) { + return Ext.getStore('VolumeUnits').formatValue(value, Traccar.app.getAttributePreference('volumeUnit')); + }, + + volumeConverter: function (value) { + return Ext.getStore('VolumeUnits').convertValue(value, Traccar.app.getAttributePreference('volumeUnit')); + }, + + hoursFormatter: function (value) { + return Ext.getStore('HoursUnits').formatValue(value, 'h'); + }, + + hoursConverter: function (value) { + return Ext.getStore('HoursUnits').convertValue(value, 'h'); + }, + + durationFormatter: function (value) { + return Ext.getStore('HoursUnits').formatValue(value, 'h', true); + }, + + deviceIdFormatter: function (value) { + var device, store; + if (value !== 0) { + store = Ext.getStore('AllDevices'); + if (store.getTotalCount() === 0) { + store = Ext.getStore('Devices'); + } + device = store.getById(value); + return device ? device.get('name') : ''; + } + return null; + }, + + groupIdFormatter: function (value) { + var group, store; + if (value !== 0) { + store = Ext.getStore('AllGroups'); + if (store.getTotalCount() === 0) { + store = Ext.getStore('Groups'); + } + group = store.getById(value); + return group ? group.get('name') : value; + } + return null; + }, + + geofenceIdFormatter: function (value) { + var geofence, store; + if (value !== 0) { + store = Ext.getStore('AllGeofences'); + if (store.getTotalCount() === 0) { + store = Ext.getStore('Geofences'); + } + geofence = store.getById(value); + return geofence ? geofence.get('name') : ''; + } + return null; + }, + + calendarIdFormatter: function (value) { + var calendar, store; + if (value !== 0) { + store = Ext.getStore('AllCalendars'); + if (store.getTotalCount() === 0) { + store = Ext.getStore('Calendars'); + } + calendar = store.getById(value); + return calendar ? calendar.get('name') : ''; + } + return null; + }, + + driverUniqueIdFormatter: function (value) { + var driver, store; + if (value !== 0) { + store = Ext.getStore('AllDrivers'); + if (store.getTotalCount() === 0) { + store = Ext.getStore('Drivers'); + } + driver = store.findRecord('uniqueId', value, 0, false, true, true); + return driver ? value + ' (' + driver.get('name') + ')' : value; + } + return null; + }, + + maintenanceIdFormatter: function (value) { + var maintenance, store; + if (value !== 0) { + store = Ext.getStore('AllMaintenances'); + if (store.getTotalCount() === 0) { + store = Ext.getStore('Maintenances'); + } + maintenance = store.getById(value); + return maintenance ? maintenance.get('name') : ''; + } + return null; + }, + + lastUpdateFormatter: function (value) { + var seconds, interval; + if (value) { + seconds = Math.floor((new Date() - value) / 1000); + if (seconds < 0) { + seconds = 0; + } + interval = Math.floor(seconds / 86400); + if (interval > 1) { + return interval + ' ' + Strings.sharedDays; + } + interval = Math.floor(seconds / 3600); + if (interval > 1) { + return interval + ' ' + Strings.sharedHours; + } + return Math.floor(seconds / 60) + ' ' + Strings.sharedMinutes; + } + return null; + }, + + commandTypeFormatter: function (value) { + var name = Strings['command' + value.charAt(0).toUpperCase() + value.slice(1)]; + return name ? name : value; + }, + + defaultFormatter: function (value) { + if (typeof value === 'number') { + return Number(value.toFixed(Traccar.Style.numberPrecision)); + } else if (typeof value === 'boolean') { + return value ? Ext.Msg.buttonText.yes : Ext.Msg.buttonText.no; + } else if (value instanceof Date) { + if (Traccar.app.getPreference('twelveHourFormat', false)) { + return Ext.Date.format(value, Traccar.Style.dateTimeFormat12); + } else { + return Ext.Date.format(value, Traccar.Style.dateTimeFormat24); + } + } + return value; + }, + + dateFormatter: function (value) { + return Ext.Date.format(value, Traccar.Style.dateFormat); + }, + + getFormatter: function (key) { + var self = this; + + switch (key) { + case 'latitude': + case 'longitude': + return function (value) { + return self.coordinateFormatter(key, value); + }; + case 'speed': + return this.speedFormatter; + case 'course': + return this.courseFormatter; + case 'distance': + case 'accuracy': + return this.distanceFormatter; + case 'duration': + return this.durationFormatter; + case 'deviceId': + return this.deviceIdFormatter; + case 'groupId': + return this.groupIdFormatter; + case 'geofenceId': + return this.geofenceIdFormatter; + case 'maintenanceId': + return this.maintenanceIdFormatter; + case 'calendarId': + return this.calendarIdFormatter; + case 'lastUpdate': + return this.lastUpdateFormatter; + case 'spentFuel': + return this.volumeFormatter; + case 'driverUniqueId': + return this.driverUniqueIdFormatter; + case 'commandType': + return this.commandTypeFormatter; + default: + return this.defaultFormatter; + } + }, + + getConverter: function (key) { + switch (key) { + case 'speed': + return this.speedConverter; + case 'distance': + case 'accuracy': + return this.distanceConverter; + case 'spentFuel': + return this.volumeConverter; + default: + return function (value) { + return value; + }; + } + }, + + getAttributeFormatter: function (key) { + var dataType = Ext.getStore('PositionAttributes').getAttributeDataType(key); + + switch (dataType) { + case 'distance': + return this.distanceFormatter; + case 'speed': + return this.speedFormatter; + case 'driverUniqueId': + return this.driverUniqueIdFormatter; + case 'voltage': + return this.numberFormatterFactory(Traccar.Style.numberPrecision, Strings.sharedVoltAbbreviation); + case 'percentage': + return this.numberFormatterFactory(Traccar.Style.numberPrecision, '%'); + case 'temperature': + return this.numberFormatterFactory(Traccar.Style.numberPrecision, '°C'); + case 'volume': + return this.volumeFormatter; + case 'hours': + return this.hoursFormatter; + case 'consumption': + return this.numberFormatterFactory(Traccar.Style.numberPrecision, Strings.sharedLiterPerHourAbbreviation); + default: + return this.defaultFormatter; + } + }, + + getAttributeConverter: function (key) { + var dataType = Ext.getStore('PositionAttributes').getAttributeDataType(key); + + switch (dataType) { + case 'distance': + return this.distanceConverter; + case 'speed': + return this.speedConverter; + case 'volume': + return this.volumeConverter; + case 'hours': + return this.hoursConverter; + default: + return function (value) { + return value; + }; + } + }, + + renderAttribute: function (value, attribute) { + if (attribute && attribute.get('dataType') === 'speed') { + return Ext.getStore('SpeedUnits').formatValue(value, Traccar.app.getAttributePreference('speedUnit', 'kn'), true); + } else if (attribute && attribute.get('dataType') === 'distance') { + return Ext.getStore('DistanceUnits').formatValue(value, Traccar.app.getAttributePreference('distanceUnit', 'km'), true); + } else if (attribute && attribute.get('dataType') === 'hours') { + return Ext.getStore('HoursUnits').formatValue(value, 'h', true); + } else { + return value; + } + } +}); diff --git a/legacy/web/app/DeviceImages.js b/legacy/web/app/DeviceImages.js new file mode 100644 index 00000000..af45ce90 --- /dev/null +++ b/legacy/web/app/DeviceImages.js @@ -0,0 +1,99 @@ +/* + * 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.DeviceImages', { + singleton: true, + + getImageSvg: function (color, zoom, angle, category) { + var i, info, svg, width, height, rotateTransform, scaleTransform, fill; + + info = Ext.getStore('DeviceImages').findRecord('key', category || 'default', 0, false, false, true); + svg = Ext.clone(info.get('svg')); + if (!svg) { + svg = this.cloneDocument(info.get('svg')); + } + + width = parseFloat(svg.documentElement.getAttribute('width')); + height = parseFloat(svg.documentElement.getAttribute('height')); + + fill = info.get('fillId'); + if (!Ext.isArray(fill)) { + fill = [fill]; + } + for (i = 0; i < fill.length; i++) { + svg.getElementById(fill[i]).style.fill = color; + } + + rotateTransform = 'rotate(' + angle + ' ' + width / 2 + ' ' + height / 2 + ')'; + svg.getElementById(info.get('rotateId')).setAttribute('transform', rotateTransform); + + if (zoom) { + width *= Traccar.Style.mapScaleSelected; + height *= Traccar.Style.mapScaleSelected; + scaleTransform = 'scale(' + Traccar.Style.mapScaleSelected + ') '; + } else { + width *= Traccar.Style.mapScaleNormal; + height *= Traccar.Style.mapScaleNormal; + scaleTransform = 'scale(' + Traccar.Style.mapScaleNormal + ') '; + } + + if (info.get('scaleId') !== info.get('rotateId')) { + svg.getElementById(info.get('scaleId')).setAttribute('transform', scaleTransform); + } else { + svg.getElementById(info.get('scaleId')).setAttribute('transform', scaleTransform + ' ' + rotateTransform); + } + + svg.documentElement.setAttribute('width', width); + svg.documentElement.setAttribute('height', height); + svg.documentElement.setAttribute('viewBox', '0 0 ' + width + ' ' + height); + + return svg; + }, + + formatSrc: function (svg) { + return 'data:image/svg+xml;charset=utf-8,' + + encodeURIComponent(new XMLSerializer().serializeToString(svg.documentElement)); + }, + + cloneDocument: function (svgDocument) { + var newDocument, newNode; + newDocument = svgDocument.implementation.createDocument(svgDocument.namespaceURI, null, null); + newNode = newDocument.importNode(svgDocument.documentElement, true); + newDocument.appendChild(newNode); + return newDocument; + }, + + getImageIcon: function (color, zoom, angle, category) { + var image, svg, width, height; + + svg = this.getImageSvg(color, zoom, angle, category); + width = parseFloat(svg.documentElement.getAttribute('width')); + height = parseFloat(svg.documentElement.getAttribute('height')); + + image = new ol.style.Icon({ + imgSize: [width, height], + src: this.formatSrc(svg) + }); + image.fill = color; + image.zoom = zoom; + image.angle = angle; + image.category = category; + + return image; + } +}); diff --git a/legacy/web/app/GeofenceConverter.js b/legacy/web/app/GeofenceConverter.js new file mode 100644 index 00000000..688f2233 --- /dev/null +++ b/legacy/web/app/GeofenceConverter.js @@ -0,0 +1,101 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.GeofenceConverter', { + singleton: true, + + wktToGeometry: function (mapView, wkt) { + var geometry, projection, resolutionAtEquator, pointResolution, resolutionFactor, + points = [], center, radius, content, i, lat, lon, coordinates; + if (wkt.lastIndexOf('POLYGON', 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.Polygon([points]); + } + } + } else if (wkt.lastIndexOf('CIRCLE', 0) === 0) { + content = wkt.match(/\([^()]+\)/); + if (content !== null) { + coordinates = content[0].match(/-?\d+\.?\d*/g); + if (coordinates !== null) { + projection = mapView.getProjection(); + center = ol.proj.transform([Number(coordinates[1]), Number(coordinates[0])], 'EPSG:4326', projection); + resolutionAtEquator = mapView.getResolution(); + pointResolution = ol.proj.getPointResolution(projection, resolutionAtEquator, center); + resolutionFactor = resolutionAtEquator / pointResolution; + radius = Number(coordinates[2]) / ol.proj.Units.METERS_PER_UNIT.m * resolutionFactor; + 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; + }, + + geometryToWkt: function (projection, geometry) { + var result, i, center, radius, edgeCoordinate, groundRadius, points; + if (geometry instanceof ol.geom.Circle) { + center = geometry.getCenter(); + radius = geometry.getRadius(); + edgeCoordinate = [center[0] + radius, center[1]]; + center = ol.proj.transform(center, projection, 'EPSG:4326'); + groundRadius = ol.sphere.getDistance( + center, ol.proj.transform(edgeCoordinate, projection, 'EPSG:4326'), 6378137); + result = 'CIRCLE ('; + result += center[1] + ' ' + center[0] + ', '; + result += groundRadius.toFixed(1) + ')'; + } else if (geometry instanceof ol.geom.Polygon) { + geometry.transform(projection, 'EPSG:4326'); + points = geometry.getCoordinates(); + result = 'POLYGON(('; + for (i = 0; i < points[0].length; i += 1) { + 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/legacy/web/app/Style.js b/legacy/web/app/Style.js new file mode 100644 index 00000000..371e05a1 --- /dev/null +++ b/legacy/web/app/Style.js @@ -0,0 +1,95 @@ +/* + * Copyright 2015 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.Style', { + singleton: true, + + refreshPeriod: 60 * 1000, + reconnectTimeout: 60 * 1000, + reportTimeout: 120 * 1000, + + normalPadding: 10, + + windowWidth: 800, + windowHeight: 600, + + formFieldWidth: 275, + + dateTimeFormat24: 'Y-m-d H:i:s', + dateTimeFormat12: 'Y-m-d g:i:s a', + timeFormat24: 'H:i', + timeFormat12: 'g:i a', + dateFormat: 'Y-m-d', + weekStartDay: 1, + + deviceWidth: 400, + toastWidth: 300, + + reportHeight: 250, + + columnWidthNormal: 100, + + mapDefaultLat: 48.8567, + mapDefaultLon: 2.3508, + mapDefaultZoom: 4, + + mapRouteColor: [ + '#F06292', + '#BA68C8', + '#4DD0E1', + '#4DB6AC', + '#FF8A65', + '#A1887F' + ], + mapRouteWidth: 5, + + mapTextColor: 'rgba(50, 50, 50, 1.0)', + mapTextStrokeColor: 'rgba(255, 255, 255, 1.0)', + mapTextStrokeWidth: 2, + mapTextOffset: 2, + mapTextFont: 'bold 12px sans-serif', + + mapColorOnline: 'rgba(77, 250, 144, 1.0)', + mapColorUnknown: 'rgba(250, 190, 77, 1.0)', + mapColorOffline: 'rgba(255, 162, 173, 1.0)', + + mapScaleNormal: 1, + mapScaleSelected: 1.5, + + mapMaxZoom: 18, + mapDelay: 500, + + mapAccuracyColor: 'rgba(96, 96, 96, 1.0)', + + mapGeofenceTextColor: 'rgba(14, 88, 141, 1.0)', + mapGeofenceColor: 'rgba(21, 127, 204, 1.0)', + mapGeofenceOverlayOpacity: 0.2, + mapGeofenceWidth: 5, + mapGeofenceRadius: 9, + + mapAnimateMarkerDuration: 2000, + mapAnimateMarkerTimeout: 40, + + coordinatePrecision: 6, + numberPrecision: 2, + + reportGridStyle: 'borderTop: 1px solid lightgray', + + chartPadding: '20 40 10 10', + chartMarkerRadius: 3, + chartMarkerHighlightScaling: 1.5 +}); diff --git a/legacy/web/app/controller/Root.js b/legacy/web/app/controller/Root.js new file mode 100644 index 00000000..22869f45 --- /dev/null +++ b/legacy/web/app/controller/Root.js @@ -0,0 +1,363 @@ +/* + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.controller.Root', { + extend: 'Ext.app.Controller', + alias: 'controller.root', + + requires: [ + 'Traccar.view.dialog.Login', + 'Traccar.view.Main', + 'Traccar.view.MainMobile', + 'Traccar.model.Position' + ], + + init: function () { + var i, data, attribute, chartTypesStore, maintenanceTypesStore; + chartTypesStore = Ext.getStore('ReportChartTypes'); + maintenanceTypesStore = Ext.getStore('MaintenanceTypes'); + Ext.state.Manager.setProvider(new Ext.state.CookieProvider()); + data = Ext.getStore('PositionAttributes').getData().items; + for (i = 0; i < data.length; i++) { + attribute = data[i]; + Traccar.model.Position.addFields([{ + name: 'attribute.' + attribute.get('key'), + attributeKey: attribute.get('key'), + calculate: this.calculateAttribute, + persist: false + }]); + if (attribute.get('valueType') === 'number') { + chartTypesStore.add({ + key: 'attribute.' + attribute.get('key'), + name: attribute.get('name') + }); + maintenanceTypesStore.add(attribute); + } + } + }, + + calculateAttribute: function (data) { + var value = data.attributes[this.attributeKey]; + if (value !== undefined) { + return Traccar.AttributeFormatter.getAttributeConverter(this.attributeKey)(value); + } + return value; + }, + + onLaunch: function () { + Ext.Ajax.request({ + scope: this, + url: 'api/server', + callback: this.onServerReturn + }); + }, + + showAnnouncement: function (announcement) { + var maxWidth = Ext.getBody().getViewSize().width - 2 * Traccar.Style.normalPadding; + if (maxWidth > Traccar.Style.windowWidth) { + maxWidth = Traccar.Style.windowWidth; + } + Ext.Msg.show({ + msg: announcement, + buttons: Ext.Msg.OK, + closable: false, + modal: false, + maxWidth: maxWidth + }).alignTo(Ext.getBody(), 't-t', [0, Traccar.Style.normalPadding]); + }, + + onServerReturn: function (options, success, response) { + var announcement, token, parameters = {}; + if (success) { + Traccar.app.setServer(Ext.decode(response.responseText)); + announcement = Traccar.app.getServer().get('announcement'); + if (announcement) { + this.showAnnouncement(announcement); + } + token = Ext.Object.fromQueryString(window.location.search).token; + if (token) { + parameters.token = token; + } + Ext.Ajax.request({ + scope: this, + url: 'api/session', + method: 'GET', + params: parameters, + callback: this.onSessionReturn + }); + } else { + Traccar.app.showError(response); + } + }, + + onSessionReturn: function (options, success, response) { + var passwordReset, dialog; + Ext.get('spinner').setVisible(false); + if (success) { + Traccar.app.setUser(Ext.decode(response.responseText)); + this.loadApp(); + } else { + this.login = Ext.create('widget.login', { + listeners: { + scope: this, + login: this.onLogin + } + }); + this.login.show(); + + passwordReset = Ext.Object.fromQueryString(window.location.search).passwordReset; + if (passwordReset) { + dialog = Ext.Msg.prompt(Strings.loginReset, Strings.userPassword, function (btn, text) { + dialog.textField.inputEl.dom.type = 'text'; + if (btn === 'ok') { + Ext.Ajax.request({ + scope: this, + method: 'POST', + url: 'api/password/update', + params: { + token: passwordReset, + password: text + }, + callback: function (options, success, response) { + if (success) { + Traccar.app.showToast(Strings.loginUpdateSuccess); + this.removeUrlParameter('passwordReset'); + } else { + Traccar.app.showError(response.responseText); + } + } + }); + } + }, this); + dialog.textField.inputEl.dom.type = 'password'; + } + } + }, + + onLogin: function () { + this.login.close(); + this.loadApp(); + }, + + loadApp: function () { + var updateView, attributionView, eventId; + + if (window.webkit && window.webkit.messageHandlers.appInterface) { + window.webkit.messageHandlers.appInterface.postMessage('login'); + } + if (window.appInterface) { + window.appInterface.postMessage('login'); + } + + Ext.getStore('Groups').load(); + Ext.getStore('Drivers').load(); + Ext.getStore('Geofences').load(); + Ext.getStore('Calendars').load(); + Ext.getStore('Maintenances').load(); + Ext.getStore('ComputedAttributes').load(); + Ext.getStore('AllCommandTypes').load(); + Ext.getStore('Commands').load(); + Ext.getStore('AllNotificationTypes').load({ + callback: function (records, operation, success) { + var store = Ext.getStore('ReportEventTypes'); + if (success) { + store.add({ + type: Traccar.store.ReportEventTypes.allEvents, + name: Strings.eventAll + }); + store.loadData(records, true); + } + } + }); + Ext.getStore('AllNotificators').load(); + Ext.getStore('Notifications').load(); + + Ext.getStore('ServerAttributes').loadData(Ext.getStore('CommonDeviceAttributes').getData().items, true); + Ext.getStore('ServerAttributes').loadData(Ext.getStore('CommonUserAttributes').getData().items, true); + Ext.getStore('UserAttributes').loadData(Ext.getStore('CommonUserAttributes').getData().items, true); + Ext.getStore('DeviceAttributes').loadData(Ext.getStore('CommonDeviceAttributes').getData().items, true); + Ext.getStore('GroupAttributes').loadData(Ext.getStore('CommonDeviceAttributes').getData().items, true); + + Ext.getStore('Devices').load({ + scope: this, + callback: function () { + this.asyncUpdate(true); + } + }); + updateView = Ext.get('update'); + if (updateView) { + updateView.remove(); + } + attributionView = Ext.get('attribution'); + if (attributionView) { + attributionView.remove(); + } + if (Traccar.app.isMobile()) { + Ext.create('widget.mainMobile'); + } else { + Ext.create('widget.main'); + } + eventId = Ext.Object.fromQueryString(window.location.search).eventId; + if (eventId) { + this.fireEvent('showsingleevent', eventId); + this.removeUrlParameter('eventId'); + } + }, + + beep: function () { + if (!this.beepSound) { + this.beepSound = new Audio('beep.wav'); + } + this.beepSound.play(); + }, + + soundPressed: function () { + var soundButton = Ext.getCmp('soundButton'); + return soundButton && soundButton.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 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 () { + Ext.Ajax.request({ + url: 'api/devices', + success: function (response) { + self.updateDevices(Ext.decode(response.responseText)); + }, + failure: function (response) { + if (response.status === 401) { + window.location.reload(); + } + } + }); + + 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 data = Ext.decode(event.data); + + if (data.devices) { + self.updateDevices(data.devices); + } + if (data.positions) { + self.updatePositions(data.positions, first); + first = false; + } + if (data.events) { + self.updateEvents(data.events); + } + }; + }, + + 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 + }); + } + } + }, + + updatePositions: function (array, first) { + var i, store, entity, uniqueId, device; + 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])); + } + if (Ext.getStore('Events').findRecord('positionId', array[i].id, 0, false, false, true)) { + Ext.getStore('EventPositions').add(Ext.create('Traccar.model.Position', array[i])); + } + } + if (first) { + uniqueId = Ext.Object.fromQueryString(window.location.search).deviceId; + if (uniqueId) { + device = Ext.getStore('VisibleDevices').findRecord('uniqueId', uniqueId, 0, false, true, true); + if (device) { + this.fireEvent('selectdevice', device, true); + } + } + if (!device) { + this.zoomToAllDevices(); + } + } + }, + + updateEvents: function (array) { + var i, store, device; + store = Ext.getStore('Events'); + for (i = 0; i < array.length; i++) { + store.insert(0, array[i]); + device = Ext.getStore('Devices').getById(array[i].deviceId); + if (device) { + if (this.soundPressed()) { + this.beep(); + } + Traccar.app.showToast(array[i].text, device.get('name')); + } else { + Traccar.app.showToast(array[i].text); + } + } + }, + + zoomToAllDevices: function () { + var lat, lon, zoom; + lat = Traccar.app.getPreference('latitude', 0); + lon = Traccar.app.getPreference('longitude', 0); + zoom = Traccar.app.getPreference('zoom', 0); + if (lat === 0 && lon === 0 && zoom === 0) { + this.fireEvent('zoomtoalldevices'); + } + } +}); diff --git a/legacy/web/app/model/Attribute.js b/legacy/web/app/model/Attribute.js new file mode 100644 index 00000000..b1586a73 --- /dev/null +++ b/legacy/web/app/model/Attribute.js @@ -0,0 +1,33 @@ +/* + * Copyright 2015 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.Attribute', { + extend: 'Ext.data.Model', + + fields: [{ + name: 'priority', + type: 'int' + }, { + name: 'name', + type: 'string' + }, { + name: 'value' + }, { + name: 'attribute', + type: 'string' + }] +}); diff --git a/legacy/web/app/model/Calendar.js b/legacy/web/app/model/Calendar.js new file mode 100644 index 00000000..8c44d625 --- /dev/null +++ b/legacy/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: 'data' + }, { + name: 'attributes' + }] +}); diff --git a/legacy/web/app/model/Command.js b/legacy/web/app/model/Command.js new file mode 100644 index 00000000..f64d2a4b --- /dev/null +++ b/legacy/web/app/model/Command.js @@ -0,0 +1,40 @@ +/* + * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.Command', { + extend: 'Ext.data.Model', + identifier: 'negative', + + fields: [{ + name: 'id', + type: 'int' + }, { + name: 'description', + type: 'string' + }, { + name: 'deviceId', + type: 'int' + }, { + name: 'type', + type: 'string' + }, { + name: 'textChannel', + type: 'boolean' + }, { + name: 'attributes' + }] +}); diff --git a/legacy/web/app/model/ComputedAttribute.js b/legacy/web/app/model/ComputedAttribute.js new file mode 100644 index 00000000..16a78ef1 --- /dev/null +++ b/legacy/web/app/model/ComputedAttribute.js @@ -0,0 +1,39 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.model.ComputedAttribute', { + extend: 'Ext.data.Model', + identifier: 'negative', + + fields: [{ + name: 'id', + type: 'int' + }, { + name: 'description', + type: 'string' + }, { + name: 'type', + type: 'string' + }, { + name: 'attribute', + type: 'string' + }, { + name: 'expression', + type: 'string' + }] +}); diff --git a/legacy/web/app/model/Device.js b/legacy/web/app/model/Device.js new file mode 100644 index 00000000..ca1e07a6 --- /dev/null +++ b/legacy/web/app/model/Device.js @@ -0,0 +1,64 @@ +/* + * Copyright 2015 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.Device', { + extend: 'Ext.data.Model', + identifier: 'negative', + + fields: [{ + name: 'id', + type: 'int' + }, { + name: 'name', + type: 'string' + }, { + name: 'uniqueId', + type: 'string' + }, { + name: 'phone', + type: 'string', + allowNull: true + }, { + name: 'model', + type: 'string', + allowNull: true + }, { + name: 'contact', + type: 'string', + allowNull: true + }, { + name: 'category', + type: 'string', + allowNull: true + }, { + name: 'status', + type: 'string', + allowNull: true + }, { + name: 'lastUpdate', + type: 'date', + dateFormat: 'c' + }, { + name: 'groupId', + type: 'int' + }, { + name: 'disabled', + type: 'boolean' + }, { + name: 'attributes' + }] +}); diff --git a/legacy/web/app/model/Driver.js b/legacy/web/app/model/Driver.js new file mode 100644 index 00000000..3c3b30e5 --- /dev/null +++ b/legacy/web/app/model/Driver.js @@ -0,0 +1,35 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.model.Driver', { + extend: 'Ext.data.Model', + identifier: 'negative', + + fields: [{ + name: 'id', + type: 'int' + }, { + name: 'name', + type: 'string' + }, { + name: 'uniqueId', + type: 'string' + }, { + name: 'attributes' + }] +}); diff --git a/legacy/web/app/model/Event.js b/legacy/web/app/model/Event.js new file mode 100644 index 00000000..d1297dd7 --- /dev/null +++ b/legacy/web/app/model/Event.js @@ -0,0 +1,81 @@ +/* + * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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.Event', { + extend: 'Ext.data.Model', + identifier: 'negative', + + fields: [{ + name: 'id', + type: 'int' + }, { + name: 'type', + type: 'string' + }, { + name: 'eventTime', + type: 'date', + dateFormat: 'c' + }, { + name: 'deviceId', + type: 'int' + }, { + name: 'positionId', + type: 'int' + }, { + name: 'geofenceId', + type: 'int' + }, { + name: 'maintenanceId', + type: 'int' + }, { + name: 'text', + convert: function (v, rec) { + var text, alarmKey, geofence, maintenance; + if (rec.get('type') === 'commandResult') { + text = Strings.eventCommandResult + ': ' + rec.get('attributes')['result']; + } else if (rec.get('type') === 'alarm') { + alarmKey = rec.get('attributes')['alarm']; + alarmKey = 'alarm' + alarmKey.charAt(0).toUpperCase() + alarmKey.slice(1); + text = Strings[alarmKey] || alarmKey; + } else if (rec.get('type') === 'textMessage') { + text = Strings.eventTextMessage + ': ' + rec.get('attributes')['message']; + } else if (rec.get('type') === 'driverChanged') { + text = Strings.eventDriverChanged + ': ' + + Traccar.AttributeFormatter.driverUniqueIdFormatter(rec.get('attributes')['driverUniqueId']); + } else { + text = Traccar.app.getEventString(rec.get('type')); + } + if (rec.get('geofenceId')) { + geofence = Ext.getStore('Geofences').getById(rec.get('geofenceId')); + if (geofence) { + text += ' "' + geofence.get('name') + '"'; + } + } + if (rec.get('maintenanceId')) { + maintenance = Ext.getStore('Maintenances').getById(rec.get('maintenanceId')); + if (maintenance) { + text += ' "' + maintenance.get('name') + '"'; + } + } + return text; + }, + depends: ['type', 'attributes', 'geofenceId', 'maintenanceId'] + }, { + name: 'attributes' + }] +}); diff --git a/legacy/web/app/model/Geofence.js b/legacy/web/app/model/Geofence.js new file mode 100644 index 00000000..12a9f878 --- /dev/null +++ b/legacy/web/app/model/Geofence.js @@ -0,0 +1,40 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.Geofence', { + extend: 'Ext.data.Model', + identifier: 'negative', + + fields: [{ + name: 'id', + type: 'int' + }, { + name: 'name', + type: 'string' + }, { + name: 'description', + type: 'string' + }, { + name: 'area', + type: 'string' + }, { + name: 'calendarId', + type: 'int' + }, { + name: 'attributes' + }] +}); diff --git a/legacy/web/app/model/Group.js b/legacy/web/app/model/Group.js new file mode 100644 index 00000000..8230fda1 --- /dev/null +++ b/legacy/web/app/model/Group.js @@ -0,0 +1,34 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.Group', { + extend: 'Ext.data.Model', + identifier: 'negative', + + fields: [{ + name: 'id', + type: 'int' + }, { + name: 'name', + type: 'string' + }, { + name: 'groupId', + type: 'int' + }, { + name: 'attributes' + }] +}); diff --git a/legacy/web/app/model/KnownAttribute.js b/legacy/web/app/model/KnownAttribute.js new file mode 100644 index 00000000..f6f41a73 --- /dev/null +++ b/legacy/web/app/model/KnownAttribute.js @@ -0,0 +1,35 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +Ext.define('Traccar.model.KnownAttribute', { + extend: 'Ext.data.Model', + idProperty: 'key', + + fields: [{ + name: 'key', + type: 'string' + }, { + name: 'name', + type: 'string' + }, { + name: 'valueType', + type: 'string' + }, { + name: 'dataType', + type: 'string' + }] +}); diff --git a/legacy/web/app/model/KnownCommand.js b/legacy/web/app/model/KnownCommand.js new file mode 100644 index 00000000..06610e32 --- /dev/null +++ b/legacy/web/app/model/KnownCommand.js @@ -0,0 +1,34 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +Ext.define('Traccar.model.KnownCommand', { + extend: 'Ext.data.Model', + idProperty: 'type', + + fields: [{ + name: 'type', + type: 'string' + }, { + name: 'name', + convert: function (v, rec) { + return Traccar.AttributeFormatter.getFormatter('commandType')(rec.get('type')); + }, + depends: ['type'] + }, { + name: 'parameters' + }] +}); diff --git a/legacy/web/app/model/KnownNotification.js b/legacy/web/app/model/KnownNotification.js new file mode 100644 index 00000000..f42ef972 --- /dev/null +++ b/legacy/web/app/model/KnownNotification.js @@ -0,0 +1,32 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +Ext.define('Traccar.model.KnownNotification', { + extend: 'Ext.data.Model', + idProperty: 'type', + + fields: [{ + name: 'type', + type: 'string' + }, { + name: 'name', + convert: function (v, rec) { + return Traccar.app.getEventString(rec.get('type')); + }, + depends: ['type'] + }] +}); diff --git a/legacy/web/app/model/KnownNotificator.js b/legacy/web/app/model/KnownNotificator.js new file mode 100644 index 00000000..7855a12b --- /dev/null +++ b/legacy/web/app/model/KnownNotificator.js @@ -0,0 +1,32 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 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.KnownNotificator', { + extend: 'Ext.data.Model', + idProperty: 'type', + + fields: [{ + name: 'type', + type: 'string' + }, { + name: 'name', + convert: function (v, rec) { + return Traccar.app.getNotificatorString(rec.get('type')); + }, + depends: ['type'] + }] +}); diff --git a/legacy/web/app/model/Maintenance.js b/legacy/web/app/model/Maintenance.js new file mode 100644 index 00000000..a0654275 --- /dev/null +++ b/legacy/web/app/model/Maintenance.js @@ -0,0 +1,41 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 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.Maintenance', { + extend: 'Ext.data.Model', + identifier: 'negative', + + fields: [{ + name: 'id', + type: 'int' + }, { + name: 'name', + type: 'string' + }, { + name: 'type', + type: 'string' + }, { + name: 'start', + type: 'float' + }, { + name: 'period', + type: 'float' + }, { + name: 'attributes' + }] +}); diff --git a/legacy/web/app/model/Notification.js b/legacy/web/app/model/Notification.js new file mode 100644 index 00000000..fc9d84d7 --- /dev/null +++ b/legacy/web/app/model/Notification.js @@ -0,0 +1,40 @@ +/* + * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.Notification', { + extend: 'Ext.data.Model', + identifier: 'negative', + + fields: [{ + name: 'id', + type: 'int' + }, { + name: 'type', + type: 'string' + }, { + name: 'always', + type: 'bool' + }, { + name: 'attributes' + }, { + name: 'notificators', + type: 'string' + }, { + name: 'calendarId', + type: 'int' + }] +}); diff --git a/legacy/web/app/model/Position.js b/legacy/web/app/model/Position.js new file mode 100644 index 00000000..6db54653 --- /dev/null +++ b/legacy/web/app/model/Position.js @@ -0,0 +1,72 @@ +/* + * Copyright 2015 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.Position', { + extend: 'Ext.data.Model', + identifier: 'negative', + + fields: [{ + name: 'id', + type: 'int' + }, { + name: 'protocol', + type: 'string' + }, { + name: 'deviceId', + type: 'int' + }, { + name: 'serverTime', + type: 'date', + dateFormat: 'c' + }, { + name: 'deviceTime', + type: 'date', + dateFormat: 'c' + }, { + name: 'fixTime', + type: 'date', + dateFormat: 'c' + }, { + name: 'valid', + type: 'boolean' + }, { + name: 'accuracy', + type: 'float', + convert: Traccar.AttributeFormatter.getConverter('accuracy') + }, { + name: 'latitude', + type: 'float' + }, { + name: 'longitude', + type: 'float' + }, { + name: 'altitude', + type: 'float' + }, { + name: 'speed', + type: 'float', + convert: Traccar.AttributeFormatter.getConverter('speed') + }, { + name: 'course', + type: 'float' + }, { + name: 'address', + type: 'string' + }, { + name: 'attributes' + }] +}); diff --git a/legacy/web/app/model/ReportStop.js b/legacy/web/app/model/ReportStop.js new file mode 100644 index 00000000..9aaa58b0 --- /dev/null +++ b/legacy/web/app/model/ReportStop.js @@ -0,0 +1,58 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.model.ReportStop', { + extend: 'Ext.data.Model', + identifier: 'negative', + + fields: [{ + name: 'deviceId', + type: 'int' + }, { + name: 'deviceName', + type: 'string' + }, { + name: 'duration', + type: 'int' + }, { + name: 'startTime', + type: 'date', + dateFormat: 'c' + }, { + name: 'startOdometer', + type: 'float', + convert: Traccar.AttributeFormatter.getConverter('distance') + }, { + name: 'address', + type: 'string' + }, { + name: 'endTime', + type: 'date', + dateFormat: 'c' + }, { + name: 'engineHours', + type: 'int' + }, { + name: 'positionId', + type: 'int' + }, { + name: 'spentFuel', + type: 'float', + convert: Traccar.AttributeFormatter.getConverter('spentFuel') + }] +}); diff --git a/legacy/web/app/model/ReportSummary.js b/legacy/web/app/model/ReportSummary.js new file mode 100644 index 00000000..559ffd41 --- /dev/null +++ b/legacy/web/app/model/ReportSummary.js @@ -0,0 +1,61 @@ +/* + * 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.ReportSummary', { + extend: 'Ext.data.Model', + identifier: 'negative', + + fields: [{ + name: 'deviceId', + type: 'int' + }, { + name: 'deviceName', + type: 'string' + }, { + name: 'startTime', + type: 'date', + dateFormat: 'c' + }, { + name: 'maxSpeed', + type: 'float', + convert: Traccar.AttributeFormatter.getConverter('speed') + }, { + name: 'averageSpeed', + type: 'float', + convert: Traccar.AttributeFormatter.getConverter('speed') + }, { + name: 'distance', + type: 'float', + convert: Traccar.AttributeFormatter.getConverter('distance') + }, { + name: 'startOdometer', + type: 'float', + convert: Traccar.AttributeFormatter.getConverter('distance') + }, { + name: 'endOdometer', + type: 'float', + convert: Traccar.AttributeFormatter.getConverter('distance') + }, { + name: 'engineHours', + type: 'int' + }, { + name: 'spentFuel', + type: 'float', + convert: Traccar.AttributeFormatter.getConverter('spentFuel') + }] +}); diff --git a/legacy/web/app/model/ReportTrip.js b/legacy/web/app/model/ReportTrip.js new file mode 100644 index 00000000..9d45fc87 --- /dev/null +++ b/legacy/web/app/model/ReportTrip.js @@ -0,0 +1,77 @@ +/* + * 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.ReportTrip', { + extend: 'Ext.data.Model', + identifier: 'negative', + + fields: [{ + name: 'deviceId', + type: 'int' + }, { + name: 'deviceName', + type: 'string' + }, { + name: 'maxSpeed', + type: 'float', + convert: Traccar.AttributeFormatter.getConverter('speed') + }, { + name: 'averageSpeed', + type: 'float', + convert: Traccar.AttributeFormatter.getConverter('speed') + }, { + name: 'distance', + type: 'float', + convert: Traccar.AttributeFormatter.getConverter('distance') + }, { + name: 'startOdometer', + type: 'float', + convert: Traccar.AttributeFormatter.getConverter('distance') + }, { + name: 'endOdometer', + type: 'float', + convert: Traccar.AttributeFormatter.getConverter('distance') + }, { + name: 'duration', + type: 'int' + }, { + name: 'startTime', + type: 'date', + dateFormat: 'c' + }, { + name: 'startAddress', + type: 'string' + }, { + name: 'endTime', + type: 'date', + dateFormat: 'c' + }, { + name: 'endAddress', + type: 'string' + }, { + name: 'spentFuel', + type: 'float', + convert: Traccar.AttributeFormatter.getConverter('spentFuel') + }, { + name: 'driverUniqueId', + type: 'string' + }, { + name: 'driverName', + type: 'string' + }] +}); diff --git a/legacy/web/app/model/Server.js b/legacy/web/app/model/Server.js new file mode 100644 index 00000000..177b4fc4 --- /dev/null +++ b/legacy/web/app/model/Server.js @@ -0,0 +1,88 @@ +/* + * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.Server', { + extend: 'Ext.data.Model', + identifier: 'negative', + + fields: [{ + name: 'id', + type: 'int' + }, { + name: 'registration', + type: 'boolean' + }, { + name: 'readonly', + type: 'boolean' + }, { + name: 'deviceReadonly', + type: 'boolean' + }, { + name: 'limitCommands', + type: 'boolean' + }, { + name: 'disableReports', + type: 'boolean' + }, { + name: 'map', + type: 'string' + }, { + name: 'bingKey', + type: 'string' + }, { + name: 'mapUrl', + type: 'string' + }, { + name: 'latitude', + type: 'float' + }, { + name: 'longitude', + type: 'float' + }, { + name: 'zoom', + type: 'int' + }, { + name: 'twelveHourFormat', + type: 'boolean' + }, { + name: 'forceSettings', + type: 'boolean' + }, { + name: 'coordinateFormat', + type: 'string' + }, { + name: 'poiLayer', + type: 'string' + }, { + name: 'announcement', + type: 'string' + }, { + name: 'attributes' + }], + + proxy: { + type: 'ajax', + url: 'api/server', + actionMethods: { + update: 'PUT' + }, + writer: { + type: 'json', + writeAllFields: true + } + } +}); diff --git a/legacy/web/app/model/Statistics.js b/legacy/web/app/model/Statistics.js new file mode 100644 index 00000000..95280ac4 --- /dev/null +++ b/legacy/web/app/model/Statistics.js @@ -0,0 +1,59 @@ +/* + * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.Statistics', { + extend: 'Ext.data.Model', + identifier: 'negative', + + fields: [{ + name: 'id', + type: 'int' + }, { + name: 'captureTime', + type: 'date', + dateFormat: 'c' + }, { + name: 'activeUsers', + type: 'int' + }, { + name: 'activeDevices', + type: 'int' + }, { + name: 'requests', + type: 'int' + }, { + name: 'messagesReceived', + type: 'int' + }, { + name: 'messagesStored', + type: 'int' + }, { + name: 'mailSent', + type: 'int' + }, { + name: 'smsSent', + type: 'int' + }, { + name: 'geocoderRequests', + type: 'int' + }, { + name: 'geolocationRequests', + type: 'int' + }, { + name: 'attributes' + }] +}); diff --git a/legacy/web/app/model/User.js b/legacy/web/app/model/User.js new file mode 100644 index 00000000..455bca64 --- /dev/null +++ b/legacy/web/app/model/User.js @@ -0,0 +1,101 @@ +/* + * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.User', { + extend: 'Ext.data.Model', + identifier: 'negative', + + fields: [{ + name: 'id', + type: 'int' + }, { + name: 'name', + type: 'string' + }, { + name: 'login', + type: 'string' + }, { + name: 'email', + type: 'string' + }, { + name: 'password', + type: 'string' + }, { + name: 'phone', + type: 'string' + }, { + name: 'readonly', + type: 'boolean' + }, { + name: 'administrator', + type: 'boolean' + }, { + name: 'map', + type: 'string' + }, { + name: 'latitude', + type: 'float' + }, { + name: 'longitude', + type: 'float' + }, { + name: 'zoom', + type: 'int' + }, { + name: 'twelveHourFormat', + type: 'boolean' + }, { + name: 'coordinateFormat', + type: 'string' + }, { + name: 'disabled', + type: 'boolean' + }, { + name: 'expirationTime', + type: 'date', + dateFormat: 'c' + }, { + name: 'deviceLimit', + type: 'int' + }, { + name: 'userLimit', + type: 'int' + }, { + name: 'deviceReadonly', + type: 'boolean' + }, { + name: 'limitCommands', + type: 'boolean' + }, { + name: 'disableReports', + type: 'boolean' + }, { + name: 'poiLayer', + type: 'string' + }, { + name: 'attributes' + }], + + proxy: { + type: 'rest', + url: 'api/users', + writer: { + type: 'json', + writeAllFields: true + } + } +}); diff --git a/legacy/web/app/store/AlarmTypes.js b/legacy/web/app/store/AlarmTypes.js new file mode 100644 index 00000000..1ee7ffe8 --- /dev/null +++ b/legacy/web/app/store/AlarmTypes.js @@ -0,0 +1,34 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 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.AlarmTypes', { + extend: 'Ext.data.Store', + fields: ['key', 'name'], + + data: (function () { + var key, items = []; + for (key in Strings) { + if (Strings.hasOwnProperty(key) && key.lastIndexOf('alarm', 0) === 0) { + items.push({ + key: key.charAt(5).toLowerCase() + key.slice(6), + name: Strings[key] + }); + } + } + return items; + })() +}); diff --git a/legacy/web/app/store/AllCalendars.js b/legacy/web/app/store/AllCalendars.js new file mode 100644 index 00000000..26557287 --- /dev/null +++ b/legacy/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/legacy/web/app/store/AllCommandTypes.js b/legacy/web/app/store/AllCommandTypes.js new file mode 100644 index 00000000..c35f50d9 --- /dev/null +++ b/legacy/web/app/store/AllCommandTypes.js @@ -0,0 +1,32 @@ +/* + * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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.AllCommandTypes', { + extend: 'Ext.data.Store', + model: 'Traccar.model.KnownCommand', + + proxy: { + type: 'rest', + url: 'api/commands/types', + listeners: { + exception: function (proxy, response) { + Traccar.app.showError(response); + } + } + } +}); diff --git a/legacy/web/app/store/AllCommands.js b/legacy/web/app/store/AllCommands.js new file mode 100644 index 00000000..7f5e1253 --- /dev/null +++ b/legacy/web/app/store/AllCommands.js @@ -0,0 +1,30 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.store.AllCommands', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Command', + + proxy: { + type: 'rest', + url: 'api/commands', + extraParams: { + all: true + } + } +}); diff --git a/legacy/web/app/store/AllComputedAttributes.js b/legacy/web/app/store/AllComputedAttributes.js new file mode 100644 index 00000000..e63feb14 --- /dev/null +++ b/legacy/web/app/store/AllComputedAttributes.js @@ -0,0 +1,30 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.store.AllComputedAttributes', { + extend: 'Ext.data.Store', + model: 'Traccar.model.ComputedAttribute', + + proxy: { + type: 'rest', + url: 'api/attributes/computed', + extraParams: { + all: true + } + } +}); diff --git a/legacy/web/app/store/AllDevices.js b/legacy/web/app/store/AllDevices.js new file mode 100644 index 00000000..338e6be7 --- /dev/null +++ b/legacy/web/app/store/AllDevices.js @@ -0,0 +1,29 @@ +/* + * Copyright 2015 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.AllDevices', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Device', + + proxy: { + type: 'rest', + url: 'api/devices', + extraParams: { + all: true + } + } +}); diff --git a/legacy/web/app/store/AllDrivers.js b/legacy/web/app/store/AllDrivers.js new file mode 100644 index 00000000..9d723885 --- /dev/null +++ b/legacy/web/app/store/AllDrivers.js @@ -0,0 +1,30 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.store.AllDrivers', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Driver', + + proxy: { + type: 'rest', + url: 'api/drivers', + extraParams: { + all: true + } + } +}); diff --git a/legacy/web/app/store/AllGeofences.js b/legacy/web/app/store/AllGeofences.js new file mode 100644 index 00000000..4042732b --- /dev/null +++ b/legacy/web/app/store/AllGeofences.js @@ -0,0 +1,29 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.AllGeofences', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Geofence', + + proxy: { + type: 'rest', + url: 'api/geofences', + extraParams: { + all: true + } + } +}); diff --git a/legacy/web/app/store/AllGroups.js b/legacy/web/app/store/AllGroups.js new file mode 100644 index 00000000..ba02e715 --- /dev/null +++ b/legacy/web/app/store/AllGroups.js @@ -0,0 +1,29 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.AllGroups', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Group', + + proxy: { + type: 'rest', + url: 'api/groups', + extraParams: { + all: true + } + } +}); diff --git a/legacy/web/app/store/AllMaintenances.js b/legacy/web/app/store/AllMaintenances.js new file mode 100644 index 00000000..8435ad40 --- /dev/null +++ b/legacy/web/app/store/AllMaintenances.js @@ -0,0 +1,30 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 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.AllMaintenances', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Maintenance', + + proxy: { + type: 'rest', + url: 'api/maintenance', + extraParams: { + all: true + } + } +}); diff --git a/legacy/web/app/store/AllNotificationTypes.js b/legacy/web/app/store/AllNotificationTypes.js new file mode 100644 index 00000000..63fec1bc --- /dev/null +++ b/legacy/web/app/store/AllNotificationTypes.js @@ -0,0 +1,32 @@ +/* + * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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.AllNotificationTypes', { + extend: 'Ext.data.Store', + model: 'Traccar.model.KnownNotification', + + proxy: { + type: 'rest', + url: 'api/notifications/types', + listeners: { + exception: function (proxy, response) { + Traccar.app.showError(response); + } + } + } +}); diff --git a/legacy/web/app/store/AllNotifications.js b/legacy/web/app/store/AllNotifications.js new file mode 100644 index 00000000..a3e59e15 --- /dev/null +++ b/legacy/web/app/store/AllNotifications.js @@ -0,0 +1,29 @@ +/* + * Copyright 2015 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.AllNotifications', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Notification', + + proxy: { + type: 'rest', + url: 'api/notifications', + extraParams: { + all: true + } + } +}); diff --git a/legacy/web/app/store/AllNotificators.js b/legacy/web/app/store/AllNotificators.js new file mode 100644 index 00000000..d81b02fd --- /dev/null +++ b/legacy/web/app/store/AllNotificators.js @@ -0,0 +1,32 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 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.AllNotificators', { + extend: 'Ext.data.Store', + model: 'Traccar.model.KnownNotificator', + + proxy: { + type: 'rest', + url: 'api/notifications/notificators', + listeners: { + exception: function (proxy, response) { + Traccar.app.showError(response); + } + } + } +}); diff --git a/legacy/web/app/store/AllTimezones.js b/legacy/web/app/store/AllTimezones.js new file mode 100644 index 00000000..2a7fa371 --- /dev/null +++ b/legacy/web/app/store/AllTimezones.js @@ -0,0 +1,798 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +Ext.define('Traccar.store.AllTimezones', { + extend: 'Ext.data.Store', + fields: ['key'], + + sorters: { + property: 'key', + direction: 'ASC' + }, + + data: [{ + key: 'Africa/Abidjan' + }, { + key: 'Africa/Accra' + }, { + key: 'Africa/Bissau' + }, { + key: 'Africa/Casablanca' + }, { + key: 'Africa/El_Aaiun' + }, { + key: 'Africa/Monrovia' + }, { + key: 'America/Danmarkshavn' + }, { + key: 'Antarctica/Troll' + }, { + key: 'Atlantic/Canary' + }, { + key: 'Atlantic/Faroe' + }, { + key: 'Atlantic/Madeira' + }, { + key: 'Atlantic/Reykjavik' + }, { + key: 'GMT' + }, { + key: 'Etc/GMT' + }, { + key: 'Etc/UCT' + }, { + key: 'Etc/UTC' + }, { + key: 'Europe/Dublin' + }, { + key: 'Europe/Lisbon' + }, { + key: 'Europe/London' + }, { + key: 'WET' + }, { + key: 'Africa/Algiers' + }, { + key: 'Africa/Ceuta' + }, { + key: 'Africa/Lagos' + }, { + key: 'Africa/Ndjamena' + }, { + key: 'Africa/Tunis' + }, { + key: 'Africa/Windhoek' + }, { + key: 'CET' + }, { + key: 'Etc/GMT-1' + }, { + key: 'Europe/Amsterdam' + }, { + key: 'Europe/Andorra' + }, { + key: 'Europe/Belgrade' + }, { + key: 'Europe/Berlin' + }, { + key: 'Europe/Brussels' + }, { + key: 'Europe/Budapest' + }, { + key: 'Europe/Copenhagen' + }, { + key: 'Europe/Gibraltar' + }, { + key: 'Europe/Luxembourg' + }, { + key: 'Europe/Madrid' + }, { + key: 'Europe/Malta' + }, { + key: 'Europe/Monaco' + }, { + key: 'Europe/Oslo' + }, { + key: 'Europe/Paris' + }, { + key: 'Europe/Prague' + }, { + key: 'Europe/Rome' + }, { + key: 'Europe/Stockholm' + }, { + key: 'Europe/Tirane' + }, { + key: 'Europe/Vienna' + }, { + key: 'Europe/Warsaw' + }, { + key: 'Europe/Zurich' + }, { + key: 'MET' + }, { + key: 'Africa/Cairo' + }, { + key: 'Africa/Johannesburg' + }, { + key: 'Africa/Maputo' + }, { + key: 'Africa/Tripoli' + }, { + key: 'Asia/Amman' + }, { + key: 'Asia/Beirut' + }, { + key: 'Asia/Damascus' + }, { + key: 'Asia/Gaza' + }, { + key: 'Asia/Hebron' + }, { + key: 'Asia/Jerusalem' + }, { + key: 'Asia/Nicosia' + }, { + key: 'EET' + }, { + key: 'Etc/GMT-2' + }, { + key: 'Europe/Athens' + }, { + key: 'Europe/Bucharest' + }, { + key: 'Europe/Chisinau' + }, { + key: 'Europe/Helsinki' + }, { + key: 'Europe/Kaliningrad' + }, { + key: 'Europe/Kiev' + }, { + key: 'Europe/Riga' + }, { + key: 'Europe/Sofia' + }, { + key: 'Europe/Tallinn' + }, { + key: 'Europe/Uzhgorod' + }, { + key: 'Europe/Vilnius' + }, { + key: 'Europe/Zaporozhye' + }, { + key: 'Africa/Khartoum' + }, { + key: 'Africa/Nairobi' + }, { + key: 'Antarctica/Syowa' + }, { + key: 'Asia/Baghdad' + }, { + key: 'Asia/Famagusta' + }, { + key: 'Asia/Qatar' + }, { + key: 'Asia/Riyadh' + }, { + key: 'Etc/GMT-3' + }, { + key: 'Europe/Istanbul' + }, { + key: 'Europe/Kirov' + }, { + key: 'Europe/Minsk' + }, { + key: 'Europe/Moscow' + }, { + key: 'Europe/Simferopol' + }, { + key: 'Europe/Volgograd' + }, { + key: 'Asia/Tehran' + }, { + key: 'Asia/Baku' + }, { + key: 'Asia/Dubai' + }, { + key: 'Asia/Tbilisi' + }, { + key: 'Asia/Yerevan' + }, { + key: 'Etc/GMT-4' + }, { + key: 'Europe/Astrakhan' + }, { + key: 'Europe/Samara' + }, { + key: 'Europe/Saratov' + }, { + key: 'Europe/Ulyanovsk' + }, { + key: 'Indian/Mahe' + }, { + key: 'Indian/Mauritius' + }, { + key: 'Indian/Reunion' + }, { + key: 'Asia/Kabul' + }, { + key: 'Antarctica/Mawson' + }, { + key: 'Asia/Aqtau' + }, { + key: 'Asia/Aqtobe' + }, { + key: 'Asia/Ashgabat' + }, { + key: 'Asia/Atyrau' + }, { + key: 'Asia/Dushanbe' + }, { + key: 'Asia/Karachi' + }, { + key: 'Asia/Oral' + }, { + key: 'Asia/Samarkand' + }, { + key: 'Asia/Tashkent' + }, { + key: 'Asia/Yekaterinburg' + }, { + key: 'Etc/GMT-5' + }, { + key: 'Indian/Kerguelen' + }, { + key: 'Indian/Maldives' + }, { + key: 'Asia/Colombo' + }, { + key: 'Asia/Kolkata' + }, { + key: 'Asia/Kathmandu' + }, { + key: 'Antarctica/Vostok' + }, { + key: 'Asia/Almaty' + }, { + key: 'Asia/Bishkek' + }, { + key: 'Asia/Dhaka' + }, { + key: 'Asia/Omsk' + }, { + key: 'Asia/Qyzylorda' + }, { + key: 'Asia/Thimphu' + }, { + key: 'Asia/Urumqi' + }, { + key: 'Etc/GMT-6' + }, { + key: 'Indian/Chagos' + }, { + key: 'Asia/Yangon' + }, { + key: 'Indian/Cocos' + }, { + key: 'Antarctica/Davis' + }, { + key: 'Asia/Bangkok' + }, { + key: 'Asia/Barnaul' + }, { + key: 'Asia/Ho_Chi_Minh' + }, { + key: 'Asia/Hovd' + }, { + key: 'Asia/Jakarta' + }, { + key: 'Asia/Krasnoyarsk' + }, { + key: 'Asia/Novokuznetsk' + }, { + key: 'Asia/Novosibirsk' + }, { + key: 'Asia/Pontianak' + }, { + key: 'Asia/Tomsk' + }, { + key: 'Etc/GMT-7' + }, { + key: 'Indian/Christmas' + }, { + key: 'Asia/Brunei' + }, { + key: 'Asia/Choibalsan' + }, { + key: 'Asia/Hong_Kong' + }, { + key: 'Asia/Irkutsk' + }, { + key: 'Asia/Kuala_Lumpur' + }, { + key: 'Asia/Kuching' + }, { + key: 'Asia/Macau' + }, { + key: 'Asia/Makassar' + }, { + key: 'Asia/Manila' + }, { + key: 'Asia/Shanghai' + }, { + key: 'Asia/Singapore' + }, { + key: 'Asia/Taipei' + }, { + key: 'Asia/Ulaanbaatar' + }, { + key: 'Australia/Perth' + }, { + key: 'Etc/GMT-8' + }, { + key: 'Asia/Pyongyang' + }, { + key: 'Australia/Eucla' + }, { + key: 'Asia/Chita' + }, { + key: 'Asia/Dili' + }, { + key: 'Asia/Jayapura' + }, { + key: 'Asia/Khandyga' + }, { + key: 'Asia/Seoul' + }, { + key: 'Asia/Tokyo' + }, { + key: 'Asia/Yakutsk' + }, { + key: 'Etc/GMT-9' + }, { + key: 'Pacific/Palau' + }, { + key: 'Australia/Adelaide' + }, { + key: 'Australia/Broken_Hill' + }, { + key: 'Australia/Darwin' + }, { + key: 'Antarctica/DumontDUrville' + }, { + key: 'Asia/Ust-Nera' + }, { + key: 'Asia/Vladivostok' + }, { + key: 'Australia/Brisbane' + }, { + key: 'Australia/Currie' + }, { + key: 'Australia/Hobart' + }, { + key: 'Australia/Lindeman' + }, { + key: 'Australia/Melbourne' + }, { + key: 'Australia/Sydney' + }, { + key: 'Etc/GMT-10' + }, { + key: 'Pacific/Chuuk' + }, { + key: 'Pacific/Guam' + }, { + key: 'Pacific/Port_Moresby' + }, { + key: 'Australia/Lord_Howe' + }, { + key: 'Antarctica/Casey' + }, { + key: 'Antarctica/Macquarie' + }, { + key: 'Asia/Magadan' + }, { + key: 'Asia/Sakhalin' + }, { + key: 'Asia/Srednekolymsk' + }, { + key: 'Etc/GMT-11' + }, { + key: 'Pacific/Bougainville' + }, { + key: 'Pacific/Efate' + }, { + key: 'Pacific/Guadalcanal' + }, { + key: 'Pacific/Kosrae' + }, { + key: 'Pacific/Norfolk' + }, { + key: 'Pacific/Noumea' + }, { + key: 'Pacific/Pohnpei' + }, { + key: 'Asia/Anadyr' + }, { + key: 'Asia/Kamchatka' + }, { + key: 'Etc/GMT-12' + }, { + key: 'Pacific/Auckland' + }, { + key: 'Pacific/Fiji' + }, { + key: 'Pacific/Funafuti' + }, { + key: 'Pacific/Kwajalein' + }, { + key: 'Pacific/Majuro' + }, { + key: 'Pacific/Nauru' + }, { + key: 'Pacific/Tarawa' + }, { + key: 'Pacific/Wake' + }, { + key: 'Pacific/Wallis' + }, { + key: 'Pacific/Chatham' + }, { + key: 'Etc/GMT-13' + }, { + key: 'Pacific/Apia' + }, { + key: 'Pacific/Enderbury' + }, { + key: 'Pacific/Fakaofo' + }, { + key: 'Pacific/Tongatapu' + }, { + key: 'Etc/GMT-14' + }, { + key: 'Pacific/Kiritimati' + }, { + key: 'America/Scoresbysund' + }, { + key: 'Atlantic/Azores' + }, { + key: 'Atlantic/Cape_Verde' + }, { + key: 'Etc/GMT+1' + }, { + key: 'America/Noronha' + }, { + key: 'Atlantic/South_Georgia' + }, { + key: 'Etc/GMT+2' + }, { + key: 'America/Araguaina' + }, { + key: 'America/Argentina/Buenos_Aires' + }, { + key: 'America/Argentina/Catamarca' + }, { + key: 'America/Argentina/Cordoba' + }, { + key: 'America/Argentina/Jujuy' + }, { + key: 'America/Argentina/La_Rioja' + }, { + key: 'America/Argentina/Mendoza' + }, { + key: 'America/Argentina/Rio_Gallegos' + }, { + key: 'America/Argentina/Salta' + }, { + key: 'America/Argentina/San_Juan' + }, { + key: 'America/Argentina/San_Luis' + }, { + key: 'America/Argentina/Tucuman' + }, { + key: 'America/Argentina/Ushuaia' + }, { + key: 'America/Bahia' + }, { + key: 'America/Belem' + }, { + key: 'America/Cayenne' + }, { + key: 'America/Fortaleza' + }, { + key: 'America/Godthab' + }, { + key: 'America/Maceio' + }, { + key: 'America/Miquelon' + }, { + key: 'America/Montevideo' + }, { + key: 'America/Paramaribo' + }, { + key: 'America/Recife' + }, { + key: 'America/Santarem' + }, { + key: 'America/Sao_Paulo' + }, { + key: 'Antarctica/Rothera' + }, { + key: 'Atlantic/Stanley' + }, { + key: 'Etc/GMT+3' + }, { + key: 'America/St_Johns' + }, { + key: 'America/Asuncion' + }, { + key: 'America/Barbados' + }, { + key: 'America/Blanc-Sablon' + }, { + key: 'America/Boa_Vista' + }, { + key: 'America/Campo_Grande' + }, { + key: 'America/Caracas' + }, { + key: 'America/Cuiaba' + }, { + key: 'America/Curacao' + }, { + key: 'America/Glace_Bay' + }, { + key: 'America/Goose_Bay' + }, { + key: 'America/Grand_Turk' + }, { + key: 'America/Guyana' + }, { + key: 'America/Halifax' + }, { + key: 'America/La_Paz' + }, { + key: 'America/Manaus' + }, { + key: 'America/Martinique' + }, { + key: 'America/Moncton' + }, { + key: 'America/Port_of_Spain' + }, { + key: 'America/Porto_Velho' + }, { + key: 'America/Puerto_Rico' + }, { + key: 'America/Santiago' + }, { + key: 'America/Santo_Domingo' + }, { + key: 'America/Thule' + }, { + key: 'Antarctica/Palmer' + }, { + key: 'Atlantic/Bermuda' + }, { + key: 'Etc/GMT+4' + }, { + key: 'America/Atikokan' + }, { + key: 'America/Bogota' + }, { + key: 'America/Cancun' + }, { + key: 'America/Detroit' + }, { + key: 'America/Eirunepe' + }, { + key: 'America/Guayaquil' + }, { + key: 'America/Havana' + }, { + key: 'America/Indiana/Indianapolis' + }, { + key: 'America/Indiana/Marengo' + }, { + key: 'America/Indiana/Petersburg' + }, { + key: 'America/Indiana/Vevay' + }, { + key: 'America/Indiana/Vincennes' + }, { + key: 'America/Indiana/Winamac' + }, { + key: 'America/Iqaluit' + }, { + key: 'America/Jamaica' + }, { + key: 'America/Kentucky/Louisville' + }, { + key: 'America/Kentucky/Monticello' + }, { + key: 'America/Lima' + }, { + key: 'America/Nassau' + }, { + key: 'America/New_York' + }, { + key: 'America/Nipigon' + }, { + key: 'America/Panama' + }, { + key: 'America/Pangnirtung' + }, { + key: 'America/Port-au-Prince' + }, { + key: 'America/Rio_Branco' + }, { + key: 'America/Thunder_Bay' + }, { + key: 'America/Toronto' + }, { + key: 'EST' + }, { + key: 'EST5EDT' + }, { + key: 'Etc/GMT+5' + }, { + key: 'America/Bahia_Banderas' + }, { + key: 'America/Belize' + }, { + key: 'America/Chicago' + }, { + key: 'America/Costa_Rica' + }, { + key: 'America/El_Salvador' + }, { + key: 'America/Guatemala' + }, { + key: 'America/Indiana/Knox' + }, { + key: 'America/Indiana/Tell_City' + }, { + key: 'America/Managua' + }, { + key: 'America/Matamoros' + }, { + key: 'America/Menominee' + }, { + key: 'America/Merida' + }, { + key: 'America/Mexico_City' + }, { + key: 'America/Monterrey' + }, { + key: 'America/North_Dakota/Beulah' + }, { + key: 'America/North_Dakota/Center' + }, { + key: 'America/North_Dakota/New_Salem' + }, { + key: 'America/Rainy_River' + }, { + key: 'America/Rankin_Inlet' + }, { + key: 'America/Regina' + }, { + key: 'America/Resolute' + }, { + key: 'America/Swift_Current' + }, { + key: 'America/Tegucigalpa' + }, { + key: 'America/Winnipeg' + }, { + key: 'CST6CDT' + }, { + key: 'Etc/GMT+6' + }, { + key: 'Pacific/Easter' + }, { + key: 'Pacific/Galapagos' + }, { + key: 'America/Boise' + }, { + key: 'America/Cambridge_Bay' + }, { + key: 'America/Chihuahua' + }, { + key: 'America/Creston' + }, { + key: 'America/Dawson_Creek' + }, { + key: 'America/Denver' + }, { + key: 'America/Edmonton' + }, { + key: 'America/Fort_Nelson' + }, { + key: 'America/Hermosillo' + }, { + key: 'America/Inuvik' + }, { + key: 'America/Mazatlan' + }, { + key: 'America/Ojinaga' + }, { + key: 'America/Phoenix' + }, { + key: 'America/Yellowknife' + }, { + key: 'Etc/GMT+7' + }, { + key: 'MST' + }, { + key: 'MST7MDT' + }, { + key: 'America/Dawson' + }, { + key: 'America/Los_Angeles' + }, { + key: 'America/Tijuana' + }, { + key: 'America/Vancouver' + }, { + key: 'America/Whitehorse' + }, { + key: 'Etc/GMT+8' + }, { + key: 'Pacific/Pitcairn' + }, { + key: 'PST8PDT' + }, { + key: 'America/Anchorage' + }, { + key: 'America/Juneau' + }, { + key: 'America/Metlakatla' + }, { + key: 'America/Nome' + }, { + key: 'America/Sitka' + }, { + key: 'America/Yakutat' + }, { + key: 'Etc/GMT+9' + }, { + key: 'Pacific/Gambier' + }, { + key: 'Pacific/Marquesas' + }, { + key: 'America/Adak' + }, { + key: 'Etc/GMT+10' + }, { + key: 'HST' + }, { + key: 'Pacific/Honolulu' + }, { + key: 'Pacific/Rarotonga' + }, { + key: 'Pacific/Tahiti' + }, { + key: 'Etc/GMT+11' + }, { + key: 'Pacific/Niue' + }, { + key: 'Pacific/Pago_Pago' + }, { + key: 'Etc/GMT+12' + }] +}); diff --git a/legacy/web/app/store/AttributeValueTypes.js b/legacy/web/app/store/AttributeValueTypes.js new file mode 100644 index 00000000..b80eba39 --- /dev/null +++ b/legacy/web/app/store/AttributeValueTypes.js @@ -0,0 +1,33 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +Ext.define('Traccar.store.AttributeValueTypes', { + extend: 'Ext.data.Store', + fields: ['id', 'name'], + proxy: 'memory', + + data: [{ + id: 'string', + name: Strings.sharedTypeString + }, { + id: 'number', + name: Strings.sharedTypeNumber + }, { + id: 'boolean', + name: Strings.sharedTypeBoolean + }] +}); diff --git a/legacy/web/app/store/Attributes.js b/legacy/web/app/store/Attributes.js new file mode 100644 index 00000000..388fa436 --- /dev/null +++ b/legacy/web/app/store/Attributes.js @@ -0,0 +1,25 @@ +/* + * Copyright 2015 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.Attributes', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Attribute', + + sorters: [{ + property: 'priority' + }] +}); diff --git a/legacy/web/app/store/Calendars.js b/legacy/web/app/store/Calendars.js new file mode 100644 index 00000000..fa8e5c66 --- /dev/null +++ b/legacy/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/legacy/web/app/store/CommandTypes.js b/legacy/web/app/store/CommandTypes.js new file mode 100644 index 00000000..3b898f2e --- /dev/null +++ b/legacy/web/app/store/CommandTypes.js @@ -0,0 +1,32 @@ +/* + * Copyright 2016 Gabor Somogyi (gabor.g.somogyi@gmail.com) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.store.CommandTypes', { + extend: 'Ext.data.Store', + model: 'Traccar.model.KnownCommand', + + proxy: { + type: 'rest', + url: 'api/commands/types', + listeners: { + 'exception': function (proxy, response) { + Traccar.app.showError(response); + } + } + } +}); diff --git a/legacy/web/app/store/Commands.js b/legacy/web/app/store/Commands.js new file mode 100644 index 00000000..3e5b7604 --- /dev/null +++ b/legacy/web/app/store/Commands.js @@ -0,0 +1,30 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.store.Commands', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Command', + + proxy: { + type: 'rest', + url: 'api/commands', + writer: { + writeAllFields: true + } + } +}); diff --git a/legacy/web/app/store/CommonDeviceAttributes.js b/legacy/web/app/store/CommonDeviceAttributes.js new file mode 100644 index 00000000..e63daa6b --- /dev/null +++ b/legacy/web/app/store/CommonDeviceAttributes.js @@ -0,0 +1,32 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +Ext.define('Traccar.store.CommonDeviceAttributes', { + extend: 'Ext.data.Store', + model: 'Traccar.model.KnownAttribute', + + data: [{ + key: 'speedLimit', + name: Strings.attributeSpeedLimit, + valueType: 'number', + dataType: 'speed' + }, { + key: 'report.ignoreOdometer', + name: Strings.attributeReportIgnoreOdometer, + valueType: 'boolean' + }] +}); diff --git a/legacy/web/app/store/CommonUserAttributes.js b/legacy/web/app/store/CommonUserAttributes.js new file mode 100644 index 00000000..0619df22 --- /dev/null +++ b/legacy/web/app/store/CommonUserAttributes.js @@ -0,0 +1,90 @@ +/* + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +Ext.define('Traccar.store.CommonUserAttributes', { + extend: 'Ext.data.Store', + model: 'Traccar.model.KnownAttribute', + + data: [{ + key: 'web.liveRouteLength', + name: Strings.attributeWebLiveRouteLength, + valueType: 'number', + allowDecimals: false + }, { + key: 'web.selectZoom', + name: Strings.attributeWebSelectZoom, + valueType: 'number', + allowDecimals: false, + minValue: Traccar.Style.mapDefaultZoom, + maxValue: Traccar.Style.mapMaxZoom + }, { + key: 'web.maxZoom', + name: Strings.attributeWebMaxZoom, + valueType: 'number', + allowDecimals: false, + minValue: Traccar.Style.mapDefaultZoom, + maxValue: Traccar.Style.mapMaxZoom + }, { + key: 'ui.disableEvents', + name: Strings.attributeUiDisableEvents, + valueType: 'boolean' + }, { + key: 'ui.disableVehicleFeatures', + name: Strings.attributeUiDisableVehicleFeatures, + valueType: 'boolean' + }, { + key: 'ui.disableDrivers', + name: Strings.attributeUiDisableDrivers, + valueType: 'boolean' + }, { + key: 'ui.disableComputedAttributes', + name: Strings.attributeUiDisableComputedAttributes, + valueType: 'boolean' + }, { + key: 'ui.disableCalendars', + name: Strings.attributeUiDisableCalendars, + valueType: 'boolean' + }, { + key: 'ui.disableMaintenance', + name: Strings.attributeUiDisableMaintenance, + valueType: 'boolean' + }, { + key: 'ui.hidePositionAttributes', + name: Strings.attributeUiHidePositionAttributes, + valueType: 'string' + }, { + key: 'distanceUnit', + name: Strings.settingsDistanceUnit, + valueType: 'string', + dataType: 'distanceUnit' + }, { + key: 'speedUnit', + name: Strings.settingsSpeedUnit, + valueType: 'string', + dataType: 'speedUnit' + }, { + key: 'volumeUnit', + name: Strings.settingsVolumeUnit, + valueType: 'string', + dataType: 'volumeUnit' + }, { + key: 'timezone', + name: Strings.sharedTimezone, + valueType: 'string', + dataType: 'timezone' + }] +}); diff --git a/legacy/web/app/store/ComputedAttributes.js b/legacy/web/app/store/ComputedAttributes.js new file mode 100644 index 00000000..33d78298 --- /dev/null +++ b/legacy/web/app/store/ComputedAttributes.js @@ -0,0 +1,30 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.store.ComputedAttributes', { + extend: 'Ext.data.Store', + model: 'Traccar.model.ComputedAttribute', + + proxy: { + type: 'rest', + url: 'api/attributes/computed', + writer: { + writeAllFields: true + } + } +}); diff --git a/legacy/web/app/store/CoordinateFormats.js b/legacy/web/app/store/CoordinateFormats.js new file mode 100644 index 00000000..d5db871a --- /dev/null +++ b/legacy/web/app/store/CoordinateFormats.js @@ -0,0 +1,56 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.CoordinateFormats', { + extend: 'Ext.data.Store', + fields: ['key', 'name'], + + data: [{ + key: 'dd', + name: Strings.sharedDecimalDegrees + }, { + key: 'ddm', + name: Strings.sharedDegreesDecimalMinutes + }, { + key: 'dms', + name: Strings.sharedDegreesMinutesSeconds + }], + + formatValue: function (key, value, unit) { + var hemisphere, degrees, minutes, seconds; + if (key === 'latitude') { + hemisphere = value >= 0 ? 'N' : 'S'; + } else { + hemisphere = value >= 0 ? 'E' : 'W'; + } + switch (unit) { + case 'ddm': + value = Math.abs(value); + degrees = Math.floor(value); + minutes = (value - degrees) * 60; + return degrees + '° ' + minutes.toFixed(Traccar.Style.coordinatePrecision) + '\' ' + hemisphere; + case 'dms': + value = Math.abs(value); + degrees = Math.floor(value); + minutes = Math.floor((value - degrees) * 60); + seconds = Math.round((value - degrees - minutes / 60) * 3600); + return degrees + '° ' + minutes + '\' ' + seconds + '" ' + hemisphere; + default: + return value.toFixed(Traccar.Style.coordinatePrecision) + '°'; + } + } +}); diff --git a/legacy/web/app/store/DeviceAttributes.js b/legacy/web/app/store/DeviceAttributes.js new file mode 100644 index 00000000..45ae6e3d --- /dev/null +++ b/legacy/web/app/store/DeviceAttributes.js @@ -0,0 +1,52 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +Ext.define('Traccar.store.DeviceAttributes', { + extend: 'Ext.data.Store', + model: 'Traccar.model.KnownAttribute', + + data: [{ + key: 'web.reportColor', + name: Strings.attributeWebReportColor, + valueType: 'color' + }, { + key: 'devicePassword', + name: Strings.attributeDevicePassword, + valueType: 'string' + }, { + key: 'processing.copyAttributes', + name: Strings.attributeProcessingCopyAttributes, + valueType: 'string' + }, { + key: 'decoder.timezone', + name: Strings.sharedTimezone, + valueType: 'string', + dataType: 'timezone' + }, { + key: 'deviceInactivityStart', + name: Strings.attributeDeviceInactivityStart, + valueType: 'number', + allowDecimals: false, + minValue: 1 + }, { + key: 'deviceInactivityPeriod', + name: Strings.attributeDeviceInactivityPeriod, + valueType: 'number', + allowDecimals: false, + minValue: 1 + }] +}); diff --git a/legacy/web/app/store/DeviceCommands.js b/legacy/web/app/store/DeviceCommands.js new file mode 100644 index 00000000..7233b3ba --- /dev/null +++ b/legacy/web/app/store/DeviceCommands.js @@ -0,0 +1,32 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.store.DeviceCommands', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Command', + + proxy: { + type: 'rest', + url: 'api/commands/send', + listeners: { + 'exception': function (proxy, response) { + Traccar.app.showError(response); + } + } + } +}); diff --git a/legacy/web/app/store/DeviceImages.js b/legacy/web/app/store/DeviceImages.js new file mode 100644 index 00000000..6f8e8cfd --- /dev/null +++ b/legacy/web/app/store/DeviceImages.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.store.DeviceImages', { + extend: 'Ext.data.Store', + fields: ['key', 'name', 'svg', 'fillId', 'rotateId', 'scaleId'], + + data: (function () { + var i, key, data = []; + for (i = 0; i < window.Images.length; i++) { + key = window.Images[i]; + data.push({ + key: key, + name: Strings['category' + key.charAt(0).toUpperCase() + key.slice(1)], + svg: document.getElementById(key + 'Svg').contentDocument, + fillId: key === 'arrow' ? 'arrow' : 'background', + rotateId: key === 'arrow' ? 'arrow' : 'background', + scaleId: key === 'arrow' ? 'arrow' : 'layer1' + }); + } + return data; + })() +}); diff --git a/legacy/web/app/store/DeviceStatuses.js b/legacy/web/app/store/DeviceStatuses.js new file mode 100644 index 00000000..eafba241 --- /dev/null +++ b/legacy/web/app/store/DeviceStatuses.js @@ -0,0 +1,35 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +Ext.define('Traccar.store.DeviceStatuses', { + extend: 'Ext.data.Store', + fields: ['id', 'name', 'color'], + + data: [{ + id: 'online', + name: Strings.deviceStatusOnline, + color: 'view-color-green' + }, { + id: 'offline', + name: Strings.deviceStatusOffline, + color: 'view-color-red' + }, { + id: 'unknown', + name: Strings.deviceStatusUnknown, + color: 'view-color-yellow' + }] +}); diff --git a/legacy/web/app/store/Devices.js b/legacy/web/app/store/Devices.js new file mode 100644 index 00000000..e69c93fa --- /dev/null +++ b/legacy/web/app/store/Devices.js @@ -0,0 +1,29 @@ +/* + * Copyright 2015 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.Devices', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Device', + + proxy: { + type: 'rest', + url: 'api/devices', + writer: { + writeAllFields: true + } + } +}); diff --git a/legacy/web/app/store/DistanceUnits.js b/legacy/web/app/store/DistanceUnits.js new file mode 100644 index 00000000..e64ce234 --- /dev/null +++ b/legacy/web/app/store/DistanceUnits.js @@ -0,0 +1,53 @@ +/* + * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.DistanceUnits', { + extend: 'Ext.data.Store', + fields: ['key', 'name', 'factor'], + + data: [{ + key: 'km', + name: Strings.sharedKm, + factor: 0.001 + }, { + key: 'mi', + name: Strings.sharedMi, + factor: 0.000621371 + }, { + key: 'nmi', + name: Strings.sharedNmi, + factor: 0.000539957 + }], + + convertValue: function (value, unit, back) { + var model; + if (!unit) { + unit = 'km'; + } + model = this.findRecord('key', unit); + return back ? value / model.get('factor') : value * model.get('factor'); + }, + + formatValue: function (value, unit, convert) { + var model; + if (!unit) { + unit = 'km'; + } + model = this.findRecord('key', unit); + return (convert ? this.convertValue(value, unit) : value).toFixed(2) + ' ' + model.get('name'); + } +}); diff --git a/legacy/web/app/store/Drivers.js b/legacy/web/app/store/Drivers.js new file mode 100644 index 00000000..fd4ca203 --- /dev/null +++ b/legacy/web/app/store/Drivers.js @@ -0,0 +1,30 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.store.Drivers', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Driver', + + proxy: { + type: 'rest', + url: 'api/drivers', + writer: { + writeAllFields: true + } + } +}); diff --git a/legacy/web/app/store/EventPositions.js b/legacy/web/app/store/EventPositions.js new file mode 100644 index 00000000..d984e4b8 --- /dev/null +++ b/legacy/web/app/store/EventPositions.js @@ -0,0 +1,31 @@ +/* + * Copyright 2015 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.EventPositions', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Position', + + trackRemoved: false, + + proxy: { + type: 'rest', + url: 'api/positions', + headers: { + 'Accept': 'application/json' + } + } +}); diff --git a/legacy/web/app/store/Events.js b/legacy/web/app/store/Events.js new file mode 100644 index 00000000..cfa0d568 --- /dev/null +++ b/legacy/web/app/store/Events.js @@ -0,0 +1,29 @@ +/* + * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.store.Events', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Event', + + trackRemoved: false, + + proxy: { + type: 'rest', + url: 'api/events' + } +}); diff --git a/legacy/web/app/store/GeofenceAttributes.js b/legacy/web/app/store/GeofenceAttributes.js new file mode 100644 index 00000000..b1d48c19 --- /dev/null +++ b/legacy/web/app/store/GeofenceAttributes.js @@ -0,0 +1,38 @@ +/* + * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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.GeofenceAttributes', { + extend: 'Ext.data.Store', + model: 'Traccar.model.KnownAttribute', + proxy: 'memory', + + data: [{ + key: 'color', + name: Strings.attributeColor, + valueType: 'color' + }, { + key: 'speedLimit', + name: Strings.attributeSpeedLimit, + valueType: 'number', + dataType: 'speed' + }, { + key: 'polylineDistance', + name: Strings.attributePolylineDistance, + valueType: 'number', + dataType: 'distance' + }] +}); diff --git a/legacy/web/app/store/GeofenceTypes.js b/legacy/web/app/store/GeofenceTypes.js new file mode 100644 index 00000000..45b79897 --- /dev/null +++ b/legacy/web/app/store/GeofenceTypes.js @@ -0,0 +1,32 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.GeofenceTypes', { + extend: 'Ext.data.Store', + fields: ['key', 'name'], + + data: [{ + key: 'Polygon', + name: Strings.mapShapePolygon + }, { + key: 'Circle', + name: Strings.mapShapeCircle + }, { + key: 'LineString', + name: Strings.mapShapePolyline + }] +}); diff --git a/legacy/web/app/store/Geofences.js b/legacy/web/app/store/Geofences.js new file mode 100644 index 00000000..5a7172be --- /dev/null +++ b/legacy/web/app/store/Geofences.js @@ -0,0 +1,29 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.Geofences', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Geofence', + + proxy: { + type: 'rest', + url: 'api/geofences', + writer: { + writeAllFields: true + } + } +}); diff --git a/legacy/web/app/store/GroupAttributes.js b/legacy/web/app/store/GroupAttributes.js new file mode 100644 index 00000000..589e4ec2 --- /dev/null +++ b/legacy/web/app/store/GroupAttributes.js @@ -0,0 +1,32 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +Ext.define('Traccar.store.GroupAttributes', { + extend: 'Ext.data.Store', + model: 'Traccar.model.KnownAttribute', + + data: [{ + key: 'processing.copyAttributes', + name: Strings.attributeProcessingCopyAttributes, + valueType: 'string' + }, { + key: 'decoder.timezone', + name: Strings.sharedTimezone, + valueType: 'string', + dataType: 'timezone' + }] +}); diff --git a/legacy/web/app/store/Groups.js b/legacy/web/app/store/Groups.js new file mode 100644 index 00000000..5f8fa60a --- /dev/null +++ b/legacy/web/app/store/Groups.js @@ -0,0 +1,29 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.Groups', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Group', + + proxy: { + type: 'rest', + url: 'api/groups', + writer: { + writeAllFields: true + } + } +}); diff --git a/legacy/web/app/store/HoursUnits.js b/legacy/web/app/store/HoursUnits.js new file mode 100644 index 00000000..02f62c65 --- /dev/null +++ b/legacy/web/app/store/HoursUnits.js @@ -0,0 +1,43 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 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.HoursUnits', { + extend: 'Ext.data.Store', + fields: ['key', 'name', 'fullName'], + + data: [{ + key: 'h', + name: Strings.sharedHourAbbreviation, + fullName: Strings.sharedHour + }], + + convertValue: function (value, unit, back) { + return back ? value * 3600000 : value / 3600000; + }, + + formatValue: function (value, unit, convert) { + var hours, minutes; + if (convert) { + hours = Math.floor(value / 3600000); + minutes = Math.floor(value % 3600000 / 60000); + } else { + hours = Math.floor(value); + minutes = Math.floor(value % 1 * 60); + } + return hours + ' ' + Strings.sharedHourAbbreviation + ' ' + minutes + ' ' + Strings.sharedMinuteAbbreviation; + } +}); diff --git a/legacy/web/app/store/KnownCommands.js b/legacy/web/app/store/KnownCommands.js new file mode 100644 index 00000000..a6089c48 --- /dev/null +++ b/legacy/web/app/store/KnownCommands.js @@ -0,0 +1,241 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +Ext.define('Traccar.store.KnownCommands', { + extend: 'Ext.data.Store', + model: 'Traccar.model.KnownCommand', + + data: [{ + type: 'custom', + parameters: [{ + key: 'data', + name: Strings.commandData, + valueType: 'string' + }] + }, { + type: 'positionPeriodic', + parameters: [{ + key: 'frequency', + name: Strings.commandFrequency, + valueType: 'number', + allowDecimals: false, + minValue: 0, + dataType: 'frequency' + }] + }, { + type: 'setTimezone', + parameters: [{ + key: 'timezone', + name: Strings.commandTimezone, + valueType: 'string', + dataType: 'timezone' + }] + }, { + type: 'sendSms', + parameters: [{ + key: 'phone', + name: Strings.commandPhone, + valueType: 'string' + }, { + key: 'message', + name: Strings.commandMessage, + valueType: 'string' + }] + }, { + type: 'message', + parameters: [{ + key: 'message', + name: Strings.commandMessage, + valueType: 'string' + }] + }, { + type: 'sendUssd', + parameters: [{ + key: 'phone', + name: Strings.commandPhone, + valueType: 'string' + }] + }, { + type: 'sosNumber', + parameters: [{ + key: 'index', + name: Strings.commandIndex, + valueType: 'number', + allowDecimals: false, + minValue: 0 + }, { + key: 'phone', + name: Strings.commandPhone, + valueType: 'string' + }] + }, { + type: 'silenceTime', + parameters: [{ + key: 'data', + name: Strings.commandData, + valueType: 'string' + }] + }, { + type: 'setPhonebook', + parameters: [{ + key: 'data', + name: Strings.commandData, + valueType: 'string' + }] + }, { + type: 'voiceMessage', + parameters: [{ + key: 'data', + name: Strings.commandData, + valueType: 'string' + }] + }, { + type: 'outputControl', + parameters: [{ + key: 'index', + name: Strings.commandIndex, + valueType: 'number', + allowDecimals: false, + minValue: 0 + }, { + key: 'data', + name: Strings.commandData, + valueType: 'string' + }] + }, { + type: 'voiceMonitoring', + parameters: [{ + key: 'enable', + name: Strings.commandEnable, + valueType: 'boolean' + }] + }, { + type: 'setAgps', + parameters: [{ + key: 'enable', + name: Strings.commandEnable, + valueType: 'boolean' + }] + }, { + type: 'setIndicator', + parameters: [{ + key: 'data', + name: Strings.commandData, + valueType: 'string' + }] + }, { + type: 'configuration', + parameters: [{ + key: 'data', + name: Strings.commandData, + valueType: 'string' + }] + }, { + type: 'setConnection', + parameters: [{ + key: 'server', + name: Strings.commandServer, + valueType: 'string' + }, { + key: 'port', + name: Strings.commandPort, + valueType: 'number', + allowDecimals: false, + minValue: 1, + maxValue: 65535 + }] + }, { + type: 'setOdometer', + parameters: [{ + key: 'data', + name: Strings.commandData, + valueType: 'string' + }] + }, { + type: 'modePowerSaving', + parameters: [{ + key: 'enable', + name: Strings.commandEnable, + valueType: 'boolean' + }] + }, { + type: 'modeDeepSleep', + parameters: [{ + key: 'enable', + name: Strings.commandEnable, + valueType: 'boolean' + }] + }, { + type: 'alarmGeofence', + parameters: [{ + key: 'radius', + name: Strings.commandRadius, + valueType: 'number', + allowDecimals: false, + minValue: 0 + }] + }, { + type: 'alarmBattery', + parameters: [{ + key: 'enable', + name: Strings.commandEnable, + valueType: 'boolean' + }] + }, { + type: 'alarmSos', + parameters: [{ + key: 'enable', + name: Strings.commandEnable, + valueType: 'boolean' + }] + }, { + type: 'alarmRemove', + parameters: [{ + key: 'enable', + name: Strings.commandEnable, + valueType: 'boolean' + }] + }, { + type: 'alarmClock', + parameters: [{ + key: 'data', + name: Strings.commandData, + valueType: 'string' + }] + }, { + type: 'alarmSpeed', + parameters: [{ + key: 'data', + name: Strings.commandData, + valueType: 'string' + }] + }, { + type: 'alarmFall', + parameters: [{ + key: 'enable', + name: Strings.commandEnable, + valueType: 'boolean' + }] + }, { + type: 'alarmVibration', + parameters: [{ + key: 'data', + name: Strings.commandData, + valueType: 'string' + }] + }] +}); diff --git a/legacy/web/app/store/Languages.js b/legacy/web/app/store/Languages.js new file mode 100644 index 00000000..32d648e0 --- /dev/null +++ b/legacy/web/app/store/Languages.js @@ -0,0 +1,34 @@ +/* + * Copyright 2015 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.Languages', { + extend: 'Ext.data.Store', + fields: ['code', 'name'], + + data: (function () { + var code, data = []; + for (code in Locale.languages) { + if (Locale.languages.hasOwnProperty(code)) { + data.push({ + code: code, + name: Locale.languages[code].name + }); + } + } + return data; + })() +}); diff --git a/legacy/web/app/store/LatestPositions.js b/legacy/web/app/store/LatestPositions.js new file mode 100644 index 00000000..f7cf5406 --- /dev/null +++ b/legacy/web/app/store/LatestPositions.js @@ -0,0 +1,21 @@ +/* + * Copyright 2015 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.LatestPositions', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Position' +}); diff --git a/legacy/web/app/store/MaintenanceTypes.js b/legacy/web/app/store/MaintenanceTypes.js new file mode 100644 index 00000000..468b67ea --- /dev/null +++ b/legacy/web/app/store/MaintenanceTypes.js @@ -0,0 +1,22 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 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.MaintenanceTypes', { + extend: 'Ext.data.Store', + model: 'Traccar.model.KnownAttribute' +}); diff --git a/legacy/web/app/store/Maintenances.js b/legacy/web/app/store/Maintenances.js new file mode 100644 index 00000000..a7aa4a07 --- /dev/null +++ b/legacy/web/app/store/Maintenances.js @@ -0,0 +1,30 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 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.Maintenances', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Maintenance', + + proxy: { + type: 'rest', + url: 'api/maintenance', + writer: { + writeAllFields: true + } + } +}); diff --git a/legacy/web/app/store/MapTypes.js b/legacy/web/app/store/MapTypes.js new file mode 100644 index 00000000..f517045d --- /dev/null +++ b/legacy/web/app/store/MapTypes.js @@ -0,0 +1,56 @@ +/* + * Copyright 2015 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.MapTypes', { + extend: 'Ext.data.Store', + fields: ['key', 'name'], + + data: [{ + key: 'locationIqStreets', + name: Strings.mapLocationIqStreets + }, { + key: 'osm', + name: Strings.mapOsm + }, { + key: 'carto', + name: Strings.mapCarto + }, { + key: 'autoNavi', + name: Strings.mapAutoNavi + }, { + key: 'bingRoad', + name: Strings.mapBingRoad + }, { + key: 'bingAerial', + name: Strings.mapBingAerial + }, { + key: 'bingHybrid', + name: Strings.mapBingHybrid + }, { + key: 'yandexMap', + name: Strings.mapYandexMap + }, { + key: 'yandexSat', + name: Strings.mapYandexSat + }, { + key: 'custom', + name: Strings.mapCustom + }, { + key: 'customArcgis', + name: Strings.mapCustomArcgis + }] +}); diff --git a/legacy/web/app/store/Notifications.js b/legacy/web/app/store/Notifications.js new file mode 100644 index 00000000..b30505fd --- /dev/null +++ b/legacy/web/app/store/Notifications.js @@ -0,0 +1,29 @@ +/* + * Copyright 2015 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.Notifications', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Notification', + + proxy: { + type: 'rest', + url: 'api/notifications', + writer: { + writeAllFields: true + } + } +}); diff --git a/legacy/web/app/store/PositionAttributes.js b/legacy/web/app/store/PositionAttributes.js new file mode 100644 index 00000000..5b1206b7 --- /dev/null +++ b/legacy/web/app/store/PositionAttributes.js @@ -0,0 +1,269 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +Ext.define('Traccar.store.PositionAttributes', { + extend: 'Ext.data.Store', + model: 'Traccar.model.KnownAttribute', + proxy: 'memory', + + data: [{ + key: 'raw', + name: Strings.positionRaw, + valueType: 'string' + }, { + key: 'index', + name: Strings.positionIndex, + valueType: 'number' + }, { + key: 'hdop', + name: Strings.positionHdop, + valueType: 'number' + }, { + key: 'vdop', + name: Strings.positionVdop, + valueType: 'number' + }, { + key: 'pdop', + name: Strings.positionPdop, + valueType: 'number' + }, { + key: 'sat', + name: Strings.positionSat, + valueType: 'number' + }, { + key: 'satVisible', + name: Strings.positionSatVisible, + valueType: 'number' + }, { + key: 'rssi', + name: Strings.positionRssi, + valueType: 'number' + }, { + key: 'gps', + name: Strings.positionGps, + valueType: 'number' + }, { + key: 'roaming', + name: Strings.positionRoaming, + valueType: 'boolean' + }, { + key: 'event', + name: Strings.positionEvent, + valueType: 'string' + }, { + key: 'alarm', + name: Strings.positionAlarm, + valueType: 'string' + }, { + key: 'status', + name: Strings.positionStatus, + valueType: 'string' + }, { + key: 'odometer', + name: Strings.positionOdometer, + valueType: 'number', + dataType: 'distance' + }, { + key: 'serviceOdometer', + name: Strings.positionServiceOdometer, + valueType: 'number', + dataType: 'distance' + }, { + key: 'tripOdometer', + name: Strings.positionTripOdometer, + valueType: 'number', + dataType: 'distance' + }, { + key: 'hours', + name: Strings.positionHours, + valueType: 'number', + dataType: 'hours' + }, { + key: 'steps', + name: Strings.positionSteps, + valueType: 'number' + }, { + key: 'input', + name: Strings.positionInput, + valueType: 'string' + }, { + key: 'output', + name: Strings.positionOutput, + valueType: 'string' + }, { + key: 'power', + name: Strings.positionPower, + valueType: 'number', + dataType: 'voltage' + }, { + key: 'battery', + name: Strings.positionBattery, + valueType: 'number', + dataType: 'voltage' + }, { + key: 'batteryLevel', + name: Strings.positionBatteryLevel, + valueType: 'number', + dataType: 'percentage' + }, { + key: 'fuel', + name: Strings.positionFuel, + valueType: 'number', + dataType: 'volume' + }, { + key: 'fuelConsumption', + name: Strings.positionFuelConsumption, + valueType: 'number', + dataType: 'consumption' + }, { + key: 'versionFw', + name: Strings.positionVersionFw, + valueType: 'string' + }, { + key: 'versionHw', + name: Strings.positionVersionHw, + valueType: 'string' + }, { + key: 'type', + name: Strings.sharedType, + valueType: 'string' + }, { + key: 'ignition', + name: Strings.positionIgnition, + valueType: 'boolean' + }, { + key: 'flags', + name: Strings.positionFlags, + valueType: 'string' + }, { + key: 'charge', + name: Strings.positionCharge, + valueType: 'boolean' + }, { + key: 'ip', + name: Strings.positionIp, + valueType: 'string' + }, { + key: 'archive', + name: Strings.positionArchive, + valueType: 'boolean' + }, { + key: 'distance', + name: Strings.positionDistance, + valueType: 'number', + dataType: 'distance' + }, { + key: 'totalDistance', + name: Strings.deviceTotalDistance, + valueType: 'number', + dataType: 'distance' + }, { + key: 'rpm', + name: Strings.positionRpm, + valueType: 'number' + }, { + key: 'vin', + name: Strings.positionVin, + valueType: 'string' + }, { + key: 'approximate', + name: Strings.positionApproximate, + valueType: 'boolean' + }, { + key: 'throttle', + name: Strings.positionThrottle, + valueType: 'number' + }, { + key: 'motion', + name: Strings.positionMotion, + valueType: 'boolean' + }, { + key: 'armed', + name: Strings.positionArmed, + valueType: 'number' + }, { + key: 'geofence', + name: Strings.sharedGeofence, + valueType: 'string' + }, { + key: 'acceleration', + name: Strings.positionAcceleration, + valueType: 'number' + }, { + key: 'deviceTemp', + name: Strings.positionDeviceTemp, + valueType: 'number', + dataType: 'temperature' + }, { + key: 'operator', + name: Strings.positionOperator, + valueType: 'string' + }, { + key: 'command', + name: Strings.deviceCommand, + valueType: 'string' + }, { + key: 'blocked', + name: Strings.positionBlocked, + valueType: 'boolean' + }, { + key: 'dtcs', + name: Strings.positionDtcs, + valueType: 'string' + }, { + key: 'obdSpeed', + name: Strings.positionObdSpeed, + valueType: 'number', + dataType: 'speed' + }, { + key: 'obdOdometer', + name: Strings.positionObdOdometer, + valueType: 'number', + dataType: 'distance' + }, { + key: 'result', + name: Strings.eventCommandResult, + valueType: 'string' + }, { + key: 'driverUniqueId', + name: Strings.positionDriverUniqueId, + valueType: 'string', + dataType: 'driverUniqueId' + }], + + getAttributeName: function (key, capitalize) { + var model = this.getById(key); + if (model) { + return model.get('name'); + } else if (capitalize) { + return key.replace(/^./, function (match) { + return match.toUpperCase(); + }); + } else { + return key; + } + }, + + getAttributeDataType: function (key) { + var model = this.getById(key); + if (model && model.get('dataType')) { + return model.get('dataType'); + } else { + return null; + } + } +}); diff --git a/legacy/web/app/store/Positions.js b/legacy/web/app/store/Positions.js new file mode 100644 index 00000000..388a3320 --- /dev/null +++ b/legacy/web/app/store/Positions.js @@ -0,0 +1,29 @@ +/* + * Copyright 2015 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.Positions', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Position', + + proxy: { + type: 'rest', + url: 'api/positions', + headers: { + 'Accept': 'application/json' + } + } +}); diff --git a/legacy/web/app/store/ReportChartTypes.js b/legacy/web/app/store/ReportChartTypes.js new file mode 100644 index 00000000..f53d3197 --- /dev/null +++ b/legacy/web/app/store/ReportChartTypes.js @@ -0,0 +1,33 @@ +/* + * 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.ReportChartTypes', { + extend: 'Ext.data.Store', + fields: ['key', 'name'], + + data: [{ + key: 'speed', + name: Strings.positionSpeed + }, { + key: 'accuracy', + name: Strings.positionAccuracy + }, { + key: 'altitude', + name: Strings.positionAltitude + }] +}); diff --git a/legacy/web/app/store/ReportEventTypes.js b/legacy/web/app/store/ReportEventTypes.js new file mode 100644 index 00000000..001f159b --- /dev/null +++ b/legacy/web/app/store/ReportEventTypes.js @@ -0,0 +1,26 @@ +/* + * Copyright 2015 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.ReportEventTypes', { + extend: 'Ext.data.Store', + fields: ['type', 'name'], + + statics: { + allEvents: 'allEvents' + } +}); diff --git a/legacy/web/app/store/ReportEvents.js b/legacy/web/app/store/ReportEvents.js new file mode 100644 index 00000000..061aaa42 --- /dev/null +++ b/legacy/web/app/store/ReportEvents.js @@ -0,0 +1,35 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.ReportEvents', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Event', + + proxy: { + type: 'rest', + url: 'api/reports/events', + timeout: Traccar.Style.reportTimeout, + headers: { + 'Accept': 'application/json' + }, + listeners: { + exception: function (proxy, exception) { + Traccar.app.showError(exception); + } + } + } +}); diff --git a/legacy/web/app/store/ReportPeriods.js b/legacy/web/app/store/ReportPeriods.js new file mode 100644 index 00000000..542fdce9 --- /dev/null +++ b/legacy/web/app/store/ReportPeriods.js @@ -0,0 +1,45 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.store.ReportPeriods', { + extend: 'Ext.data.Store', + fields: ['key', 'name'], + + data: [{ + key: 'custom', + name: Strings.reportCustom + }, { + key: 'today', + name: Strings.reportToday + }, { + key: 'yesterday', + name: Strings.reportYesterday + }, { + key: 'thisWeek', + name: Strings.reportThisWeek + }, { + key: 'previousWeek', + name: Strings.reportPreviousWeek + }, { + key: 'thisMonth', + name: Strings.reportThisMonth + }, { + key: 'previousMonth', + name: Strings.reportPreviousMonth + }] +}); diff --git a/legacy/web/app/store/ReportRoute.js b/legacy/web/app/store/ReportRoute.js new file mode 100644 index 00000000..7babe163 --- /dev/null +++ b/legacy/web/app/store/ReportRoute.js @@ -0,0 +1,35 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.ReportRoute', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Position', + + proxy: { + type: 'rest', + url: 'api/reports/route', + timeout: Traccar.Style.reportTimeout, + headers: { + 'Accept': 'application/json' + }, + listeners: { + exception: function (proxy, exception) { + Traccar.app.showError(exception); + } + } + } +}); diff --git a/legacy/web/app/store/ReportStops.js b/legacy/web/app/store/ReportStops.js new file mode 100644 index 00000000..75c9fc18 --- /dev/null +++ b/legacy/web/app/store/ReportStops.js @@ -0,0 +1,36 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.store.ReportStops', { + extend: 'Ext.data.Store', + model: 'Traccar.model.ReportStop', + + proxy: { + type: 'rest', + url: 'api/reports/stops', + timeout: Traccar.Style.reportTimeout, + headers: { + 'Accept': 'application/json' + }, + listeners: { + exception: function (proxy, exception) { + Traccar.app.showError(exception); + } + } + } +}); diff --git a/legacy/web/app/store/ReportSummary.js b/legacy/web/app/store/ReportSummary.js new file mode 100644 index 00000000..f328da2d --- /dev/null +++ b/legacy/web/app/store/ReportSummary.js @@ -0,0 +1,36 @@ +/* + * 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.ReportSummary', { + extend: 'Ext.data.Store', + model: 'Traccar.model.ReportSummary', + + proxy: { + type: 'rest', + url: 'api/reports/summary', + timeout: Traccar.Style.reportTimeout, + headers: { + 'Accept': 'application/json' + }, + listeners: { + exception: function (proxy, exception) { + Traccar.app.showError(exception); + } + } + } +}); diff --git a/legacy/web/app/store/ReportTrips.js b/legacy/web/app/store/ReportTrips.js new file mode 100644 index 00000000..057cc7c0 --- /dev/null +++ b/legacy/web/app/store/ReportTrips.js @@ -0,0 +1,36 @@ +/* + * 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.ReportTrips', { + extend: 'Ext.data.Store', + model: 'Traccar.model.ReportTrip', + + proxy: { + type: 'rest', + url: 'api/reports/trips', + timeout: Traccar.Style.reportTimeout, + headers: { + 'Accept': 'application/json' + }, + listeners: { + exception: function (proxy, exception) { + Traccar.app.showError(exception); + } + } + } +}); diff --git a/legacy/web/app/store/ReportTypes.js b/legacy/web/app/store/ReportTypes.js new file mode 100644 index 00000000..ceaba9d2 --- /dev/null +++ b/legacy/web/app/store/ReportTypes.js @@ -0,0 +1,44 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.ReportTypes', { + extend: 'Ext.data.Store', + fields: ['key', 'name'], + + data: [{ + key: 'route', + name: Strings.reportRoute + }, { + key: 'events', + name: Strings.reportEvents + }, { + key: 'trips', + name: Strings.reportTrips + }, { + key: 'stops', + name: Strings.reportStops + }, { + key: 'summary', + name: Strings.reportSummary + }, { + key: 'daily', + name: Strings.reportDaily + }, { + key: 'chart', + name: Strings.reportChart + }] +}); diff --git a/legacy/web/app/store/ServerAttributes.js b/legacy/web/app/store/ServerAttributes.js new file mode 100644 index 00000000..204f885b --- /dev/null +++ b/legacy/web/app/store/ServerAttributes.js @@ -0,0 +1,23 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +Ext.define('Traccar.store.ServerAttributes', { + extend: 'Ext.data.Store', + model: 'Traccar.model.KnownAttribute', + + data: [] +}); diff --git a/legacy/web/app/store/SpeedUnits.js b/legacy/web/app/store/SpeedUnits.js new file mode 100644 index 00000000..a36be928 --- /dev/null +++ b/legacy/web/app/store/SpeedUnits.js @@ -0,0 +1,53 @@ +/* + * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.SpeedUnits', { + extend: 'Ext.data.Store', + fields: ['key', 'name', 'factor'], + + data: [{ + key: 'kn', + name: Strings.sharedKn, + factor: 1 + }, { + key: 'kmh', + name: Strings.sharedKmh, + factor: 1.852 + }, { + key: 'mph', + name: Strings.sharedMph, + factor: 1.15078 + }], + + convertValue: function (value, unit, back) { + var model; + if (!unit) { + unit = 'kn'; + } + model = this.findRecord('key', unit); + return back ? value / model.get('factor') : value * model.get('factor'); + }, + + formatValue: function (value, unit, convert) { + var model; + if (!unit) { + unit = 'kn'; + } + model = this.findRecord('key', unit); + return (convert ? this.convertValue(value, unit) : value).toFixed(1) + ' ' + model.get('name'); + } +}); diff --git a/legacy/web/app/store/Statistics.js b/legacy/web/app/store/Statistics.js new file mode 100644 index 00000000..1d44c6e3 --- /dev/null +++ b/legacy/web/app/store/Statistics.js @@ -0,0 +1,26 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.Statistics', { + extend: 'Ext.data.Store', + model: 'Traccar.model.Statistics', + + proxy: { + type: 'rest', + url: 'api/statistics' + } +}); diff --git a/legacy/web/app/store/TimeUnits.js b/legacy/web/app/store/TimeUnits.js new file mode 100644 index 00000000..0d16c4bb --- /dev/null +++ b/legacy/web/app/store/TimeUnits.js @@ -0,0 +1,44 @@ +/* + * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.TimeUnits', { + extend: 'Ext.data.Store', + fields: ['key', 'name', 'factor'], + + data: [{ + key: 's', + name: Strings.sharedSecondAbbreviation, + factor: 1 + }, { + key: 'm', + name: Strings.sharedMinuteAbbreviation, + factor: 60 + }, { + key: 'h', + name: Strings.sharedHourAbbreviation, + factor: 3600 + }], + + convertValue: function (value, unit, back) { + var model; + if (!unit) { + unit = 'kn'; + } + model = this.findRecord('key', unit); + return back ? value * model.get('factor') : value / model.get('factor'); + } +}); diff --git a/legacy/web/app/store/UserAttributes.js b/legacy/web/app/store/UserAttributes.js new file mode 100644 index 00000000..dfe69421 --- /dev/null +++ b/legacy/web/app/store/UserAttributes.js @@ -0,0 +1,70 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +Ext.define('Traccar.store.UserAttributes', { + extend: 'Ext.data.Store', + model: 'Traccar.model.KnownAttribute', + + data: [{ + key: 'mail.smtp.host', + name: Strings.attributeMailSmtpHost, + valueType: 'string' + }, { + key: 'mail.smtp.port', + name: Strings.attributeMailSmtpPort, + valueType: 'number', + allowDecimals: false, + minValue: 1, + maxValue: 65535 + }, { + key: 'mail.smtp.starttls.enable', + name: Strings.attributeMailSmtpStarttlsEnable, + valueType: 'boolean' + }, { + key: 'mail.smtp.starttls.required', + name: Strings.attributeMailSmtpStarttlsRequired, + valueType: 'boolean' + }, { + key: 'mail.smtp.ssl.enable', + name: Strings.attributeMailSmtpSslEnable, + valueType: 'boolean' + }, { + key: 'mail.smtp.ssl.trust', + name: Strings.attributeMailSmtpSslTrust, + valueType: 'string' + }, { + key: 'mail.smtp.ssl.protocols', + name: Strings.attributeMailSmtpSslProtocols, + valueType: 'string' + }, { + key: 'mail.smtp.from', + name: Strings.attributeMailSmtpFrom, + valueType: 'string' + }, { + key: 'mail.smtp.auth', + name: Strings.attributeMailSmtpAuth, + valueType: 'boolean' + }, { + key: 'mail.smtp.username', + name: Strings.attributeMailSmtpUsername, + valueType: 'string' + }, { + key: 'mail.smtp.password', + name: Strings.attributeMailSmtpPassword, + valueType: 'string' + }] +}); diff --git a/legacy/web/app/store/Users.js b/legacy/web/app/store/Users.js new file mode 100644 index 00000000..0279afea --- /dev/null +++ b/legacy/web/app/store/Users.js @@ -0,0 +1,29 @@ +/* + * Copyright 2015 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.Users', { + extend: 'Ext.data.Store', + model: 'Traccar.model.User', + + proxy: { + type: 'rest', + url: 'api/users', + writer: { + writeAllFields: true + } + } +}); diff --git a/legacy/web/app/store/VisibleDevices.js b/legacy/web/app/store/VisibleDevices.js new file mode 100644 index 00000000..db1ca7da --- /dev/null +++ b/legacy/web/app/store/VisibleDevices.js @@ -0,0 +1,22 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.store.VisibleDevices', { + extend: 'Ext.data.ChainedStore', + source: 'Devices' +}); diff --git a/legacy/web/app/store/VolumeUnits.js b/legacy/web/app/store/VolumeUnits.js new file mode 100644 index 00000000..2bdf6684 --- /dev/null +++ b/legacy/web/app/store/VolumeUnits.js @@ -0,0 +1,57 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.store.VolumeUnits', { + extend: 'Ext.data.Store', + fields: ['key', 'name', 'fullName', 'factor'], + + data: [{ + key: 'ltr', + name: Strings.sharedLiterAbbreviation, + fullName: Strings.sharedLiter, + factor: 1 + }, { + key: 'impGal', + name: Strings.sharedGallonAbbreviation, + fullName: Strings.sharedImpGallon, + factor: 4.546 + }, { + key: 'usGal', + name: Strings.sharedGallonAbbreviation, + fullName: Strings.sharedUsGallon, + factor: 3.785 + }], + + convertValue: function (value, unit, back) { + var model; + if (!unit) { + unit = 'ltr'; + } + model = this.findRecord('key', unit); + return back ? value * model.get('factor') : value / model.get('factor'); + }, + + formatValue: function (value, unit, convert) { + var model; + if (!unit) { + unit = 'ltr'; + } + model = this.findRecord('key', unit); + return (convert ? this.convertValue(value, unit) : value).toFixed(1) + ' ' + model.get('name'); + } +}); diff --git a/legacy/web/app/view/ArrayListFilter.js b/legacy/web/app/view/ArrayListFilter.js new file mode 100644 index 00000000..519096eb --- /dev/null +++ b/legacy/web/app/view/ArrayListFilter.js @@ -0,0 +1,50 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.ArrayListFilter', { + extend: 'Ext.grid.filters.filter.List', + alias: 'grid.filter.arraylist', + + type: 'arraylist', + + constructor: function (config) { + this.callParent([config]); + this.filter.setFilterFn(function (item) { + var i, property, value, splits; + property = item.get(this.getProperty()); + value = this.getValue(); + if (Ext.isArray(property)) { + for (i = 0; i < property.length; i++) { + if (value.indexOf(property[i]) !== -1) { + return true; + } + } + } else if (property.match(/[ ,]+/)) { + splits = property.split(/[ ,]+/).filter(Boolean); + for (i = 0; i < splits.length; i++) { + if (value.indexOf(splits[i]) !== -1) { + return true; + } + } + } else if (value.indexOf(property) !== -1) { + return true; + } + return false; + }); + } +}); diff --git a/legacy/web/app/view/BaseWindow.js b/legacy/web/app/view/BaseWindow.js new file mode 100644 index 00000000..bf698e08 --- /dev/null +++ b/legacy/web/app/view/BaseWindow.js @@ -0,0 +1,32 @@ +/* + * Copyright 2015 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.BaseWindow', { + extend: 'Ext.window.Window', + + width: Traccar.Style.windowWidth, + height: Traccar.Style.windowHeight, + layout: 'fit', + + initComponent: function () { + if (window.innerWidth < Traccar.Style.windowWidth || window.innerHeight < Traccar.Style.windowHeight) { + this.maximized = true; + this.style = 'border-width: 0'; + } + this.callParent(); + } +}); diff --git a/legacy/web/app/view/ClearableComboBox.js b/legacy/web/app/view/ClearableComboBox.js new file mode 100644 index 00000000..cf811d1d --- /dev/null +++ b/legacy/web/app/view/ClearableComboBox.js @@ -0,0 +1,31 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +Ext.define('Traccar.view.ClearableComboBox', { + extend: 'Ext.form.field.ComboBox', + xtype: 'clearableComboBox', + + editable: false, + triggers: { + clear: { + cls: 'iconCls: x-fa fa-times', + handler: function (button) { + button.clearValue(); + } + } + } +}); diff --git a/legacy/web/app/view/ColorPicker.js b/legacy/web/app/view/ColorPicker.js new file mode 100644 index 00000000..5de03aa3 --- /dev/null +++ b/legacy/web/app/view/ColorPicker.js @@ -0,0 +1,43 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +Ext.define('Traccar.view.ColorPicker', { + extend: 'Ext.form.field.Picker', + xtype: 'customcolorpicker', + + config: { + value: '#008000' + }, + + editable: false, + + createPicker: function () { + return Ext.create('Ext.picker.Color', { + floating: true, + picker: this, + select: function (selColor) { + this.picker.setValue('#' + selColor); + this.picker.collapse(); + } + }); + }, + + setValue: function (color) { + this.callParent([color]); + this.setFieldStyle('background-color:' + color); + } +}); diff --git a/legacy/web/app/view/CustomNumberField.js b/legacy/web/app/view/CustomNumberField.js new file mode 100644 index 00000000..8cfac1ee --- /dev/null +++ b/legacy/web/app/view/CustomNumberField.js @@ -0,0 +1,109 @@ +/* + * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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.CustomNumberField', { + extend: 'Ext.form.field.Number', + xtype: 'customNumberField', + + beforeEl: '<div style="width:100%;display:inline-table;">', + unitEl: '<div id="numberUnitEl" style="display:table-cell;padding-left:10px;vertical-align:middle;width:1px;white-space:nowrap;">', + + constructor: function (config) { + var unitName = ''; + if (config.dataType) { + config.beforeBodyEl = this.beforeEl; + switch (config.dataType) { + case 'speed': + config.units = {}; + config.units.getStore = function () { + return Ext.getStore('SpeedUnits'); + }; + config.units.getValue = function () { + return Traccar.app.getAttributePreference('speedUnit', 'kn'); + }; + unitName = Ext.getStore('SpeedUnits').findRecord('key', config.units.getValue()).get('name'); + break; + case 'distance': + config.units = {}; + config.units.getStore = function () { + return Ext.getStore('DistanceUnits'); + }; + config.units.getValue = function () { + return Traccar.app.getAttributePreference('distanceUnit', 'km'); + }; + unitName = Ext.getStore('DistanceUnits').findRecord('key', config.units.getValue()).get('name'); + break; + case 'frequency': + if (!config.listeners) { + config.listeners = {}; + } + config.listeners.afterrender = function () { + if (!this.units) { + this.units = Ext.create({ + xtype: 'combobox', + renderTo: 'numberUnitEl', + store: 'TimeUnits', + displayField: 'name', + valueField: 'key', + editable: false, + numberField: this, + value: 's', + width: '70px', + listeners: { + select: function () { + this.numberField.step = this.getStore().convertValue(1, this.getValue(), true); + } + } + }); + } + }; + break; + case 'hours': + config.units = {}; + config.units.getStore = function () { + return Ext.getStore('HoursUnits'); + }; + config.units.getValue = function () { + return 'h'; + }; + unitName = Strings.sharedHourAbbreviation; + break; + default: + break; + } + config.afterBodyEl = this.unitEl + unitName + '</div></div>'; + config.rawToValue = function (rawValue) { + if (this.units) { + return this.units.getStore().convertValue(this.parseValue(rawValue), this.units.getValue(), true); + } else { + return this.parseValue(rawValue); + } + }; + config.valueToRaw = function (value) { + if (this.units) { + return String(this.units.getStore().convertValue(value, this.units.getValue(), false)); + } else { + return String(value); + } + }; + if (config.units) { + config.step = config.units.getStore().convertValue(1, config.units.getValue(), true); + } + } + this.callParent(arguments); + } +}); diff --git a/legacy/web/app/view/CustomTimeField.js b/legacy/web/app/view/CustomTimeField.js new file mode 100644 index 00000000..c2b44ce1 --- /dev/null +++ b/legacy/web/app/view/CustomTimeField.js @@ -0,0 +1,30 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.CustomTimeField', { + extend: 'Ext.form.field.Time', + xtype: 'customTimeField', + + constructor: function (config) { + if (Traccar.app.getPreference('twelveHourFormat', false)) { + config.format = Traccar.Style.timeFormat12; + } else { + config.format = Traccar.Style.timeFormat24; + } + this.callParent(arguments); + } +}); diff --git a/legacy/web/app/view/DeviceMenu.js b/legacy/web/app/view/DeviceMenu.js new file mode 100644 index 00000000..06b272ad --- /dev/null +++ b/legacy/web/app/view/DeviceMenu.js @@ -0,0 +1,72 @@ +/* + * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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.DeviceMenu', { + extend: 'Ext.button.Button', + xtype: 'deviceMenu', + + requires: [ + 'Traccar.view.DeviceMenuController' + ], + + glyph: 'xf013@FontAwesome', + tooltip: Strings.settingsTitle, + tooltipType: 'title', + + menu: { + controller: 'deviceMenu', + + items: [{ + text: Strings.sharedDrivers, + glyph: 'xf084@FontAwesome', + handler: 'onDriversClick', + reference: 'menuDriversButton' + }, { + text: Strings.sharedGeofences, + glyph: 'xf21d@FontAwesome', + handler: 'onGeofencesClick', + reference: 'menuGeofencesButton' + }, { + text: Strings.sharedNotifications, + glyph: 'xf003@FontAwesome', + handler: 'onNotificationsClick', + reference: 'menuNotificationsButton' + }, { + text: Strings.sharedComputedAttributes, + glyph: 'xf0ae@FontAwesome', + handler: 'onComputedAttributesClick', + reference: 'menuComputedAttributesButton' + }, { + text: Strings.sharedSavedCommands, + glyph: 'xf093@FontAwesome', + handler: 'onCommandsClick', + reference: 'menuCommandsButton' + }, { + text: Strings.sharedMaintenance, + glyph: 'xf0ad@FontAwesome', + handler: 'onMaintenancesClick', + reference: 'menuMaintenancesButton' + }, { + hidden: true, + text: Strings.sharedDeviceAccumulators, + glyph: 'xf0e4@FontAwesome', + handler: 'onDeviceAccumulatorsClick', + reference: 'menuDeviceAccumulatorsButton' + }] + } +}); diff --git a/legacy/web/app/view/DeviceMenuController.js b/legacy/web/app/view/DeviceMenuController.js new file mode 100644 index 00000000..830ea7ec --- /dev/null +++ b/legacy/web/app/view/DeviceMenuController.js @@ -0,0 +1,134 @@ +/* + * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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.DeviceMenuController', { + extend: 'Ext.app.ViewController', + alias: 'controller.deviceMenu', + + requires: [ + 'Traccar.view.permissions.Geofences', + 'Traccar.view.permissions.Drivers', + 'Traccar.view.permissions.Notifications', + 'Traccar.view.edit.ComputedAttributes', + 'Traccar.view.permissions.SavedCommands', + 'Traccar.view.permissions.Maintenances', + 'Traccar.view.dialog.DeviceAccumulators', + 'Traccar.view.BaseWindow' + ], + + init: function () { + this.lookupReference('menuDriversButton').setHidden( + Traccar.app.getVehicleFeaturesDisabled() || Traccar.app.getBooleanAttributePreference('ui.disableDrivers')); + this.lookupReference('menuComputedAttributesButton').setHidden( + Traccar.app.getBooleanAttributePreference('ui.disableComputedAttributes')); + this.lookupReference('menuCommandsButton').setHidden(Traccar.app.getPreference('limitCommands', false)); + this.lookupReference('menuDeviceAccumulatorsButton').setHidden( + !Traccar.app.getUser().get('administrator') && Traccar.app.getUser().get('userLimit') === 0 || Traccar.app.getVehicleFeaturesDisabled()); + this.lookupReference('menuMaintenancesButton').setHidden( + Traccar.app.getVehicleFeaturesDisabled() || Traccar.app.getBooleanAttributePreference('ui.disableMaintenance')); + }, + + onGeofencesClick: function () { + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedGeofences, + items: { + xtype: 'linkGeofencesView', + baseObjectName: 'deviceId', + linkObjectName: 'geofenceId', + storeName: 'Geofences', + baseObject: this.getView().up('deviceMenu').device.getId() + } + }).show(); + }, + + onNotificationsClick: function () { + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedNotifications, + items: { + xtype: 'linkNotificationsView', + baseObjectName: 'deviceId', + linkObjectName: 'notificationId', + storeName: 'Notifications', + baseObject: this.getView().up('deviceMenu').device.getId() + } + }).show(); + }, + + onComputedAttributesClick: function () { + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedComputedAttributes, + items: { + xtype: 'linkComputedAttributesView', + baseObjectName: 'deviceId', + linkObjectName: 'attributeId', + storeName: 'ComputedAttributes', + baseObject: this.getView().up('deviceMenu').device.getId() + } + }).show(); + }, + + onDriversClick: function () { + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedDrivers, + items: { + xtype: 'linkDriversView', + baseObjectName: 'deviceId', + linkObjectName: 'driverId', + storeName: 'Drivers', + baseObject: this.getView().up('deviceMenu').device.getId() + } + }).show(); + }, + + onCommandsClick: function () { + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedSavedCommands, + items: { + xtype: 'linkSavedCommandsView', + baseObjectName: 'deviceId', + linkObjectName: 'commandId', + storeName: 'Commands', + baseObject: this.getView().up('deviceMenu').device.getId() + } + }).show(); + }, + + onMaintenancesClick: function () { + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedMaintenance, + items: { + xtype: 'linkMaintenancesView', + baseObjectName: 'deviceId', + linkObjectName: 'maintenanceId', + storeName: 'Maintenances', + baseObject: this.getView().up('deviceMenu').device.getId() + } + }).show(); + }, + + onDeviceAccumulatorsClick: function () { + var position, dialog = Ext.create('Traccar.view.dialog.DeviceAccumulators'); + dialog.deviceId = this.getView().up('deviceMenu').device.getId(); + position = Ext.getStore('LatestPositions').findRecord('deviceId', dialog.deviceId, 0, false, false, true); + if (position) { + dialog.lookupReference('totalDistance').setValue(position.get('attributes').totalDistance); + dialog.lookupReference('hours').setValue(position.get('attributes').hours); + } + dialog.show(); + } +}); diff --git a/legacy/web/app/view/Events.js b/legacy/web/app/view/Events.js new file mode 100644 index 00000000..439de5af --- /dev/null +++ b/legacy/web/app/view/Events.js @@ -0,0 +1,117 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.Events', { + extend: 'Traccar.view.GridPanel', + xtype: 'eventsView', + + requires: [ + 'Traccar.view.EventsController' + ], + + controller: 'events', + + store: 'Events', + + stateful: true, + stateId: 'events-grid', + + title: Strings.reportEvents, + + sortableColumns: false, + + header: false, + + tbar: { + componentCls: 'toolbar-header-style', + defaults: { + xtype: 'button', + tooltipType: 'title', + stateEvents: ['toggle'], + enableToggle: true, + stateful: { + pressed: true + } + }, + items: [{ + xtype: 'tbtext', + html: Strings.reportEvents, + baseCls: 'x-panel-header-title-default' + }, { + xtype: 'tbfill' + }, { + glyph: 'xf063@FontAwesome', + pressed: true, + toggleHandler: 'onScrollToLastClick', + stateId: 'events-scroll-to-last-button', + tooltip: Strings.eventsScrollToLast, + reference: 'scrollToLastButton' + }, { + id: 'soundButton', + glyph: 'xf0a2@FontAwesome', + tooltip: Strings.sharedSound, + stateId: 'sound-button' + }, { + glyph: 'xf014@FontAwesome', + tooltip: Strings.sharedRemove, + handler: 'onRemoveClick', + reference: 'removeEventButton', + disabled: true, + stateful: false, + enableToggle: false + }, { + glyph: 'xf1f8@FontAwesome', + tooltip: Strings.reportClear, + handler: 'onClearClick', + stateful: false, + enableToggle: false + }, { + glyph: 'xf00d@FontAwesome', + tooltip: Strings.sharedHide, + handler: 'onHideEvents', + reference: 'hideEventsButton', + hidden: true, + stateful: false, + enableToggle: false + }] + }, + + listeners: { + selectionchange: 'onSelectionChange' + }, + + columns: { + defaults: { + flex: 1, + minWidth: Traccar.Style.columnWidthNormal + }, + items: [{ + text: Strings.sharedDevice, + dataIndex: 'deviceId', + renderer: Traccar.AttributeFormatter.getFormatter('deviceId') + }, { + flex: 2, + text: Strings.positionEvent, + dataIndex: 'text' + }, { + text: Strings.positionFixTime, + dataIndex: 'eventTime', + renderer: Traccar.AttributeFormatter.getFormatter('eventTime') + }] + } +}); diff --git a/legacy/web/app/view/EventsController.js b/legacy/web/app/view/EventsController.js new file mode 100644 index 00000000..e11b4ff6 --- /dev/null +++ b/legacy/web/app/view/EventsController.js @@ -0,0 +1,126 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.EventsController', { + extend: 'Ext.app.ViewController', + alias: 'controller.events', + + config: { + listen: { + controller: { + '*': { + selectdevice: 'deselectEvent', + selectreport: 'deselectEvent' + }, + 'map': { + deselectfeature: 'deselectFeature' + } + }, + store: { + '#Events': { + add: 'onAddEvent' + } + } + } + }, + + init: function () { + var self = this; + setInterval(function () { + self.getView().getView().refresh(); + }, Traccar.Style.refreshPeriod); + + if (Traccar.app.isMobile()) { + this.lookupReference('hideEventsButton').setHidden(false); + } + }, + + onRemoveClick: function () { + var event, positionId; + event = this.getView().getSelectionModel().getSelection()[0]; + if (event) { + Ext.getStore('Events').remove(event); + positionId = event.get('positionId'); + if (positionId && !Ext.getStore('Events').findRecord('positionId', positionId, 0, false, false, true)) { + Ext.getStore('EventPositions').remove(Ext.getStore('EventPositions').getById(positionId)); + } + } + }, + + onClearClick: function () { + Ext.getStore('Events').removeAll(); + Ext.getStore('EventPositions').removeAll(); + }, + + onAddEvent: function () { + if (this.lookupReference('scrollToLastButton').pressed) { + this.getView().scrollBy(0, Number.POSITIVE_INFINITY, true); + } + }, + + onScrollToLastClick: function (button, pressed) { + if (pressed) { + this.onAddEvent(); + } + }, + + onHideEvents: function () { + Traccar.app.showEvents(false); + }, + + + deselectEvent: function (object) { + if (object) { + this.deselectFeature(); + } + }, + + deselectFeature: function () { + this.getView().getSelectionModel().deselectAll(); + }, + + onSelectionChange: function (selection, selected) { + var event, positionId, position; + event = selected.length > 0 ? selected[0] : null; + if (event) { + positionId = event.get('positionId'); + if (positionId) { + position = Ext.getStore('EventPositions').getById(positionId); + if (position) { + this.fireEvent('selectevent', position); + } else { + Ext.getStore('EventPositions').load({ + params: { + id: positionId + }, + scope: this, + addRecords: true, + callback: function (records, operation, success) { + if (success && records.length > 0) { + this.fireEvent('selectevent', records[0]); + } + } + }); + } + } else { + this.fireEvent('selectevent'); + } + } + this.lookupReference('removeEventButton').setDisabled(!event); + } +}); diff --git a/legacy/web/app/view/GridPanel.js b/legacy/web/app/view/GridPanel.js new file mode 100644 index 00000000..848af081 --- /dev/null +++ b/legacy/web/app/view/GridPanel.js @@ -0,0 +1,34 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +Ext.define('Traccar.view.GridPanel', { + extend: 'Ext.grid.Panel', + xtype: 'customGridPanel', + + requires: [ + 'Ext.grid.filters.Filters' + ], + + plugins: 'gridfilters', + + viewConfig: { + enableTextSelection: true, + getRowClass: function () { + return this.enableTextSelection ? 'x-selectable' : ''; + } + } +}); diff --git a/legacy/web/app/view/Main.js b/legacy/web/app/view/Main.js new file mode 100644 index 00000000..0504245e --- /dev/null +++ b/legacy/web/app/view/Main.js @@ -0,0 +1,84 @@ +/* + * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.Main', { + extend: 'Ext.container.Viewport', + alias: 'widget.main', + + requires: [ + 'Traccar.view.MainController', + 'Traccar.view.edit.Devices', + 'Traccar.view.State', + 'Traccar.view.Report', + 'Traccar.view.Events', + 'Traccar.view.map.Map' + ], + + controller: 'mainController', + + layout: 'border', + + defaults: { + header: false, + collapsible: true, + split: true + }, + + items: [{ + region: 'west', + layout: 'border', + width: Traccar.Style.deviceWidth, + title: Strings.devicesAndState, + titleCollapse: true, + floatable: false, + stateful: true, + stateId: 'devices-and-state-panel', + + defaults: { + split: true, + flex: 1 + }, + + items: [{ + region: 'center', + xtype: 'devicesView' + }, { + region: 'south', + xtype: 'stateView' + }] + }, { + region: 'south', + xtype: 'reportView', + reference: 'reportView', + height: Traccar.Style.reportHeight, + collapsed: true, + titleCollapse: true, + floatable: false + }, { + region: 'center', + xtype: 'mapView', + collapsible: false + }, { + region: 'east', + xtype: 'eventsView', + reference: 'eventsView', + width: Traccar.Style.deviceWidth, + collapsed: true, + titleCollapse: true, + floatable: false + }] +}); diff --git a/legacy/web/app/view/MainController.js b/legacy/web/app/view/MainController.js new file mode 100644 index 00000000..8ed986af --- /dev/null +++ b/legacy/web/app/view/MainController.js @@ -0,0 +1,26 @@ +/* + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +Ext.define('Traccar.view.MainController', { + extend: 'Ext.app.ViewController', + alias: 'controller.mainController', + + init: function () { + this.lookupReference('reportView').setHidden(Traccar.app.getPreference('disableReports', false)); + this.lookupReference('eventsView').setHidden(Traccar.app.getBooleanAttributePreference('ui.disableEvents')); + } +}); diff --git a/legacy/web/app/view/MainMobile.js b/legacy/web/app/view/MainMobile.js new file mode 100644 index 00000000..8aab7710 --- /dev/null +++ b/legacy/web/app/view/MainMobile.js @@ -0,0 +1,73 @@ +/* + * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.MainMobile', { + extend: 'Ext.container.Viewport', + alias: 'widget.mainMobile', + + id: 'rootPanel', + + requires: [ + 'Traccar.view.edit.Devices', + 'Traccar.view.State', + 'Traccar.view.Report', + 'Traccar.view.Events', + 'Traccar.view.map.Map' + ], + + layout: 'card', + + items: [{ + layout: 'border', + + defaults: { + header: false, + collapsible: true, + split: true + }, + + items: [{ + region: 'east', + xtype: 'stateView', + title: Strings.stateTitle, + flex: 4, + collapsed: true, + collapseMode: 'mini', + titleCollapse: true, + floatable: false, + stateId: 'mobile-state-grid' + }, { + region: 'center', + xtype: 'mapView', + collapsible: false, + flex: 2 + }, { + region: 'south', + xtype: 'devicesView', + title: Strings.deviceTitle, + flex: 1, + collapsed: true, + titleCollapse: true, + floatable: false, + stateId: 'mobile-devices-grid' + }] + }, { + xtype: 'reportView' + }, { + xtype: 'eventsView' + }] +}); diff --git a/legacy/web/app/view/Report.js b/legacy/web/app/view/Report.js new file mode 100644 index 00000000..deedb747 --- /dev/null +++ b/legacy/web/app/view/Report.js @@ -0,0 +1,115 @@ +/* + * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.Report', { + extend: 'Ext.panel.Panel', + xtype: 'reportView', + + requires: [ + 'Traccar.view.ReportController', + 'Traccar.view.GridPanel' + ], + + controller: 'report', + + title: Strings.reportTitle, + + tools: [{ + type: 'close', + tooltip: Strings.sharedHide, + handler: 'hideReports' + }], + + tbar: { + scrollable: true, + items: [{ + xtype: 'tbtext', + html: Strings.sharedType + }, { + xtype: 'combobox', + reference: 'reportTypeField', + store: 'ReportTypes', + displayField: 'name', + valueField: 'key', + editable: false, + listeners: { + change: 'onTypeChange' + } + }, '-', { + text: Strings.reportConfigure, + handler: 'onConfigureClick' + }, '-', { + text: Strings.reportShow, + reference: 'showButton', + disabled: true, + handler: 'onReportClick' + }, { + text: Strings.reportExport, + reference: 'exportButton', + disabled: true, + handler: 'onReportClick' + }, { + text: Strings.reportEmail, + reference: 'emailButton', + disabled: true, + handler: 'onReportClick' + }, { + text: Strings.reportClear, + handler: 'onClearClick' + }] + }, + + layout: 'card', + + items: [{ + xtype: 'customGridPanel', + itemId: 'grid', + listeners: { + selectionchange: 'onSelectionChange' + }, + columns: { + defaults: { + flex: 1, + minWidth: Traccar.Style.columnWidthNormal + }, + items: [ + ] + }, + style: Traccar.Style.reportGridStyle + }, { + xtype: 'cartesian', + itemId: 'chart', + plugins: { + ptype: 'chartitemevents', + moveEvents: true + }, + store: 'ReportRoute', + axes: [{ + title: Strings.reportChart, + type: 'numeric', + position: 'left' + }, { + type: 'time', + position: 'bottom', + fields: ['fixTime'] + }], + listeners: { + itemclick: 'onChartMarkerClick' + }, + insetPadding: Traccar.Style.chartPadding + }] +}); diff --git a/legacy/web/app/view/ReportController.js b/legacy/web/app/view/ReportController.js new file mode 100644 index 00000000..8f63bd31 --- /dev/null +++ b/legacy/web/app/view/ReportController.js @@ -0,0 +1,678 @@ +/* + * 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.ReportController', { + extend: 'Ext.app.ViewController', + alias: 'controller.report', + + requires: [ + 'Traccar.AttributeFormatter', + 'Traccar.model.Position', + 'Traccar.model.ReportTrip', + 'Traccar.view.dialog.ReportConfig', + 'Traccar.store.ReportEventTypes' + ], + + config: { + listen: { + controller: { + '*': { + selectdevice: 'deselectReport', + selectevent: 'deselectReport', + showsingleevent: 'showSingleEvent' + }, + 'map': { + selectreport: 'selectReport', + deselectfeature: 'deselectFeature' + } + }, + global: { + routegeocode: 'onGeocode' + }, + store: { + '#ReportEvents': { + add: 'loadRelatedPositions', + load: 'loadRelatedPositions' + }, + '#ReportRoute': { + load: 'loadRoute' + }, + '#ReportStops': { + load: 'loadRelatedPositions' + } + } + } + }, + + hideReports: function () { + Traccar.app.showReports(false); + }, + + getGrid: function () { + return this.getView().getComponent('grid'); + }, + + getChart: function () { + return this.getView().getComponent('chart'); + }, + + init: function () { + var i, data, attribute; + data = Ext.getStore('PositionAttributes').getData().items; + for (i = 0; i < data.length; i++) { + attribute = data[i]; + this.routeColumns.push({ + text: attribute.get('name'), + dataIndex: 'attribute.' + attribute.get('key'), + renderer: Traccar.AttributeFormatter.getAttributeFormatter(attribute.get('key')), + hidden: true + }); + } + if (Traccar.app.getVehicleFeaturesDisabled()) { + for (i = 0; i < this.summaryColumns.length; i++) { + if (this.summaryColumns[i].dataIndex.match('engineHours|spentFuel')) { + this.summaryColumns[i].hidden = true; + } + } + for (i = 0; i < this.tripsColumns.length; i++) { + if (this.tripsColumns[i].dataIndex.match('spentFuel|driverUniqueId')) { + this.tripsColumns[i].hidden = true; + } + } + for (i = 0; i < this.stopsColumns.length; i++) { + if (this.stopsColumns[i].dataIndex.match('engineHours|spentFuel')) { + this.stopsColumns[i].hidden = true; + } + } + } + }, + + onConfigureClick: function () { + var dialog = Ext.create('Traccar.view.dialog.ReportConfig'); + dialog.lookupReference('eventTypeField').setHidden(this.lookupReference('reportTypeField').getValue() !== 'events'); + dialog.lookupReference('chartTypeField').setHidden(this.lookupReference('reportTypeField').getValue() !== 'chart'); + dialog.callingPanel = this; + dialog.lookupReference('deviceField').setValue(this.deviceId); + dialog.lookupReference('groupField').setValue(this.groupId); + if (this.eventType !== undefined) { + dialog.lookupReference('eventTypeField').setValue(this.eventType); + } else { + dialog.lookupReference('eventTypeField').setValue([Traccar.store.ReportEventTypes.allEvents]); + } + if (this.chartType !== undefined) { + dialog.lookupReference('chartTypeField').setValue(this.chartType); + } + if (this.showMarkers !== undefined) { + dialog.lookupReference('showMarkersField').setValue(this.showMarkers); + } + if (this.fromDate !== undefined) { + dialog.lookupReference('fromDateField').setValue(this.fromDate); + } + if (this.fromTime !== undefined) { + dialog.lookupReference('fromTimeField').setValue(this.fromTime); + } + if (this.toDate !== undefined) { + dialog.lookupReference('toDateField').setValue(this.toDate); + } + if (this.toTime !== undefined) { + dialog.lookupReference('toTimeField').setValue(this.toTime); + } + if (this.period !== undefined) { + dialog.lookupReference('periodField').setValue(this.period); + } + dialog.show(); + }, + + updateButtons: function () { + var reportType, disabled, devices, time; + reportType = this.lookupReference('reportTypeField').getValue(); + devices = this.deviceId && this.deviceId.length !== 0 || this.groupId && this.groupId.length !== 0; + time = this.fromDate && this.fromTime && this.toDate && this.toTime; + disabled = !reportType || !devices || !time || this.reportProgress; + this.lookupReference('showButton').setDisabled(disabled); + this.lookupReference('exportButton').setDisabled(reportType === 'chart' || disabled); + this.lookupReference('emailButton').setDisabled(reportType === 'chart' || disabled); + }, + + onReportClick: function (button) { + var reportType, from, to, store, url, daily; + + this.getGrid().getSelectionModel().deselectAll(); + + reportType = this.lookupReference('reportTypeField').getValue(); + if (reportType && (this.deviceId || this.groupId)) { + from = new Date( + this.fromDate.getFullYear(), this.fromDate.getMonth(), this.fromDate.getDate(), + this.fromTime.getHours(), this.fromTime.getMinutes(), this.fromTime.getSeconds(), this.fromTime.getMilliseconds()); + + to = new Date( + this.toDate.getFullYear(), this.toDate.getMonth(), this.toDate.getDate(), + this.toTime.getHours(), this.toTime.getMinutes(), this.toTime.getSeconds(), this.toTime.getMilliseconds()); + + daily = reportType === 'daily'; + + this.reportProgress = true; + this.updateButtons(); + + if (button.reference === 'showButton') { + if (reportType === 'chart') { + store = this.getChart().getStore(); + this.getChart().setSeries([]); + } else { + store = this.getGrid().getStore(); + } + store.showMarkers = this.showMarkers; + store.load({ + scope: this, + callback: function () { + this.reportProgress = false; + this.updateButtons(); + }, + params: { + deviceId: this.deviceId, + groupId: this.groupId, + type: this.eventType, + from: from.toISOString(), + to: to.toISOString(), + daily: daily + } + }); + } else { + url = this.getGrid().getStore().getProxy().url; + this.excelReport(url, { + deviceId: this.deviceId, + groupId: this.groupId, + type: this.eventType, + from: Ext.Date.format(from, 'c'), + to: Ext.Date.format(to, 'c'), + daily: daily, + mail: button.reference === 'emailButton' + }); + } + } + }, + + onClearClick: function () { + var reportType = this.lookupReference('reportTypeField').getValue(); + this.clearReport(reportType); + }, + + clearReport: function (reportType) { + this.getGrid().getStore().removeAll(); + if (reportType === 'trips' || reportType === 'events' || reportType === 'stops') { + Ext.getStore('ReportRoute').removeAll(); + } + if (reportType === 'chart') { + this.getChart().getStore().removeAll(); + } + }, + + onSelectionChange: function (selection, selected) { + var report; + if (selected.length > 0) { + report = selected[0]; + this.fireEvent('selectreport', report, true); + if (report instanceof Traccar.model.ReportTrip) { + this.selectTrip(report); + } + if (report instanceof Traccar.model.Event || report instanceof Traccar.model.ReportStop) { + this.selectPositionRelated(report); + } + } + }, + + selectReport: function (object) { + var positionRelated, reportType = this.lookupReference('reportTypeField').getValue(); + if (object instanceof Traccar.model.Position) { + if (reportType === 'route') { + this.getGrid().getSelectionModel().select([object], false, true); + this.getGrid().getView().focusRow(object); + } else if (reportType === 'events' || reportType === 'stops') { + positionRelated = this.getGrid().getStore().findRecord('positionId', object.get('id'), 0, false, true, true); + this.getGrid().getSelectionModel().select([positionRelated], false, true); + this.getGrid().getView().focusRow(positionRelated); + } + } + }, + + deselectReport: function (object) { + if (object) { + this.deselectFeature(); + } + }, + + deselectFeature: function () { + if (this.lookupReference('reportTypeField').getValue() !== 'trips') { + this.getGrid().getSelectionModel().deselectAll(); + } + }, + + selectTrip: function (trip) { + var from, to; + from = new Date(trip.get('startTime')); + to = new Date(trip.get('endTime')); + Ext.getStore('ReportRoute').removeAll(); + Ext.getStore('ReportRoute').showMarkers = this.showMarkers; + Ext.getStore('ReportRoute').load({ + params: { + deviceId: trip.get('deviceId'), + from: from.toISOString(), + to: to.toISOString() + } + }); + }, + + selectPositionRelated: function (report) { + var position; + if (report.get('positionId')) { + position = Ext.getStore('ReportRoute').getById(report.get('positionId')); + if (position) { + this.fireEvent('selectreport', position, true); + } + } + }, + + loadRelatedPositions: function (store, data) { + var i, reportObject, positionIds = []; + Ext.getStore('ReportRoute').removeAll(); + if (data) { + for (i = 0; i < data.length; i++) { + reportObject = data[i]; + if (reportObject.get('positionId')) { + positionIds.push(reportObject.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').showMarkers = this.showMarkers; + Ext.getStore('ReportRoute').add(records); + if (records.length === 1) { + this.fireEvent('selectreport', records[0], false); + } + } + } + }); + } + }, + + loadRoute: function (store) { + var i, deviceIds, chartSeries, deviceStore; + if (this.lookupReference('reportTypeField').getValue() === 'chart') { + this.getChart().getAxes()[0].setTitle( + Ext.getStore('ReportChartTypes').findRecord('key', this.chartType).get('name')); + chartSeries = []; + deviceIds = store.collect('deviceId'); + for (i = 0; i < deviceIds.length; i++) { + deviceStore = Ext.create('Ext.data.ChainedStore', { + source: 'ReportRoute', + filters: [{ + property: 'deviceId', + value: deviceIds[i] + }] + }); + chartSeries.push({ + type: 'line', + store: deviceStore, + yField: this.chartType, + xField: 'fixTime', + highlightCfg: { + scaling: Traccar.Style.chartMarkerHighlightScaling + }, + colors: [Traccar.app.getReportColor(deviceIds[i])], + marker: { + type: 'circle', + radius: Traccar.Style.chartMarkerRadius, + fill: Traccar.app.getReportColor(deviceIds[i]) + } + }); + } + this.getChart().setSeries(chartSeries); + } + }, + + onChartMarkerClick: function (chart, item) { + this.fireEvent('selectreport', item.record, true); + }, + + 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.getGrid().getSelectionModel().select([records[0]], false, true); + this.getGrid().getView().focusRow(records[0]); + } + } + } + }); + }, + + excelReport: function (requestUrl, requestParams) { + Ext.Ajax.request({ + url: requestUrl, + method: 'GET', + timeout: Traccar.Style.reportTimeout, + params: requestParams, + headers: { + Accept: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' + }, + binary: true, + scope: this, + callback: function (options, success, response) { + var disposition, filename, type, blob, url, downloadUrl; + if (success && !requestParams.mail) { + disposition = response.getResponseHeader('Content-Disposition'); + filename = disposition.slice(disposition.indexOf('=') + 1, disposition.length); + type = response.getResponseHeader('Content-Type'); + blob = new Blob([response.responseBytes], {type: type}); + if (typeof window.navigator.msSaveBlob !== 'undefined') { + // IE workaround + window.navigator.msSaveBlob(blob, filename); + } else { + url = window.URL || window.webkitURL; + downloadUrl = url.createObjectURL(blob); + if (filename) { + Ext.dom.Helper.append(Ext.getBody(), { + tag: 'a', + href: downloadUrl, + download: filename + }).click(); + } + setTimeout(function () { + url.revokeObjectURL(downloadUrl); + }, 100); + } + } + this.reportProgress = false; + this.updateButtons(); + } + }); + }, + + onTypeChange: function (combobox, newValue, oldValue) { + if (oldValue !== null) { + this.clearReport(oldValue); + } + + if (newValue === 'route') { + this.getGrid().reconfigure('ReportRoute', this.routeColumns); + this.getView().getLayout().setActiveItem('grid'); + } else if (newValue === 'events') { + this.getGrid().reconfigure('ReportEvents', this.eventsColumns); + this.getView().getLayout().setActiveItem('grid'); + } else if (newValue === 'summary' || newValue === 'daily') { + this.getGrid().reconfigure('ReportSummary', this.summaryColumns); + this.getView().getLayout().setActiveItem('grid'); + } else if (newValue === 'trips') { + this.getGrid().reconfigure('ReportTrips', this.tripsColumns); + this.getView().getLayout().setActiveItem('grid'); + } else if (newValue === 'stops') { + this.getGrid().reconfigure('ReportStops', this.stopsColumns); + this.getView().getLayout().setActiveItem('grid'); + } else if (newValue === 'chart') { + this.getView().getLayout().setActiveItem('chart'); + } + + this.updateButtons(); + }, + + onGeocode: function (positionId) { + var position = Ext.getStore('ReportRoute').getById(positionId); + if (position && !position.get('address')) { + Ext.Ajax.request({ + scope: this, + method: 'GET', + url: 'api/server/geocode', + params: { + latitude: position.get('latitude'), + longitude: position.get('longitude') + }, + success: function (response) { + position.set('address', response.responseText); + position.commit(); + this.fireEvent('selectReport', position); + }, + failure: function (response) { + Traccar.app.showError(response); + } + }); + } + }, + + routeColumns: [{ + text: Strings.reportDeviceName, + dataIndex: 'deviceId', + renderer: Traccar.AttributeFormatter.getFormatter('deviceId') + }, { + text: Strings.positionValid, + dataIndex: 'valid', + renderer: Traccar.AttributeFormatter.getFormatter('valid') + }, { + text: Strings.positionFixTime, + dataIndex: 'fixTime', + xtype: 'datecolumn', + renderer: Traccar.AttributeFormatter.getFormatter('fixTime') + }, { + text: Strings.positionLatitude, + dataIndex: 'latitude', + renderer: Traccar.AttributeFormatter.getFormatter('latitude') + }, { + text: Strings.positionLongitude, + dataIndex: 'longitude', + renderer: Traccar.AttributeFormatter.getFormatter('longitude') + }, { + text: Strings.positionAltitude, + dataIndex: 'altitude', + renderer: Traccar.AttributeFormatter.getFormatter('altitude') + }, { + text: Strings.positionSpeed, + dataIndex: 'speed', + renderer: Traccar.AttributeFormatter.getFormatter('speed') + }, { + text: Strings.positionAddress, + dataIndex: 'address', + renderer: function (value, metaData, record) { + if (!value) { + return '<a href="#" onclick="Ext.fireEvent(\'routegeocode\', ' + + record.getId() + ')" >' + + Strings.sharedShowAddress + '</a>'; + } + return Traccar.AttributeFormatter.getFormatter('address')(value); + } + }], + + eventsColumns: [{ + text: Strings.positionFixTime, + dataIndex: 'eventTime', + xtype: 'datecolumn', + renderer: Traccar.AttributeFormatter.getFormatter('eventTime') + }, { + text: Strings.reportDeviceName, + dataIndex: 'deviceId', + renderer: Traccar.AttributeFormatter.getFormatter('deviceId') + }, { + text: Strings.sharedType, + dataIndex: 'type', + renderer: function (value) { + return Traccar.app.getEventString(value); + } + }, { + text: Strings.positionAlarm, + dataIndex: 'attributes', + renderer: function (value) { + return value['alarm']; + } + }, { + text: Strings.sharedGeofence, + dataIndex: 'geofenceId', + renderer: Traccar.AttributeFormatter.getFormatter('geofenceId') + }, { + text: Strings.sharedMaintenance, + dataIndex: 'maintenanceId', + renderer: Traccar.AttributeFormatter.getFormatter('maintenanceId') + }], + + summaryColumns: [{ + text: Strings.reportDeviceName, + dataIndex: 'deviceId', + renderer: Traccar.AttributeFormatter.getFormatter('deviceId') + }, { + text: Strings.reportStartDate, + dataIndex: 'startTime', + xtype: 'datecolumn', + renderer: Traccar.AttributeFormatter.dateFormatter + }, { + text: Strings.sharedDistance, + dataIndex: 'distance', + renderer: Traccar.AttributeFormatter.getFormatter('distance') + }, { + text: Strings.reportStartOdometer, + dataIndex: 'startOdometer', + renderer: Traccar.AttributeFormatter.getFormatter('distance') + }, { + text: Strings.reportEndOdometer, + dataIndex: 'endOdometer', + renderer: Traccar.AttributeFormatter.getFormatter('distance') + }, { + text: Strings.reportAverageSpeed, + dataIndex: 'averageSpeed', + renderer: Traccar.AttributeFormatter.getFormatter('speed') + }, { + text: Strings.reportMaximumSpeed, + dataIndex: 'maxSpeed', + renderer: Traccar.AttributeFormatter.getFormatter('speed') + }, { + text: Strings.reportEngineHours, + dataIndex: 'engineHours', + renderer: Traccar.AttributeFormatter.getFormatter('duration') + }, { + text: Strings.reportSpentFuel, + dataIndex: 'spentFuel', + renderer: Traccar.AttributeFormatter.getFormatter('spentFuel') + }], + + tripsColumns: [{ + text: Strings.reportDeviceName, + dataIndex: 'deviceId', + renderer: Traccar.AttributeFormatter.getFormatter('deviceId') + }, { + text: Strings.reportStartTime, + dataIndex: 'startTime', + xtype: 'datecolumn', + renderer: Traccar.AttributeFormatter.getFormatter('startTime') + }, { + text: Strings.reportStartOdometer, + dataIndex: 'startOdometer', + renderer: Traccar.AttributeFormatter.getFormatter('distance') + }, { + text: Strings.reportStartAddress, + dataIndex: 'startAddress', + renderer: Traccar.AttributeFormatter.getFormatter('address') + }, { + text: Strings.reportEndTime, + dataIndex: 'endTime', + xtype: 'datecolumn', + renderer: Traccar.AttributeFormatter.getFormatter('endTime') + }, { + text: Strings.reportEndOdometer, + dataIndex: 'endOdometer', + renderer: Traccar.AttributeFormatter.getFormatter('distance') + }, { + text: Strings.reportEndAddress, + dataIndex: 'endAddress', + renderer: Traccar.AttributeFormatter.getFormatter('address') + }, { + text: Strings.sharedDistance, + dataIndex: 'distance', + renderer: Traccar.AttributeFormatter.getFormatter('distance') + }, { + text: Strings.reportAverageSpeed, + dataIndex: 'averageSpeed', + renderer: Traccar.AttributeFormatter.getFormatter('speed') + }, { + text: Strings.reportMaximumSpeed, + dataIndex: 'maxSpeed', + renderer: Traccar.AttributeFormatter.getFormatter('speed') + }, { + text: Strings.reportDuration, + dataIndex: 'duration', + renderer: Traccar.AttributeFormatter.getFormatter('duration') + }, { + text: Strings.reportSpentFuel, + dataIndex: 'spentFuel', + renderer: Traccar.AttributeFormatter.getFormatter('spentFuel') + }, { + text: Strings.sharedDriver, + dataIndex: 'driverUniqueId', + renderer: Traccar.AttributeFormatter.getFormatter('driverUniqueId') + }], + + stopsColumns: [{ + text: Strings.reportDeviceName, + dataIndex: 'deviceId', + renderer: Traccar.AttributeFormatter.getFormatter('deviceId') + }, { + text: Strings.reportStartTime, + dataIndex: 'startTime', + xtype: 'datecolumn', + renderer: Traccar.AttributeFormatter.getFormatter('startTime') + }, { + text: Strings.positionOdometer, + dataIndex: 'startOdometer', + renderer: Traccar.AttributeFormatter.getFormatter('distance') + }, { + text: Strings.positionAddress, + dataIndex: 'address', + renderer: Traccar.AttributeFormatter.getFormatter('address') + }, { + text: Strings.reportEndTime, + dataIndex: 'endTime', + xtype: 'datecolumn', + renderer: Traccar.AttributeFormatter.getFormatter('endTime') + }, { + text: Strings.reportDuration, + dataIndex: 'duration', + renderer: Traccar.AttributeFormatter.getFormatter('duration') + }, { + text: Strings.reportEngineHours, + dataIndex: 'engineHours', + renderer: Traccar.AttributeFormatter.getFormatter('duration') + }, { + text: Strings.reportSpentFuel, + dataIndex: 'spentFuel', + renderer: Traccar.AttributeFormatter.getFormatter('spentFuel') + }] +}); diff --git a/legacy/web/app/view/SettingsMenu.js b/legacy/web/app/view/SettingsMenu.js new file mode 100644 index 00000000..0a81d520 --- /dev/null +++ b/legacy/web/app/view/SettingsMenu.js @@ -0,0 +1,111 @@ +/* + * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.SettingsMenu', { + extend: 'Ext.button.Button', + xtype: 'settingsMenu', + + requires: [ + 'Traccar.view.SettingsMenuController' + ], + + glyph: 'xf013@FontAwesome', + tooltip: Strings.settingsTitle, + tooltipType: 'title', + + menu: { + controller: 'settings', + + items: [{ + hidden: true, + text: Strings.settingsUser, + glyph: 'xf007@FontAwesome', + handler: 'onUserClick', + reference: 'settingsUserButton' + }, { + hidden: true, + text: Strings.settingsGroups, + glyph: 'xf247@FontAwesome', + handler: 'onGroupsClick', + reference: 'settingsGroupsButton' + }, { + hidden: true, + text: Strings.sharedDrivers, + glyph: 'xf084@FontAwesome', + handler: 'onDriversClick', + reference: 'settingsDriversButton' + }, { + hidden: true, + text: Strings.sharedGeofences, + glyph: 'xf21d@FontAwesome', + handler: 'onGeofencesClick', + reference: 'settingsGeofencesButton' + }, { + hidden: true, + text: Strings.settingsServer, + glyph: 'xf233@FontAwesome', + handler: 'onServerClick', + reference: 'settingsServerButton' + }, { + hidden: true, + text: Strings.settingsUsers, + glyph: 'xf0c0@FontAwesome', + handler: 'onUsersClick', + reference: 'settingsUsersButton' + }, { + hidden: true, + text: Strings.sharedNotifications, + glyph: 'xf003@FontAwesome', + handler: 'onNotificationsClick', + reference: 'settingsNotificationsButton' + }, { + hidden: true, + text: Strings.sharedComputedAttributes, + glyph: 'xf0ae@FontAwesome', + handler: 'onComputedAttributesClick', + reference: 'settingsComputedAttributesButton' + }, { + hidden: true, + text: Strings.statisticsTitle, + glyph: 'xf080@FontAwesome', + handler: 'onStatisticsClick', + reference: 'settingsStatisticsButton' + }, { + hidden: true, + text: Strings.sharedCalendars, + glyph: 'xf073@FontAwesome', + handler: 'onCalendarsClick', + reference: 'settingsCalendarsButton' + }, { + hidden: true, + text: Strings.sharedSavedCommands, + glyph: 'xf093@FontAwesome', + handler: 'onCommandsClick', + reference: 'settingsCommandsButton' + }, { + hidden: true, + text: Strings.sharedMaintenance, + glyph: 'xf0ad@FontAwesome', + handler: 'onMaintenancesClick', + reference: 'settingsMaintenancesButton' + }, { + text: Strings.loginLogout, + glyph: 'xf08b@FontAwesome', + handler: 'onLogoutClick' + }] + } +}); diff --git a/legacy/web/app/view/SettingsMenuController.js b/legacy/web/app/view/SettingsMenuController.js new file mode 100644 index 00000000..c8018f66 --- /dev/null +++ b/legacy/web/app/view/SettingsMenuController.js @@ -0,0 +1,176 @@ +/* + * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.SettingsMenuController', { + extend: 'Ext.app.ViewController', + alias: 'controller.settings', + + requires: [ + 'Traccar.view.dialog.LoginController', + 'Traccar.view.dialog.User', + 'Traccar.view.dialog.Server', + 'Traccar.view.edit.Users', + 'Traccar.view.edit.Groups', + 'Traccar.view.edit.Geofences', + 'Traccar.view.edit.Drivers', + 'Traccar.view.edit.Notifications', + 'Traccar.view.edit.ComputedAttributes', + 'Traccar.view.Statistics', + 'Traccar.view.edit.Calendars', + 'Traccar.view.edit.SavedCommands', + 'Traccar.view.edit.Maintenances', + 'Traccar.view.BaseWindow' + ], + + init: function () { + var admin, manager, readonly; + admin = Traccar.app.getUser().get('administrator'); + manager = Traccar.app.getUser().get('userLimit') !== 0; + readonly = Traccar.app.getPreference('readonly', false); + if (admin) { + this.lookupReference('settingsServerButton').setHidden(false); + this.lookupReference('settingsStatisticsButton').setHidden(false); + this.lookupReference('settingsComputedAttributesButton').setHidden( + Traccar.app.getBooleanAttributePreference('ui.disableComputedAttributes')); + } + if (admin || manager) { + this.lookupReference('settingsUsersButton').setHidden(false); + } + if (admin || !readonly) { + this.lookupReference('settingsUserButton').setHidden(false); + this.lookupReference('settingsGroupsButton').setHidden(false); + this.lookupReference('settingsGeofencesButton').setHidden(false); + this.lookupReference('settingsNotificationsButton').setHidden(false); + this.lookupReference('settingsCalendarsButton').setHidden( + Traccar.app.getBooleanAttributePreference('ui.disableCalendars')); + this.lookupReference('settingsDriversButton').setHidden( + Traccar.app.getVehicleFeaturesDisabled() || Traccar.app.getBooleanAttributePreference('ui.disableDrivers')); + this.lookupReference('settingsCommandsButton').setHidden(Traccar.app.getPreference('limitCommands', false)); + this.lookupReference('settingsMaintenancesButton').setHidden( + Traccar.app.getVehicleFeaturesDisabled() || Traccar.app.getBooleanAttributePreference('ui.disableMaintenance')); + } + }, + + onUserClick: function () { + var dialog = Ext.create('Traccar.view.dialog.User', { + selfEdit: true + }); + dialog.down('form').loadRecord(Traccar.app.getUser()); + dialog.lookupReference('testNotificationButton').setHidden(false); + dialog.show(); + }, + + onGroupsClick: function () { + Ext.create('Traccar.view.BaseWindow', { + title: Strings.settingsGroups, + items: { + xtype: 'groupsView' + } + }).show(); + }, + + onGeofencesClick: function () { + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedGeofences, + items: { + xtype: 'geofencesView' + } + }).show(); + }, + + onServerClick: function () { + var dialog = Ext.create('Traccar.view.dialog.Server'); + dialog.down('form').loadRecord(Traccar.app.getServer()); + dialog.show(); + }, + + onUsersClick: function () { + Ext.create('Traccar.view.BaseWindow', { + title: Strings.settingsUsers, + items: { + xtype: 'usersView' + } + }).show(); + }, + + onNotificationsClick: function () { + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedNotifications, + items: { + xtype: 'notificationsView' + } + }).show(); + }, + + onComputedAttributesClick: function () { + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedComputedAttributes, + items: { + xtype: 'computedAttributesView' + } + }).show(); + }, + + onStatisticsClick: function () { + Ext.create('Traccar.view.BaseWindow', { + title: Strings.statisticsTitle, + items: { + xtype: 'statisticsView' + } + }).show(); + }, + + onCalendarsClick: function () { + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedCalendars, + items: { + xtype: 'calendarsView' + } + }).show(); + }, + + onDriversClick: function () { + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedDrivers, + items: { + xtype: 'driversView' + } + }).show(); + }, + + onCommandsClick: function () { + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedSavedCommands, + items: { + xtype: 'savedCommandsView' + } + }).show(); + }, + + onMaintenancesClick: function () { + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedMaintenance, + items: { + xtype: 'maintenancesView' + } + }).show(); + }, + + onLogoutClick: function () { + Ext.create('Traccar.view.dialog.LoginController').logout(); + } +}); diff --git a/legacy/web/app/view/State.js b/legacy/web/app/view/State.js new file mode 100644 index 00000000..c0a430d9 --- /dev/null +++ b/legacy/web/app/view/State.js @@ -0,0 +1,85 @@ +/* + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.State', { + extend: 'Traccar.view.GridPanel', + xtype: 'stateView', + + requires: [ + 'Traccar.view.StateController' + ], + + controller: 'state', + store: 'Attributes', + + stateful: true, + stateId: 'state-grid', + + tbar: { + componentCls: 'toolbar-header-style', + items: [{ + xtype: 'tbtext', + html: Strings.stateTitle, + baseCls: 'x-panel-header-title-default' + }, { + xtype: 'tbfill' + }, { + xtype: 'button', + disabled: true, + handler: 'onComputedAttributesClick', + reference: 'computedAttributesButton', + glyph: 'xf0ae@FontAwesome', + tooltip: Strings.sharedComputedAttributes, + tooltipType: 'title' + }] + }, + + columns: { + defaults: { + minWidth: Traccar.Style.columnWidthNormal, + flex: 1 + }, + items: [{ + text: Strings.stateName, + dataIndex: 'name' + }, { + text: Strings.stateValue, + dataIndex: 'value', + cellWrap: true, + renderer: function (value, metaData, record) { + var position, device, attribute; + attribute = record.get('attribute'); + if (attribute === 'alarm') { + metaData.tdCls = 'view-color-red'; + } else if (attribute === 'address' && !value) { + return '<a href="#" onclick="Ext.fireEvent(\'stategeocode\')" >' + + Strings.sharedShowAddress + '</a>'; + } else if (attribute === 'image' || attribute === 'video' || attribute === 'audio') { + position = this.getController().position; + if (position) { + device = Ext.getStore('Devices').getById(position.get('deviceId')); + if (device) { + return '<a target="_blank" href="/api/media/' + + device.get('uniqueId') + '/' + value + '" >' + value + '</a>'; + } + } + } + return value; + } + }] + } +}); diff --git a/legacy/web/app/view/StateController.js b/legacy/web/app/view/StateController.js new file mode 100644 index 00000000..f04d7185 --- /dev/null +++ b/legacy/web/app/view/StateController.js @@ -0,0 +1,216 @@ +/* + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.StateController', { + extend: 'Ext.app.ViewController', + alias: 'controller.state', + + requires: [ + 'Traccar.AttributeFormatter', + 'Traccar.model.Attribute', + 'Traccar.model.Position', + 'Traccar.view.BaseWindow', + 'Traccar.view.edit.ComputedAttributes' + ], + + config: { + listen: { + controller: { + '*': { + selectdevice: 'selectDevice', + selectreport: 'selectPosition', + selectevent: 'selectPosition', + deselectfeature: 'deselectFeature' + } + }, + global: { + stategeocode: 'onGeocode' + }, + store: { + '#LatestPositions': { + add: 'updateLatest', + update: 'updateLatest' + }, + '#ReportRoute': { + clear: 'clearReport' + } + } + } + }, + + init: function () { + var i, hideAttributesPreference, attributesList; + if (Traccar.app.getUser().get('administrator') || + !Traccar.app.getUser().get('deviceReadonly') && !Traccar.app.getPreference('readonly', false)) { + this.lookupReference('computedAttributesButton').setDisabled( + Traccar.app.getBooleanAttributePreference('ui.disableComputedAttributes')); + } + hideAttributesPreference = Traccar.app.getAttributePreference('ui.hidePositionAttributes'); + this.hideAttributes = {}; + if (hideAttributesPreference) { + attributesList = hideAttributesPreference.split(/[ ,]+/).filter(Boolean); + for (i = 0; i < attributesList.length; i++) { + this.hideAttributes[attributesList[i]] = true; + } + } + }, + + onComputedAttributesClick: function () { + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedComputedAttributes, + items: { + xtype: 'computedAttributesView' + } + }).show(); + }, + + keys: (function () { + var i, list, result; + result = {}; + list = ['fixTime', 'latitude', 'longitude', 'valid', 'accuracy', 'altitude', 'speed', 'course', 'address', 'protocol']; + for (i = 0; i < list.length; i++) { + result[list[i]] = { + priority: i, + name: Strings['position' + list[i].replace(/^\w/g, function (s) { + return s.toUpperCase(); + })] + }; + } + return result; + })(), + + updateLatest: function (store, data) { + var i; + if (!Ext.isArray(data)) { + data = [data]; + } + for (i = 0; i < data.length; i++) { + if (this.deviceId === data[i].get('deviceId')) { + this.position = data[i]; + this.updatePosition(); + } + } + }, + + formatValue: function (value) { + if (typeof id === 'number') { + return Number(value.toFixed(2)); + } else { + return value; + } + }, + + findAttribute: function (record) { + return record.get('deviceId') === this.position.get('deviceId') && record.get('attribute') === this.lookupAttribute; + }, + + updatePosition: function () { + var attributes, store, key, name, value; + store = Ext.getStore('Attributes'); + store.removeAll(); + + for (key in this.position.data) { + if (this.position.data.hasOwnProperty(key) && this.keys[key] !== undefined) { + store.add(Ext.create('Traccar.model.Attribute', { + priority: this.keys[key].priority, + name: this.keys[key].name, + attribute: key, + value: Traccar.AttributeFormatter.getFormatter(key)(this.position.get(key)) + })); + } + } + + attributes = this.position.get('attributes'); + if (attributes instanceof Object) { + for (key in attributes) { + if (attributes.hasOwnProperty(key) && !this.hideAttributes[key]) { + this.lookupAttribute = key; + name = Ext.getStore('PositionAttributes').getAttributeName(key, true); + if (this.position.get('attribute.' + key) !== undefined) { + value = Traccar.AttributeFormatter.getAttributeFormatter(key)(this.position.get('attribute.' + key)); + } else { + value = Traccar.AttributeFormatter.defaultFormatter(attributes[key]); + } + store.add(Ext.create('Traccar.model.Attribute', { + priority: 1024, + name: name, + attribute: key, + value: value + })); + } + } + } + }, + + selectDevice: function (device) { + var position; + this.deviceId = device.get('id'); + position = Ext.getStore('LatestPositions').findRecord('deviceId', this.deviceId, 0, false, false, true); + if (position) { + this.position = position; + this.updatePosition(); + } else { + this.position = null; + Ext.getStore('Attributes').removeAll(); + } + }, + + selectPosition: function (position) { + if (position instanceof Traccar.model.Position) { + this.deviceId = null; + this.position = position; + this.updatePosition(); + } + }, + + deselectFeature: function () { + this.deviceId = null; + this.position = null; + Ext.getStore('Attributes').removeAll(); + }, + + clearReport: function () { + if (!this.deviceId) { + this.position = null; + Ext.getStore('Attributes').removeAll(); + } + }, + + onGeocode: function () { + var positionId = this.position.getId(); + if (!this.position.get('address')) { + Ext.Ajax.request({ + scope: this, + method: 'GET', + url: 'api/server/geocode', + params: { + latitude: this.position.get('latitude'), + longitude: this.position.get('longitude') + }, + success: function (response) { + if (this.position && this.position.getId() === positionId) { + this.position.set('address', response.responseText); + this.updatePosition(); + } + }, + failure: function (response) { + Traccar.app.showError(response); + } + }); + } + } +}); diff --git a/legacy/web/app/view/Statistics.js b/legacy/web/app/view/Statistics.js new file mode 100644 index 00000000..af199a02 --- /dev/null +++ b/legacy/web/app/view/Statistics.js @@ -0,0 +1,93 @@ +/* + * Copyright 2016 - 2017 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. + */ + +Ext.define('Traccar.view.Statistics', { + extend: 'Traccar.view.GridPanel', + xtype: 'statisticsView', + + requires: [ + 'Traccar.view.StatisticsController' + ], + + controller: 'statistics', + store: 'Statistics', + + tbar: { + scrollable: true, + items: [{ + xtype: 'tbtext', + html: Strings.reportFrom + }, { + xtype: 'datefield', + reference: 'fromDateField', + startDay: Traccar.Style.weekStartDay, + format: Traccar.Style.dateFormat, + value: new Date(new Date().getTime() - 24 * 60 * 60 * 1000) + }, '-', { + xtype: 'tbtext', + html: Strings.reportTo + }, { + xtype: 'datefield', + reference: 'toDateField', + startDay: Traccar.Style.weekStartDay, + format: Traccar.Style.dateFormat, + value: new Date() + }, '-', { + text: Strings.reportShow, + handler: 'onShowClick' + }] + }, + + columns: { + defaults: { + flex: 1, + minWidth: Traccar.Style.columnWidthNormal + }, + items: [{ + text: Strings.statisticsCaptureTime, + dataIndex: 'captureTime', + xtype: 'datecolumn', + renderer: Traccar.AttributeFormatter.defaultFormatter() + }, { + text: Strings.statisticsActiveUsers, + dataIndex: 'activeUsers' + }, { + text: Strings.statisticsActiveDevices, + dataIndex: 'activeDevices' + }, { + text: Strings.statisticsRequests, + dataIndex: 'requests' + }, { + text: Strings.statisticsMessagesReceived, + dataIndex: 'messagesReceived' + }, { + text: Strings.statisticsMessagesStored, + dataIndex: 'messagesStored' + }, { + text: Strings.notificatorMail, + dataIndex: 'mailSent' + }, { + text: Strings.notificatorSms, + dataIndex: 'smsSent' + }, { + text: Strings.statisticsGeocoder, + dataIndex: 'geocoderRequests' + }, { + text: Strings.statisticsGeolocation, + dataIndex: 'geolocationRequests' + }] + } +}); diff --git a/legacy/web/app/view/StatisticsController.js b/legacy/web/app/view/StatisticsController.js new file mode 100644 index 00000000..c4ce9d37 --- /dev/null +++ b/legacy/web/app/view/StatisticsController.js @@ -0,0 +1,29 @@ +/* + * 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. + */ + +Ext.define('Traccar.view.StatisticsController', { + extend: 'Ext.app.ViewController', + alias: 'controller.statistics', + + onShowClick: function () { + Ext.getStore('Statistics').load({ + params: { + from: this.lookupReference('fromDateField').getValue().toISOString(), + to: this.lookupReference('toDateField').getValue().toISOString() + } + }); + } +}); diff --git a/legacy/web/app/view/TouchFix62.js b/legacy/web/app/view/TouchFix62.js new file mode 100644 index 00000000..300d4f70 --- /dev/null +++ b/legacy/web/app/view/TouchFix62.js @@ -0,0 +1,48 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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/>. + */ + +/* + * Workaround for bug in ExtJs 6.2.0. + * Resolved in current yet unreleased version + */ + +Ext.define('Traccar.view.TouchFix62', { + override: 'Ext.dom.Element' +}, +function () { + var additiveEvents = this.prototype.additiveEvents, + eventMap = this.prototype.eventMap; + if (Ext.supports.TouchEvents && Ext.firefoxVersion >= 52 && Ext.os.is.Desktop) { + eventMap['touchstart'] = 'mousedown'; + eventMap['touchmove'] = 'mousemove'; + eventMap['touchend'] = 'mouseup'; + eventMap['touchcancel'] = 'mouseup'; + eventMap['click'] = 'click'; + eventMap['dblclick'] = 'dblclick'; + additiveEvents['mousedown'] = 'mousedown'; + additiveEvents['mousemove'] = 'mousemove'; + additiveEvents['mouseup'] = 'mouseup'; + additiveEvents['touchstart'] = 'touchstart'; + additiveEvents['touchmove'] = 'touchmove'; + additiveEvents['touchend'] = 'touchend'; + additiveEvents['touchcancel'] = 'touchcancel'; + additiveEvents['pointerdown'] = 'mousedown'; + additiveEvents['pointermove'] = 'mousemove'; + additiveEvents['pointerup'] = 'mouseup'; + additiveEvents['pointercancel'] = 'mouseup'; + } +}); diff --git a/legacy/web/app/view/UnescapedTextAreaField.js b/legacy/web/app/view/UnescapedTextAreaField.js new file mode 100644 index 00000000..5de267ce --- /dev/null +++ b/legacy/web/app/view/UnescapedTextAreaField.js @@ -0,0 +1,29 @@ +/* + * Copyright 2019 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.UnescapedTextAreaField', { + extend: 'Ext.form.field.TextArea', + xtype: 'unescapedTextAreaField', + + initComponent: function () { + this.callParent(); + this.on('change', this.onValueChange); + }, + + onValueChange: function (field, newValue) { + field.setValue(Ext.String.htmlDecode(newValue)); + } +}); diff --git a/legacy/web/app/view/UnescapedTextField.js b/legacy/web/app/view/UnescapedTextField.js new file mode 100644 index 00000000..3b1b2798 --- /dev/null +++ b/legacy/web/app/view/UnescapedTextField.js @@ -0,0 +1,29 @@ +/* + * Copyright 2019 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.UnescapedTextField', { + extend: 'Ext.form.field.Text', + xtype: 'unescapedTextField', + + initComponent: function () { + this.callParent(); + this.on('change', this.onValueChange); + }, + + onValueChange: function (field, newValue) { + field.setValue(Ext.String.htmlDecode(newValue)); + } +}); diff --git a/legacy/web/app/view/dialog/Attribute.js b/legacy/web/app/view/dialog/Attribute.js new file mode 100644 index 00000000..a85cad05 --- /dev/null +++ b/legacy/web/app/view/dialog/Attribute.js @@ -0,0 +1,65 @@ +/* + * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.dialog.Attribute', { + extend: 'Traccar.view.dialog.Base', + + requires: [ + 'Traccar.view.dialog.AttributeController', + 'Traccar.view.ColorPicker', + 'Traccar.view.CustomNumberField', + 'Traccar.view.UnescapedTextField' + ], + + controller: 'attribute', + title: Strings.sharedAttribute, + + items: { + xtype: 'form', + listeners: { + validitychange: 'onValidityChange' + }, + items: [{ + xtype: 'unescapedTextField', + reference: 'nameTextField', + name: 'name', + allowBlank: false, + fieldLabel: Strings.sharedName + }, { + xtype: 'textfield', + name: 'value', + reference: 'valueField', + allowBlank: false, + fieldLabel: Strings.stateValue + }] + }, + + buttons: [{ + glyph: 'xf00c@FontAwesome', + reference: 'saveButton', + tooltip: Strings.sharedSave, + tooltipType: 'title', + minWidth: 0, + handler: 'onSaveClick' + }, { + glyph: 'xf00d@FontAwesome', + tooltip: Strings.sharedCancel, + tooltipType: 'title', + minWidth: 0, + handler: 'closeView' + }] +}); diff --git a/legacy/web/app/view/dialog/AttributeController.js b/legacy/web/app/view/dialog/AttributeController.js new file mode 100644 index 00000000..9fd452a4 --- /dev/null +++ b/legacy/web/app/view/dialog/AttributeController.js @@ -0,0 +1,126 @@ +/* + * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.dialog.AttributeController', { + extend: 'Ext.app.ViewController', + alias: 'controller.attribute', + + onSaveClick: function (button) { + var dialog, store, record; + dialog = button.up('window').down('form'); + dialog.updateRecord(); + record = dialog.getRecord(); + store = record.store; + if (store) { + if (record.phantom) { + store.add(record); + } + store.sync({ + failure: function (batch) { + store.rejectChanges(); + Traccar.app.showError(batch.exceptions[0].getError().response); + } + }); + } else { + record.save(); + } + button.up('window').close(); + }, + + onValidityChange: function (form, valid) { + this.lookupReference('saveButton').setDisabled(!valid); + }, + + defaultFieldConfig: { + name: 'value', + reference: 'valueField', + allowBlank: false, + fieldLabel: Strings.stateValue + }, + + onNameChange: function (combobox, newValue) { + var config, attribute, valueField = this.lookupReference('valueField'); + attribute = combobox.getStore().getById(newValue); + if (attribute) { + config = Ext.clone(this.defaultFieldConfig); + switch (attribute.get('valueType')) { + case 'number': + config.xtype = 'customNumberField'; + if (attribute.get('allowDecimals') !== undefined) { + config.allowDecimals = attribute.get('allowDecimals'); + } else { + config.allowDecimals = true; + } + config.dataType = attribute.get('dataType'); + config.maxValue = attribute.get('maxValue'); + config.minValue = attribute.get('minValue'); + break; + case 'boolean': + config.xtype = 'checkboxfield'; + config.inputValue = true; + config.uncheckedValue = false; + break; + case 'color': + config.xtype = 'customcolorpicker'; + break; + default: + if (attribute.get('dataType')) { + config.xtype = 'combobox'; + config.queryMode = 'local'; + config.editable = false; + switch (attribute.get('dataType')) { + case 'distanceUnit': + config.store = 'DistanceUnits'; + config.displayField = 'name'; + config.valueField = 'key'; + break; + case 'speedUnit': + config.store = 'SpeedUnits'; + config.displayField = 'name'; + config.valueField = 'key'; + break; + case 'volumeUnit': + config.store = 'VolumeUnits'; + config.displayField = 'fullName'; + config.valueField = 'key'; + break; + case 'timezone': + config.store = 'AllTimezones'; + config.displayField = 'key'; + break; + default: + break; + } + } else { + config.xtype = 'textfield'; + } + break; + } + if (valueField.getXType() !== config.xtype || + config.xtype === 'customNumberField' && valueField.dataType !== config.dataType) { + this.getView().down('form').insert(this.getView().down('form').items.indexOf(valueField), config); + this.getView().down('form').remove(valueField); + } else if (config.xtype === 'customNumberField') { + valueField.setConfig(config); + valueField.validate(); + } else if (config.xtype === 'combobox') { + valueField.setConfig(config); + valueField.setValue(); + } + } + } +}); diff --git a/legacy/web/app/view/dialog/Base.js b/legacy/web/app/view/dialog/Base.js new file mode 100644 index 00000000..6affb370 --- /dev/null +++ b/legacy/web/app/view/dialog/Base.js @@ -0,0 +1,32 @@ +/* + * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.dialog.Base', { + extend: 'Ext.window.Window', + + bodyPadding: Traccar.Style.normalPadding, + resizable: false, + scrollable: true, + constrain: true, + + initComponent: function () { + if (window.innerHeight) { + this.maxHeight = window.innerHeight - Traccar.Style.normalPadding * 2; + } + this.callParent(); + } +}); diff --git a/legacy/web/app/view/dialog/BaseEdit.js b/legacy/web/app/view/dialog/BaseEdit.js new file mode 100644 index 00000000..286afba5 --- /dev/null +++ b/legacy/web/app/view/dialog/BaseEdit.js @@ -0,0 +1,46 @@ +/* + * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.dialog.BaseEdit', { + extend: 'Traccar.view.dialog.Base', + + requires: [ + 'Traccar.view.dialog.BaseEditController' + ], + + controller: 'baseEdit', + + buttons: [{ + text: Strings.sharedAttributes, + handler: 'showAttributesView' + }, { + xtype: 'tbfill' + }, { + glyph: 'xf00c@FontAwesome', + reference: 'saveButton', + tooltip: Strings.sharedSave, + tooltipType: 'title', + minWidth: 0, + handler: 'onSaveClick' + }, { + glyph: 'xf00d@FontAwesome', + tooltip: Strings.sharedCancel, + tooltipType: 'title', + minWidth: 0, + handler: 'closeView' + }] +}); diff --git a/legacy/web/app/view/dialog/BaseEditController.js b/legacy/web/app/view/dialog/BaseEditController.js new file mode 100644 index 00000000..91379e2d --- /dev/null +++ b/legacy/web/app/view/dialog/BaseEditController.js @@ -0,0 +1,61 @@ +/* + * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.dialog.BaseEditController', { + extend: 'Ext.app.ViewController', + alias: 'controller.baseEdit', + + requires: [ + 'Traccar.view.BaseWindow', + 'Traccar.view.edit.Attributes' + ], + + onSaveClick: function (button) { + var dialog, store, record; + dialog = button.up('window').down('form'); + dialog.updateRecord(); + record = dialog.getRecord(); + store = record.store; + if (store) { + if (record.phantom) { + store.add(record); + } + store.sync({ + failure: function (batch) { + store.rejectChanges(); + Traccar.app.showError(batch.exceptions[0].getError().response); + } + }); + } else { + record.save(); + } + this.closeView(); + }, + + showAttributesView: function (button) { + var dialog, record; + dialog = button.up('window').down('form'); + record = dialog.getRecord(); + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedAttributes, + items: { + xtype: 'attributesView', + record: record + } + }).show(); + } +}); diff --git a/legacy/web/app/view/dialog/Calendar.js b/legacy/web/app/view/dialog/Calendar.js new file mode 100644 index 00000000..5f00a8be --- /dev/null +++ b/legacy/web/app/view/dialog/Calendar.js @@ -0,0 +1,63 @@ +/* + * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.dialog.Calendar', { + extend: 'Traccar.view.dialog.BaseEdit', + + requires: [ + 'Traccar.view.dialog.CalendarController', + 'Traccar.view.UnescapedTextField' + ], + + controller: 'calendar', + title: Strings.sharedCalendar, + + items: { + xtype: 'form', + items: [{ + xtype: 'fieldset', + title: Strings.sharedRequired, + items: [{ + xtype: 'unescapedTextField', + 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: 'data', + allowBlank: false, + reference: 'dataField' + }] + } +}); diff --git a/legacy/web/app/view/dialog/CalendarController.js b/legacy/web/app/view/dialog/CalendarController.js new file mode 100644 index 00000000..fb8cbff6 --- /dev/null +++ b/legacy/web/app/view/dialog/CalendarController.js @@ -0,0 +1,37 @@ +/* + * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.dialog.CalendarController', { + extend: 'Traccar.view.dialog.BaseEditController', + alias: 'controller.calendar', + + onFileChange: function (fileField) { + var reader; + if (fileField.fileInputEl.dom.files.length > 0) { + reader = new FileReader(); + reader.onload = function (event) { + fileField.up('window').lookupReference('dataField').setValue( + event.target.result.substr(event.target.result.indexOf(',') + 1)); + }; + reader.onerror = function (event) { + Traccar.app.showError(event.target.error); + }; + reader.readAsDataURL(fileField.fileInputEl.dom.files[0]); + } + } +}); diff --git a/legacy/web/app/view/dialog/ComputedAttribute.js b/legacy/web/app/view/dialog/ComputedAttribute.js new file mode 100644 index 00000000..adae7f7b --- /dev/null +++ b/legacy/web/app/view/dialog/ComputedAttribute.js @@ -0,0 +1,84 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.dialog.ComputedAttribute', { + extend: 'Traccar.view.dialog.BaseEdit', + + requires: [ + 'Traccar.view.dialog.ComputedAttributeController', + 'Traccar.view.UnescapedTextField', + 'Traccar.view.UnescapedTextAreaField' + ], + + controller: 'computedAttribute', + title: Strings.sharedComputedAttribute, + + items: { + xtype: 'form', + items: [{ + xtype: 'unescapedTextField', + name: 'description', + fieldLabel: Strings.sharedDescription + }, { + xtype: 'combobox', + name: 'attribute', + fieldLabel: Strings.sharedAttribute, + store: 'PositionAttributes', + displayField: 'name', + valueField: 'key', + listeners: { + change: 'onAttributeChange' + } + }, { + xtype: 'unescapedTextAreaField', + reference: 'expressionField', + name: 'expression', + fieldLabel: Strings.sharedExpression, + allowBlank: false + }, { + xtype: 'combobox', + name: 'type', + reference: 'typeComboField', + store: 'AttributeValueTypes', + fieldLabel: Strings.sharedType, + displayField: 'name', + valueField: 'id', + editable: false + }] + }, + + buttons: [{ + glyph: 'xf128@FontAwesome', + tooltip: Strings.sharedCheckComputedAttribute, + tooltipType: 'title', + minWidth: 0, + handler: 'onCheckClick' + }, { + glyph: 'xf00c@FontAwesome', + tooltip: Strings.sharedSave, + tooltipType: 'title', + minWidth: 0, + handler: 'onSaveClick' + }, { + glyph: 'xf00d@FontAwesome', + tooltip: Strings.sharedCancel, + tooltipType: 'title', + minWidth: 0, + handler: 'closeView' + }] +}); diff --git a/legacy/web/app/view/dialog/ComputedAttributeController.js b/legacy/web/app/view/dialog/ComputedAttributeController.js new file mode 100644 index 00000000..f680b1b5 --- /dev/null +++ b/legacy/web/app/view/dialog/ComputedAttributeController.js @@ -0,0 +1,45 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.dialog.ComputedAttributeController', { + extend: 'Traccar.view.dialog.BaseEditController', + alias: 'controller.computedAttribute', + + requires: [ + 'Traccar.view.dialog.SelectDevice' + ], + + onAttributeChange: function (combobox, newValue) { + var attribute = Ext.getStore('PositionAttributes').getById(newValue); + if (attribute) { + this.getView().lookupReference('typeComboField').setValue(attribute.get('valueType')); + this.getView().lookupReference('typeComboField').setReadOnly(true); + } else { + this.getView().lookupReference('typeComboField').setReadOnly(false); + } + }, + + onCheckClick: function (button) { + var dialog, form; + dialog = Ext.create('Traccar.view.dialog.SelectDevice'); + form = button.up('window').down('form'); + form.updateRecord(); + dialog.record = form.getRecord(); + dialog.show(); + } +}); diff --git a/legacy/web/app/view/dialog/Device.js b/legacy/web/app/view/dialog/Device.js new file mode 100644 index 00000000..60a8f716 --- /dev/null +++ b/legacy/web/app/view/dialog/Device.js @@ -0,0 +1,99 @@ +/* + * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.dialog.Device', { + extend: 'Traccar.view.dialog.BaseEdit', + + requires: [ + 'Traccar.view.ClearableComboBox', + 'Traccar.view.dialog.DeviceController', + 'Traccar.view.UnescapedTextField' + ], + + controller: 'device', + title: Strings.sharedDevice, + + items: { + xtype: 'form', + items: [{ + xtype: 'fieldset', + title: Strings.sharedRequired, + items: [{ + xtype: 'unescapedTextField', + name: 'name', + fieldLabel: Strings.sharedName, + allowBlank: false + }, { + xtype: 'unescapedTextField', + name: 'uniqueId', + fieldLabel: Strings.deviceIdentifier, + allowBlank: false + }] + }, { + xtype: 'fieldset', + title: Strings.sharedExtra, + collapsible: true, + collapsed: true, + items: [{ + xtype: 'clearableComboBox', + name: 'groupId', + fieldLabel: Strings.groupParent, + store: 'Groups', + queryMode: 'local', + displayField: 'name', + valueField: 'id' + }, { + xtype: 'unescapedTextField', + name: 'phone', + fieldLabel: Strings.sharedPhone + }, { + xtype: 'unescapedTextField', + name: 'model', + fieldLabel: Strings.deviceModel + }, { + xtype: 'unescapedTextField', + name: 'contact', + fieldLabel: Strings.deviceContact + }, { + xtype: 'combobox', + name: 'category', + fieldLabel: Strings.deviceCategory, + store: 'DeviceImages', + queryMode: 'local', + displayField: 'name', + valueField: 'key', + editable: false, + listConfig: { + getInnerTpl: function () { + return '<table><tr valign="middle" ><td><div align="center" style="width:40px;height:40px;" >' + + '{[new XMLSerializer().serializeToString(Traccar.DeviceImages.getImageSvg(' + + 'Traccar.Style.mapColorOnline, false, 0, values.key))]}</div></td>' + + '<td>{name}</td></tr></table>'; + } + } + }, { + xtype: 'checkboxfield', + inputValue: true, + uncheckedValue: false, + name: 'disabled', + fieldLabel: Strings.sharedDisabled, + hidden: true, + reference: 'disabledField' + }] + }] + } +}); diff --git a/legacy/web/app/view/dialog/DeviceAccumulators.js b/legacy/web/app/view/dialog/DeviceAccumulators.js new file mode 100644 index 00000000..eaa4e9f5 --- /dev/null +++ b/legacy/web/app/view/dialog/DeviceAccumulators.js @@ -0,0 +1,55 @@ +/* + * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.dialog.DeviceAccumulators', { + extend: 'Traccar.view.dialog.Base', + + requires: [ + 'Traccar.view.dialog.DeviceAccumulatorsController' + ], + + controller: 'deviceAccumulators', + title: Strings.sharedDeviceAccumulators, + + items: [{ + xtype: 'customNumberField', + dataType: 'distance', + reference: 'totalDistance', + fieldLabel: Strings.deviceTotalDistance + }, { + xtype: 'customNumberField', + dataType: 'hours', + reference: 'hours', + fieldLabel: Strings.positionHours + }], + + buttons: [{ + reference: 'setButton', + glyph: 'xf00c@FontAwesome', + tooltip: Strings.sharedSet, + tooltipType: 'title', + minWidth: 0, + handler: 'onSetClick' + }, { + glyph: 'xf00d@FontAwesome', + tooltip: Strings.sharedCancel, + tooltipType: 'title', + minWidth: 0, + handler: 'closeView' + }] +}); diff --git a/legacy/web/app/view/dialog/DeviceAccumulatorsController.js b/legacy/web/app/view/dialog/DeviceAccumulatorsController.js new file mode 100644 index 00000000..2fdae6c5 --- /dev/null +++ b/legacy/web/app/view/dialog/DeviceAccumulatorsController.js @@ -0,0 +1,48 @@ +/* + * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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.dialog.DeviceAccumulatorsController', { + extend: 'Ext.app.ViewController', + alias: 'controller.deviceAccumulators', + + onSetClick: function () { + var totalDistance, hours, data = { + deviceId: this.getView().deviceId + }; + totalDistance = this.lookupReference('totalDistance'); + if (!isNaN(totalDistance.getRawValue())) { + data.totalDistance = totalDistance.getValue(); + } + hours = this.lookupReference('hours'); + if (!isNaN(hours.getRawValue())) { + data.hours = hours.getValue(); + } + Ext.Ajax.request({ + scope: this, + method: 'PUT', + url: 'api/devices/' + data.deviceId + '/accumulators', + jsonData: Ext.util.JSON.encode(data), + callback: function (options, success, response) { + if (!success) { + Traccar.app.showError(response); + } + } + }); + this.closeView(); + } +}); diff --git a/legacy/web/app/view/dialog/DeviceController.js b/legacy/web/app/view/dialog/DeviceController.js new file mode 100644 index 00000000..d7a4493b --- /dev/null +++ b/legacy/web/app/view/dialog/DeviceController.js @@ -0,0 +1,29 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.dialog.DeviceController', { + extend: 'Traccar.view.dialog.BaseEditController', + alias: 'controller.device', + + init: function () { + if (Traccar.app.getUser().get('administrator')) { + this.lookupReference('disabledField').setHidden(false); + } + } + +}); diff --git a/legacy/web/app/view/dialog/Driver.js b/legacy/web/app/view/dialog/Driver.js new file mode 100644 index 00000000..9b1c17b5 --- /dev/null +++ b/legacy/web/app/view/dialog/Driver.js @@ -0,0 +1,46 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.dialog.Driver', { + extend: 'Traccar.view.dialog.BaseEdit', + + requires: [ + 'Traccar.view.UnescapedTextField' + ], + + title: Strings.sharedDriver, + + items: { + xtype: 'form', + items: [{ + xtype: 'fieldset', + title: Strings.sharedRequired, + items: [{ + xtype: 'unescapedTextField', + name: 'name', + fieldLabel: Strings.sharedName, + allowBlank: false + }, { + xtype: 'unescapedTextField', + name: 'uniqueId', + fieldLabel: Strings.deviceIdentifier, + allowBlank: false + }] + }] + } +}); diff --git a/legacy/web/app/view/dialog/Geofence.js b/legacy/web/app/view/dialog/Geofence.js new file mode 100644 index 00000000..1e22cd7b --- /dev/null +++ b/legacy/web/app/view/dialog/Geofence.js @@ -0,0 +1,89 @@ +/* + * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.dialog.Geofence', { + extend: 'Traccar.view.dialog.BaseEdit', + + requires: [ + 'Traccar.view.ClearableComboBox', + 'Traccar.view.dialog.GeofenceController', + 'Traccar.view.UnescapedTextField' + ], + + controller: 'geofence', + title: Strings.sharedGeofence, + + items: { + xtype: 'form', + items: [{ + xtype: 'fieldset', + title: Strings.sharedRequired, + items: [{ + xtype: 'unescapedTextField', + name: 'name', + fieldLabel: Strings.sharedName + }] + }, { + xtype: 'fieldset', + title: Strings.sharedExtra, + collapsible: true, + collapsed: true, + items: [{ + xtype: 'unescapedTextField', + name: 'description', + fieldLabel: Strings.sharedDescription + }, { + xtype: 'clearableComboBox', + reference: 'calendarCombo', + name: 'calendarId', + store: 'Calendars', + queryMode: 'local', + displayField: 'name', + valueField: 'id', + fieldLabel: Strings.sharedCalendar + }, { + xtype: 'hiddenfield', + name: 'area', + allowBlank: false, + reference: 'areaField' + }] + }] + }, + + buttons: [{ + text: Strings.sharedArea, + glyph: 'xf21d@FontAwesome', + handler: 'onAreaClick' + }, { + text: Strings.sharedAttributes, + handler: 'showAttributesView' + }, { + xtype: 'tbfill' + }, { + glyph: 'xf00c@FontAwesome', + tooltip: Strings.sharedSave, + tooltipType: 'title', + minWidth: 0, + handler: 'onSaveClick' + }, { + glyph: 'xf00d@FontAwesome', + tooltip: Strings.sharedCancel, + tooltipType: 'title', + minWidth: 0, + handler: 'closeView' + }] +}); diff --git a/legacy/web/app/view/dialog/GeofenceController.js b/legacy/web/app/view/dialog/GeofenceController.js new file mode 100644 index 00000000..e4ac5a2e --- /dev/null +++ b/legacy/web/app/view/dialog/GeofenceController.js @@ -0,0 +1,58 @@ +/* + * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.dialog.GeofenceController', { + extend: 'Traccar.view.dialog.BaseEditController', + alias: 'controller.geofence', + + requires: [ + 'Traccar.view.BaseWindow', + 'Traccar.view.map.GeofenceMap' + ], + + config: { + listen: { + controller: { + '*': { + savearea: 'saveArea' + } + } + } + }, + + init: function () { + this.lookupReference('calendarCombo').setHidden( + Traccar.app.getBooleanAttributePreference('ui.disableCalendars')); + }, + + saveArea: function (value) { + this.lookupReference('areaField').setValue(value); + }, + + onAreaClick: function (button) { + var dialog, record; + dialog = button.up('window').down('form'); + record = dialog.getRecord(); + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedArea, + items: { + xtype: 'geofenceMapView', + area: record.get('area') + } + }).show(); + } +}); diff --git a/legacy/web/app/view/dialog/Group.js b/legacy/web/app/view/dialog/Group.js new file mode 100644 index 00000000..61ca193d --- /dev/null +++ b/legacy/web/app/view/dialog/Group.js @@ -0,0 +1,55 @@ +/* + * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.dialog.Group', { + extend: 'Traccar.view.dialog.BaseEdit', + + requires: [ + 'Traccar.view.ClearableComboBox', + 'Traccar.view.UnescapedTextField' + ], + + title: Strings.groupDialog, + + items: { + xtype: 'form', + items: [{ + xtype: 'fieldset', + title: Strings.sharedRequired, + items: [{ + xtype: 'unescapedTextField', + name: 'name', + fieldLabel: Strings.sharedName, + allowBlank: false + }] + }, { + xtype: 'fieldset', + title: Strings.sharedExtra, + collapsible: true, + collapsed: true, + items: [{ + xtype: 'clearableComboBox', + name: 'groupId', + fieldLabel: Strings.groupParent, + store: 'Groups', + queryMode: 'local', + displayField: 'name', + valueField: 'id' + }] + }] + } +}); diff --git a/legacy/web/app/view/dialog/Login.js b/legacy/web/app/view/dialog/Login.js new file mode 100644 index 00000000..592efb33 --- /dev/null +++ b/legacy/web/app/view/dialog/Login.js @@ -0,0 +1,151 @@ +/* + * Copyright 2015 - 2023 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.dialog.Login', { + extend: 'Traccar.view.dialog.Base', + alias: 'widget.login', + + requires: [ + 'Traccar.view.dialog.LoginController' + ], + + controller: 'login', + + header: false, + closable: false, + + items: { + xtype: 'form', + reference: 'form', + + autoEl: { + tag: 'form', + method: 'POST', + action: 'fake-login.html', + target: 'submitTarget' + }, + + items: [{ + xtype: 'image', + src: 'logo.svg', + alt: Strings.loginLogo, + width: 240, + height: 64, + style: { + display: 'block', + margin: '10px auto 25px' + } + }, { + xtype: 'pickerfield', + fieldLabel: Strings.settingsServer, + editable: false, + value: window.location.host, + hidden: !window.appInterface && !(window.webkit && window.webkit.messageHandlers.appInterface), + createPicker: function () { + var self = this, popup = Ext.create({ + xtype: 'window', + closeAction: 'hide', + referenceHolder: true, + minWidth: 204, + layout: 'form', + header: false, + resizable: true, + items: [{ + xtype: 'textfield', + anchor: '100%', + reference: 'serverAddress', + value: window.location.href + }], + fbar: [{ + text: Strings.sharedSet, + handler: function () { + var message = 'server|' + popup.lookupReference('serverAddress').getValue(); + if (window.webkit && window.webkit.messageHandlers.appInterface) { + window.webkit.messageHandlers.appInterface.postMessage(message); + } + if (window.appInterface) { + window.appInterface.postMessage(message); + } + } + }, { + text: Strings.sharedCancel, + handler: function () { + self.collapse(); + } + }] + }); + return popup; + } + }, { + xtype: 'combobox', + name: 'language', + fieldLabel: Strings.loginLanguage, + store: 'Languages', + displayField: 'name', + valueField: 'code', + editable: false, + submitValue: false, + listeners: { + select: 'onSelectLanguage' + }, + reference: 'languageField' + }, { + xtype: 'textfield', + name: 'email', + reference: 'userField', + fieldLabel: Strings.userEmail, + allowBlank: false, + enableKeyEvents: true, + listeners: { + specialKey: 'onSpecialKey', + afterrender: 'onAfterRender' + }, + inputAttrTpl: ['autocomplete="on" autocapitalize="none"'] + }, { + xtype: 'textfield', + name: 'password', + reference: 'passwordField', + fieldLabel: Strings.userPassword, + inputType: 'password', + allowBlank: false, + enableKeyEvents: true, + listeners: { + specialKey: 'onSpecialKey' + }, + inputAttrTpl: ['autocomplete="on"'] + }, { + xtype: 'component', + html: '<iframe id="submitTarget" name="submitTarget" style="display:none"></iframe>' + }, { + xtype: 'component', + html: '<input type="submit" id="submitButton" style="display:none">' + }] + }, + + buttons: [{ + text: Strings.loginReset, + handler: 'onResetClick', + reference: 'resetButton' + }, { + text: Strings.loginRegister, + handler: 'onRegisterClick', + reference: 'registerButton' + }, { + text: Strings.loginLogin, + handler: 'onLoginClick' + }] +}); diff --git a/legacy/web/app/view/dialog/LoginController.js b/legacy/web/app/view/dialog/LoginController.js new file mode 100644 index 00000000..a21866eb --- /dev/null +++ b/legacy/web/app/view/dialog/LoginController.js @@ -0,0 +1,132 @@ +/* + * Copyright 2015 - 2023 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.dialog.LoginController', { + extend: 'Ext.app.ViewController', + alias: 'controller.login', + + requires: [ + 'Traccar.view.dialog.Register' + ], + + init: function () { + this.lookupReference('resetButton').setHidden(!Traccar.app.getServer().get('emailEnabled')); + this.lookupReference('registerButton').setDisabled(!Traccar.app.getServer().get('registration')); + this.lookupReference('languageField').setValue(Locale.language); + }, + + login: function () { + var form = this.lookupReference('form'); + if (form.isValid()) { + Ext.get('spinner').setVisible(true); + this.getView().setVisible(false); + Ext.Ajax.request({ + scope: this, + method: 'POST', + url: 'api/session', + params: form.getValues(), + callback: function (options, success, response) { + Ext.get('spinner').setVisible(false); + if (success) { + Traccar.app.setUser(Ext.decode(response.responseText)); + this.fireViewEvent('login'); + } else { + this.getView().setVisible(true); + if (response.status === 401) { + Traccar.app.showError(Strings.loginFailed); + } else { + Traccar.app.showError(response.responseText); + } + } + } + }); + } + }, + + logout: function () { + Ext.util.Cookies.clear('user'); + Ext.util.Cookies.clear('password'); + Ext.Ajax.request({ + scope: this, + method: 'DELETE', + url: 'api/session', + callback: function () { + window.location.reload(); + } + }); + }, + + onSelectLanguage: function (selected) { + var paramName, paramValue, url, prefix, suffix; + paramName = 'locale'; + paramValue = selected.getValue(); + url = window.location.href; + if (url.indexOf(paramName + '=') >= 0) { + prefix = url.substring(0, url.indexOf(paramName)); + suffix = url.substring(url.indexOf(paramName)); + suffix = suffix.substring(suffix.indexOf('=') + 1); + suffix = suffix.indexOf('&') >= 0 ? suffix.substring(suffix.indexOf('&')) : ''; + url = prefix + paramName + '=' + paramValue + suffix; + } else if (url.indexOf('?') < 0) { + url += '?' + paramName + '=' + paramValue; + } else { + url += '&' + paramName + '=' + paramValue; + } + window.location.href = url; + }, + + onAfterRender: function (field) { + field.focus(); + }, + + onSpecialKey: function (field, e) { + if (e.getKey() === e.ENTER) { + this.login(); + } + }, + + onLoginClick: function () { + Ext.getElementById('submitButton').click(); + this.login(); + }, + + onRegisterClick: function () { + Ext.create('Traccar.view.dialog.Register').show(); + }, + + onResetClick: function () { + Ext.Msg.prompt(Strings.loginReset, Strings.userEmail, function (btn, text) { + if (btn === 'ok') { + Ext.Ajax.request({ + scope: this, + method: 'POST', + url: 'api/password/reset', + params: { + email: text + }, + callback: function (options, success, response) { + if (success) { + Traccar.app.showToast(Strings.loginResetSuccess); + } else { + Traccar.app.showError(response.responseText); + } + } + }); + } + }); + } +}); diff --git a/legacy/web/app/view/dialog/Maintenance.js b/legacy/web/app/view/dialog/Maintenance.js new file mode 100644 index 00000000..d844d259 --- /dev/null +++ b/legacy/web/app/view/dialog/Maintenance.js @@ -0,0 +1,75 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 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.dialog.Maintenance', { + extend: 'Traccar.view.dialog.BaseEdit', + + requires: [ + 'Traccar.view.dialog.MaintenanceController', + 'Traccar.view.CustomNumberField', + 'Traccar.view.UnescapedTextField' + ], + + controller: 'maintenance', + + title: Strings.sharedMaintenance, + + items: { + xtype: 'form', + listeners: { + validitychange: 'onValidityChange' + }, + items: [{ + xtype: 'fieldset', + title: Strings.sharedRequired, + items: [{ + xtype: 'unescapedTextField', + name: 'name', + fieldLabel: Strings.sharedName, + allowBlank: false + }, { + xtype: 'combobox', + name: 'type', + reference: 'typeComboField', + fieldLabel: Strings.sharedType, + displayField: 'name', + valueField: 'key', + allowBlank: false, + queryMode: 'local', + store: 'MaintenanceTypes', + listeners: { + change: 'onNameChange' + } + }, { + xtype: 'customNumberField', + name: 'start', + reference: 'startField', + fieldLabel: Strings.maintenanceStart + }, { + xtype: 'customNumberField', + name: 'period', + reference: 'periodField', + allowBlank: false, + fieldLabel: Strings.maintenancePeriod, + validator: function (value) { + return this.parseValue(value) !== 0 ? true : Strings.errorZero; + } + }] + }] + } +}); diff --git a/legacy/web/app/view/dialog/MaintenanceController.js b/legacy/web/app/view/dialog/MaintenanceController.js new file mode 100644 index 00000000..d5a27b54 --- /dev/null +++ b/legacy/web/app/view/dialog/MaintenanceController.js @@ -0,0 +1,65 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 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.dialog.MaintenanceController', { + extend: 'Traccar.view.dialog.BaseEditController', + alias: 'controller.maintenance', + + init: function () { + this.startConfig = Ext.clone(this.lookupReference('startField').initialConfig); + this.startConfig.value = 0; + this.periodConfig = Ext.clone(this.lookupReference('periodField').initialConfig); + this.periodConfig.value = 0; + this.lookupReference('saveButton').setDisabled(true); + }, + + onValidityChange: function (form, valid) { + this.lookupReference('saveButton').setDisabled(!valid); + }, + + updateFieldConfig: function (fieldReference, initialConfig, newConfig) { + var field = this.lookupReference(fieldReference); + if (field.dataType !== newConfig.dataType) { + this.getView().down('fieldset').insert(this.getView().down('fieldset').items.indexOf(field), + Ext.merge({}, initialConfig, newConfig)); + this.getView().down('fieldset').remove(field); + this.lookupReference(fieldReference).validate(); + } else { + field.setConfig(newConfig); + field.validate(); + } + }, + + onNameChange: function (combobox, newValue) { + var attribute, config = {}; + attribute = combobox.getStore().getById(newValue); + if (attribute) { + if (attribute.get('allowDecimals') !== undefined) { + config.allowDecimals = attribute.get('allowDecimals'); + } else { + config.allowDecimals = true; + } + config.dataType = attribute.get('dataType'); + config.maxValue = attribute.get('maxValue'); + config.minValue = attribute.get('minValue'); + } + + this.updateFieldConfig('startField', this.startConfig, config); + this.updateFieldConfig('periodField', this.periodConfig, config); + } +}); diff --git a/legacy/web/app/view/dialog/MapPickerController.js b/legacy/web/app/view/dialog/MapPickerController.js new file mode 100644 index 00000000..8641e377 --- /dev/null +++ b/legacy/web/app/view/dialog/MapPickerController.js @@ -0,0 +1,42 @@ +/* + * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.dialog.MapPickerController', { + extend: 'Traccar.view.dialog.BaseEditController', + alias: 'controller.mapPicker', + + config: { + listen: { + controller: { + '*': { + mapstate: 'setMapState' + } + } + } + }, + + getMapState: function () { + this.fireEvent('mapstaterequest'); + }, + + setMapState: function (lat, lon, zoom) { + this.lookupReference('latitude').setValue(lat); + this.lookupReference('longitude').setValue(lon); + this.lookupReference('zoom').setValue(zoom); + } +}); diff --git a/legacy/web/app/view/dialog/Notification.js b/legacy/web/app/view/dialog/Notification.js new file mode 100644 index 00000000..51af5b8e --- /dev/null +++ b/legacy/web/app/view/dialog/Notification.js @@ -0,0 +1,95 @@ +/* + * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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.dialog.Notification', { + extend: 'Traccar.view.dialog.BaseEdit', + + requires: [ + 'Traccar.view.ClearableComboBox', + 'Traccar.view.dialog.NotificationController' + ], + + controller: 'notification', + title: Strings.sharedNotification, + + items: { + xtype: 'form', + items: [{ + xtype: 'fieldset', + title: Strings.sharedRequired, + items: [{ + xtype: 'combobox', + name: 'type', + fieldLabel: Strings.sharedType, + store: 'AllNotificationTypes', + queryMode: 'local', + displayField: 'name', + valueField: 'type', + editable: false, + allowBlank: false, + listeners: { + change: 'onTypeChange' + } + }, { + xtype: 'checkboxfield', + inputValue: true, + uncheckedValue: false, + name: 'always', + fieldLabel: Strings.notificationAlways + }, { + xtype: 'tagfield', + reference: 'alarmsField', + fieldLabel: Strings.sharedAlarms, + maxWidth: Traccar.Style.formFieldWidth, + store: 'AlarmTypes', + valueField: 'key', + displayField: 'name', + queryMode: 'local', + hidden: true, + listeners: { + beforerender: 'onAlarmsLoad', + change: 'onAlarmsChange' + } + }, { + xtype: 'tagfield', + fieldLabel: Strings.notificationNotificators, + name: 'notificators', + maxWidth: Traccar.Style.formFieldWidth, + store: 'AllNotificators', + valueField: 'type', + displayField: 'name', + queryMode: 'local' + }] + }, { + xtype: 'fieldset', + title: Strings.sharedExtra, + collapsible: true, + collapsed: true, + items: [{ + xtype: 'clearableComboBox', + reference: 'calendarCombo', + name: 'calendarId', + store: 'Calendars', + queryMode: 'local', + displayField: 'name', + valueField: 'id', + fieldLabel: Strings.sharedCalendar + }] + }] + } +}); diff --git a/legacy/web/app/view/dialog/NotificationController.js b/legacy/web/app/view/dialog/NotificationController.js new file mode 100644 index 00000000..5da669a4 --- /dev/null +++ b/legacy/web/app/view/dialog/NotificationController.js @@ -0,0 +1,53 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 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.dialog.NotificationController', { + extend: 'Traccar.view.dialog.BaseEditController', + alias: 'controller.notification', + + init: function () { + this.lookupReference('calendarCombo').setHidden( + Traccar.app.getBooleanAttributePreference('ui.disableCalendars')); + }, + + onTypeChange: function (view, value) { + this.lookupReference('alarmsField').setHidden(value !== 'alarm'); + }, + + onAlarmsLoad: function (view) { + var attributes, record = view.up('form').getRecord(); + attributes = record.get('attributes') || {}; + if (attributes['alarms']) { + view.suspendEvents(false); + view.setValue(attributes['alarms'].split(',')); + view.resumeEvents(); + } + }, + + onAlarmsChange: function (view, value) { + var attributes, record = view.up('window').down('form').getRecord(); + attributes = record.get('attributes') || {}; + + value = value.join(); + if (attributes['alarms'] !== value) { + attributes['alarms'] = value; + record.set('attributes', attributes); + record.dirty = true; + } + } +}); diff --git a/legacy/web/app/view/dialog/Register.js b/legacy/web/app/view/dialog/Register.js new file mode 100644 index 00000000..f9608cef --- /dev/null +++ b/legacy/web/app/view/dialog/Register.js @@ -0,0 +1,67 @@ +/* + * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.dialog.Register', { + extend: 'Traccar.view.dialog.Base', + + requires: [ + 'Traccar.view.dialog.RegisterController' + ], + + controller: 'register', + + title: Strings.loginRegister, + + items: { + xtype: 'form', + reference: 'form', + jsonSubmit: true, + + items: [{ + xtype: 'textfield', + name: 'name', + fieldLabel: Strings.sharedName, + allowBlank: false + }, { + xtype: 'textfield', + name: 'email', + fieldLabel: Strings.userEmail, + validator: function (val) { + if (/(.+)@(.+)\.(.{2,})/.test(val)) { + return true; + } else { + return Ext.form.field.VTypes.emailText; + } + }, + allowBlank: false + }, { + xtype: 'textfield', + name: 'password', + fieldLabel: Strings.userPassword, + inputType: 'password', + allowBlank: false + }] + }, + + buttons: [{ + text: Strings.sharedSave, + handler: 'onCreateClick' + }, { + text: Strings.sharedCancel, + handler: 'closeView' + }] +}); diff --git a/legacy/web/app/view/dialog/RegisterController.js b/legacy/web/app/view/dialog/RegisterController.js new file mode 100644 index 00000000..c102581e --- /dev/null +++ b/legacy/web/app/view/dialog/RegisterController.js @@ -0,0 +1,44 @@ +/* + * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.dialog.RegisterController', { + extend: 'Ext.app.ViewController', + alias: 'controller.register', + + onCreateClick: function () { + var form = this.lookupReference('form'); + if (form.isValid()) { + Ext.Ajax.request({ + scope: this, + method: 'POST', + url: 'api/users', + jsonData: form.getValues(), + callback: this.onCreateReturn + }); + } + }, + + onCreateReturn: function (options, success, response) { + if (success) { + this.closeView(); + Traccar.app.showToast(Strings.loginCreated); + } else { + Traccar.app.showError(response); + } + } + +}); diff --git a/legacy/web/app/view/dialog/ReportConfig.js b/legacy/web/app/view/dialog/ReportConfig.js new file mode 100644 index 00000000..35cc95b4 --- /dev/null +++ b/legacy/web/app/view/dialog/ReportConfig.js @@ -0,0 +1,136 @@ +/* + * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.dialog.ReportConfig', { + extend: 'Traccar.view.dialog.Base', + + requires: [ + 'Traccar.view.dialog.ReportConfigController', + 'Traccar.view.CustomTimeField' + ], + + controller: 'reportConfig', + title: Strings.reportConfigure, + + items: [{ + fieldLabel: Strings.reportDevice, + xtype: 'tagfield', + reference: 'deviceField', + maxWidth: Traccar.Style.formFieldWidth, + store: 'Devices', + valueField: 'id', + displayField: 'name', + queryMode: 'local' + }, { + fieldLabel: Strings.reportGroup, + xtype: 'tagfield', + reference: 'groupField', + maxWidth: Traccar.Style.formFieldWidth, + store: 'Groups', + valueField: 'id', + displayField: 'name', + queryMode: 'local' + }, { + fieldLabel: Strings.reportEventTypes, + xtype: 'tagfield', + reference: 'eventTypeField', + maxWidth: Traccar.Style.formFieldWidth, + store: 'ReportEventTypes', + hidden: true, + valueField: 'type', + displayField: 'name', + queryMode: 'local' + }, { + fieldLabel: Strings.reportChartType, + xtype: 'combobox', + reference: 'chartTypeField', + store: 'ReportChartTypes', + hidden: true, + value: 'speed', + valueField: 'key', + displayField: 'name', + queryMode: 'local' + }, { + fieldLabel: Strings.reportShowMarkers, + xtype: 'checkbox', + reference: 'showMarkersField', + inputValue: true, + uncheckedValue: false, + value: false + }, { + fieldLabel: Strings.reportPeriod, + reference: 'periodField', + xtype: 'combobox', + store: 'ReportPeriods', + editable: false, + valueField: 'key', + displayField: 'name', + queryMode: 'local', + listeners: { + change: 'onPeriodChange' + } + }, { + xtype: 'fieldcontainer', + layout: 'vbox', + reference: 'fromContainer', + hidden: true, + fieldLabel: Strings.reportFrom, + items: [{ + xtype: 'datefield', + reference: 'fromDateField', + startDay: Traccar.Style.weekStartDay, + format: Traccar.Style.dateFormat, + value: new Date(new Date().getTime() - 30 * 60 * 1000) + }, { + xtype: 'customTimeField', + reference: 'fromTimeField', + value: new Date(new Date().getTime() - 30 * 60 * 1000) + }] + }, { + xtype: 'fieldcontainer', + layout: 'vbox', + reference: 'toContainer', + hidden: true, + fieldLabel: Strings.reportTo, + items: [{ + xtype: 'datefield', + reference: 'toDateField', + startDay: Traccar.Style.weekStartDay, + format: Traccar.Style.dateFormat, + value: new Date() + }, { + xtype: 'customTimeField', + reference: 'toTimeField', + value: new Date() + }] + }], + + buttons: [{ + glyph: 'xf00c@FontAwesome', + tooltip: Strings.sharedSave, + tooltipType: 'title', + minWidth: 0, + handler: 'onSaveClick' + }, { + glyph: 'xf00d@FontAwesome', + tooltip: Strings.sharedCancel, + tooltipType: 'title', + minWidth: 0, + handler: 'closeView' + }] +}); diff --git a/legacy/web/app/view/dialog/ReportConfigController.js b/legacy/web/app/view/dialog/ReportConfigController.js new file mode 100644 index 00000000..6d029428 --- /dev/null +++ b/legacy/web/app/view/dialog/ReportConfigController.js @@ -0,0 +1,99 @@ +/* + * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.dialog.ReportConfigController', { + extend: 'Ext.app.ViewController', + alias: 'controller.reportConfig', + + requires: [ + 'Traccar.store.ReportEventTypes', + 'Traccar.store.AllNotifications' + ], + + onSaveClick: function (button) { + var eventType, callingPanel; + callingPanel = this.getView().callingPanel; + + callingPanel.deviceId = this.lookupReference('deviceField').getValue(); + callingPanel.groupId = this.lookupReference('groupField').getValue(); + eventType = this.lookupReference('eventTypeField').getValue(); + if (eventType.indexOf(Traccar.store.ReportEventTypes.allEvents) > -1) { + eventType = [Traccar.store.ReportEventTypes.allEvents]; + } else if (eventType.length === this.lookupReference('eventTypeField').getStore().getCount() - 1) { + eventType = [Traccar.store.ReportEventTypes.allEvents]; + } + callingPanel.eventType = eventType; + callingPanel.chartType = this.lookupReference('chartTypeField').getValue(); + callingPanel.showMarkers = this.lookupReference('showMarkersField').getValue(); + callingPanel.fromDate = this.lookupReference('fromDateField').getValue(); + callingPanel.fromTime = this.lookupReference('fromTimeField').getValue(); + callingPanel.toDate = this.lookupReference('toDateField').getValue(); + callingPanel.toTime = this.lookupReference('toTimeField').getValue(); + callingPanel.period = this.lookupReference('periodField').getValue(); + callingPanel.updateButtons(); + button.up('window').close(); + }, + + onPeriodChange: function (combobox, newValue) { + var day, first, from, to, custom = newValue === 'custom'; + this.lookupReference('fromContainer').setHidden(!custom); + this.lookupReference('toContainer').setHidden(!custom); + if (!custom) { + from = new Date(); + to = new Date(); + switch (newValue) { + case 'today': + to.setDate(to.getDate() + 1); + break; + case 'yesterday': + from.setDate(to.getDate() - 1); + break; + case 'thisWeek': + day = from.getDay(); + first = from.getDate() - day + (day === 0 ? -6 : 1); + from.setDate(first); + to.setDate(first + 7); + break; + case 'previousWeek': + day = from.getDay(); + first = from.getDate() - day + (day === 0 ? -6 : 1); + from.setDate(first - 7); + to.setDate(first); + break; + case 'thisMonth': + from.setDate(1); + to.setDate(1); + to.setMonth(from.getMonth() + 1); + break; + case 'previousMonth': + from.setDate(1); + from.setMonth(from.getMonth() - 1); + to.setDate(1); + break; + default: + break; + } + from.setHours(0, 0, 0, 0); + to.setHours(0, 0, 0, 0); + this.lookupReference('fromDateField').setValue(from); + this.lookupReference('fromTimeField').setValue(from); + this.lookupReference('toDateField').setValue(to); + this.lookupReference('toTimeField').setValue(to); + } + } +}); diff --git a/legacy/web/app/view/dialog/SavedCommand.js b/legacy/web/app/view/dialog/SavedCommand.js new file mode 100644 index 00000000..b1aeae73 --- /dev/null +++ b/legacy/web/app/view/dialog/SavedCommand.js @@ -0,0 +1,83 @@ +/* + * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.dialog.SavedCommand', { + extend: 'Traccar.view.dialog.BaseEdit', + + requires: [ + 'Traccar.view.dialog.SavedCommandController', + 'Traccar.view.UnescapedTextField' + ], + + controller: 'savedCommand', + title: Strings.sharedSavedCommand, + + items: [{ + xtype: 'form', + listeners: { + validitychange: 'onValidityChange' + }, + items: [{ + xtype: 'fieldset', + title: Strings.sharedRequired, + items: [{ + xtype: 'unescapedTextField', + name: 'description', + fieldLabel: Strings.sharedDescription + }, { + xtype: 'checkboxfield', + name: 'textChannel', + inputValue: true, + uncheckedValue: false, + fieldLabel: Strings.commandSendSms + }, { + xtype: 'combobox', + name: 'type', + reference: 'commandType', + fieldLabel: Strings.sharedType, + store: 'AllCommandTypes', + queryMode: 'local', + displayField: 'name', + valueField: 'type', + editable: false, + allowBlank: false, + listeners: { + change: 'onTypeChange' + } + }, { + xtype: 'fieldcontainer', + reference: 'parameters' + }] + }] + }], + + buttons: [{ + glyph: 'xf00c@FontAwesome', + reference: 'saveButton', + tooltip: Strings.sharedSave, + tooltipType: 'title', + minWidth: 0, + disabled: true, + handler: 'onSaveClick' + }, { + glyph: 'xf00d@FontAwesome', + tooltip: Strings.sharedCancel, + tooltipType: 'title', + minWidth: 0, + handler: 'closeView' + }] +}); diff --git a/legacy/web/app/view/dialog/SavedCommandController.js b/legacy/web/app/view/dialog/SavedCommandController.js new file mode 100644 index 00000000..37c56603 --- /dev/null +++ b/legacy/web/app/view/dialog/SavedCommandController.js @@ -0,0 +1,99 @@ +/* + * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.dialog.SavedCommandController', { + extend: 'Traccar.view.dialog.BaseEditController', + alias: 'controller.savedCommand', + + defaultFieldConfig: { + allowBlank: false + }, + + onTypeChange: function (combo, newValue) { + var i, config, command, parameters, parameter, record; + record = combo.up('window').down('form').getRecord(); + this.lookupReference('parameters').removeAll(); + command = Ext.getStore('KnownCommands').getById(newValue); + if (command && command.get('parameters')) { + parameters = command.get('parameters'); + for (i = 0; i < parameters.length; i++) { + parameter = new Traccar.model.KnownAttribute(parameters[i]); + config = Ext.clone(this.defaultFieldConfig); + config.key = parameter.get('key'); + config.fieldLabel = parameter.get('name'); + if (record.get('attributes')) { + config.value = record.get('attributes')[parameter.get('key')]; + } + config.disabled = combo.isDisabled(); + switch (parameter.get('valueType')) { + case 'number': + config.xtype = 'customNumberField'; + if (parameter.get('allowDecimals') !== undefined) { + config.allowDecimals = parameter.get('allowDecimals'); + } else { + config.allowDecimals = true; + } + config.dataType = parameter.get('dataType'); + config.maxValue = parameter.get('maxValue'); + config.minValue = parameter.get('minValue'); + break; + case 'boolean': + config.xtype = 'checkboxfield'; + config.inputValue = true; + config.uncheckedValue = false; + break; + default: + if (parameter.get('dataType') === 'timezone') { + config.xtype = 'combobox'; + config.queryMode = 'local'; + config.displayField = 'key'; + config.editable = false; + config.store = 'AllTimezones'; + } else { + config.xtype = 'textfield'; + } + } + this.lookupReference('parameters').add(config); + } + } + }, + + fillAttributes: function (button) { + var i, form, record, parameters, attributes = {}; + + form = button.up('window').down('form'); + form.updateRecord(); + record = form.getRecord(); + parameters = this.lookupReference('parameters').items.items; + + for (i = 0; i < parameters.length; i++) { + attributes[parameters[i].key] = parameters[i].getValue(); + } + + record.set('attributes', attributes); + }, + + onSaveClick: function (button) { + this.fillAttributes(button); + this.callParent(arguments); + }, + + onValidityChange: function (form, valid) { + this.lookupReference('saveButton').setDisabled(!valid); + } + +}); diff --git a/legacy/web/app/view/dialog/SelectDevice.js b/legacy/web/app/view/dialog/SelectDevice.js new file mode 100644 index 00000000..5b11c03f --- /dev/null +++ b/legacy/web/app/view/dialog/SelectDevice.js @@ -0,0 +1,59 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +Ext.define('Traccar.view.dialog.SelectDevice', { + extend: 'Traccar.view.dialog.Base', + + requires: [ + 'Traccar.view.dialog.SelectDeviceController' + ], + + controller: 'selectDevice', + title: Strings.sharedDevice, + + items: { + xtype: 'form', + items: [{ + xtype: 'combobox', + reference: 'deviceField', + store: 'Devices', + queryMode: 'local', + displayField: 'name', + valueField: 'id', + editable: false, + listeners: { + change: 'onDeviceChange' + } + }] + }, + + buttons: [{ + glyph: 'xf00c@FontAwesome', + reference: 'saveButton', + tooltip: Strings.sharedSave, + tooltipType: 'title', + minWidth: 0, + handler: 'onSaveClick', + disabled: true + }, { + glyph: 'xf00d@FontAwesome', + tooltip: Strings.sharedCancel, + tooltipType: 'title', + minWidth: 0, + handler: 'closeView' + }] +}); diff --git a/legacy/web/app/view/dialog/SelectDeviceController.js b/legacy/web/app/view/dialog/SelectDeviceController.js new file mode 100644 index 00000000..9437991c --- /dev/null +++ b/legacy/web/app/view/dialog/SelectDeviceController.js @@ -0,0 +1,45 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.dialog.SelectDeviceController', { + extend: 'Ext.app.ViewController', + alias: 'controller.selectDevice', + + onSaveClick: function (button) { + var deviceId, record; + deviceId = this.lookupReference('deviceField').getValue(); + record = this.getView().record.data; + Ext.Ajax.request({ + url: 'api/attributes/computed/test?deviceId=' + deviceId, + method: 'POST', + jsonData: Ext.util.JSON.encode(record), + callback: function (options, success, response) { + if (success) { + Ext.Msg.alert(Strings.sharedInfoTitle, response.responseText || response.statusText); + } else { + Traccar.app.showError(response); + } + } + }); + button.up('window').close(); + }, + + onDeviceChange: function (combobox, newValue) { + this.lookupReference('saveButton').setDisabled(newValue === null); + } +}); diff --git a/legacy/web/app/view/dialog/SendCommand.js b/legacy/web/app/view/dialog/SendCommand.js new file mode 100644 index 00000000..79954739 --- /dev/null +++ b/legacy/web/app/view/dialog/SendCommand.js @@ -0,0 +1,98 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.dialog.SendCommand', { + extend: 'Traccar.view.dialog.Base', + + requires: [ + 'Traccar.view.dialog.SendCommandController' + ], + + controller: 'sendCommand', + title: Strings.commandTitle, + + items: [{ + xtype: 'combobox', + reference: 'commandsComboBox', + fieldLabel: Strings.deviceCommand, + displayField: 'description', + valueField: 'id', + store: 'DeviceCommands', + queryMode: 'local', + editable: false, + allowBlank: false, + listeners: { + select: 'onCommandSelect' + } + }, { + xtype: 'form', + listeners: { + validitychange: 'onValidityChange' + }, + items: [{ + xtype: 'fieldset', + reference: 'newCommandFields', + disabled: true, + items: [{ + xtype: 'checkboxfield', + name: 'textChannel', + reference: 'textChannelCheckBox', + inputValue: true, + uncheckedValue: false, + fieldLabel: Strings.commandSendSms, + listeners: { + change: 'onTextChannelChange' + } + }, { + xtype: 'combobox', + name: 'type', + reference: 'commandType', + fieldLabel: Strings.sharedType, + store: 'CommandTypes', + displayField: 'name', + valueField: 'type', + editable: false, + allowBlank: false, + listeners: { + change: 'onTypeChange' + } + }, { + xtype: 'fieldcontainer', + reference: 'parameters' + }] + }] + }], + + buttons: [{ + xtype: 'tbfill' + }, { + glyph: 'xf093@FontAwesome', + tooltip: Strings.sharedSend, + tooltipType: 'title', + minWidth: 0, + disabled: true, + reference: 'sendButton', + handler: 'onSendClick' + }, { + glyph: 'xf00d@FontAwesome', + tooltip: Strings.sharedCancel, + tooltipType: 'title', + minWidth: 0, + handler: 'closeView' + }] +}); diff --git a/legacy/web/app/view/dialog/SendCommandController.js b/legacy/web/app/view/dialog/SendCommandController.js new file mode 100644 index 00000000..c6351587 --- /dev/null +++ b/legacy/web/app/view/dialog/SendCommandController.js @@ -0,0 +1,78 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.dialog.SendCommandController', { + extend: 'Traccar.view.dialog.SavedCommandController', + alias: 'controller.sendCommand', + + requires: [ + 'Traccar.view.permissions.SavedCommands' + ], + + onSendClick: function (button) { + var record; + this.fillAttributes(button); + record = button.up('window').down('form').getRecord(); + + Ext.Ajax.request({ + scope: this, + url: 'api/commands/send', + jsonData: record.getData(), + callback: this.onSendResult + }); + }, + + onValidityChange: function (form, valid) { + this.lookupReference('sendButton').setDisabled(!valid || + this.lookupReference('commandsComboBox').getValue() === null); + }, + + onTextChannelChange: function (checkbox, newValue) { + var typesStore = this.lookupReference('commandType').getStore(); + typesStore.getProxy().setExtraParam('textChannel', newValue); + typesStore.reload(); + }, + + onCommandSelect: function (selected) { + var record, form, command = selected.getStore().getById(selected.getValue()); + command.set('deviceId', this.getView().deviceId); + form = selected.up('window').down('form'); + record = form.getRecord(); + form.loadRecord(command); + if (record && command.get('type') === record.get('type')) { + this.onTypeChange(this.lookupReference('commandType'), command.get('type')); + } + + this.lookupReference('newCommandFields').setDisabled(command.getId() !== 0); + this.lookupReference('sendButton').setDisabled(command.getId() === 0); + }, + + onSendResult: function (options, success, response) { + if (success) { + this.closeView(); + Traccar.app.showToast(response.status === 202 ? Strings.commandQueued : Strings.commandSent); + } else { + Traccar.app.showError(response); + } + }, + + closeView: function () { + this.lookupReference('commandsComboBox').getStore().removeAll(); + this.callParent(arguments); + } +}); diff --git a/legacy/web/app/view/dialog/Server.js b/legacy/web/app/view/dialog/Server.js new file mode 100644 index 00000000..6ee250b6 --- /dev/null +++ b/legacy/web/app/view/dialog/Server.js @@ -0,0 +1,159 @@ +/* + * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.dialog.Server', { + extend: 'Traccar.view.dialog.BaseEdit', + + requires: [ + 'Traccar.view.ClearableComboBox', + 'Traccar.view.dialog.MapPickerController', + 'Traccar.view.UnescapedTextField' + ], + + controller: 'mapPicker', + title: Strings.serverTitle, + + items: { + xtype: 'form', + items: [{ + xtype: 'fieldset', + title: Strings.sharedPreferences, + items: [{ + xtype: 'clearableComboBox', + name: 'map', + fieldLabel: Strings.mapLayer, + store: 'MapTypes', + displayField: 'name', + valueField: 'key' + }, { + xtype: 'unescapedTextField', + name: 'bingKey', + fieldLabel: Strings.mapBingKey + }, { + xtype: 'unescapedTextField', + reference: 'mapUrlField', + name: 'mapUrl', + fieldLabel: Strings.mapCustomLabel + }, { + xtype: 'numberfield', + reference: 'latitude', + name: 'latitude', + fieldLabel: Strings.positionLatitude, + decimalPrecision: Traccar.Style.coordinatePrecision + }, { + xtype: 'numberfield', + reference: 'longitude', + name: 'longitude', + fieldLabel: Strings.positionLongitude, + decimalPrecision: Traccar.Style.coordinatePrecision + }, { + xtype: 'numberfield', + reference: 'zoom', + name: 'zoom', + fieldLabel: Strings.serverZoom + }, { + xtype: 'checkboxfield', + inputValue: true, + uncheckedValue: false, + name: 'twelveHourFormat', + fieldLabel: Strings.settingsTwelveHourFormat + }, { + xtype: 'checkboxfield', + inputValue: true, + uncheckedValue: false, + name: 'forceSettings', + fieldLabel: Strings.serverForceSettings + }, { + xtype: 'clearableComboBox', + name: 'coordinateFormat', + fieldLabel: Strings.settingsCoordinateFormat, + store: 'CoordinateFormats', + displayField: 'name', + valueField: 'key' + }, { + xtype: 'unescapedTextField', + name: 'poiLayer', + fieldLabel: Strings.mapPoiLayer + }, { + xtype: 'unescapedTextField', + name: 'announcement', + fieldLabel: Strings.serverAnnouncement + }] + }, { + xtype: 'fieldset', + title: Strings.sharedPermissions, + collapsible: true, + collapsed: true, + items: [{ + xtype: 'checkboxfield', + inputValue: true, + uncheckedValue: false, + name: 'registration', + fieldLabel: Strings.serverRegistration + }, { + xtype: 'checkboxfield', + inputValue: true, + uncheckedValue: false, + name: 'readonly', + fieldLabel: Strings.serverReadonly + }, { + xtype: 'checkboxfield', + inputValue: true, + uncheckedValue: false, + name: 'deviceReadonly', + fieldLabel: Strings.userDeviceReadonly + }, { + xtype: 'checkboxfield', + inputValue: true, + uncheckedValue: false, + name: 'limitCommands', + fieldLabel: Strings.userLimitCommands + }, { + xtype: 'checkboxfield', + inputValue: true, + uncheckedValue: false, + name: 'disableReports', + fieldLabel: Strings.userDisableReports + }] + }] + }, + + buttons: [{ + text: Strings.sharedAttributes, + handler: 'showAttributesView' + }, { + glyph: 'xf041@FontAwesome', + minWidth: 0, + handler: 'getMapState', + tooltip: Strings.sharedGetMapState, + tooltipType: 'title' + }, { + xtype: 'tbfill' + }, { + glyph: 'xf00c@FontAwesome', + tooltip: Strings.sharedSave, + tooltipType: 'title', + minWidth: 0, + handler: 'onSaveClick' + }, { + glyph: 'xf00d@FontAwesome', + tooltip: Strings.sharedCancel, + tooltipType: 'title', + minWidth: 0, + handler: 'closeView' + }] +}); diff --git a/legacy/web/app/view/dialog/User.js b/legacy/web/app/view/dialog/User.js new file mode 100644 index 00000000..5da56424 --- /dev/null +++ b/legacy/web/app/view/dialog/User.js @@ -0,0 +1,211 @@ +/* + * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.dialog.User', { + extend: 'Traccar.view.dialog.BaseEdit', + + requires: [ + 'Traccar.view.ClearableComboBox', + 'Traccar.view.dialog.UserController', + 'Traccar.view.UnescapedTextField' + ], + + controller: 'user', + title: Strings.settingsUser, + + items: { + xtype: 'form', + items: [{ + xtype: 'fieldset', + title: Strings.sharedRequired, + items: [{ + xtype: 'unescapedTextField', + name: 'name', + fieldLabel: Strings.sharedName + }, { + xtype: 'unescapedTextField', + name: 'email', + fieldLabel: Strings.userEmail, + allowBlank: false + }, { + xtype: 'textfield', + name: 'password', + fieldLabel: Strings.userPassword, + inputType: 'password', + allowBlank: false + }] + }, { + xtype: 'fieldset', + title: Strings.sharedPreferences, + collapsible: true, + collapsed: true, + items: [{ + xtype: 'unescapedTextField', + name: 'phone', + fieldLabel: Strings.sharedPhone + }, { + xtype: 'clearableComboBox', + name: 'map', + fieldLabel: Strings.mapLayer, + store: 'MapTypes', + displayField: 'name', + valueField: 'key' + }, { + xtype: 'numberfield', + reference: 'latitude', + name: 'latitude', + fieldLabel: Strings.positionLatitude, + decimalPrecision: Traccar.Style.coordinatePrecision + }, { + xtype: 'numberfield', + reference: 'longitude', + name: 'longitude', + fieldLabel: Strings.positionLongitude, + decimalPrecision: Traccar.Style.coordinatePrecision + }, { + xtype: 'numberfield', + reference: 'zoom', + name: 'zoom', + fieldLabel: Strings.serverZoom + }, { + xtype: 'checkboxfield', + inputValue: true, + uncheckedValue: false, + name: 'twelveHourFormat', + fieldLabel: Strings.settingsTwelveHourFormat + }, { + xtype: 'clearableComboBox', + name: 'coordinateFormat', + fieldLabel: Strings.settingsCoordinateFormat, + store: 'CoordinateFormats', + displayField: 'name', + valueField: 'key' + }, { + xtype: 'unescapedTextField', + name: 'poiLayer', + fieldLabel: Strings.mapPoiLayer + }] + }, { + xtype: 'fieldset', + title: Strings.sharedPermissions, + collapsible: true, + collapsed: true, + items: [{ + xtype: 'checkboxfield', + inputValue: true, + uncheckedValue: false, + name: 'disabled', + fieldLabel: Strings.sharedDisabled, + disabled: true, + reference: 'disabledField' + }, { + xtype: 'checkboxfield', + inputValue: true, + uncheckedValue: false, + name: 'administrator', + fieldLabel: Strings.userAdmin, + disabled: true, + reference: 'adminField' + }, { + xtype: 'checkboxfield', + inputValue: true, + uncheckedValue: false, + name: 'readonly', + fieldLabel: Strings.serverReadonly, + disabled: true, + reference: 'readonlyField' + }, { + xtype: 'checkboxfield', + inputValue: true, + uncheckedValue: false, + name: 'deviceReadonly', + fieldLabel: Strings.userDeviceReadonly, + disabled: true, + reference: 'deviceReadonlyField' + }, { + xtype: 'checkboxfield', + inputValue: true, + uncheckedValue: false, + name: 'limitCommands', + fieldLabel: Strings.userLimitCommands, + disabled: true, + reference: 'limitCommandsField' + }, { + xtype: 'checkboxfield', + inputValue: true, + uncheckedValue: false, + name: 'disableReports', + fieldLabel: Strings.userDisableReports, + disabled: true, + reference: 'disableReportsField' + }, { + xtype: 'datefield', + name: 'expirationTime', + fieldLabel: Strings.userExpirationTime, + disabled: true, + reference: 'expirationTimeField', + startDay: Traccar.Style.weekStartDay, + format: Traccar.Style.dateFormat + }, { + xtype: 'numberfield', + name: 'deviceLimit', + fieldLabel: Strings.userDeviceLimit, + disabled: true, + reference: 'deviceLimitField' + }, { + xtype: 'numberfield', + name: 'userLimit', + fieldLabel: Strings.userUserLimit, + disabled: true, + reference: 'userLimitField' + }] + }] + }, + + buttons: [{ + text: Strings.sharedAttributes, + handler: 'showAttributesView' + }, { + glyph: 'xf041@FontAwesome', + minWidth: 0, + handler: 'getMapState', + tooltip: Strings.sharedGetMapState, + tooltipType: 'title' + }, { + glyph: 'xf003@FontAwesome', + minWidth: 0, + handler: 'testNotification', + hidden: true, + reference: 'testNotificationButton', + tooltip: Strings.sharedTestNotification, + tooltipType: 'title' + }, { + xtype: 'tbfill' + }, { + glyph: 'xf00c@FontAwesome', + tooltip: Strings.sharedSave, + tooltipType: 'title', + minWidth: 0, + handler: 'onSaveClick' + }, { + glyph: 'xf00d@FontAwesome', + tooltip: Strings.sharedCancel, + tooltipType: 'title', + minWidth: 0, + handler: 'closeView' + }] +}); diff --git a/legacy/web/app/view/dialog/UserController.js b/legacy/web/app/view/dialog/UserController.js new file mode 100644 index 00000000..0d620614 --- /dev/null +++ b/legacy/web/app/view/dialog/UserController.js @@ -0,0 +1,69 @@ +/* + * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.dialog.UserController', { + extend: 'Traccar.view.dialog.MapPickerController', + alias: 'controller.user', + + init: function () { + if (Traccar.app.getUser().get('administrator')) { + this.lookupReference('adminField').setDisabled(false); + this.lookupReference('deviceLimitField').setDisabled(false); + this.lookupReference('userLimitField').setDisabled(false); + } + if (Traccar.app.getUser().get('administrator') || !this.getView().selfEdit) { + this.lookupReference('readonlyField').setDisabled(false); + this.lookupReference('disabledField').setDisabled(false); + this.lookupReference('expirationTimeField').setDisabled(false); + this.lookupReference('deviceReadonlyField').setDisabled(false); + this.lookupReference('limitCommandsField').setDisabled(false); + this.lookupReference('disableReportsField').setDisabled(false); + } + }, + + testNotification: function () { + Ext.Ajax.request({ + url: 'api/notifications/test', + method: 'POST', + failure: function (response) { + Traccar.app.showError(response); + } + }); + }, + + onSaveClick: function (button) { + var dialog, record, store; + dialog = button.up('window').down('form'); + dialog.updateRecord(); + record = dialog.getRecord(); + if (record === Traccar.app.getUser()) { + record.save(); + } else { + store = Ext.getStore('Users'); + if (record.phantom) { + store.add(record); + } + store.sync({ + failure: function (batch) { + store.rejectChanges(); + Traccar.app.showError(batch.exceptions[0].getError().response); + } + }); + } + button.up('window').close(); + } +}); diff --git a/legacy/web/app/view/edit/Attributes.js b/legacy/web/app/view/edit/Attributes.js new file mode 100644 index 00000000..af4f5a90 --- /dev/null +++ b/legacy/web/app/view/edit/Attributes.js @@ -0,0 +1,65 @@ +/* + * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.edit.Attributes', { + extend: 'Traccar.view.GridPanel', + xtype: 'attributesView', + + requires: [ + 'Traccar.view.edit.AttributesController', + 'Traccar.view.edit.Toolbar' + ], + + controller: 'attributes', + + tbar: { + xtype: 'editToolbar' + }, + + listeners: { + selectionchange: 'onSelectionChange' + }, + + columns: { + defaults: { + flex: 1, + minWidth: Traccar.Style.columnWidthNormal + }, + items: [{ + text: Strings.sharedName, + dataIndex: 'name', + filter: 'string', + renderer: function (value) { + var attribute; + if (this.attributesStore) { + attribute = Ext.getStore(this.attributesStore).getById(value); + } + return attribute && attribute.get('name') || value; + } + }, { + text: Strings.stateValue, + dataIndex: 'value', + renderer: function (value, metaData, record) { + var attribute; + if (this.attributesStore) { + attribute = Ext.getStore(this.attributesStore).getById(record.get('name')); + } + return Traccar.AttributeFormatter.renderAttribute(value, attribute); + } + }] + } +}); diff --git a/legacy/web/app/view/edit/AttributesController.js b/legacy/web/app/view/edit/AttributesController.js new file mode 100644 index 00000000..84ff6adf --- /dev/null +++ b/legacy/web/app/view/edit/AttributesController.js @@ -0,0 +1,124 @@ +/* + * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.edit.AttributesController', { + extend: 'Traccar.view.edit.ToolbarController', + alias: 'controller.attributes', + + requires: [ + 'Traccar.view.dialog.Attribute', + 'Traccar.store.Attributes', + 'Traccar.model.Attribute' + ], + + removeTitle: Strings.stateName, + + init: function () { + var store, propertyName, i = 0, attributes; + store = Ext.create('Traccar.store.Attributes'); + store.setProxy(Ext.create('Ext.data.proxy.Memory')); + if (typeof this.getView().record.get('attributes') === 'undefined') { + this.getView().record.set('attributes', {}); + } + attributes = this.getView().record.get('attributes'); + for (propertyName in attributes) { + if (attributes.hasOwnProperty(propertyName)) { + store.add(Ext.create('Traccar.model.Attribute', { + priority: i++, + name: propertyName, + value: attributes[propertyName] + })); + } + } + store.addListener('add', function (store, records) { + var i, view; + view = this.getView(); + for (i = 0; i < records.length; i++) { + view.record.get('attributes')[records[i].get('name')] = records[i].get('value'); + } + view.record.dirty = true; + }, this); + store.addListener('update', function (store, record, operation) { + var view; + view = this.getView(); + if (operation === Ext.data.Model.EDIT) { + if (record.modified.name !== record.get('name')) { + delete view.record.get('attributes')[record.modified.name]; + } + view.record.get('attributes')[record.get('name')] = record.get('value'); + view.record.dirty = true; + } + }, this); + store.addListener('remove', function (store, records) { + var i, view; + view = this.getView(); + for (i = 0; i < records.length; i++) { + delete view.record.get('attributes')[records[i].get('name')]; + } + view.record.dirty = true; + }, this); + + this.getView().setStore(store); + if (this.getView().record instanceof Traccar.model.Device) { + this.getView().attributesStore = 'DeviceAttributes'; + } else if (this.getView().record instanceof Traccar.model.Geofence) { + this.getView().attributesStore = 'GeofenceAttributes'; + } else if (this.getView().record instanceof Traccar.model.Group) { + this.getView().attributesStore = 'GroupAttributes'; + } else if (this.getView().record instanceof Traccar.model.Server) { + this.getView().attributesStore = 'ServerAttributes'; + } else if (this.getView().record instanceof Traccar.model.User) { + this.getView().attributesStore = 'UserAttributes'; + } + }, + + comboConfig: { + xtype: 'combobox', + reference: 'nameComboField', + name: 'name', + fieldLabel: Strings.sharedName, + displayField: 'name', + valueField: 'key', + allowBlank: false, + queryMode: 'local', + listeners: { + change: 'onNameChange' + } + }, + + initDialog: function (record) { + var nameTextField, dialog = Ext.create('Traccar.view.dialog.Attribute'); + if (this.getView().attributesStore) { + this.comboConfig.store = this.getView().attributesStore; + nameTextField = dialog.lookupReference('nameTextField'); + dialog.down('form').insert(0, this.comboConfig); + dialog.down('form').remove(nameTextField); + } + dialog.down('form').loadRecord(record); + dialog.show(); + }, + + onAddClick: function () { + var objectInstance = Ext.create('Traccar.model.Attribute'); + objectInstance.store = this.getView().getStore(); + this.initDialog(objectInstance); + }, + + onEditClick: function () { + this.initDialog(this.getView().getSelectionModel().getSelection()[0]); + } +}); diff --git a/legacy/web/app/view/edit/Calendars.js b/legacy/web/app/view/edit/Calendars.js new file mode 100644 index 00000000..23f20e25 --- /dev/null +++ b/legacy/web/app/view/edit/Calendars.js @@ -0,0 +1,50 @@ +/* + * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.edit.Calendars', { + extend: 'Traccar.view.GridPanel', + xtype: 'calendarsView', + + requires: [ + 'Traccar.view.edit.CalendarsController', + 'Traccar.view.edit.Toolbar' + ], + + controller: 'calendars', + store: 'Calendars', + + tbar: { + xtype: 'editToolbar' + }, + + listeners: { + selectionchange: 'onSelectionChange' + }, + + columns: { + defaults: { + flex: 1, + minWidth: Traccar.Style.columnWidthNormal + }, + items: [{ + text: Strings.sharedName, + dataIndex: 'name', + filter: 'string' + }] + } +}); diff --git a/legacy/web/app/view/edit/CalendarsController.js b/legacy/web/app/view/edit/CalendarsController.js new file mode 100644 index 00000000..d11ec379 --- /dev/null +++ b/legacy/web/app/view/edit/CalendarsController.js @@ -0,0 +1,31 @@ +/* + * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.edit.CalendarsController', { + extend: 'Traccar.view.edit.ToolbarController', + alias: 'controller.calendars', + + requires: [ + 'Traccar.view.dialog.Calendar', + 'Traccar.model.Calendar' + ], + + objectModel: 'Traccar.model.Calendar', + objectDialog: 'Traccar.view.dialog.Calendar', + removeTitle: Strings.sharedCalendar +}); diff --git a/legacy/web/app/view/edit/ComputedAttributes.js b/legacy/web/app/view/edit/ComputedAttributes.js new file mode 100644 index 00000000..9f0b9396 --- /dev/null +++ b/legacy/web/app/view/edit/ComputedAttributes.js @@ -0,0 +1,80 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.edit.ComputedAttributes', { + extend: 'Traccar.view.GridPanel', + xtype: 'computedAttributesView', + + requires: [ + 'Traccar.view.edit.ComputedAttributesController', + 'Traccar.view.edit.Toolbar' + ], + + controller: 'computedAttributes', + store: 'ComputedAttributes', + + tbar: { + xtype: 'editToolbar' + }, + + listeners: { + selectionchange: 'onSelectionChange' + }, + + columns: { + defaults: { + flex: 1, + minWidth: Traccar.Style.columnWidthNormal + }, + items: [{ + text: Strings.sharedDescription, + dataIndex: 'description', + filter: 'string' + }, { + text: Strings.sharedAttribute, + dataIndex: 'attribute', + filter: { + type: 'list', + labelField: 'name', + store: 'PositionAttributes' + }, + renderer: function (value) { + return Ext.getStore('PositionAttributes').getAttributeName(value); + } + }, { + text: Strings.sharedExpression, + dataIndex: 'expression' + }, { + text: Strings.sharedType, + dataIndex: 'type', + filter: { + type: 'list', + labelField: 'name', + store: 'AttributeValueTypes' + }, + renderer: function (value) { + var type = Ext.getStore('AttributeValueTypes').getById(value); + if (type) { + return type.get('name'); + } else { + return value; + } + } + }] + } +}); diff --git a/legacy/web/app/view/edit/ComputedAttributesController.js b/legacy/web/app/view/edit/ComputedAttributesController.js new file mode 100644 index 00000000..6ae14102 --- /dev/null +++ b/legacy/web/app/view/edit/ComputedAttributesController.js @@ -0,0 +1,31 @@ +/* + * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.edit.ComputedAttributesController', { + extend: 'Traccar.view.edit.ToolbarController', + alias: 'controller.computedAttributes', + + requires: [ + 'Traccar.view.dialog.ComputedAttribute', + 'Traccar.model.ComputedAttribute' + ], + + objectModel: 'Traccar.model.ComputedAttribute', + objectDialog: 'Traccar.view.dialog.ComputedAttribute', + removeTitle: Strings.sharedComputedAttribute +}); diff --git a/legacy/web/app/view/edit/Devices.js b/legacy/web/app/view/edit/Devices.js new file mode 100644 index 00000000..5f54202a --- /dev/null +++ b/legacy/web/app/view/edit/Devices.js @@ -0,0 +1,161 @@ +/* + * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.edit.Devices', { + extend: 'Traccar.view.GridPanel', + xtype: 'devicesView', + + requires: [ + 'Traccar.AttributeFormatter', + 'Traccar.view.edit.DevicesController', + 'Traccar.view.ArrayListFilter', + 'Traccar.view.DeviceMenu' + ], + + controller: 'devices', + + store: 'VisibleDevices', + + stateful: true, + stateId: 'devices-grid', + + tbar: { + componentCls: 'toolbar-header-style', + defaults: { + xtype: 'button', + disabled: true, + tooltipType: 'title' + }, + items: [{ + xtype: 'tbtext', + html: Strings.deviceTitle, + baseCls: 'x-panel-header-title-default' + }, { + xtype: 'tbfill', + disabled: false + }, { + handler: 'onAddClick', + reference: 'toolbarAddButton', + glyph: 'xf067@FontAwesome', + tooltip: Strings.sharedAdd + }, { + handler: 'onEditClick', + reference: 'toolbarEditButton', + glyph: 'xf040@FontAwesome', + tooltip: Strings.sharedEdit + }, { + handler: 'onRemoveClick', + reference: 'toolbarRemoveButton', + glyph: 'xf00d@FontAwesome', + tooltip: Strings.sharedRemove + }, { + handler: 'onCommandClick', + reference: 'deviceCommandButton', + glyph: 'xf093@FontAwesome', + tooltip: Strings.deviceCommand + }, { + xtype: 'deviceMenu', + reference: 'toolbarDeviceMenu', + enableToggle: false + }] + }, + + listeners: { + selectionchange: 'onSelectionChange' + }, + + viewConfig: { + enableTextSelection: true, + getRowClass: function (record) { + var result = '', status = record.get('status'); + if (record.get('disabled')) { + result = 'view-item-disabled '; + } + if (status) { + result += Ext.getStore('DeviceStatuses').getById(status).get('color'); + } + return result; + } + }, + + columns: { + defaults: { + flex: 1, + minWidth: Traccar.Style.columnWidthNormal + }, + items: [{ + text: Strings.sharedName, + dataIndex: 'name', + filter: 'string' + }, { + text: Strings.deviceIdentifier, + dataIndex: 'uniqueId', + hidden: true, + filter: 'string' + }, { + text: Strings.sharedPhone, + dataIndex: 'phone', + hidden: true + }, { + text: Strings.deviceModel, + dataIndex: 'model', + hidden: true + }, { + text: Strings.deviceContact, + dataIndex: 'contact', + hidden: true + }, { + text: Strings.groupDialog, + dataIndex: 'groupId', + hidden: true, + filter: { + type: 'list', + labelField: 'name', + store: 'Groups' + }, + renderer: Traccar.AttributeFormatter.getFormatter('groupId') + }, { + text: Strings.sharedDisabled, + dataIndex: 'disabled', + renderer: Traccar.AttributeFormatter.getFormatter('disabled'), + hidden: true, + filter: 'boolean' + }, { + text: Strings.deviceStatus, + dataIndex: 'status', + filter: { + type: 'list', + labelField: 'name', + store: 'DeviceStatuses' + }, + renderer: function (value) { + var status; + if (value) { + status = Ext.getStore('DeviceStatuses').getById(value); + if (status) { + return status.get('name'); + } + } + return null; + } + }, { + text: Strings.deviceLastUpdate, + dataIndex: 'lastUpdate', + renderer: Traccar.AttributeFormatter.getFormatter('lastUpdate') + }] + } +}); diff --git a/legacy/web/app/view/edit/DevicesController.js b/legacy/web/app/view/edit/DevicesController.js new file mode 100644 index 00000000..16e54b21 --- /dev/null +++ b/legacy/web/app/view/edit/DevicesController.js @@ -0,0 +1,139 @@ +/* + * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.edit.DevicesController', { + extend: 'Traccar.view.edit.ToolbarController', + alias: 'controller.devices', + + requires: [ + 'Traccar.view.dialog.SendCommand', + 'Traccar.view.dialog.Device', + 'Traccar.view.permissions.Geofences', + 'Traccar.view.permissions.ComputedAttributes', + 'Traccar.view.permissions.Drivers', + 'Traccar.view.permissions.SavedCommands', + 'Traccar.view.BaseWindow', + 'Traccar.model.Device', + 'Traccar.model.Command' + ], + + config: { + listen: { + controller: { + '*': { + selectreport: 'deselectDevice', + selectevent: 'deselectDevice' + }, + 'root': { + selectdevice: 'selectDevice' + }, + 'map': { + selectdevice: 'selectDevice', + deselectfeature: 'deselectFeature' + } + }, + store: { + '#Devices': { + update: 'onUpdateDevice' + } + } + } + }, + + objectModel: 'Traccar.model.Device', + objectDialog: 'Traccar.view.dialog.Device', + removeTitle: Strings.sharedDevice, + + init: function () { + var self = this, readonly, deviceReadonly; + deviceReadonly = Traccar.app.getPreference('deviceReadonly', false) && !Traccar.app.getUser().get('administrator'); + readonly = Traccar.app.getPreference('readonly', false) && !Traccar.app.getUser().get('administrator'); + this.lookupReference('toolbarAddButton').setDisabled(readonly || deviceReadonly); + this.lookupReference('toolbarDeviceMenu').setHidden(readonly || deviceReadonly); + + setInterval(function () { + self.getView().getView().refresh(); + }, Traccar.Style.refreshPeriod); + }, + + onCommandClick: function () { + var device, deviceId, dialog, typesStore, commandsStore; + device = this.getView().getSelectionModel().getSelection()[0]; + deviceId = device.get('id'); + + dialog = Ext.create('Traccar.view.dialog.SendCommand'); + dialog.deviceId = deviceId; + + commandsStore = dialog.lookupReference('commandsComboBox').getStore(); + commandsStore.getProxy().setExtraParam('deviceId', deviceId); + if (!Traccar.app.getPreference('limitCommands', false)) { + commandsStore.add({ + id: 0, + description: Strings.sharedNew + }); + } + commandsStore.load({ + addRecords: true + }); + + typesStore = dialog.lookupReference('commandType').getStore(); + typesStore.getProxy().setExtraParam('deviceId', deviceId); + typesStore.load(); + + dialog.show(); + }, + + updateButtons: function (selected) { + var readonly, deviceReadonly, empty, deviceMenu; + deviceReadonly = Traccar.app.getPreference('deviceReadonly', false) && !Traccar.app.getUser().get('administrator'); + readonly = Traccar.app.getPreference('readonly', false) && !Traccar.app.getUser().get('administrator'); + empty = selected.length === 0; + this.lookupReference('toolbarEditButton').setDisabled(empty || readonly || deviceReadonly); + this.lookupReference('toolbarRemoveButton').setDisabled(empty || readonly || deviceReadonly); + deviceMenu = this.lookupReference('toolbarDeviceMenu'); + deviceMenu.device = empty ? null : selected[0]; + deviceMenu.setDisabled(empty); + this.lookupReference('deviceCommandButton').setDisabled(empty || readonly); + }, + + onSelectionChange: function (el, records) { + if (records && records.length) { + this.updateButtons(records); + this.fireEvent('selectdevice', records[0], true); + } + }, + + selectDevice: function (device) { + this.getView().getSelectionModel().select([device], false, true); + this.updateButtons(this.getView().getSelectionModel().getSelected().items); + this.getView().getView().focusRow(device); + }, + + deselectDevice: function (object) { + if (object) { + this.deselectFeature(); + } + }, + + onUpdateDevice: function () { + this.updateButtons(this.getView().getSelectionModel().getSelected().items); + }, + + deselectFeature: function () { + this.getView().getSelectionModel().deselectAll(); + } +}); diff --git a/legacy/web/app/view/edit/Drivers.js b/legacy/web/app/view/edit/Drivers.js new file mode 100644 index 00000000..7bd10a68 --- /dev/null +++ b/legacy/web/app/view/edit/Drivers.js @@ -0,0 +1,54 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.edit.Drivers', { + extend: 'Traccar.view.GridPanel', + xtype: 'driversView', + + requires: [ + 'Traccar.view.edit.DriversController', + 'Traccar.view.edit.Toolbar' + ], + + controller: 'drivers', + store: 'Drivers', + + tbar: { + xtype: 'editToolbar' + }, + + listeners: { + selectionchange: 'onSelectionChange' + }, + + columns: { + defaults: { + flex: 1, + minWidth: Traccar.Style.columnWidthNormal + }, + items: [{ + text: Strings.sharedName, + dataIndex: 'name', + filter: 'string' + }, { + text: Strings.deviceIdentifier, + dataIndex: 'uniqueId', + filter: 'string' + }] + } +}); diff --git a/legacy/web/app/view/edit/DriversController.js b/legacy/web/app/view/edit/DriversController.js new file mode 100644 index 00000000..6c8a63cc --- /dev/null +++ b/legacy/web/app/view/edit/DriversController.js @@ -0,0 +1,31 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.edit.DriversController', { + extend: 'Traccar.view.edit.ToolbarController', + alias: 'controller.drivers', + + requires: [ + 'Traccar.view.dialog.Driver', + 'Traccar.model.Driver' + ], + + objectModel: 'Traccar.model.Driver', + objectDialog: 'Traccar.view.dialog.Driver', + removeTitle: Strings.sharedDriver +}); diff --git a/legacy/web/app/view/edit/Geofences.js b/legacy/web/app/view/edit/Geofences.js new file mode 100644 index 00000000..0e1e6773 --- /dev/null +++ b/legacy/web/app/view/edit/Geofences.js @@ -0,0 +1,63 @@ +/* + * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.edit.Geofences', { + extend: 'Traccar.view.GridPanel', + xtype: 'geofencesView', + + requires: [ + 'Traccar.view.edit.GeofencesController', + 'Traccar.view.edit.Toolbar' + ], + + controller: 'geofences', + store: 'Geofences', + + tbar: { + xtype: 'editToolbar' + }, + + listeners: { + selectionchange: 'onSelectionChange' + }, + + columns: { + defaults: { + flex: 1, + minWidth: Traccar.Style.columnWidthNormal + }, + items: [{ + text: Strings.sharedName, + dataIndex: 'name', + filter: 'string' + }, { + text: Strings.sharedDescription, + dataIndex: 'description', + filter: 'string' + }, { + text: Strings.sharedCalendar, + dataIndex: 'calendarId', + hidden: true, + filter: { + type: 'list', + labelField: 'name', + store: 'AllCalendars' + }, + renderer: Traccar.AttributeFormatter.getFormatter('calendarId') + }] + } +}); diff --git a/legacy/web/app/view/edit/GeofencesController.js b/legacy/web/app/view/edit/GeofencesController.js new file mode 100644 index 00000000..73d367ac --- /dev/null +++ b/legacy/web/app/view/edit/GeofencesController.js @@ -0,0 +1,30 @@ +/* + * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.edit.GeofencesController', { + extend: 'Traccar.view.edit.ToolbarController', + alias: 'controller.geofences', + + requires: [ + 'Traccar.view.dialog.Geofence', + 'Traccar.model.Geofence' + ], + + objectModel: 'Traccar.model.Geofence', + objectDialog: 'Traccar.view.dialog.Geofence', + removeTitle: Strings.sharedGeofence +}); diff --git a/legacy/web/app/view/edit/Groups.js b/legacy/web/app/view/edit/Groups.js new file mode 100644 index 00000000..8b09316c --- /dev/null +++ b/legacy/web/app/view/edit/Groups.js @@ -0,0 +1,109 @@ +/* + * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.edit.Groups', { + extend: 'Traccar.view.GridPanel', + xtype: 'groupsView', + + requires: [ + 'Traccar.AttributeFormatter', + 'Traccar.view.edit.GroupsController', + 'Traccar.view.edit.Toolbar' + ], + + controller: 'groups', + store: 'Groups', + + tbar: { + xtype: 'editToolbar', + items: [{ + xtype: 'button', + disabled: true, + handler: 'onGeofencesClick', + reference: 'toolbarGeofencesButton', + glyph: 'xf21d@FontAwesome', + tooltip: Strings.sharedGeofences, + tooltipType: 'title' + }, { + xtype: 'button', + disabled: true, + handler: 'onAttributesClick', + reference: 'toolbarAttributesButton', + glyph: 'xf0ae@FontAwesome', + tooltip: Strings.sharedComputedAttributes, + tooltipType: 'title' + }, { + xtype: 'button', + disabled: true, + handler: 'onDriversClick', + reference: 'toolbarDriversButton', + glyph: 'xf084@FontAwesome', + tooltip: Strings.sharedDrivers, + tooltipType: 'title' + }, { + xtype: 'button', + disabled: true, + handler: 'onCommandsClick', + reference: 'toolbarCommandsButton', + glyph: 'xf093@FontAwesome', + tooltip: Strings.sharedSavedCommands, + tooltipType: 'title' + }, { + xtype: 'button', + disabled: true, + handler: 'onNotificationsClick', + reference: 'toolbarNotificationsButton', + glyph: 'xf003@FontAwesome', + tooltip: Strings.sharedNotifications, + tooltipType: 'title' + }, { + xtype: 'button', + disabled: true, + handler: 'onMaintenancesClick', + reference: 'toolbarMaintenancesButton', + glyph: 'xf0ad@FontAwesome', + tooltip: Strings.sharedMaintenance, + tooltipType: 'title' + }] + }, + + listeners: { + selectionchange: 'onSelectionChange' + }, + + columns: { + defaults: { + flex: 1, + minWidth: Traccar.Style.columnWidthNormal + }, + items: [{ + text: Strings.sharedName, + dataIndex: 'name', + filter: 'string' + }, { + text: Strings.groupDialog, + dataIndex: 'groupId', + hidden: true, + filter: { + type: 'list', + labelField: 'name', + store: 'AllGroups' + }, + renderer: Traccar.AttributeFormatter.getFormatter('groupId') + }] + } +}); diff --git a/legacy/web/app/view/edit/GroupsController.js b/legacy/web/app/view/edit/GroupsController.js new file mode 100644 index 00000000..ae96a248 --- /dev/null +++ b/legacy/web/app/view/edit/GroupsController.js @@ -0,0 +1,141 @@ +/* + * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.edit.GroupsController', { + extend: 'Traccar.view.edit.ToolbarController', + alias: 'controller.groups', + + requires: [ + 'Traccar.view.dialog.Group', + 'Traccar.view.permissions.Geofences', + 'Traccar.view.permissions.ComputedAttributes', + 'Traccar.view.permissions.Drivers', + 'Traccar.view.permissions.SavedCommands', + 'Traccar.view.permissions.Maintenances', + 'Traccar.view.BaseWindow', + 'Traccar.model.Group' + ], + + objectModel: 'Traccar.model.Group', + objectDialog: 'Traccar.view.dialog.Group', + removeTitle: Strings.groupDialog, + + init: function () { + this.lookupReference('toolbarDriversButton').setHidden( + Traccar.app.getVehicleFeaturesDisabled() || Traccar.app.getBooleanAttributePreference('ui.disableDrivers')); + this.lookupReference('toolbarAttributesButton').setHidden( + Traccar.app.getBooleanAttributePreference('ui.disableComputedAttributes')); + this.lookupReference('toolbarCommandsButton').setHidden(Traccar.app.getPreference('limitCommands', false)); + this.lookupReference('toolbarMaintenancesButton').setHidden( + Traccar.app.getVehicleFeaturesDisabled() || Traccar.app.getBooleanAttributePreference('ui.disableMaintenance')); + }, + + onGeofencesClick: function () { + var group = this.getView().getSelectionModel().getSelection()[0]; + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedGeofences, + items: { + xtype: 'linkGeofencesView', + baseObjectName: 'groupId', + linkObjectName: 'geofenceId', + storeName: 'Geofences', + baseObject: group.getId() + } + }).show(); + }, + + onAttributesClick: function () { + var group = this.getView().getSelectionModel().getSelection()[0]; + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedComputedAttributes, + items: { + xtype: 'linkComputedAttributesView', + baseObjectName: 'groupId', + linkObjectName: 'attributeId', + storeName: 'ComputedAttributes', + baseObject: group.getId() + } + }).show(); + }, + + onDriversClick: function () { + var group = this.getView().getSelectionModel().getSelection()[0]; + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedDrivers, + items: { + xtype: 'linkDriversView', + baseObjectName: 'groupId', + linkObjectName: 'driverId', + storeName: 'Drivers', + baseObject: group.getId() + } + }).show(); + }, + + onCommandsClick: function () { + var group = this.getView().getSelectionModel().getSelection()[0]; + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedSavedCommands, + items: { + xtype: 'linkSavedCommandsView', + baseObjectName: 'groupId', + linkObjectName: 'commandId', + storeName: 'Commands', + baseObject: group.getId() + } + }).show(); + }, + + onNotificationsClick: function () { + var group = this.getView().getSelectionModel().getSelection()[0]; + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedNotifications, + items: { + xtype: 'linkNotificationsView', + baseObjectName: 'groupId', + linkObjectName: 'notificationId', + storeName: 'Notifications', + baseObject: group.getId() + } + }).show(); + }, + + onMaintenancesClick: function () { + var group = this.getView().getSelectionModel().getSelection()[0]; + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedMaintenance, + items: { + xtype: 'linkMaintenancesView', + baseObjectName: 'groupId', + linkObjectName: 'maintenanceId', + storeName: 'Maintenances', + baseObject: group.getId() + } + }).show(); + }, + + onSelectionChange: function (selection, selected) { + var disabled = selected.length === 0; + this.lookupReference('toolbarGeofencesButton').setDisabled(disabled); + this.lookupReference('toolbarAttributesButton').setDisabled(disabled); + this.lookupReference('toolbarDriversButton').setDisabled(disabled); + this.lookupReference('toolbarCommandsButton').setDisabled(disabled); + this.lookupReference('toolbarNotificationsButton').setDisabled(disabled); + this.lookupReference('toolbarMaintenancesButton').setDisabled(disabled); + this.callParent(arguments); + } +}); diff --git a/legacy/web/app/view/edit/Maintenances.js b/legacy/web/app/view/edit/Maintenances.js new file mode 100644 index 00000000..da129154 --- /dev/null +++ b/legacy/web/app/view/edit/Maintenances.js @@ -0,0 +1,77 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 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.edit.Maintenances', { + extend: 'Traccar.view.GridPanel', + xtype: 'maintenancesView', + + requires: [ + 'Traccar.view.edit.MaintenancesController', + 'Traccar.view.edit.Toolbar' + ], + + controller: 'maintenances', + store: 'Maintenances', + + tbar: { + xtype: 'editToolbar' + }, + + listeners: { + selectionchange: 'onSelectionChange' + }, + + columns: { + defaults: { + flex: 1, + minWidth: Traccar.Style.columnWidthNormal + }, + items: [{ + text: Strings.sharedName, + dataIndex: 'name', + filter: 'string' + }, { + text: Strings.sharedType, + dataIndex: 'type', + filter: { + type: 'list', + idField: 'key', + labelField: 'name', + store: 'MaintenanceTypes' + }, + renderer: function (value) { + var attribute = Ext.getStore('MaintenanceTypes').getById(value); + return attribute && attribute.get('name') || value; + } + }, { + text: Strings.maintenanceStart, + dataIndex: 'start', + renderer: function (value, metaData, record) { + return Traccar.AttributeFormatter.renderAttribute( + value, Ext.getStore('MaintenanceTypes').getById(record.get('type'))); + } + }, { + text: Strings.maintenancePeriod, + dataIndex: 'period', + renderer: function (value, metaData, record) { + return Traccar.AttributeFormatter.renderAttribute( + value, Ext.getStore('MaintenanceTypes').getById(record.get('type'))); + } + }] + } +}); diff --git a/legacy/web/app/view/edit/MaintenancesController.js b/legacy/web/app/view/edit/MaintenancesController.js new file mode 100644 index 00000000..19762e61 --- /dev/null +++ b/legacy/web/app/view/edit/MaintenancesController.js @@ -0,0 +1,31 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 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.edit.MaintenancesController', { + extend: 'Traccar.view.edit.ToolbarController', + alias: 'controller.maintenances', + + requires: [ + 'Traccar.view.dialog.Maintenance', + 'Traccar.model.Maintenance' + ], + + objectModel: 'Traccar.model.Maintenance', + objectDialog: 'Traccar.view.dialog.Maintenance', + removeTitle: Strings.sharedMaintenance +}); diff --git a/legacy/web/app/view/edit/Notifications.js b/legacy/web/app/view/edit/Notifications.js new file mode 100644 index 00000000..9cf97b19 --- /dev/null +++ b/legacy/web/app/view/edit/Notifications.js @@ -0,0 +1,111 @@ +/* + * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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.edit.Notifications', { + extend: 'Traccar.view.GridPanel', + xtype: 'notificationsView', + + requires: [ + 'Traccar.view.edit.NotificationsController', + 'Traccar.view.edit.Toolbar' + ], + + controller: 'notifications', + store: 'Notifications', + + tbar: { + xtype: 'editToolbar' + }, + + listeners: { + selectionchange: 'onSelectionChange' + }, + + columns: { + defaults: { + flex: 1, + minWidth: Traccar.Style.columnWidthNormal + }, + items: [{ + text: Strings.notificationType, + dataIndex: 'type', + flex: 2, + renderer: function (value) { + return Traccar.app.getEventString(value); + }, + filter: { + type: 'list', + idField: 'type', + labelField: 'name', + store: 'AllNotificationTypes' + } + }, { + text: Strings.notificationAlways, + dataIndex: 'always', + renderer: Traccar.AttributeFormatter.getFormatter('always'), + filter: 'boolean' + }, { + text: Strings.sharedAlarms, + dataIndex: 'attributes', + renderer: function (value) { + var i, key, result = '', alarms = value && value['alarms']; + if (alarms) { + alarms = alarms.split(','); + for (i = 0; i < alarms.length; i++) { + key = 'alarm' + alarms[i].charAt(0).toUpperCase() + alarms[i].slice(1); + if (result) { + result += ', '; + } + result += Strings[key] || key; + } + } + return result; + } + }, { + text: Strings.notificationNotificators, + dataIndex: 'notificators', + flex: 2, + filter: { + type: 'arraylist', + idField: 'type', + labelField: 'name', + store: 'AllNotificators' + }, + renderer: function (value) { + var result = '', i, notificators; + if (value) { + notificators = value.split(/[ ,]+/).filter(Boolean); + for (i = 0; i < notificators.length; i++) { + result += Traccar.app.getNotificatorString(notificators[i]) + (i < notificators.length - 1 ? ', ' : ''); + } + } + return result; + } + }, { + text: Strings.sharedCalendar, + dataIndex: 'calendarId', + hidden: true, + filter: { + type: 'list', + labelField: 'name', + store: 'AllCalendars' + }, + renderer: Traccar.AttributeFormatter.getFormatter('calendarId') + }] + } +}); diff --git a/legacy/web/app/view/edit/NotificationsController.js b/legacy/web/app/view/edit/NotificationsController.js new file mode 100644 index 00000000..ad22a686 --- /dev/null +++ b/legacy/web/app/view/edit/NotificationsController.js @@ -0,0 +1,31 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.edit.NotificationsController', { + extend: 'Traccar.view.edit.ToolbarController', + alias: 'controller.notifications', + + requires: [ + 'Traccar.view.dialog.Notification', + 'Traccar.model.Notification' + ], + + objectModel: 'Traccar.model.Notification', + objectDialog: 'Traccar.view.dialog.Notification', + removeTitle: Strings.sharedNotification +}); diff --git a/legacy/web/app/view/edit/SavedCommands.js b/legacy/web/app/view/edit/SavedCommands.js new file mode 100644 index 00000000..9e5f4869 --- /dev/null +++ b/legacy/web/app/view/edit/SavedCommands.js @@ -0,0 +1,65 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.edit.SavedCommands', { + extend: 'Traccar.view.GridPanel', + xtype: 'savedCommandsView', + + requires: [ + 'Traccar.view.edit.SavedCommandsController', + 'Traccar.view.edit.Toolbar' + ], + + controller: 'savedCommands', + store: 'Commands', + + tbar: { + xtype: 'editToolbar' + }, + + listeners: { + selectionchange: 'onSelectionChange' + }, + + columns: { + defaults: { + flex: 1, + minWidth: Traccar.Style.columnWidthNormal + }, + items: [{ + text: Strings.sharedDescription, + dataIndex: 'description', + filter: 'string' + }, { + text: Strings.sharedType, + dataIndex: 'type', + filter: { + type: 'list', + idField: 'type', + labelField: 'name', + store: 'AllCommandTypes' + }, + renderer: Traccar.AttributeFormatter.getFormatter('commandType') + }, { + text: Strings.commandSendSms, + dataIndex: 'textChannel', + renderer: Traccar.AttributeFormatter.getFormatter('textChannel'), + filter: 'boolean' + }] + } +}); diff --git a/legacy/web/app/view/edit/SavedCommandsController.js b/legacy/web/app/view/edit/SavedCommandsController.js new file mode 100644 index 00000000..1511661e --- /dev/null +++ b/legacy/web/app/view/edit/SavedCommandsController.js @@ -0,0 +1,31 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.edit.SavedCommandsController', { + extend: 'Traccar.view.edit.ToolbarController', + alias: 'controller.savedCommands', + + requires: [ + 'Traccar.view.dialog.SavedCommand', + 'Traccar.model.Command' + ], + + objectModel: 'Traccar.model.Command', + objectDialog: 'Traccar.view.dialog.SavedCommand', + removeTitle: Strings.sharedSavedCommand +}); diff --git a/legacy/web/app/view/edit/Toolbar.js b/legacy/web/app/view/edit/Toolbar.js new file mode 100644 index 00000000..6999030b --- /dev/null +++ b/legacy/web/app/view/edit/Toolbar.js @@ -0,0 +1,49 @@ +/* + * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.edit.Toolbar', { + extend: 'Ext.toolbar.Toolbar', + xtype: 'editToolbar', + + initComponent: function () { + this.callParent(arguments); + this.add(0, [{ + xtype: 'button', + handler: 'onAddClick', + reference: 'toolbarAddButton', + glyph: 'xf067@FontAwesome', + tooltip: Strings.sharedAdd, + tooltipType: 'title' + }, { + xtype: 'button', + disabled: true, + handler: 'onEditClick', + reference: 'toolbarEditButton', + glyph: 'xf040@FontAwesome', + tooltip: Strings.sharedEdit, + tooltipType: 'title' + }, { + xtype: 'button', + disabled: true, + handler: 'onRemoveClick', + reference: 'toolbarRemoveButton', + glyph: 'xf00d@FontAwesome', + tooltip: Strings.sharedRemove, + tooltipType: 'title' + }]); + } +}); diff --git a/legacy/web/app/view/edit/ToolbarController.js b/legacy/web/app/view/edit/ToolbarController.js new file mode 100644 index 00000000..d3ca9de6 --- /dev/null +++ b/legacy/web/app/view/edit/ToolbarController.js @@ -0,0 +1,70 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +Ext.define('Traccar.view.edit.ToolbarController', { + extend: 'Ext.app.ViewController', + alias: 'controller.toolbarController', + + onAddClick: function () { + var dialog, objectInstance = Ext.create(this.objectModel); + objectInstance.store = this.getView().getStore(); + if (objectInstance.store instanceof Ext.data.ChainedStore) { + objectInstance.store = objectInstance.store.getSource(); + } + dialog = Ext.create(this.objectDialog); + dialog.down('form').loadRecord(objectInstance); + dialog.show(); + }, + + onEditClick: function () { + var dialog, objectInstance = this.getView().getSelectionModel().getSelection()[0]; + dialog = Ext.create(this.objectDialog); + dialog.down('form').loadRecord(objectInstance); + dialog.show(); + }, + + onRemoveClick: function () { + var objectInstance = this.getView().getSelectionModel().getSelection()[0]; + Ext.Msg.show({ + title: this.removeTitle, + message: Strings.sharedRemoveConfirm, + buttons: Ext.Msg.YESNO, + buttonText: { + yes: Strings.sharedRemove, + no: Strings.sharedCancel + }, + fn: function (btn) { + var store = objectInstance.store; + if (btn === 'yes') { + store.remove(objectInstance); + store.sync({ + failure: function (batch) { + store.rejectChanges(); + Traccar.app.showError(batch.exceptions[0].getError().response); + } + }); + } + } + }); + }, + + onSelectionChange: function (selection, selected) { + var disabled = selected.length === 0; + this.lookupReference('toolbarEditButton').setDisabled(disabled); + this.lookupReference('toolbarRemoveButton').setDisabled(disabled); + } +}); diff --git a/legacy/web/app/view/edit/Users.js b/legacy/web/app/view/edit/Users.js new file mode 100644 index 00000000..5d9a14f0 --- /dev/null +++ b/legacy/web/app/view/edit/Users.js @@ -0,0 +1,156 @@ +/* + * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 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.edit.Users', { + extend: 'Traccar.view.GridPanel', + xtype: 'usersView', + + requires: [ + 'Traccar.view.edit.UsersController', + 'Traccar.view.edit.Toolbar' + ], + + controller: 'users', + store: 'Users', + + tbar: { + xtype: 'editToolbar', + scrollable: true, + items: [{ + disabled: true, + handler: 'onGeofencesClick', + reference: 'userGeofencesButton', + glyph: 'xf21d@FontAwesome', + tooltip: Strings.sharedGeofences, + tooltipType: 'title' + }, { + disabled: true, + handler: 'onDevicesClick', + reference: 'userDevicesButton', + glyph: 'xf248@FontAwesome', + tooltip: Strings.deviceTitle, + tooltipType: 'title' + }, { + disabled: true, + handler: 'onGroupsClick', + reference: 'userGroupsButton', + glyph: 'xf247@FontAwesome', + tooltip: Strings.settingsGroups, + tooltipType: 'title' + }, { + disabled: true, + handler: 'onUsersClick', + reference: 'userUsersButton', + glyph: 'xf0c0@FontAwesome', + tooltip: Strings.settingsUsers, + tooltipType: 'title' + }, { + disabled: true, + handler: 'onNotificationsClick', + reference: 'userNotificationsButton', + glyph: 'xf003@FontAwesome', + tooltip: Strings.sharedNotifications, + tooltipType: 'title' + }, { + disabled: true, + handler: 'onCalendarsClick', + reference: 'userCalendarsButton', + glyph: 'xf073@FontAwesome', + tooltip: Strings.sharedCalendars, + tooltipType: 'title' + }, { + disabled: true, + handler: 'onAttributesClick', + reference: 'userAttributesButton', + glyph: 'xf0ae@FontAwesome', + tooltip: Strings.sharedComputedAttributes, + tooltipType: 'title' + }, { + disabled: true, + handler: 'onDriversClick', + reference: 'userDriversButton', + glyph: 'xf084@FontAwesome', + tooltip: Strings.sharedDrivers, + tooltipType: 'title' + }, { + xtype: 'button', + disabled: true, + handler: 'onCommandsClick', + reference: 'userCommandsButton', + glyph: 'xf093@FontAwesome', + tooltip: Strings.sharedSavedCommands, + tooltipType: 'title' + }, { + xtype: 'button', + disabled: true, + handler: 'onMaintenancesClick', + reference: 'userMaintenancesButton', + glyph: 'xf0ad@FontAwesome', + tooltip: Strings.sharedMaintenance, + tooltipType: 'title' + }] + }, + + listeners: { + selectionchange: 'onSelectionChange' + }, + + columns: { + defaults: { + flex: 1, + minWidth: Traccar.Style.columnWidthNormal + }, + items: [{ + text: Strings.sharedName, + dataIndex: 'name', + filter: 'string' + }, { + text: Strings.userEmail, + dataIndex: 'email', + filter: 'string' + }, { + text: Strings.userAdmin, + dataIndex: 'administrator', + renderer: Traccar.AttributeFormatter.getFormatter('administrator'), + filter: 'boolean' + }, { + text: Strings.serverReadonly, + dataIndex: 'readonly', + hidden: true, + renderer: Traccar.AttributeFormatter.getFormatter('readonly'), + filter: 'boolean' + }, { + text: Strings.userDeviceReadonly, + dataIndex: 'deviceReadonly', + renderer: Traccar.AttributeFormatter.getFormatter('deviceReadonly'), + hidden: true, + filter: 'boolean' + }, { + text: Strings.sharedDisabled, + dataIndex: 'disabled', + renderer: Traccar.AttributeFormatter.getFormatter('disabled'), + filter: 'boolean' + }, { + text: Strings.userExpirationTime, + dataIndex: 'expirationTime', + hidden: true, + renderer: Traccar.AttributeFormatter.getFormatter('expirationTime'), + filter: 'date' + }] + } +}); diff --git a/legacy/web/app/view/edit/UsersController.js b/legacy/web/app/view/edit/UsersController.js new file mode 100644 index 00000000..9e810435 --- /dev/null +++ b/legacy/web/app/view/edit/UsersController.js @@ -0,0 +1,244 @@ +/* + * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.edit.UsersController', { + extend: 'Traccar.view.edit.ToolbarController', + alias: 'controller.users', + + requires: [ + 'Traccar.view.dialog.User', + 'Traccar.view.permissions.Devices', + 'Traccar.view.permissions.Groups', + 'Traccar.view.permissions.Geofences', + 'Traccar.view.permissions.Calendars', + 'Traccar.view.permissions.Users', + 'Traccar.view.permissions.ComputedAttributes', + 'Traccar.view.permissions.Drivers', + 'Traccar.view.permissions.SavedCommands', + 'Traccar.view.permissions.Notifications', + 'Traccar.view.permissions.Maintenances', + 'Traccar.view.BaseWindow', + 'Traccar.model.User' + ], + + objectModel: 'Traccar.model.User', + objectDialog: 'Traccar.view.dialog.User', + removeTitle: Strings.settingsUser, + + init: function () { + Ext.getStore('Users').load(); + this.lookupReference('userUsersButton').setHidden(!Traccar.app.getUser().get('administrator')); + this.lookupReference('userDriversButton').setHidden( + Traccar.app.getVehicleFeaturesDisabled() || Traccar.app.getBooleanAttributePreference('ui.disableDrivers')); + this.lookupReference('userAttributesButton').setHidden( + Traccar.app.getBooleanAttributePreference('ui.disableComputedAttributes')); + this.lookupReference('userCalendarsButton').setHidden( + Traccar.app.getBooleanAttributePreference('ui.disableCalendars')); + this.lookupReference('userCommandsButton').setHidden(Traccar.app.getPreference('limitCommands', false)); + this.lookupReference('userMaintenancesButton').setHidden( + Traccar.app.getVehicleFeaturesDisabled() || Traccar.app.getBooleanAttributePreference('ui.disableMaintenance')); + }, + + onEditClick: function () { + var dialog, user = this.getView().getSelectionModel().getSelection()[0]; + dialog = Ext.create('Traccar.view.dialog.User', { + selfEdit: user.get('id') === Traccar.app.getUser().get('id') + }); + dialog.down('form').loadRecord(user); + dialog.show(); + }, + + onAddClick: function () { + var user, dialog; + user = Ext.create('Traccar.model.User'); + if (Traccar.app.getUser().get('administrator')) { + user.set('deviceLimit', -1); + } + if (Traccar.app.getUser().get('expirationTime')) { + user.set('expirationTime', Traccar.app.getUser().get('expirationTime')); + } + dialog = Ext.create('Traccar.view.dialog.User'); + dialog.down('form').loadRecord(user); + dialog.show(); + }, + + onDevicesClick: function () { + var user = this.getView().getSelectionModel().getSelection()[0]; + Ext.getStore('AllGroups').load(); + Ext.create('Traccar.view.BaseWindow', { + title: Strings.deviceTitle, + items: { + xtype: 'linkDevicesView', + baseObjectName: 'userId', + linkObjectName: 'deviceId', + storeName: 'AllDevices', + linkStoreName: 'Devices', + baseObject: user.getId() + } + }).show(); + }, + + onGroupsClick: function () { + var user = this.getView().getSelectionModel().getSelection()[0]; + Ext.create('Traccar.view.BaseWindow', { + title: Strings.settingsGroups, + items: { + xtype: 'linkGroupsView', + baseObjectName: 'userId', + linkObjectName: 'groupId', + storeName: 'AllGroups', + linkStoreName: 'Groups', + baseObject: user.getId() + } + }).show(); + }, + + onGeofencesClick: function () { + var user = this.getView().getSelectionModel().getSelection()[0]; + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedGeofences, + items: { + xtype: 'linkGeofencesView', + baseObjectName: 'userId', + linkObjectName: 'geofenceId', + storeName: 'AllGeofences', + linkStoreName: 'Geofences', + baseObject: user.getId() + } + }).show(); + }, + + onNotificationsClick: function () { + var user = this.getView().getSelectionModel().getSelection()[0]; + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedNotifications, + items: { + xtype: 'linkNotificationsView', + baseObjectName: 'userId', + linkObjectName: 'notificationId', + storeName: 'AllNotifications', + linkStoreName: 'Notifications', + baseObject: user.getId() + } + }).show(); + }, + + onCalendarsClick: function () { + var user = this.getView().getSelectionModel().getSelection()[0]; + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedCalendars, + items: { + xtype: 'linkCalendarsView', + baseObjectName: 'userId', + linkObjectName: 'calendarId', + storeName: 'AllCalendars', + linkStoreName: 'Calendars', + baseObject: user.getId() + } + }).show(); + }, + + onUsersClick: function () { + var user = this.getView().getSelectionModel().getSelection()[0]; + Ext.create('Traccar.view.BaseWindow', { + title: Strings.settingsUsers, + items: { + xtype: 'linkUsersView', + baseObjectName: 'userId', + linkObjectName: 'managedUserId', + storeName: 'Users', + baseObject: user.getId() + } + }).show(); + }, + + onAttributesClick: function () { + var user = this.getView().getSelectionModel().getSelection()[0]; + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedComputedAttributes, + items: { + xtype: 'linkComputedAttributesView', + baseObjectName: 'userId', + linkObjectName: 'attributeId', + storeName: 'AllComputedAttributes', + linkStoreName: 'ComputedAttributes', + baseObject: user.getId() + } + }).show(); + }, + + onDriversClick: function () { + var user = this.getView().getSelectionModel().getSelection()[0]; + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedDrivers, + items: { + xtype: 'linkDriversView', + baseObjectName: 'userId', + linkObjectName: 'driverId', + storeName: 'AllDrivers', + linkStoreName: 'Drivers', + baseObject: user.getId() + } + }).show(); + }, + + onCommandsClick: function () { + var user = this.getView().getSelectionModel().getSelection()[0]; + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedSavedCommands, + items: { + xtype: 'linkSavedCommandsView', + baseObjectName: 'userId', + linkObjectName: 'commandId', + storeName: 'AllCommands', + linkStoreName: 'Commands', + baseObject: user.getId() + } + }).show(); + }, + + onMaintenancesClick: function () { + var user = this.getView().getSelectionModel().getSelection()[0]; + Ext.create('Traccar.view.BaseWindow', { + title: Strings.sharedMaintenance, + items: { + xtype: 'linkMaintenancesView', + baseObjectName: 'userId', + linkObjectName: 'maintenanceId', + storeName: 'AllMaintenances', + linkStoreName: 'Maintenances', + baseObject: user.getId() + } + }).show(); + }, + + onSelectionChange: function (selection, selected) { + var disabled = selected.length === 0; + this.lookupReference('userDevicesButton').setDisabled(disabled); + this.lookupReference('userGroupsButton').setDisabled(disabled); + this.lookupReference('userGeofencesButton').setDisabled(disabled); + this.lookupReference('userNotificationsButton').setDisabled(disabled); + this.lookupReference('userCalendarsButton').setDisabled(disabled); + this.lookupReference('userAttributesButton').setDisabled(disabled); + this.lookupReference('userDriversButton').setDisabled(disabled); + this.lookupReference('userCommandsButton').setDisabled(disabled); + this.lookupReference('userMaintenancesButton').setDisabled(disabled); + this.lookupReference('userUsersButton').setDisabled(disabled || selected[0].get('userLimit') === 0); + this.callParent(arguments); + } +}); diff --git a/legacy/web/app/view/map/BaseMap.js b/legacy/web/app/view/map/BaseMap.js new file mode 100644 index 00000000..9192a53b --- /dev/null +++ b/legacy/web/app/view/map/BaseMap.js @@ -0,0 +1,243 @@ +/* + * Copyright 2016 - 2021 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.map.BaseMap', { + extend: 'Ext.panel.Panel', + xtype: 'baseMapView', + + layout: 'fit', + + getMap: function () { + return this.map; + }, + + getMapView: function () { + return this.mapView; + }, + + initMap: function () { + var server, layer, type, bingKey, locationIqKey, lat, lon, zoom, maxZoom, target, poiLayer, self = this; + + server = Traccar.app.getServer(); + + type = Traccar.app.getPreference('map', null); + bingKey = server.get('bingKey'); + locationIqKey = Traccar.app.getAttributePreference('locationIqKey', 'pk.0f147952a41c555a5b70614039fd148b'); + + layer = new ol.layer.Group({ + title: Strings.mapLayer, + layers: [ + new ol.layer.Tile({ + title: Strings.mapCustom, + type: 'base', + visible: type === 'custom', + source: new ol.source.XYZ({ + url: Ext.String.htmlDecode(server.get('mapUrl')), + attributions: '' + }) + }), + new ol.layer.Tile({ + title: Strings.mapCustomArcgis, + type: 'base', + visible: type === 'customArcgis', + source: new ol.source.TileArcGISRest({ + url: Ext.String.htmlDecode(server.get('mapUrl')) + }) + }), + new ol.layer.Tile({ + title: Strings.mapBingRoad, + type: 'base', + visible: type === 'bingRoad', + source: new ol.source.BingMaps({ + key: bingKey, + imagerySet: 'Road' + }) + }), + new ol.layer.Tile({ + title: Strings.mapBingAerial, + type: 'base', + visible: type === 'bingAerial', + source: new ol.source.BingMaps({ + key: bingKey, + imagerySet: 'Aerial' + }) + }), + new ol.layer.Tile({ + title: Strings.mapBingHybrid, + type: 'base', + visible: type === 'bingHybrid', + source: new ol.source.BingMaps({ + key: bingKey, + imagerySet: 'AerialWithLabels' + }) + }), + new ol.layer.Tile({ + title: Strings.mapCarto, + type: 'base', + visible: type === 'carto', + source: new ol.source.XYZ({ + url: 'https://cartodb-basemaps-{a-d}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png', + attributions: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> ' + + 'contributors, © <a href="https://carto.com/attributions">CARTO</a>' + }) + }), + new ol.layer.Tile({ + title: Strings.mapAutoNavi, + type: 'base', + visible: type === 'autoNavi' || type === 'baidu', + source: new ol.source.OSM({ + url: 'https://webrd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}' + }) + }), + new ol.layer.Tile({ + title: Strings.mapYandexMap, + type: 'base', + visible: type === 'yandexMap', + source: new ol.source.XYZ({ + url: 'https://core-renderer-tiles.maps.yandex.net/tiles?l=map&x={x}&y={y}&z={z}', + projection: 'EPSG:3395', + attributions: '© <a href="https://yandex.com/maps/">Yandex</a>' + }) + }), + new ol.layer.Tile({ + title: Strings.mapYandexSat, + type: 'base', + visible: type === 'yandexSat', + source: new ol.source.XYZ({ + url: 'https://core-sat.maps.yandex.net/tiles?l=sat&x={x}&y={y}&z={z}', + projection: 'EPSG:3395', + attributions: '© <a href="https://yandex.com/maps/">Yandex</a>' + }) + }), + new ol.layer.Tile({ + title: Strings.mapOsm, + type: 'base', + visible: type === 'osm', + source: new ol.source.OSM({}) + }), + new ol.layer.Tile({ + title: Strings.mapLocationIqStreets, + type: 'base', + visible: type === 'locationIqStreets' || type === 'wikimedia' || !type, + source: new ol.source.XYZ({ + url: 'https://{a-c}-tiles.locationiq.com/v3/streets/r/{z}/{x}/{y}.png?key=' + locationIqKey, + attributions: '© <a href="https://locationiq.com/">LocationIQ</a>' + }) + }) + ] + }); + + lat = Traccar.app.getPreference('latitude', Traccar.Style.mapDefaultLat); + lon = Traccar.app.getPreference('longitude', Traccar.Style.mapDefaultLon); + zoom = Traccar.app.getPreference('zoom', Traccar.Style.mapDefaultZoom); + maxZoom = Traccar.app.getAttributePreference('web.maxZoom', Traccar.Style.mapMaxZoom); + + this.mapView = new ol.View({ + center: ol.proj.fromLonLat([lon, lat]), + zoom: zoom, + maxZoom: maxZoom + }); + + this.map = new ol.Map({ + target: this.body.dom.id, + layers: [layer], + view: this.mapView + }); + + poiLayer = Traccar.app.getPreference('poiLayer', null); + + if (poiLayer) { + this.map.addLayer(new ol.layer.Vector({ + source: new ol.source.Vector({ + url: poiLayer, + format: new ol.format.KML() + }) + })); + } + + switch (Traccar.app.getAttributePreference('distanceUnit', 'km')) { + case 'mi': + this.map.addControl(new ol.control.ScaleLine({ + units: 'us' + })); + break; + case 'nmi': + this.map.addControl(new ol.control.ScaleLine({ + units: 'nautical' + })); + break; + default: + this.map.addControl(new ol.control.ScaleLine()); + break; + } + + this.map.addControl(new ol.control.LayerSwitcher()); + + target = this.map.getTarget(); + if (typeof target === 'string') { + target = Ext.get(target).dom; + } + + this.map.on('pointermove', function (e) { + var hit = this.forEachFeatureAtPixel(e.pixel, function () { + return true; + }); + if (hit) { + target.style.cursor = 'pointer'; + } else { + target.style.cursor = ''; + } + }); + + this.map.on('click', function (e) { + var i, features = self.map.getFeaturesAtPixel(e.pixel, { + layerFilter: function (layer) { + return !layer.get('name'); + } + }); + if (features) { + for (i = 0; i < features.length; i++) { + self.fireEvent('selectfeature', features[i]); + } + } else { + self.fireEvent('deselectfeature'); + } + }); + + this.map.once('postrender', function () { + self.fireEvent('mapready'); + }); + }, + + listeners: { + afterrender: function () { + this.initMap(); + }, + + resize: function () { + this.map.updateSize(); + } + } +}, function () { + var projection; + proj4.defs('EPSG:3395', '+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs'); + ol.proj.proj4.register(proj4); + projection = ol.proj.get('EPSG:3395'); + if (projection) { + projection.setExtent([-20037508.342789244, -20037508.342789244, 20037508.342789244, 20037508.342789244]); + } +}); diff --git a/legacy/web/app/view/map/GeofenceMap.js b/legacy/web/app/view/map/GeofenceMap.js new file mode 100644 index 00000000..cc1b7efe --- /dev/null +++ b/legacy/web/app/view/map/GeofenceMap.js @@ -0,0 +1,150 @@ +/* + * Copyright 2016 - 2021 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.map.GeofenceMap', { + extend: 'Traccar.view.map.BaseMap', + xtype: 'geofenceMapView', + + requires: [ + 'Traccar.view.map.GeofenceMapController', + 'Traccar.GeofenceConverter' + ], + + controller: 'geofenceMap', + bodyBorder: true, + + tbar: { + items: [{ + xtype: 'combobox', + store: 'GeofenceTypes', + valueField: 'key', + displayField: 'name', + editable: false, + listeners: { + select: 'onTypeSelect' + } + }, '-', { + xtype: 'tbtext', + html: Strings.sharedImport + }, { + xtype: 'filefield', + name: 'file', + buttonConfig: { + glyph: 'xf093@FontAwesome', + text: '', + tooltip: Strings.sharedSelectFile, + tooltipType: 'title' + }, + listeners: { + change: 'onFileChange', + afterrender: function (fileField) { + fileField.fileInputEl.set({ + accept: '.gpx' + }); + } + } + }, { + xtype: 'tbfill' + }, { + glyph: 'xf00c@FontAwesome', + tooltip: Strings.sharedSave, + tooltipType: 'title', + minWidth: 0, + handler: 'onSaveClick' + }, { + glyph: 'xf00d@FontAwesome', + tooltip: Strings.sharedCancel, + tooltipType: 'title', + minWidth: 0, + handler: 'onCancelClick' + }] + }, + + getFeatures: function () { + return this.features; + }, + + initMap: function () { + var map, mapView, featureOverlay, geometry, fillColor; + this.callParent(); + + map = this.map; + mapView = this.mapView; + + this.features = new ol.Collection(); + if (this.area) { + geometry = Traccar.GeofenceConverter.wktToGeometry(mapView, this.area); + this.features.push(new ol.Feature(geometry)); + this.map.once('postrender', function () { + mapView.fit(geometry, { + padding: [20, 20, 20, 20] + }); + }); + } else { + this.controller.fireEvent('mapstaterequest'); + } + fillColor = ol.color.asArray(Traccar.Style.mapGeofenceColor); + fillColor[3] = Traccar.Style.mapGeofenceOverlayOpacity; + featureOverlay = new ol.layer.Vector({ + source: new ol.source.Vector({ + features: this.features + }), + style: new ol.style.Style({ + fill: new ol.style.Fill({ + color: fillColor + }), + stroke: new ol.style.Stroke({ + color: Traccar.Style.mapGeofenceColor, + width: Traccar.Style.mapGeofenceWidth + }), + image: new ol.style.Circle({ + radius: Traccar.Style.mapGeofenceRadius, + fill: new ol.style.Fill({ + color: Traccar.Style.mapGeofenceColor + }) + }) + }) + }); + featureOverlay.setMap(map); + + map.addInteraction(new ol.interaction.Modify({ + features: this.features, + deleteCondition: function (event) { + return ol.events.condition.shiftKeyOnly(event) && ol.events.condition.singleClick(event); + } + })); + }, + + addInteraction: function (type) { + var self = this; + this.draw = new ol.interaction.Draw({ + features: this.features, + type: type + }); + this.draw.on('drawstart', function () { + self.features.clear(); + }); + this.map.addInteraction(this.draw); + }, + + removeInteraction: function () { + if (this.draw) { + this.map.removeInteraction(this.draw); + this.draw = null; + } + } +}); diff --git a/legacy/web/app/view/map/GeofenceMapController.js b/legacy/web/app/view/map/GeofenceMapController.js new file mode 100644 index 00000000..31ab586c --- /dev/null +++ b/legacy/web/app/view/map/GeofenceMapController.js @@ -0,0 +1,85 @@ +/* + * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.map.GeofenceMapController', { + extend: 'Ext.app.ViewController', + alias: 'controller.geofenceMap', + + requires: [ + 'Traccar.GeofenceConverter' + ], + + config: { + listen: { + controller: { + '*': { + mapstate: 'setMapState' + } + } + } + }, + + onFileChange: function (fileField) { + var reader, view = this.getView(); + if (fileField.fileInputEl.dom.files.length > 0) { + reader = new FileReader(); + reader.onload = function () { + var parser, xml, segment, projection, points = []; + parser = new DOMParser(); + xml = parser.parseFromString(reader.result, 'text/xml'); + segment = xml.getElementsByTagName('trkseg')[0]; + projection = view.mapView.getProjection(); + Array.from(segment.getElementsByTagName('trkpt')).forEach(function (point) { + var lat, lon; + lat = Number(point.getAttribute('lat')); + lon = Number(point.getAttribute('lon')); + points.push(ol.proj.transform([lon, lat], 'EPSG:4326', projection)); + }); + view.getFeatures().clear(); + view.getFeatures().push(new ol.Feature(new ol.geom.LineString(points))); + }; + reader.onerror = function (event) { + Traccar.app.showError(event.target.error); + }; + reader.readAsText(fileField.fileInputEl.dom.files[0]); + } + }, + + onSaveClick: function (button) { + var geometry, projection; + if (this.getView().getFeatures().getLength() > 0) { + geometry = this.getView().getFeatures().pop().getGeometry(); + projection = this.getView().getMapView().getProjection(); + this.fireEvent('savearea', Traccar.GeofenceConverter.geometryToWkt(projection, geometry)); + button.up('window').close(); + } + }, + + onCancelClick: function (button) { + button.up('window').close(); + }, + + onTypeSelect: function (combo) { + this.getView().removeInteraction(); + this.getView().addInteraction(combo.getValue()); + }, + + setMapState: function (lat, lon, zoom) { + this.getView().getMapView().setCenter(ol.proj.fromLonLat([lon, lat])); + this.getView().getMapView().setZoom(zoom); + } +}); diff --git a/legacy/web/app/view/map/Map.js b/legacy/web/app/view/map/Map.js new file mode 100644 index 00000000..36e81de7 --- /dev/null +++ b/legacy/web/app/view/map/Map.js @@ -0,0 +1,158 @@ +/* + * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.map.Map', { + extend: 'Traccar.view.map.BaseMap', + xtype: 'mapView', + + requires: [ + 'Traccar.view.map.MapController', + 'Traccar.view.SettingsMenu' + ], + + controller: 'map', + + title: Strings.mapTitle, + tbar: { + componentCls: 'toolbar-header-style', + defaults: { + xtype: 'button', + tooltipType: 'title', + stateEvents: ['toggle'], + enableToggle: true, + stateful: { + pressed: true + } + }, + items: [{ + xtype: 'tbtext', + html: Strings.mapTitle, + baseCls: 'x-panel-header-title-default' + }, { + xtype: 'tbfill' + }, { + handler: 'showReports', + reference: 'showReportsButton', + glyph: 'xf0f6@FontAwesome', + stateful: false, + enableToggle: false, + tooltip: Strings.reportTitle + }, { + handler: 'showEvents', + reference: 'showEventsButton', + glyph: 'xf27b@FontAwesome', + stateful: false, + enableToggle: false, + tooltip: Strings.reportEvents + }, { + handler: 'updateGeofences', + reference: 'showGeofencesButton', + glyph: 'xf21d@FontAwesome', + pressed: true, + stateId: 'show-geofences-button', + tooltip: Strings.sharedGeofences + }, { + handler: 'showAccuracy', + reference: 'showAccuracyButton', + glyph: 'xf140@FontAwesome', + pressed: true, + stateId: 'show-accuracy-button', + tooltip: Strings.positionAccuracy + }, { + handler: 'showCurrentLocation', + glyph: 'xf124@FontAwesome', + tooltip: Strings.mapCurrentLocation + }, { + handler: 'showLiveRoutes', + reference: 'showLiveRoutes', + glyph: 'xf1b0@FontAwesome', + stateId: 'show-live-routes-button', + tooltip: Strings.mapLiveRoutes + }, { + reference: 'deviceFollowButton', + glyph: 'xf05b@FontAwesome', + tooltip: Strings.deviceFollow, + stateId: 'device-follow-button', + toggleHandler: 'onFollowClick' + }, { + xtype: 'settingsMenu', + enableToggle: false + }] + }, + + getMarkersSource: function () { + return this.markersSource; + }, + + getAccuracySource: function () { + return this.accuracySource; + }, + + getAccuracyLayer: function () { + return this.accuracyLayer; + }, + + getRouteSource: function () { + return this.routeSource; + }, + + getGeofencesSource: function () { + return this.geofencesSource; + }, + + getLiveRouteSource: function () { + return this.liveRouteSource; + }, + + getLiveRouteLayer: function () { + return this.liveRouteLayer; + }, + + initMap: function () { + this.callParent(); + + this.geofencesSource = new ol.source.Vector({}); + this.map.addLayer(new ol.layer.Vector({ + name: 'geofencesLayer', + source: this.geofencesSource + })); + + this.liveRouteSource = new ol.source.Vector({}); + this.liveRouteLayer = new ol.layer.Vector({ + source: this.liveRouteSource, + visible: this.lookupReference('showLiveRoutes').pressed + }); + this.map.addLayer(this.liveRouteLayer); + + this.routeSource = new ol.source.Vector({}); + this.map.addLayer(new ol.layer.Vector({ + source: this.routeSource + })); + + this.accuracySource = new ol.source.Vector({}); + this.accuracyLayer = new ol.layer.Vector({ + name: 'accuracyLayer', + source: this.accuracySource + }); + this.map.addLayer(this.accuracyLayer); + + this.markersSource = new ol.source.Vector({}); + this.map.addLayer(new ol.layer.Vector({ + source: this.markersSource + })); + } +}); diff --git a/legacy/web/app/view/map/MapController.js b/legacy/web/app/view/map/MapController.js new file mode 100644 index 00000000..f6d88eed --- /dev/null +++ b/legacy/web/app/view/map/MapController.js @@ -0,0 +1,101 @@ +/* + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.map.MapController', { + extend: 'Traccar.view.map.MapMarkerController', + alias: 'controller.map', + + requires: [ + 'Traccar.GeofenceConverter' + ], + + config: { + listen: { + controller: { + '*': { + mapstaterequest: 'getMapState', + zoomtoalldevices: 'zoomToAllDevices' + } + }, + store: { + '#Geofences': { + load: 'updateGeofences', + add: 'updateGeofences', + update: 'updateGeofences', + remove: 'updateGeofences' + } + } + } + }, + + init: function () { + this.callParent(); + this.lookupReference('showReportsButton').setVisible( + Traccar.app.isMobile() && !Traccar.app.getPreference('disableReports', false)); + this.lookupReference('showEventsButton').setVisible( + Traccar.app.isMobile() && !Traccar.app.getBooleanAttributePreference('ui.disableEvents')); + }, + + showReports: function () { + Traccar.app.showReports(true); + }, + + showEvents: function () { + Traccar.app.showEvents(true); + }, + + onFollowClick: function (button, pressed) { + if (pressed && this.selectedMarker) { + this.getView().getMapView().setCenter(this.selectedMarker.getGeometry().getCoordinates()); + } + }, + + showLiveRoutes: function (button) { + this.getView().getLiveRouteLayer().setVisible(button.pressed); + }, + + showAccuracy: function (button) { + this.getView().getAccuracyLayer().setVisible(button.pressed); + }, + + getMapState: function () { + var zoom, center, projection; + projection = this.getView().getMapView().getProjection(); + center = ol.proj.transform(this.getView().getMapView().getCenter(), projection, 'EPSG:4326'); + zoom = this.getView().getMapView().getZoom(); + this.fireEvent('mapstate', center[1], center[0], zoom); + }, + + updateGeofences: function () { + this.getView().getGeofencesSource().clear(); + if (this.lookupReference('showGeofencesButton').pressed) { + Ext.getStore('Geofences').each(function (geofence) { + var feature = new ol.Feature( + Traccar.GeofenceConverter.wktToGeometry(this.getView().getMapView(), geofence.get('area'))); + feature.setStyle(this.getAreaStyle( + Ext.String.htmlDecode(geofence.get('name')), + geofence.get('attributes') ? geofence.get('attributes').color : null)); + this.getView().getGeofencesSource().addFeature(feature); + return true; + }, this); + } + }, + + zoomToAllDevices: function () { + this.zoomToAllPositions(Ext.getStore('LatestPositions').getData().items); + } +}); diff --git a/legacy/web/app/view/map/MapMarkerController.js b/legacy/web/app/view/map/MapMarkerController.js new file mode 100644 index 00000000..2fef4870 --- /dev/null +++ b/legacy/web/app/view/map/MapMarkerController.js @@ -0,0 +1,687 @@ +/* + * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.map.MapMarkerController', { + extend: 'Ext.app.ViewController', + alias: 'controller.mapMarker', + + requires: [ + 'Traccar.model.Position', + 'Traccar.model.Device', + 'Traccar.DeviceImages' + ], + + config: { + listen: { + controller: { + '*': { + selectdevice: 'selectDevice', + selectreport: 'selectReport', + selectevent: 'selectEvent' + }, + 'devices': { + deselectfeature: 'deselectDevice' + } + }, + store: { + '#Devices': { + add: 'updateDevice', + update: 'updateDevice', + remove: 'removeDevice' + }, + '#VisibleDevices': { + add: 'updateVisibleDevices', + update: 'updateVisibleDevices', + remove: 'updateVisibleDevices', + refresh: 'filterDevices' + }, + '#LatestPositions': { + add: 'updateLatest', + update: 'updateLatest' + }, + '#ReportRoute': { + add: 'addReportMarkers', + load: 'loadReport', + clear: 'clearReport' + }, + '#Events': { + remove: 'clearEvent', + clear: 'clearEvent' + } + }, + component: { + '#': { + mapready: 'initGeolocation', + selectfeature: 'selectFeature', + deselectfeature: 'deselectFeature' + } + } + } + }, + + init: function () { + this.latestMarkers = {}; + this.reportMarkers = {}; + this.accuracyCircles = {}; + this.liveRoutes = {}; + this.liveRouteLength = Traccar.app.getAttributePreference('web.liveRouteLength', 10); + this.selectZoom = Traccar.app.getAttributePreference('web.selectZoom', 0); + }, + + initGeolocation: function () { + var geolocation, accuracyFeature, positionFeature; + + geolocation = new ol.Geolocation({ + trackingOptions: { + enableHighAccuracy: true + }, + projection: this.getView().getMapView().getProjection() + }); + + geolocation.on('error', function (error) { + Traccar.app.showError(error.message); + }); + + accuracyFeature = new ol.Feature(); + geolocation.on('change:accuracyGeometry', function () { + accuracyFeature.setGeometry(geolocation.getAccuracyGeometry()); + }); + + positionFeature = new ol.Feature(); + positionFeature.setStyle(new ol.style.Style({ + image: new ol.style.Circle({ + radius: 6, + fill: new ol.style.Fill({ + color: '#3399CC' + }), + stroke: new ol.style.Stroke({ + color: '#fff', + width: 2 + }) + }) + })); + + geolocation.on('change:position', function () { + var coordinates = geolocation.getPosition(); + positionFeature.setGeometry(coordinates ? new ol.geom.Point(coordinates) : null); + }); + + this.getView().getAccuracySource().addFeature(accuracyFeature); + this.getView().getMarkersSource().addFeature(positionFeature); + + this.geolocation = geolocation; + }, + + showCurrentLocation: function (view) { + this.geolocation.setTracking(view.pressed); + }, + + getAreaStyle: function (label, color) { + var fillColor, strokeColor, styleConfig; + if (color) { + fillColor = ol.color.asArray(color); + strokeColor = color; + } else { + fillColor = ol.color.asArray(Traccar.Style.mapGeofenceColor); + strokeColor = Traccar.Style.mapGeofenceColor; + } + fillColor[3] = Traccar.Style.mapGeofenceOverlayOpacity; + styleConfig = { + fill: new ol.style.Fill({ + color: fillColor + }), + stroke: new ol.style.Stroke({ + color: strokeColor, + width: Traccar.Style.mapGeofenceWidth + }) + }; + if (label) { + styleConfig.text = new ol.style.Text({ + text: label, + overflow: true, + fill: new ol.style.Fill({ + color: Traccar.Style.mapGeofenceTextColor + }), + stroke: new ol.style.Stroke({ + color: Traccar.Style.mapTextStrokeColor, + width: Traccar.Style.mapTextStrokeWidth + }), + font: Traccar.Style.mapTextFont + }); + } + return new ol.style.Style(styleConfig); + }, + + 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, deviceName, 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')) { + this.updateDeviceMarker(style, this.getDeviceColor(device), device.get('category')); + marker.changed(); + } + deviceName = Ext.String.htmlDecode(device.get('name')); + if (style.getText().getText() !== deviceName) { + style.getText().setText(deviceName); + marker.changed(); + } + } + } + }, + + removeDevice: function (store, data) { + var i, deviceId, markersSource; + if (!Ext.isArray(data)) { + data = [data]; + } + + markersSource = this.getView().getMarkersSource(); + + for (i = 0; i < data.length; i++) { + deviceId = data[i].get('id'); + if (this.latestMarkers[deviceId]) { + if (markersSource.getFeatureById(this.latestMarkers[deviceId].getId())) { + markersSource.removeFeature(this.latestMarkers[deviceId]); + } + delete this.latestMarkers[deviceId]; + } + if (this.accuracyCircles[deviceId]) { + if (markersSource.getFeatureById(this.accuracyCircles[deviceId].getId())) { + markersSource.removeFeature(this.accuracyCircles[deviceId]); + } + delete this.accuracyCircles[deviceId]; + } + if (this.liveRoutes[deviceId]) { + if (markersSource.getFeatureById(this.liveRoutes[deviceId].getId())) { + markersSource.removeFeature(this.liveRoutes[deviceId]); + } + delete this.liveRoutes[deviceId]; + } + } + }, + + animateMarker: function (marker, geometry, course) { + var start, end, duration, timeout, line, updatePosition, self, follow; + + start = marker.getGeometry().getCoordinates(); + end = geometry.getCoordinates(); + line = new ol.geom.LineString([start, end]); + duration = Traccar.Style.mapAnimateMarkerDuration; + timeout = Traccar.Style.mapAnimateMarkerTimeout; + self = this; + follow = this.lookupReference('deviceFollowButton').pressed; + + updatePosition = function (position, marker) { + var coordinate, style; + coordinate = marker.get('line').getCoordinateAt(position / (duration / timeout)); + style = marker.getStyle(); + marker.setGeometry(new ol.geom.Point(coordinate)); + if (marker === self.selectedMarker && follow) { + self.getView().getMapView().setCenter(marker.getGeometry().getCoordinates()); + } + if (position < duration / timeout) { + setTimeout(updatePosition, timeout, position + 1, marker); + } else { + if (style.getImage().angle !== marker.get('nextCourse')) { + self.rotateMarker(style, marker.get('nextCourse')); + } + marker.set('animating', false); + } + }; + + marker.set('line', line); + marker.set('nextCourse', course); + if (!marker.get('animating')) { + marker.set('animating', true); + updatePosition(1, marker); + } + }, + + updateLatest: function (store, data) { + var i, position, device, deviceStore; + + if (!Ext.isArray(data)) { + data = [data]; + } + + deviceStore = Ext.getStore('Devices'); + + for (i = 0; i < data.length; i++) { + position = data[i]; + device = deviceStore.getById(position.get('deviceId')); + + if (device) { + this.updateAccuracy(position, device); + this.updateLatestMarker(position, device); + this.updateLiveRoute(position, device); + } + } + }, + + updateAccuracy: function (position, device) { + var center, radius, feature; + feature = this.accuracyCircles[position.get('deviceId')]; + + if (position.get('accuracy')) { + center = ol.proj.fromLonLat([position.get('longitude'), position.get('latitude')]); + radius = Ext.getStore('DistanceUnits').convertValue( + position.get('accuracy'), Traccar.app.getAttributePreference('distanceUnit'), true); + + if (feature) { + feature.getGeometry().setCenter(center); + feature.getGeometry().setRadius(radius); + } else { + feature = new ol.Feature(new ol.geom.Circle(center, radius)); + feature.setStyle(this.getAreaStyle(null, Traccar.Style.mapAccuracyColor)); + feature.setId(position.get('deviceId')); + this.accuracyCircles[position.get('deviceId')] = feature; + if (this.isDeviceVisible(device)) { + this.getView().getAccuracySource().addFeature(feature); + } + } + } else { + if (feature && this.getView().getAccuracySource().getFeatureById(feature.getId())) { + this.getView().getAccuracySource().removeFeature(feature); + } + delete this.accuracyCircles[position.get('deviceId')]; + } + }, + + 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]; + this.animateMarker(marker, geometry, position.get('course')); + } 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(Ext.String.htmlDecode(device.get('name'))); + marker.setStyle(style); + marker.setId(device.get('id')); + this.latestMarkers[deviceId] = marker; + if (this.isDeviceVisible(device)) { + this.getView().getMarkersSource().addFeature(marker); + } + if (marker === this.selectedMarker && this.lookupReference('deviceFollowButton').pressed) { + this.getView().getMapView().setCenter(marker.getGeometry().getCoordinates()); + } + } + }, + + updateLiveRoute: function (position, device) { + 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)); + liveLine.setId(deviceId); + this.liveRoutes[deviceId] = liveLine; + if (this.isDeviceVisible(device)) { + this.getView().getMarkersSource().addFeature(liveLine); + } + } + }, + + loadReport: function (store, data) { + var i, position, point, routeSource; + if (data) { + this.addReportMarkers(store, data); + routeSource = this.getView().getRouteSource(); + + 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'))); + routeSource.addFeature(this.reportRoute[this.reportRoute.length - 1]); + } + this.reportRoute[this.reportRoute.length - 1].getGeometry().appendCoordinate(point); + } + } + }, + + addReportMarker: function (position) { + var geometry, marker, style, 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); + style = this.getReportMarker(position.get('deviceId'), position.get('course')); + marker.setStyle(style); + this.getView().getMarkersSource().addFeature(marker); + return marker; + }, + + addReportMarkers: function (store, data) { + var i; + this.clearReport(); + for (i = 0; i < data.length; i++) { + if (store.showMarkers) { + this.reportMarkers[data[i].get('id')] = this.addReportMarker(data[i]); + } + } + this.zoomToAllPositions(data); + }, + + clearReport: function () { + var key, i, reportSource, markersSource; + + reportSource = this.getView().getRouteSource(); + + if (this.reportRoute) { + for (i = 0; i < this.reportRoute.length; i++) { + reportSource.removeFeature(this.reportRoute[i]); + } + this.reportRoute = null; + } + + if (this.reportMarkers) { + markersSource = this.getView().getMarkersSource(); + for (key in this.reportMarkers) { + if (this.reportMarkers.hasOwnProperty(key)) { + markersSource.removeFeature(this.reportMarkers[key]); + } + } + this.reportMarkers = {}; + } + + if (this.selectedMarker && !this.selectedMarker.get('event') && + this.selectedMarker.get('record') instanceof Traccar.model.Position) { + this.selectedMarker = null; + } + }, + + clearEvent: function () { + if (this.selectedMarker && this.selectedMarker.get('event')) { + this.selectMarker(null, false); + } + }, + + getRouteStyle: function (deviceId) { + return new ol.style.Style({ + stroke: new ol.style.Stroke({ + color: Traccar.app.getReportColor(deviceId), + 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) { + return this.getMarkerStyle(false, Traccar.app.getReportColor(deviceId), 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); + style.setText(text); + style.setImage(image); + }, + + rotateMarker: function (style, angle) { + style.setImage(Traccar.DeviceImages.getImageIcon( + style.getImage().fill, style.getImage().zoom, angle, style.getImage().category)); + }, + + 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); + style.setText(text); + style.setImage(image); + }, + + selectMarker: function (marker, center) { + if (this.selectedMarker) { + if (this.selectedMarker.get('event')) { + this.getView().getMarkersSource().removeFeature(this.selectedMarker); + } else if (!Ext.getStore('ReportRoute').showMarkers && + this.selectedMarker.get('record') instanceof Traccar.model.Position) { + this.getView().getMarkersSource().removeFeature(this.selectedMarker); + delete this.reportMarkers[this.selectedMarker.get('record').get('id')]; + } else { + this.resizeMarker(this.selectedMarker.getStyle(), false); + this.selectedMarker.getStyle().setZIndex(0); + this.selectedMarker.changed(); + } + } + + if (marker) { + this.resizeMarker(marker.getStyle(), true); + marker.getStyle().setZIndex(1); + marker.changed(); + if (center) { + this.getView().getMapView().setCenter(marker.getGeometry().getCoordinates()); + if (this.selectZoom !== 0 && this.selectZoom > this.getView().getMapView().getZoom()) { + this.getView().getMapView().setZoom(this.selectZoom); + } + } + } + + 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) { + if (!Ext.getStore('ReportRoute').showMarkers) { + this.reportMarkers[position.get('id')] = this.addReportMarker(position); + } + this.selectMarker(this.reportMarkers[position.get('id')], center); + } else if (this.selectedMarker) { + this.selectMarker(null, false); + } + }, + + selectEvent: function (position) { + var marker; + if (position) { + marker = this.addReportMarker(position); + marker.set('event', true); + this.selectMarker(marker, true); + } else if (this.selectedMarker && this.selectedMarker.get('event')) { + this.selectMarker(null, false); + } + }, + + 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); + } + } + }, + + deselectFeature: function () { + this.deselectDevice(); + this.fireEvent('deselectfeature'); + }, + + deselectDevice: function () { + this.selectMarker(null, false); + }, + + zoomToAllPositions: function (data) { + var i, point, minx, miny, maxx, maxy; + for (i = 0; i < data.length; i++) { + point = ol.proj.fromLonLat([ + data[i].get('longitude'), + data[i].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); + } + } + if (minx !== maxx || miny !== maxy) { + this.getView().getMapView().fit([minx, miny, maxx, maxy]); + } else if (point) { + this.getView().getMapView().fit(new ol.geom.Point(point)); + } + }, + + updateVisibleDevices: function (store, data) { + var i, device; + + if (!Ext.isArray(data)) { + data = [data]; + } + + for (i = 0; i < data.length; i++) { + device = data[i]; + if (device.get('id') in this.latestMarkers) { + this.updateDeviceVisibility(device); + } + } + }, + + isDeviceVisible: function (device) { + return Ext.getStore('VisibleDevices').contains(device); + }, + + updateDeviceVisibility: function (device) { + var deviceId, accuracy, liveLine, marker; + deviceId = device.get('id'); + marker = this.latestMarkers[deviceId]; + accuracy = this.accuracyCircles[deviceId]; + liveLine = this.liveRoutes[deviceId]; + if (this.isDeviceVisible(device)) { + if (marker && !this.getView().getMarkersSource().getFeatureById(marker.getId())) { + this.getView().getMarkersSource().addFeature(marker); + } + if (accuracy && !this.getView().getAccuracySource().getFeatureById(accuracy.getId())) { + this.getView().getAccuracySource().addFeature(accuracy); + } + if (liveLine && !this.getView().getLiveRouteSource().getFeatureById(liveLine.getId())) { + this.getView().getLiveRouteSource().addFeature(liveLine); + } + } else { + if (marker && this.getView().getMarkersSource().getFeatureById(marker.getId())) { + this.getView().getMarkersSource().removeFeature(marker); + } + if (accuracy && this.getView().getAccuracySource().getFeatureById(accuracy.getId())) { + this.getView().getAccuracySource().removeFeature(accuracy); + } + if (liveLine && this.getView().getLiveRouteSource().getFeatureById(liveLine.getId())) { + this.getView().getLiveRouteSource().removeFeature(liveLine); + } + } + }, + + filterDevices: function () { + Ext.getStore('Devices').each(this.updateDeviceVisibility, this, false); + } +}); diff --git a/legacy/web/app/view/permissions/Base.js b/legacy/web/app/view/permissions/Base.js new file mode 100644 index 00000000..57017531 --- /dev/null +++ b/legacy/web/app/view/permissions/Base.js @@ -0,0 +1,37 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +Ext.define('Traccar.view.permissions.Base', { + extend: 'Traccar.view.GridPanel', + + requires: [ + 'Traccar.view.permissions.BaseController' + ], + + controller: 'base', + + selModel: { + selType: 'checkboxmodel', + checkOnly: true, + showHeaderCheckbox: false + }, + + listeners: { + beforedeselect: 'onBeforeDeselect', + beforeselect: 'onBeforeSelect' + } +}); diff --git a/legacy/web/app/view/permissions/BaseController.js b/legacy/web/app/view/permissions/BaseController.js new file mode 100644 index 00000000..5cb9c302 --- /dev/null +++ b/legacy/web/app/view/permissions/BaseController.js @@ -0,0 +1,84 @@ +/* + * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.permissions.BaseController', { + extend: 'Ext.app.ViewController', + alias: 'controller.base', + + init: function () { + var params = {}, linkStoreName, storeName; + params[this.getView().baseObjectName] = this.getView().baseObject; + linkStoreName = this.getView().linkStoreName; + storeName = this.getView().storeName; + linkStoreName = typeof linkStoreName === 'undefined' ? storeName : linkStoreName; + this.getView().setStore(Ext.getStore(storeName)); + this.getView().getStore().load({ + scope: this, + callback: function () { + var linkStore = Ext.create('Traccar.store.' + linkStoreName); + linkStore.load({ + params: params, + scope: this, + callback: function (records, operation, success) { + var i, index; + if (success) { + for (i = 0; i < records.length; i++) { + index = this.getView().getStore().getById(records[i].getId()); + this.getView().getSelectionModel().select(index, true, true); + } + } + } + }); + } + }); + }, + + onBeforeSelect: function (selection, record) { + var data = {}; + data[this.getView().baseObjectName] = this.getView().baseObject; + data[this.getView().linkObjectName] = record.getId(); + Ext.Ajax.request({ + scope: this, + url: 'api/permissions', + jsonData: Ext.util.JSON.encode(data), + callback: function (options, success, response) { + if (!success) { + selection.deselect(record, true); + Traccar.app.showError(response); + } + } + }); + }, + + onBeforeDeselect: function (selection, record) { + var data = {}; + data[this.getView().baseObjectName] = this.getView().baseObject; + data[this.getView().linkObjectName] = record.getId(); + Ext.Ajax.request({ + scope: this, + method: 'DELETE', + url: 'api/permissions', + jsonData: Ext.util.JSON.encode(data), + callback: function (options, success, response) { + if (!success) { + selection.select(record, true, true); + Traccar.app.showError(response); + } + } + }); + } +}); diff --git a/legacy/web/app/view/permissions/Calendars.js b/legacy/web/app/view/permissions/Calendars.js new file mode 100644 index 00000000..3d08efca --- /dev/null +++ b/legacy/web/app/view/permissions/Calendars.js @@ -0,0 +1,32 @@ +/* + * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.permissions.Calendars', { + extend: 'Traccar.view.permissions.Base', + xtype: 'linkCalendarsView', + + columns: { + items: [{ + text: Strings.sharedName, + dataIndex: 'name', + flex: 1, + minWidth: Traccar.Style.columnWidthNormal, + filter: 'string' + }] + } +}); diff --git a/legacy/web/app/view/permissions/ComputedAttributes.js b/legacy/web/app/view/permissions/ComputedAttributes.js new file mode 100644 index 00000000..19af72ad --- /dev/null +++ b/legacy/web/app/view/permissions/ComputedAttributes.js @@ -0,0 +1,45 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.permissions.ComputedAttributes', { + extend: 'Traccar.view.permissions.Base', + xtype: 'linkComputedAttributesView', + + columns: { + items: [{ + text: Strings.sharedDescription, + dataIndex: 'description', + flex: 1, + minWidth: Traccar.Style.columnWidthNormal, + filter: 'string' + }, { + text: Strings.sharedAttribute, + dataIndex: 'attribute', + flex: 1, + minWidth: Traccar.Style.columnWidthNormal, + filter: { + type: 'list', + labelField: 'name', + store: 'PositionAttributes' + }, + renderer: function (value) { + return Ext.getStore('PositionAttributes').getAttributeName(value); + } + }] + } +}); diff --git a/legacy/web/app/view/permissions/Devices.js b/legacy/web/app/view/permissions/Devices.js new file mode 100644 index 00000000..3180b107 --- /dev/null +++ b/legacy/web/app/view/permissions/Devices.js @@ -0,0 +1,82 @@ +/* + * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.permissions.Devices', { + extend: 'Traccar.view.permissions.Base', + xtype: 'linkDevicesView', + + requires: [ + 'Traccar.AttributeFormatter' + ], + + columns: { + items: [{ + text: Strings.sharedName, + dataIndex: 'name', + flex: 1, + minWidth: Traccar.Style.columnWidthNormal, + filter: 'string' + }, { + text: Strings.deviceIdentifier, + dataIndex: 'uniqueId', + flex: 1, + minWidth: Traccar.Style.columnWidthNormal, + filter: 'string' + }, { + text: Strings.sharedPhone, + dataIndex: 'phone', + flex: 1, + minWidth: Traccar.Style.columnWidthNormal, + hidden: true, + filter: 'string' + }, { + text: Strings.deviceModel, + dataIndex: 'model', + flex: 1, + minWidth: Traccar.Style.columnWidthNormal, + hidden: true, + filter: 'string' + }, { + text: Strings.deviceContact, + dataIndex: 'contact', + flex: 1, + minWidth: Traccar.Style.columnWidthNormal, + hidden: true, + filter: 'string' + }, { + text: Strings.sharedDisabled, + dataIndex: 'disabled', + flex: 1, + minWidth: Traccar.Style.columnWidthNormal, + renderer: Traccar.AttributeFormatter.getFormatter('disabled'), + hidden: true, + filter: 'boolean' + }, { + text: Strings.groupDialog, + dataIndex: 'groupId', + flex: 1, + minWidth: Traccar.Style.columnWidthNormal, + hidden: true, + filter: { + type: 'list', + labelField: 'name', + store: 'AllGroups' + }, + renderer: Traccar.AttributeFormatter.getFormatter('groupId') + }] + } +}); diff --git a/legacy/web/app/view/permissions/Drivers.js b/legacy/web/app/view/permissions/Drivers.js new file mode 100644 index 00000000..33cf2f76 --- /dev/null +++ b/legacy/web/app/view/permissions/Drivers.js @@ -0,0 +1,38 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.permissions.Drivers', { + extend: 'Traccar.view.permissions.Base', + xtype: 'linkDriversView', + + columns: { + items: [{ + text: Strings.sharedName, + dataIndex: 'name', + flex: 1, + minWidth: Traccar.Style.columnWidthNormal, + filter: 'string' + }, { + text: Strings.deviceIdentifier, + dataIndex: 'uniqueId', + flex: 1, + minWidth: Traccar.Style.columnWidthNormal, + filter: 'string' + }] + } +}); diff --git a/legacy/web/app/view/permissions/Geofences.js b/legacy/web/app/view/permissions/Geofences.js new file mode 100644 index 00000000..e2e85a36 --- /dev/null +++ b/legacy/web/app/view/permissions/Geofences.js @@ -0,0 +1,43 @@ +/* + * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.permissions.Geofences', { + extend: 'Traccar.view.permissions.Base', + xtype: 'linkGeofencesView', + + columns: { + items: [{ + text: Strings.sharedName, + dataIndex: 'name', + flex: 1, + minWidth: Traccar.Style.columnWidthNormal, + filter: 'string' + }, { + text: Strings.sharedCalendar, + dataIndex: 'calendarId', + flex: 1, + minWidth: Traccar.Style.columnWidthNormal, + hidden: true, + filter: { + type: 'list', + labelField: 'name', + store: 'AllCalendars' + }, + renderer: Traccar.AttributeFormatter.getFormatter('calendarId') + }] + } +}); diff --git a/legacy/web/app/view/permissions/Groups.js b/legacy/web/app/view/permissions/Groups.js new file mode 100644 index 00000000..91a639c0 --- /dev/null +++ b/legacy/web/app/view/permissions/Groups.js @@ -0,0 +1,47 @@ +/* + * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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.permissions.Groups', { + extend: 'Traccar.view.permissions.Base', + xtype: 'linkGroupsView', + + requires: [ + 'Traccar.AttributeFormatter' + ], + + columns: { + items: [{ + text: Strings.sharedName, + dataIndex: 'name', + flex: 1, + minWidth: Traccar.Style.columnWidthNormal, + filter: 'string' + }, { + text: Strings.groupDialog, + dataIndex: 'groupId', + flex: 1, + minWidth: Traccar.Style.columnWidthNormal, + hidden: true, + filter: { + type: 'list', + labelField: 'name', + store: 'AllGroups' + }, + renderer: Traccar.AttributeFormatter.getFormatter('groupId') + }] + } +}); diff --git a/legacy/web/app/view/permissions/Maintenances.js b/legacy/web/app/view/permissions/Maintenances.js new file mode 100644 index 00000000..c5255769 --- /dev/null +++ b/legacy/web/app/view/permissions/Maintenances.js @@ -0,0 +1,65 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 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.permissions.Maintenances', { + extend: 'Traccar.view.permissions.Base', + xtype: 'linkMaintenancesView', + + columns: { + items: [{ + text: Strings.sharedName, + dataIndex: 'name', + flex: 1, + minWidth: Traccar.Style.columnWidthNormal, + filter: 'string' + }, { + text: Strings.sharedType, + dataIndex: 'type', + flex: 1, + minWidth: Traccar.Style.columnWidthNormal, + filter: { + type: 'list', + idField: 'key', + labelField: 'name', + store: 'MaintenanceTypes' + }, + renderer: function (value) { + var attribute = Ext.getStore('MaintenanceTypes').getById(value); + return attribute && attribute.get('name') || value; + } + }, { + text: Strings.maintenanceStart, + dataIndex: 'start', + flex: 1, + minWidth: Traccar.Style.columnWidthNormal, + renderer: function (value, metaData, record) { + return Traccar.AttributeFormatter.renderAttribute( + value, Ext.getStore('MaintenanceTypes').getById(record.get('type'))); + } + }, { + text: Strings.maintenancePeriod, + dataIndex: 'period', + flex: 1, + minWidth: Traccar.Style.columnWidthNormal, + renderer: function (value, metaData, record) { + return Traccar.AttributeFormatter.renderAttribute( + value, Ext.getStore('MaintenanceTypes').getById(record.get('type'))); + } + }] + } +}); diff --git a/legacy/web/app/view/permissions/Notifications.js b/legacy/web/app/view/permissions/Notifications.js new file mode 100644 index 00000000..a8570fea --- /dev/null +++ b/legacy/web/app/view/permissions/Notifications.js @@ -0,0 +1,78 @@ +/* + * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 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.permissions.Notifications', { + extend: 'Traccar.view.permissions.Base', + xtype: 'linkNotificationsView', + + columns: { + items: [{ + text: Strings.notificationType, + dataIndex: 'type', + flex: 2, + renderer: function (value) { + return Traccar.app.getEventString(value); + }, + filter: { + type: 'list', + idField: 'type', + labelField: 'name', + store: 'AllNotificationTypes' + } + }, { + text: Strings.notificationAlways, + dataIndex: 'always', + flex: 1, + minWidth: Traccar.Style.columnWidthNormal, + renderer: Traccar.AttributeFormatter.getFormatter('always'), + filter: 'boolean' + }, { + text: Strings.notificationNotificators, + dataIndex: 'notificators', + flex: 2, + filter: { + type: 'arraylist', + idField: 'type', + labelField: 'name', + store: 'AllNotificators' + }, + renderer: function (value) { + var result = '', i, notificators; + if (value) { + notificators = value.split(/[ ,]+/).filter(Boolean); + for (i = 0; i < notificators.length; i++) { + result += Traccar.app.getNotificatorString(notificators[i]) + (i < notificators.length - 1 ? ', ' : ''); + } + } + return result; + } + }, { + text: Strings.sharedCalendar, + dataIndex: 'calendarId', + flex: 1, + minWidth: Traccar.Style.columnWidthNormal, + hidden: true, + filter: { + type: 'list', + labelField: 'name', + store: 'AllCalendars' + }, + renderer: Traccar.AttributeFormatter.getFormatter('calendarId') + }] + } +}); diff --git a/legacy/web/app/view/permissions/SavedCommands.js b/legacy/web/app/view/permissions/SavedCommands.js new file mode 100644 index 00000000..b57c07a0 --- /dev/null +++ b/legacy/web/app/view/permissions/SavedCommands.js @@ -0,0 +1,50 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.permissions.SavedCommands', { + extend: 'Traccar.view.permissions.Base', + xtype: 'linkSavedCommandsView', + + columns: { + items: [{ + text: Strings.sharedDescription, + dataIndex: 'description', + flex: 1, + minWidth: Traccar.Style.columnWidthNormal, + filter: 'string' + }, { + text: Strings.sharedType, + dataIndex: 'type', + flex: 1, + minWidth: Traccar.Style.columnWidthNormal, + filter: { + type: 'list', + idField: 'type', + labelField: 'name', + store: 'AllCommandTypes' + }, + renderer: Traccar.AttributeFormatter.getFormatter('commandType') + }, { + text: Strings.commandSendSms, + dataIndex: 'textChannel', + flex: 1, + minWidth: Traccar.Style.columnWidthNormal, + filter: 'boolean' + }] + } +}); diff --git a/legacy/web/app/view/permissions/Users.js b/legacy/web/app/view/permissions/Users.js new file mode 100644 index 00000000..66cf5d62 --- /dev/null +++ b/legacy/web/app/view/permissions/Users.js @@ -0,0 +1,32 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Ext.define('Traccar.view.permissions.Users', { + extend: 'Traccar.view.permissions.Base', + xtype: 'linkUsersView', + + columns: { + items: [{ + text: Strings.sharedName, + dataIndex: 'name', + flex: 1, + minWidth: Traccar.Style.columnWidthNormal, + filter: 'string' + }] + } +}); |