EVOLUTION-MANAGER
Edit File: app.min.js
Ext.define('Traccar.view.TouchFix62',{override:'Ext.dom.Element'},function(){var additiveEvents=this.prototype.additiveEvents,eventMap=this.prototype.eventMap;Ext.supports.TouchEvents&&52<=Ext.firefoxVersion&&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')}); Ext.define('Traccar.Style',{singleton:!0,refreshPeriod:6E4,reconnectTimeout:6E4,reportTimeout:12E4,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'.split(' '), 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:.2, mapGeofenceWidth:5,mapGeofenceRadius:9,mapAnimateMarkerDuration:2E3,mapAnimateMarkerTimeout:40,coordinatePrecision:6,numberPrecision:2,reportGridStyle:'borderTop: 1px solid lightgray',chartPadding:'20 40 10 10',chartMarkerRadius:3,chartMarkerHighlightScaling:1.5}); Ext.define('Traccar.AttributeFormatter',{singleton:!0,numberFormatterFactory:function(precision,suffix){return function(value){return void 0!==value?Number(value.toFixed(precision))+' '+suffix: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){return'N NE E SE S SW W NW'.split(' ')[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',!0)},deviceIdFormatter:function(value){if(0!== value){var store=Ext.getStore('AllDevices');0===store.getTotalCount()&&(store=Ext.getStore('Devices'));return(value=store.getById(value))?value.get('name'):''}return null},groupIdFormatter:function(value){if(0!==value){var group=Ext.getStore('AllGroups');0===group.getTotalCount()&&(group=Ext.getStore('Groups'));return(group=group.getById(value))?group.get('name'):value}return null},geofenceIdFormatter:function(value){if(0!==value){var store=Ext.getStore('AllGeofences');0===store.getTotalCount()&& (store=Ext.getStore('Geofences'));return(value=store.getById(value))?value.get('name'):''}return null},calendarIdFormatter:function(value){if(0!==value){var store=Ext.getStore('AllCalendars');0===store.getTotalCount()&&(store=Ext.getStore('Calendars'));return(value=store.getById(value))?value.get('name'):''}return null},driverUniqueIdFormatter:function(value){if(0!==value){var driver=Ext.getStore('AllDrivers');0===driver.getTotalCount()&&(driver=Ext.getStore('Drivers'));return(driver=driver.findRecord('uniqueId', value,0,!1,!0,!0))?value+' ('+driver.get('name')+')':value}return null},maintenanceIdFormatter:function(value){if(0!==value){var store=Ext.getStore('AllMaintenances');0===store.getTotalCount()&&(store=Ext.getStore('Maintenances'));return(value=store.getById(value))?value.get('name'):''}return null},lastUpdateFormatter:function(value){if(value){value=Math.floor((new Date-value)/1E3);0>value&&(value=0);var interval=Math.floor(value/86400);if(1<interval)return interval+' '+Strings.sharedDays;interval= Math.floor(value/3600);return 1<interval?interval+' '+Strings.sharedHours:Math.floor(value/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){return'number'===typeof value?Number(value.toFixed(Traccar.Style.numberPrecision)):'boolean'===typeof value?value?Ext.Msg.buttonText.yes:Ext.Msg.buttonText.no:value instanceof Date?Traccar.app.getPreference('twelveHourFormat', !1)?Ext.Date.format(value,Traccar.Style.dateTimeFormat12):Ext.Date.format(value,Traccar.Style.dateTimeFormat24):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){switch(Ext.getStore('PositionAttributes').getAttributeDataType(key)){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,'\x26#37;');case 'temperature':return this.numberFormatterFactory(Traccar.Style.numberPrecision,'\x26deg;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){switch(Ext.getStore('PositionAttributes').getAttributeDataType(key)){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){return attribute&&'speed'===attribute.get('dataType')?Ext.getStore('SpeedUnits').formatValue(value,Traccar.app.getAttributePreference('speedUnit','kn'),!0):attribute&&'distance'===attribute.get('dataType')?Ext.getStore('DistanceUnits').formatValue(value,Traccar.app.getAttributePreference('distanceUnit', 'km'),!0):attribute&&'hours'===attribute.get('dataType')?Ext.getStore('HoursUnits').formatValue(value,'h',!0):value}}); 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:'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:!0}}}); 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:'poiLayer',type:'string'},{name:'token',type:'string'},{name:'attributes'}],proxy:{type:'rest',url:'api/users',writer:{type:'json',writeAllFields:!0}}}); 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'}]}); 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:!0},{name:'model',type:'string',allowNull:!0},{name:'contact',type:'string',allowNull:!0},{name:'category',type:'string',allowNull:!0},{name:'status',type:'string',allowNull:!0},{name:'lastUpdate',type:'date',dateFormat:'c'},{name:'groupId',type:'int'},{name:'disabled',type:'boolean'},{name:'geofenceIds'}, {name:'attributes'}]}); 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'}]});Ext.define('Traccar.model.Attribute',{extend:Ext.data.Model,fields:[{name:'priority',type:'int'},{name:'name',type:'string'},{name:'value'},{name:'attribute',type:'string'}]}); 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'}]}); 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 geofence;'commandResult'===rec.get('type')?v=Strings.eventCommandResult+': '+rec.get('attributes').result:'alarm'===rec.get('type')?(v=rec.get('attributes').alarm, v='alarm'+v.charAt(0).toUpperCase()+v.slice(1),v=Strings[v]||v):v='textMessage'===rec.get('type')?Strings.eventTextMessage+': '+rec.get('attributes').message:'driverChanged'===rec.get('type')?Strings.eventDriverChanged+': '+Traccar.AttributeFormatter.driverUniqueIdFormatter(rec.get('attributes').driverUniqueId):Traccar.app.getEventString(rec.get('type'));rec.get('geofenceId')&&(geofence=Ext.getStore('Geofences').getById(rec.get('geofenceId')))&&(v+=' "'+geofence.get('name')+'"');rec.get('maintenanceId')&& (rec=Ext.getStore('Maintenances').getById(rec.get('maintenanceId')))&&(v+=' "'+rec.get('name')+'"');return v},depends:['type','attributes','geofenceId','maintenanceId']},{name:'attributes'}]});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'}]}); 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'}]}); 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')}]}); 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'}]}); 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')}]}); Ext.define('Traccar.model.Calendar',{extend:Ext.data.Model,identifier:'negative',fields:[{name:'id',type:'int'},{name:'name',type:'string'},{name:'data'},{name:'attributes'}]});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'}]}); 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'}]});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'}]}); 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']}]});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'}]}); Ext.define('Traccar.store.Groups',{extend:Ext.data.Store,model:'Traccar.model.Group',proxy:{type:'rest',url:'api/groups',writer:{writeAllFields:!0}}});Ext.define('Traccar.store.Devices',{extend:Ext.data.Store,model:'Traccar.model.Device',proxy:{type:'rest',url:'api/devices',writer:{writeAllFields:!0}}});Ext.define('Traccar.store.AllGroups',{extend:Ext.data.Store,model:'Traccar.model.Group',proxy:{type:'rest',url:'api/groups',extraParams:{all:!0}}}); Ext.define('Traccar.store.AllDevices',{extend:Ext.data.Store,model:'Traccar.model.Device',proxy:{type:'rest',url:'api/devices',extraParams:{all:!0}}});Ext.define('Traccar.store.AlarmTypes',{extend:Ext.data.Store,fields:['key','name'],data:function(){var key,items=[];for(key in Strings)Strings.hasOwnProperty(key)&&0===key.lastIndexOf('alarm',0)&&items.push({key:key.charAt(5).toLowerCase()+key.slice(6),name:Strings[key]});return items}()}); Ext.define('Traccar.store.Positions',{extend:Ext.data.Store,model:'Traccar.model.Position',proxy:{type:'rest',url:'api/positions',headers:{Accept:'application/json'}}});Ext.define('Traccar.store.LatestPositions',{extend:Ext.data.Store,model:'Traccar.model.Position'});Ext.define('Traccar.store.EventPositions',{extend:Ext.data.Store,model:'Traccar.model.Position',trackRemoved:!1,proxy:{type:'rest',url:'api/positions',headers:{Accept:'application/json'}}}); Ext.define('Traccar.store.Users',{extend:Ext.data.Store,model:'Traccar.model.User',proxy:{type:'rest',url:'api/users',writer:{writeAllFields:!0}}});Ext.define('Traccar.store.Attributes',{extend:Ext.data.Store,model:'Traccar.model.Attribute',sorters:[{property:'priority'}]}); Ext.define('Traccar.store.MapTypes',{extend:Ext.data.Store,fields:['key','name'],data:[{key:'carto',name:Strings.mapCarto},{key:'osm',name:Strings.mapOsm},{key:'bingRoad',name:Strings.mapBingRoad},{key:'bingAerial',name:Strings.mapBingAerial},{key:'bingHybrid',name:Strings.mapBingHybrid},{key:'autoNavi',name:Strings.mapAutoNavi},{key:'yandexMap',name:Strings.mapYandexMap},{key:'yandexSat',name:Strings.mapYandexSat},{key:'wikimedia',name:Strings.mapWikimedia},{key:'custom',name:Strings.mapCustom}, {key:'customArcgis',name:Strings.mapCustomArcgis}]}); Ext.define('Traccar.store.DistanceUnits',{extend:Ext.data.Store,fields:['key','name','factor'],data:[{key:'km',name:Strings.sharedKm,factor:.001},{key:'mi',name:Strings.sharedMi,factor:6.21371E-4},{key:'nmi',name:Strings.sharedNmi,factor:5.39957E-4}],convertValue:function(value,unit,back){unit||(unit='km');unit=this.findRecord('key',unit);return back?value/unit.get('factor'):value*unit.get('factor')},formatValue:function(value,unit,convert){unit||(unit='km');var model=this.findRecord('key',unit); return(convert?this.convertValue(value,unit):value).toFixed(2)+' '+model.get('name')}}); 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){unit||(unit='kn');unit=this.findRecord('key',unit);return back?value/unit.get('factor'):value*unit.get('factor')},formatValue:function(value,unit,convert){unit||(unit='kn');var model=this.findRecord('key',unit);return(convert? this.convertValue(value,unit):value).toFixed(1)+' '+model.get('name')}}); 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){key='latitude'===key?0<=value?'N':'S':0<=value?'E':'W';switch(unit){case 'ddm':return value=Math.abs(value),unit=Math.floor(value),unit+'° '+(60*(value-unit)).toFixed(Traccar.Style.coordinatePrecision)+"' "+key;case 'dms':value= Math.abs(value);unit=Math.floor(value);var minutes=Math.floor(60*(value-unit));value=Math.round(3600*(value-unit-minutes/60));return unit+'° '+minutes+"' "+value+'" '+key;default:return value.toFixed(Traccar.Style.coordinatePrecision)+'°'}}});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)}}}}); 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){unit||(unit='kn');unit=this.findRecord('key',unit);return back?value*unit.get('factor'):value/unit.get('factor')}}); Ext.define('Traccar.store.Languages',{extend:Ext.data.Store,fields:['code','name'],data:function(){var code,data=[];for(code in Locale.languages)Locale.languages.hasOwnProperty(code)&&data.push({code:code,name:Locale.languages[code].name});return data}()});Ext.define('Traccar.store.Events',{extend:Ext.data.Store,model:'Traccar.model.Event',trackRemoved:!1,proxy:{type:'rest',url:'api/events'}}); Ext.define('Traccar.store.Geofences',{extend:Ext.data.Store,model:'Traccar.model.Geofence',proxy:{type:'rest',url:'api/geofences',writer:{writeAllFields:!0}}});Ext.define('Traccar.store.AllGeofences',{extend:Ext.data.Store,model:'Traccar.model.Geofence',proxy:{type:'rest',url:'api/geofences',extraParams:{all:!0}}});Ext.define('Traccar.store.Notifications',{extend:Ext.data.Store,model:'Traccar.model.Notification',proxy:{type:'rest',url:'api/notifications',writer:{writeAllFields:!0}}}); Ext.define('Traccar.store.AllNotifications',{extend:Ext.data.Store,model:'Traccar.model.Notification',proxy:{type:'rest',url:'api/notifications',extraParams:{all:!0}}});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}]}); 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)}}}}); 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)}}}}); 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)}}}}); 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)}}}}); 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)}}}}); 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}]});Ext.define('Traccar.store.ReportEventTypes',{extend:Ext.data.Store,fields:['type','name'],statics:{allEvents:'allEvents'}}); 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}]}); 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}]}); 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'}]}); Ext.define('Traccar.store.Statistics',{extend:Ext.data.Store,model:'Traccar.model.Statistics',proxy:{type:'rest',url:'api/statistics'}}); Ext.define('Traccar.store.DeviceImages',{extend:Ext.data.Store,fields:'key name svg fillId rotateId scaleId'.split(' '),data:function(){var i,data=[];for(i=0;i<window.Images.length;i++){var 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:'arrow'===key?'arrow':'background',rotateId:'arrow'===key?'arrow':'background',scaleId:'arrow'===key?'arrow':'layer1'})}return data}()}); Ext.define('Traccar.store.Calendars',{extend:Ext.data.Store,model:'Traccar.model.Calendar',proxy:{type:'rest',url:'api/calendars',writer:{writeAllFields:!0}}});Ext.define('Traccar.store.AllCalendars',{extend:Ext.data.Store,model:'Traccar.model.Calendar',proxy:{type:'rest',url:'api/calendars',extraParams:{all:!0}}}); 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'}]});Ext.define('Traccar.store.VisibleDevices',{extend:Ext.data.ChainedStore,source:'Devices'});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'}]}); 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'}]}); 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:!1,minValue:1},{key:'deviceInactivityPeriod',name:Strings.attributeDeviceInactivityPeriod,valueType:'number',allowDecimals:!1,minValue:1}]}); 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'}]}); 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'}]});Ext.define('Traccar.store.ServerAttributes',{extend:Ext.data.Store,model:'Traccar.model.KnownAttribute',data:[]}); Ext.define('Traccar.store.CommonUserAttributes',{extend:Ext.data.Store,model:'Traccar.model.KnownAttribute',data:[{key:'web.liveRouteLength',name:Strings.attributeWebLiveRouteLength,valueType:'number',allowDecimals:!1},{key:'web.selectZoom',name:Strings.attributeWebSelectZoom,valueType:'number',allowDecimals:!1,minValue:Traccar.Style.mapDefaultZoom,maxValue:Traccar.Style.mapMaxZoom},{key:'web.maxZoom',name:Strings.attributeWebMaxZoom,valueType:'number',allowDecimals:!1,minValue:Traccar.Style.mapDefaultZoom, maxValue:Traccar.Style.mapMaxZoom},{key:'ui.disableReport',name:Strings.attributeUiDisableReport,valueType:'boolean'},{key:'ui.disableEvents',name:Strings.attributeUiDisableEvents,valueType:'boolean'},{key:'ui.disableVehicleFetures',name:Strings.attributeUiDisableVehicleFetures,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'}]}); 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:!1,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'}]});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'}]});Ext.define('Traccar.store.ComputedAttributes',{extend:Ext.data.Store,model:'Traccar.model.ComputedAttribute',proxy:{type:'rest',url:'api/attributes/computed',writer:{writeAllFields:!0}}}); Ext.define('Traccar.store.AllComputedAttributes',{extend:Ext.data.Store,model:'Traccar.model.ComputedAttribute',proxy:{type:'rest',url:'api/attributes/computed',extraParams:{all:!0}}}); 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);return model?model.get('name'):capitalize?key.replace(/^./,function(match){return match.toUpperCase()}):key},getAttributeDataType:function(key){return(key=this.getById(key))&&key.get('dataType')?key.get('dataType'):null}}); 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}]});Ext.define('Traccar.store.Drivers',{extend:Ext.data.Store,model:'Traccar.model.Driver',proxy:{type:'rest',url:'api/drivers',writer:{writeAllFields:!0}}}); Ext.define('Traccar.store.AllDrivers',{extend:Ext.data.Store,model:'Traccar.model.Driver',proxy:{type:'rest',url:'api/drivers',extraParams:{all:!0}}}); 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:!1,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:!1,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:!1,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:!1,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:'movementAlarm',parameters:[{key:'radius',name:Strings.commandRadius,valueType:'number',allowDecimals:!1,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'}]}]}); 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){unit||(unit='ltr');unit=this.findRecord('key',unit);return back?value* unit.get('factor'):value/unit.get('factor')},formatValue:function(value,unit,convert){unit||(unit='ltr');var model=this.findRecord('key',unit);return(convert?this.convertValue(value,unit):value).toFixed(1)+' '+model.get('name')}});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)}}}}); Ext.define('Traccar.store.Commands',{extend:Ext.data.Store,model:'Traccar.model.Command',proxy:{type:'rest',url:'api/commands',writer:{writeAllFields:!0}}});Ext.define('Traccar.store.AllCommands',{extend:Ext.data.Store,model:'Traccar.model.Command',proxy:{type:'rest',url:'api/commands',extraParams:{all:!0}}});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)}}}}); 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)}}}});Ext.define('Traccar.store.Maintenances',{extend:Ext.data.Store,model:'Traccar.model.Maintenance',proxy:{type:'rest',url:'api/maintenance',writer:{writeAllFields:!0}}}); Ext.define('Traccar.store.AllMaintenances',{extend:Ext.data.Store,model:'Traccar.model.Maintenance',proxy:{type:'rest',url:'api/maintenance',extraParams:{all:!0}}});Ext.define('Traccar.store.MaintenanceTypes',{extend:Ext.data.Store,model:'Traccar.model.KnownAttribute'}); 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?36E5*value:value/36E5},formatValue:function(value,unit,convert){convert?(unit=Math.floor(value/36E5),value=Math.floor(value%36E5/6E4)):(unit=Math.floor(value),value=Math.floor(value%1*60));return unit+' '+Strings.sharedHourAbbreviation+' '+value+' '+Strings.sharedMinuteAbbreviation}}); 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']}]});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)}}}}); Ext.define('Traccar.view.dialog.Base',{extend:Ext.window.Window,bodyPadding:Traccar.Style.normalPadding,resizable:!1,scrollable:!0,constrain:!0,initComponent:function(){window.innerHeight&&(this.maxHeight=window.innerHeight-2*Traccar.Style.normalPadding);this.callParent()}}); Ext.define('Traccar.view.dialog.RegisterController',{extend:Ext.app.ViewController,alias:'controller.register',onCreateClick:function(){var form=this.lookupReference('form');form.isValid()&&Ext.Ajax.request({scope:this,method:'POST',url:'api/users',jsonData:form.getValues(),callback:this.onCreateReturn})},onCreateReturn:function(options,success,response){success?(this.closeView(),Traccar.app.showToast(Strings.loginCreated)):Traccar.app.showError(response)}}); Ext.define('Traccar.view.dialog.Register',{extend:Traccar.view.dialog.Base,controller:'register',title:Strings.loginRegister,items:{xtype:'form',reference:'form',jsonSubmit:!0,items:[{xtype:'textfield',name:'name',fieldLabel:Strings.sharedName,allowBlank:!1},{xtype:'textfield',name:'email',fieldLabel:Strings.userEmail,validator:function(val){return/(.+)@(.+)\.(.{2,})/.test(val)?!0:Ext.form.field.VTypes.emailText},allowBlank:!1},{xtype:'textfield',name:'password',fieldLabel:Strings.userPassword,inputType:'password', allowBlank:!1}]},buttons:[{text:Strings.sharedSave,handler:'onCreateClick'},{text:Strings.sharedCancel,handler:'closeView'}]}); Ext.define('Traccar.view.dialog.LoginController',{extend:Ext.app.ViewController,alias:'controller.login',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');form.isValid()&&(Ext.get('spinner').setVisible(!0),this.getView().setVisible(!1), Ext.Ajax.request({scope:this,method:'POST',url:'api/session',params:form.getValues(),callback:function(options,success,response){Ext.get('spinner').setVisible(!1);success?(this.lookupReference('rememberField').getValue()&&(options=Ext.util.Base64.encode(this.lookupReference('userField').getValue()),success=Ext.util.Base64.encode(this.lookupReference('passwordField').getValue()),Ext.util.Cookies.set('user',options,Ext.Date.add(new Date,Ext.Date.YEAR,1)),Ext.util.Cookies.set('password',success,Ext.Date.add(new Date, Ext.Date.YEAR,1))),Traccar.app.setUser(Ext.decode(response.responseText)),this.fireViewEvent('login')):(this.getView().setVisible(!0),401===response.status?Traccar.app.showError(Strings.loginFailed):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){selected=selected.getValue(); var url=window.location.href;if(0<=url.indexOf('locale\x3d')){var prefix=url.substring(0,url.indexOf('locale'));url=url.substring(url.indexOf('locale'));url=url.substring(url.indexOf('\x3d')+1);url=0<=url.indexOf('\x26')?url.substring(url.indexOf('\x26')):'';url=prefix+'locale\x3d'+selected+url}else url=0>url.indexOf('?')?url+('?locale\x3d'+selected):url+('\x26locale\x3d'+selected);window.location.href=url},onAfterRender:function(field){field.focus()},onSpecialKey:function(field,e){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){'ok'===btn&&Ext.Ajax.request({scope:this,method:'POST',url:'api/password/reset',params:{email:text},callback:function(options,success,response){success?Traccar.app.showToast(Strings.loginResetSuccess):Traccar.app.showError(response.responseText)}})})}}); Ext.define('Traccar.view.dialog.Login',{extend:Traccar.view.dialog.Base,alias:'widget.login',controller:'login',header:!1,closable:!1,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:'combobox',name:'language',fieldLabel:Strings.loginLanguage,store:'Languages',displayField:'name',valueField:'code', editable:!1,submitValue:!1,listeners:{select:'onSelectLanguage'},reference:'languageField'},{xtype:'textfield',name:'email',reference:'userField',fieldLabel:Strings.userEmail,allowBlank:!1,enableKeyEvents:!0,listeners:{specialKey:'onSpecialKey',afterrender:'onAfterRender'},inputAttrTpl:['autocomplete\x3d"on" autocapitalize\x3d"none"']},{xtype:'textfield',name:'password',reference:'passwordField',fieldLabel:Strings.userPassword,inputType:'password',allowBlank:!1,enableKeyEvents:!0,listeners:{specialKey:'onSpecialKey'}, inputAttrTpl:['autocomplete\x3d"on"']},{xtype:'checkboxfield',inputValue:!0,uncheckedValue:!1,reference:'rememberField',fieldLabel:Strings.userRemember},{xtype:'component',html:'\x3ciframe id\x3d"submitTarget" name\x3d"submitTarget" style\x3d"display:none"\x3e\x3c/iframe\x3e'},{xtype:'component',html:'\x3cinput type\x3d"submit" id\x3d"submitButton" style\x3d"display:none"\x3e'}]},buttons:[{text:Strings.loginReset,handler:'onResetClick',reference:'resetButton'},{text:Strings.loginRegister,handler:'onRegisterClick', reference:'registerButton'},{text:Strings.loginLogin,handler:'onLoginClick'}]});Ext.define('Traccar.view.MainController',{extend:Ext.app.ViewController,alias:'controller.mainController',init:function(){this.lookupReference('reportView').setHidden(Traccar.app.getBooleanAttributePreference('ui.disableReport'));this.lookupReference('eventsView').setHidden(Traccar.app.getBooleanAttributePreference('ui.disableEvents'))}}); Ext.define('Traccar.view.GridPanel',{extend:Ext.grid.Panel,xtype:'customGridPanel',plugins:'gridfilters',viewConfig:{enableTextSelection:!0,getRowClass:function(){return this.enableTextSelection?'x-selectable':''}}}); Ext.define('Traccar.view.edit.ToolbarController',{extend:Ext.app.ViewController,alias:'controller.toolbarController',onAddClick:function(){var objectInstance=Ext.create(this.objectModel);objectInstance.store=this.getView().getStore();objectInstance.store instanceof Ext.data.ChainedStore&&(objectInstance.store=objectInstance.store.getSource());var dialog=Ext.create(this.objectDialog);dialog.down('form').loadRecord(objectInstance);dialog.show()},onEditClick:function(){var objectInstance=this.getView().getSelectionModel().getSelection()[0]; var 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;'yes'===btn&&(store.remove(objectInstance),store.sync({failure:function(batch){store.rejectChanges(); Traccar.app.showError(batch.exceptions[0].getError().response)}}))}})},onSelectionChange:function(selection,selected){selection=0===selected.length;this.lookupReference('toolbarEditButton').setDisabled(selection);this.lookupReference('toolbarRemoveButton').setDisabled(selection)}}); 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=!0,this.style='border-width: 0';this.callParent()}}); Ext.define('Traccar.view.dialog.AttributeController',{extend:Ext.app.ViewController,alias:'controller.attribute',onSaveClick:function(button){var store;var dialog=button.up('window').down('form');dialog.updateRecord();dialog=dialog.getRecord();(store=dialog.store)?(dialog.phantom&&store.add(dialog),store.sync({failure:function(batch){store.rejectChanges();Traccar.app.showError(batch.exceptions[0].getError().response)}})):dialog.save();button.up('window').close()},onValidityChange:function(form,valid){this.lookupReference('saveButton').setDisabled(!valid)}, defaultFieldConfig:{name:'value',reference:'valueField',allowBlank:!1,fieldLabel:Strings.stateValue},onNameChange:function(combobox,newValue){var valueField=this.lookupReference('valueField');if(newValue=combobox.getStore().getById(newValue)){combobox=Ext.clone(this.defaultFieldConfig);switch(newValue.get('valueType')){case 'number':combobox.xtype='customNumberField';void 0!==newValue.get('allowDecimals')?combobox.allowDecimals=newValue.get('allowDecimals'):combobox.allowDecimals=!0;combobox.dataType= newValue.get('dataType');combobox.maxValue=newValue.get('maxValue');combobox.minValue=newValue.get('minValue');break;case 'boolean':combobox.xtype='checkboxfield';combobox.inputValue=!0;combobox.uncheckedValue=!1;break;case 'color':combobox.xtype='customcolorpicker';break;default:if(newValue.get('dataType'))switch(combobox.xtype='combobox',combobox.queryMode='local',combobox.editable=!1,newValue.get('dataType')){case 'distanceUnit':combobox.store='DistanceUnits';combobox.displayField='name';combobox.valueField= 'key';break;case 'speedUnit':combobox.store='SpeedUnits';combobox.displayField='name';combobox.valueField='key';break;case 'volumeUnit':combobox.store='VolumeUnits';combobox.displayField='fullName';combobox.valueField='key';break;case 'timezone':combobox.store='AllTimezones',combobox.displayField='key'}else combobox.xtype='textfield'}valueField.getXType()!==combobox.xtype||'customNumberField'===combobox.xtype&&valueField.dataType!==combobox.dataType?(this.getView().down('form').insert(this.getView().down('form').items.indexOf(valueField), combobox),this.getView().down('form').remove(valueField)):'customNumberField'===combobox.xtype?(valueField.setConfig(combobox),valueField.validate()):'combobox'===combobox.xtype&&(valueField.setConfig(combobox),valueField.setValue())}}}); Ext.define('Traccar.view.ColorPicker',{extend:Ext.form.field.Picker,xtype:'customcolorpicker',config:{value:'#008000'},editable:!1,createPicker:function(){return Ext.create('Ext.picker.Color',{floating:!0,picker:this,select:function(selColor){this.picker.setValue('#'+selColor);this.picker.collapse()}})},setValue:function(color){this.callParent([color]);this.setFieldStyle('background-color:'+color)}}); Ext.define('Traccar.view.CustomNumberField',{extend:Ext.form.field.Number,xtype:'customNumberField',beforeEl:'\x3cdiv style\x3d"width:100%;display:inline-table;"\x3e',unitEl:'\x3cdiv id\x3d"numberUnitEl" style\x3d"display:table-cell;padding-left:10px;vertical-align:middle;width:1px;white-space:nowrap;"\x3e',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':config.listeners|| (config.listeners={});config.listeners.afterrender=function(){this.units||(this.units=Ext.create({xtype:'combobox',renderTo:'numberUnitEl',store:'TimeUnits',displayField:'name',valueField:'key',editable:!1,numberField:this,value:'s',width:'70px',listeners:{select:function(){this.numberField.step=this.getStore().convertValue(1,this.getValue(),!0)}}}))};break;case 'hours':config.units={},config.units.getStore=function(){return Ext.getStore('HoursUnits')},config.units.getValue=function(){return'h'}, unitName=Strings.sharedHourAbbreviation}config.afterBodyEl=this.unitEl+unitName+'\x3c/div\x3e\x3c/div\x3e';config.rawToValue=function(rawValue){return this.units?this.units.getStore().convertValue(this.parseValue(rawValue),this.units.getValue(),!0):this.parseValue(rawValue)};config.valueToRaw=function(value){return this.units?String(this.units.getStore().convertValue(value,this.units.getValue(),!1)):String(value)};config.units&&(config.step=config.units.getStore().convertValue(1,config.units.getValue(), !0))}this.callParent(arguments)}});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))}}); Ext.define('Traccar.view.dialog.Attribute',{extend:Traccar.view.dialog.Base,controller:'attribute',title:Strings.sharedAttribute,items:{xtype:'form',listeners:{validitychange:'onValidityChange'},items:[{xtype:'unescapedTextField',reference:'nameTextField',name:'name',allowBlank:!1,fieldLabel:Strings.sharedName},{xtype:'textfield',name:'value',reference:'valueField',allowBlank:!1,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'}]}); Ext.define('Traccar.view.edit.AttributesController',{extend:Traccar.view.edit.ToolbarController,alias:'controller.attributes',removeTitle:Strings.stateName,init:function(){var propertyName,i=0;var store$jscomp$0=Ext.create('Traccar.store.Attributes');store$jscomp$0.setProxy(Ext.create('Ext.data.proxy.Memory'));'undefined'===typeof this.getView().record.get('attributes')&&this.getView().record.set('attributes',{});var attributes=this.getView().record.get('attributes');for(propertyName in attributes)attributes.hasOwnProperty(propertyName)&& store$jscomp$0.add(Ext.create('Traccar.model.Attribute',{priority:i++,name:propertyName,value:attributes[propertyName]}));store$jscomp$0.addListener('add',function(store,records){var view=this.getView();for(store=0;store<records.length;store++)view.record.get('attributes')[records[store].get('name')]=records[store].get('value');view.record.dirty=!0},this);store$jscomp$0.addListener('update',function(store,record,operation){store=this.getView();operation===Ext.data.Model.EDIT&&(record.modified.name!== record.get('name')&&delete store.record.get('attributes')[record.modified.name],store.record.get('attributes')[record.get('name')]=record.get('value'),store.record.dirty=!0)},this);store$jscomp$0.addListener('remove',function(store,records){var view=this.getView();for(store=0;store<records.length;store++)delete view.record.get('attributes')[records[store].get('name')];view.record.dirty=!0},this);this.getView().setStore(store$jscomp$0);this.getView().record instanceof Traccar.model.Device?this.getView().attributesStore= 'DeviceAttributes':this.getView().record instanceof Traccar.model.Geofence?this.getView().attributesStore='GeofenceAttributes':this.getView().record instanceof Traccar.model.Group?this.getView().attributesStore='GroupAttributes':this.getView().record instanceof Traccar.model.Server?this.getView().attributesStore='ServerAttributes':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:!1,queryMode:'local',listeners:{change:'onNameChange'}},initDialog:function(record){var dialog=Ext.create('Traccar.view.dialog.Attribute');if(this.getView().attributesStore){this.comboConfig.store=this.getView().attributesStore;var 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])}}); 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:!0,handler:'onEditClick',reference:'toolbarEditButton',glyph:'xf040@FontAwesome',tooltip:Strings.sharedEdit,tooltipType:'title'},{xtype:'button',disabled:!0,handler:'onRemoveClick',reference:'toolbarRemoveButton', glyph:'xf00d@FontAwesome',tooltip:Strings.sharedRemove,tooltipType:'title'}])}}); Ext.define('Traccar.view.edit.Attributes',{extend:Traccar.view.GridPanel,xtype:'attributesView',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;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;this.attributesStore&&(attribute=Ext.getStore(this.attributesStore).getById(record.get('name')));return Traccar.AttributeFormatter.renderAttribute(value,attribute)}}]}}); Ext.define('Traccar.view.dialog.BaseEditController',{extend:Ext.app.ViewController,alias:'controller.baseEdit',onSaveClick:function(button){var store;button=button.up('window').down('form');button.updateRecord();button=button.getRecord();(store=button.store)?(button.phantom&&store.add(button),store.sync({failure:function(batch){store.rejectChanges();Traccar.app.showError(batch.exceptions[0].getError().response)}})):button.save();this.closeView()},showAttributesView:function(button){button=button.up('window').down('form').getRecord(); Ext.create('Traccar.view.BaseWindow',{title:Strings.sharedAttributes,items:{xtype:'attributesView',record:button}}).show()}}); Ext.define('Traccar.view.dialog.SavedCommandController',{extend:Traccar.view.dialog.BaseEditController,alias:'controller.savedCommand',defaultFieldConfig:{allowBlank:!1},onTypeChange:function(combo,newValue){var record=combo.up('window').down('form').getRecord();this.lookupReference('parameters').removeAll();if((newValue=Ext.getStore('KnownCommands').getById(newValue))&&newValue.get('parameters')){var parameters=newValue.get('parameters');for(newValue=0;newValue<parameters.length;newValue++){var parameter= new Traccar.model.KnownAttribute(parameters[newValue]);var config=Ext.clone(this.defaultFieldConfig);config.key=parameter.get('key');config.fieldLabel=parameter.get('name');record.get('attributes')&&(config.value=record.get('attributes')[parameter.get('key')]);config.disabled=combo.isDisabled();switch(parameter.get('valueType')){case 'number':config.xtype='customNumberField';void 0!==parameter.get('allowDecimals')?config.allowDecimals=parameter.get('allowDecimals'):config.allowDecimals=!0;config.dataType= parameter.get('dataType');config.maxValue=parameter.get('maxValue');config.minValue=parameter.get('minValue');break;case 'boolean':config.xtype='checkboxfield';config.inputValue=!0;config.uncheckedValue=!1;break;default:'timezone'===parameter.get('dataType')?(config.xtype='combobox',config.queryMode='local',config.displayField='key',config.editable=!1,config.store='AllTimezones'):config.xtype='textfield'}this.lookupReference('parameters').add(config)}}},fillAttributes:function(button){var attributes= {};button=button.up('window').down('form');button.updateRecord();var record=button.getRecord();var parameters=this.lookupReference('parameters').items.items;for(button=0;button<parameters.length;button++)attributes[parameters[button].key]=parameters[button].getValue();record.set('attributes',attributes)},onSaveClick:function(button){this.fillAttributes(button);this.callParent(arguments)},onValidityChange:function(form,valid){this.lookupReference('saveButton').setDisabled(!valid)}}); Ext.define('Traccar.view.permissions.BaseController',{extend:Ext.app.ViewController,alias:'controller.base',init:function(){var params={};params[this.getView().baseObjectName]=this.getView().baseObject;var linkStoreName=this.getView().linkStoreName;var storeName=this.getView().storeName;linkStoreName='undefined'===typeof linkStoreName?storeName:linkStoreName;this.getView().setStore(Ext.getStore(storeName));this.getView().getStore().load({scope:this,callback:function(){Ext.create('Traccar.store.'+ linkStoreName).load({params:params,scope:this,callback:function(records,operation,success){if(success)for(operation=0;operation<records.length;operation++)success=this.getView().getStore().getById(records[operation].getId()),this.getView().getSelectionModel().select(success,!0,!0)}})}})},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){success||(selection.deselect(record,!0),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){success||(selection.select(record, !0,!0),Traccar.app.showError(response))}})}});Ext.define('Traccar.view.permissions.Base',{extend:Traccar.view.GridPanel,controller:'base',selModel:{selType:'checkboxmodel',checkOnly:!0,showHeaderCheckbox:!1},listeners:{beforedeselect:'onBeforeDeselect',beforeselect:'onBeforeSelect'}}); 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'}]}}); Ext.define('Traccar.view.dialog.SendCommandController',{extend:Traccar.view.dialog.SavedCommandController,alias:'controller.sendCommand',onSendClick:function(button){this.fillAttributes(button);button=button.up('window').down('form').getRecord();Ext.Ajax.request({scope:this,url:'api/commands/send',jsonData:button.getData(),callback:this.onSendResult})},onValidityChange:function(form,valid){this.lookupReference('sendButton').setDisabled(!valid||null===this.lookupReference('commandsComboBox').getValue())}, onTextChannelChange:function(checkbox,newValue){checkbox=this.lookupReference('commandType').getStore();checkbox.getProxy().setExtraParam('textChannel',newValue);checkbox.reload()},onCommandSelect:function(selected){var command=selected.getStore().getById(selected.getValue());command.set('deviceId',this.getView().deviceId);var form=selected.up('window').down('form');selected=form.getRecord();form.loadRecord(command);if(selected&&command.get('type')===selected.get('type'))this.onTypeChange(this.lookupReference('commandType'), command.get('type'));this.lookupReference('newCommandFields').setDisabled(0!==command.getId());this.lookupReference('sendButton').setDisabled(0===command.getId())},onSendResult:function(options,success,response){success?(this.closeView(),Traccar.app.showToast(202===response.status?Strings.commandQueued:Strings.commandSent)):Traccar.app.showError(response)},closeView:function(){this.lookupReference('commandsComboBox').getStore().removeAll();this.callParent(arguments)}}); Ext.define('Traccar.view.dialog.SendCommand',{extend:Traccar.view.dialog.Base,controller:'sendCommand',title:Strings.commandTitle,items:[{xtype:'combobox',reference:'commandsComboBox',fieldLabel:Strings.deviceCommand,displayField:'description',valueField:'id',store:'DeviceCommands',queryMode:'local',editable:!1,allowBlank:!1,listeners:{select:'onCommandSelect'}},{xtype:'form',listeners:{validitychange:'onValidityChange'},items:[{xtype:'fieldset',reference:'newCommandFields',disabled:!0,items:[{xtype:'checkboxfield', name:'textChannel',reference:'textChannelCheckBox',inputValue:!0,uncheckedValue:!1,fieldLabel:Strings.commandSendSms,listeners:{change:'onTextChannelChange'}},{xtype:'combobox',name:'type',reference:'commandType',fieldLabel:Strings.sharedType,store:'CommandTypes',displayField:'name',valueField:'type',editable:!1,allowBlank:!1,listeners:{change:'onTypeChange'}},{xtype:'fieldcontainer',reference:'parameters'}]}]}],buttons:[{xtype:'tbfill'},{glyph:'xf093@FontAwesome',tooltip:Strings.sharedSend,tooltipType:'title', minWidth:0,disabled:!0,reference:'sendButton',handler:'onSendClick'},{glyph:'xf00d@FontAwesome',tooltip:Strings.sharedCancel,tooltipType:'title',minWidth:0,handler:'closeView'}]}); Ext.define('Traccar.view.dialog.BaseEdit',{extend:Traccar.view.dialog.Base,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'}]}); Ext.define('Traccar.view.ClearableComboBox',{extend:Ext.form.field.ComboBox,xtype:'clearableComboBox',editable:!1,triggers:{clear:{cls:'iconCls: x-fa fa-times',handler:function(button){button.clearValue()}}}});Ext.define('Traccar.view.dialog.DeviceController',{extend:Traccar.view.dialog.BaseEditController,alias:'controller.device',init:function(){Traccar.app.getUser().get('administrator')&&this.lookupReference('disabledField').setHidden(!1)}}); Ext.define('Traccar.view.dialog.Device',{extend:Traccar.view.dialog.BaseEdit,controller:'device',title:Strings.sharedDevice,items:{xtype:'form',items:[{xtype:'fieldset',title:Strings.sharedRequired,items:[{xtype:'unescapedTextField',name:'name',fieldLabel:Strings.sharedName,allowBlank:!1},{xtype:'unescapedTextField',name:'uniqueId',fieldLabel:Strings.deviceIdentifier,allowBlank:!1}]},{xtype:'fieldset',title:Strings.sharedExtra,collapsible:!0,collapsed:!0,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:!1,listConfig:{getInnerTpl:function(){return'\x3ctable\x3e\x3ctr valign\x3d"middle" \x3e\x3ctd\x3e\x3cdiv align\x3d"center" style\x3d"width:40px;height:40px;" \x3e{[new XMLSerializer().serializeToString(Traccar.DeviceImages.getImageSvg(Traccar.Style.mapColorOnline, false, 0, values.key))]}\x3c/div\x3e\x3c/td\x3e\x3ctd\x3e{name}\x3c/td\x3e\x3c/tr\x3e\x3c/table\x3e'}}}, {xtype:'checkboxfield',inputValue:!0,uncheckedValue:!1,name:'disabled',fieldLabel:Strings.sharedDisabled,hidden:!0,reference:'disabledField'}]}]}}); 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:!0,filter:{type:'list',labelField:'name',store:'AllCalendars'},renderer:Traccar.AttributeFormatter.getFormatter('calendarId')}]}}); 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)}}]}}); 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'}]}}); Ext.define('Traccar.view.edit.DevicesController',{extend:Traccar.view.edit.ToolbarController,alias:'controller.devices',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; var deviceReadonly=Traccar.app.getPreference('deviceReadonly',!1)&&!Traccar.app.getUser().get('administrator');var readonly=Traccar.app.getPreference('readonly',!1)&&!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 deviceId=this.getView().getSelectionModel().getSelection()[0].get('id'); var dialog=Ext.create('Traccar.view.dialog.SendCommand');dialog.deviceId=deviceId;var typesStore=dialog.lookupReference('commandsComboBox').getStore();typesStore.getProxy().setExtraParam('deviceId',deviceId);Traccar.app.getPreference('limitCommands',!1)||typesStore.add({id:0,description:Strings.sharedNew});typesStore.load({addRecords:!0});typesStore=dialog.lookupReference('commandType').getStore();typesStore.getProxy().setExtraParam('deviceId',deviceId);typesStore.load();dialog.show()},updateButtons:function(selected){var deviceReadonly= Traccar.app.getPreference('deviceReadonly',!1)&&!Traccar.app.getUser().get('administrator');var readonly=Traccar.app.getPreference('readonly',!1)&&!Traccar.app.getUser().get('administrator');var empty=0===selected.length;this.lookupReference('toolbarEditButton').setDisabled(empty||readonly||deviceReadonly);this.lookupReference('toolbarRemoveButton').setDisabled(empty||readonly||deviceReadonly);deviceReadonly=this.lookupReference('toolbarDeviceMenu');deviceReadonly.device=empty?null:selected[0];deviceReadonly.setDisabled(empty); this.lookupReference('deviceCommandButton').setDisabled(empty||readonly)},onSelectionChange:function(el,records){records&&records.length&&(this.updateButtons(records),this.fireEvent('selectdevice',records[0],!0))},selectDevice:function(device){this.getView().getSelectionModel().select([device],!1,!0);this.updateButtons(this.getView().getSelectionModel().getSelected().items);this.getView().getView().focusRow(device)},deselectDevice:function(object){object&&this.deselectFeature()},onUpdateDevice:function(){this.updateButtons(this.getView().getSelectionModel().getSelected().items)}, deselectFeature:function(){this.getView().getSelectionModel().deselectAll()}}); 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 property=item.get(this.getProperty());var value=this.getValue();if(Ext.isArray(property))for(item=0;item<property.length;item++){if(-1!==value.indexOf(property[item]))return!0}else if(property.match(/[ ,]+/))for(property=property.split(/[ ,]+/).filter(Boolean),item=0;item<property.length;item++){if(-1!== value.indexOf(property[item]))return!0}else if(-1!==value.indexOf(property))return!0;return!1})}}); 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='';if(value){var notificators=value.split(/[ ,]+/).filter(Boolean);for(value=0;value<notificators.length;value++)result+=Traccar.app.getNotificatorString(notificators[value])+(value<notificators.length-1?', ':'')}return result}},{text:Strings.sharedCalendar,dataIndex:'calendarId',flex:1,minWidth:Traccar.Style.columnWidthNormal, hidden:!0,filter:{type:'list',labelField:'name',store:'AllCalendars'},renderer:Traccar.AttributeFormatter.getFormatter('calendarId')}]}}); Ext.define('Traccar.view.dialog.SelectDeviceController',{extend:Ext.app.ViewController,alias:'controller.selectDevice',onSaveClick:function(button){var deviceId=this.lookupReference('deviceField').getValue();var record=this.getView().record.data;Ext.Ajax.request({url:'api/attributes/computed/test?deviceId\x3d'+deviceId,method:'POST',jsonData:Ext.util.JSON.encode(record),callback:function(options,success,response){success?Ext.Msg.alert(Strings.sharedInfoTitle,response.responseText||response.statusText): Traccar.app.showError(response)}});button.up('window').close()},onDeviceChange:function(combobox,newValue){this.lookupReference('saveButton').setDisabled(null===newValue)}}); Ext.define('Traccar.view.dialog.SelectDevice',{extend:Traccar.view.dialog.Base,controller:'selectDevice',title:Strings.sharedDevice,items:{xtype:'form',items:[{xtype:'combobox',reference:'deviceField',store:'Devices',queryMode:'local',displayField:'name',valueField:'id',editable:!1,listeners:{change:'onDeviceChange'}}]},buttons:[{glyph:'xf00c@FontAwesome',reference:'saveButton',tooltip:Strings.sharedSave,tooltipType:'title',minWidth:0,handler:'onSaveClick',disabled:!0},{glyph:'xf00d@FontAwesome', tooltip:Strings.sharedCancel,tooltipType:'title',minWidth:0,handler:'closeView'}]}); Ext.define('Traccar.view.dialog.ComputedAttributeController',{extend:Traccar.view.dialog.BaseEditController,alias:'controller.computedAttribute',onAttributeChange:function(combobox,newValue){(combobox=Ext.getStore('PositionAttributes').getById(newValue))?(this.getView().lookupReference('typeComboField').setValue(combobox.get('valueType')),this.getView().lookupReference('typeComboField').setReadOnly(!0)):this.getView().lookupReference('typeComboField').setReadOnly(!1)},onCheckClick:function(button){var dialog= Ext.create('Traccar.view.dialog.SelectDevice');button=button.up('window').down('form');button.updateRecord();dialog.record=button.getRecord();dialog.show()}});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))}}); Ext.define('Traccar.view.dialog.ComputedAttribute',{extend:Traccar.view.dialog.BaseEdit,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:!1},{xtype:'combobox',name:'type',reference:'typeComboField',store:'AttributeValueTypes',fieldLabel:Strings.sharedType,displayField:'name',valueField:'id',editable:!1}]},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'}]});Ext.define('Traccar.view.edit.ComputedAttributesController',{extend:Traccar.view.edit.ToolbarController,alias:'controller.computedAttributes',objectModel:'Traccar.model.ComputedAttribute',objectDialog:'Traccar.view.dialog.ComputedAttribute',removeTitle:Strings.sharedComputedAttribute}); Ext.define('Traccar.view.edit.ComputedAttributes',{extend:Traccar.view.GridPanel,xtype:'computedAttributesView',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);return type?type.get('name'):value}}]}}); 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')))}}]}}); Ext.define('Traccar.view.dialog.DeviceAccumulatorsController',{extend:Ext.app.ViewController,alias:'controller.deviceAccumulators',onSetClick:function(){var data={deviceId:this.getView().deviceId};var totalDistance=this.lookupReference('totalDistance');isNaN(totalDistance.getRawValue())||(data.totalDistance=totalDistance.getValue());totalDistance=this.lookupReference('hours');isNaN(totalDistance.getRawValue())||(data.hours=totalDistance.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){success||Traccar.app.showError(response)}});this.closeView()}}); Ext.define('Traccar.view.dialog.DeviceAccumulators',{extend:Traccar.view.dialog.Base,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'}]}); Ext.define('Traccar.view.DeviceMenuController',{extend:Ext.app.ViewController,alias:'controller.deviceMenu',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', !1));this.lookupReference('menuDeviceAccumulatorsButton').setHidden(!Traccar.app.getUser().get('administrator')&&0===Traccar.app.getUser().get('userLimit')||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();if(position=Ext.getStore('LatestPositions').findRecord('deviceId',dialog.deviceId,0,!1,!1,!0))dialog.lookupReference('totalDistance').setValue(position.get('attributes').totalDistance),dialog.lookupReference('hours').setValue(position.get('attributes').hours);dialog.show()}}); Ext.define('Traccar.view.DeviceMenu',{extend:Ext.button.Button,xtype:'deviceMenu',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:!0,text:Strings.sharedDeviceAccumulators,glyph:'xf0e4@FontAwesome',handler:'onDeviceAccumulatorsClick', reference:'menuDeviceAccumulatorsButton'}]}}); Ext.define('Traccar.view.edit.Devices',{extend:Traccar.view.GridPanel,xtype:'devicesView',controller:'devices',store:'VisibleDevices',stateful:!0,stateId:'devices-grid',tbar:{componentCls:'toolbar-header-style',defaults:{xtype:'button',disabled:!0,tooltipType:'title'},items:[{xtype:'tbtext',html:Strings.deviceTitle,baseCls:'x-panel-header-title-default'},{xtype:'tbfill',disabled:!1},{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:!1}]},listeners:{selectionchange:'onSelectionChange'},viewConfig:{enableTextSelection:!0,getRowClass:function(record){var result= '',status=record.get('status');record.get('disabled')&&(result='view-item-disabled ');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:!0,filter:'string'},{text:Strings.sharedPhone,dataIndex:'phone',hidden:!0},{text:Strings.deviceModel,dataIndex:'model',hidden:!0}, {text:Strings.deviceContact,dataIndex:'contact',hidden:!0},{text:Strings.groupDialog,dataIndex:'groupId',hidden:!0,filter:{type:'list',labelField:'name',store:'Groups'},renderer:Traccar.AttributeFormatter.getFormatter('groupId')},{text:Strings.sharedDisabled,dataIndex:'disabled',renderer:Traccar.AttributeFormatter.getFormatter('disabled'),hidden:!0,filter:'boolean'},{text:Strings.sharedGeofences,dataIndex:'geofenceIds',hidden:!0,filter:{type:'arraylist',idField:'id',labelField:'name',store:'Geofences'}, renderer:function(value){var i,name,result='';if(Ext.isArray(value))for(i=0;i<value.length;i++)(name=Traccar.AttributeFormatter.geofenceIdFormatter(value[i]))&&(result+=name+(i<value.length-1?', ':''));return result}},{text:Strings.deviceStatus,dataIndex:'status',filter:{type:'list',labelField:'name',store:'DeviceStatuses'},renderer:function(value){return value&&(value=Ext.getStore('DeviceStatuses').getById(value))?value.get('name'):null}},{text:Strings.deviceLastUpdate,dataIndex:'lastUpdate',renderer:Traccar.AttributeFormatter.getFormatter('lastUpdate')}]}}); Ext.define('Traccar.view.StateController',{extend:Ext.app.ViewController,alias:'controller.state',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(){(Traccar.app.getUser().get('administrator')||!Traccar.app.getUser().get('deviceReadonly')&& !Traccar.app.getPreference('readonly',!1))&&this.lookupReference('computedAttributesButton').setDisabled(Traccar.app.getBooleanAttributePreference('ui.disableComputedAttributes'));var i=Traccar.app.getAttributePreference('ui.hidePositionAttributes');this.hideAttributes={};if(i){var attributesList=i.split(/[ ,]+/).filter(Boolean);for(i=0;i<attributesList.length;i++)this.hideAttributes[attributesList[i]]=!0}},onComputedAttributesClick:function(){Ext.create('Traccar.view.BaseWindow',{title:Strings.sharedComputedAttributes, items:{xtype:'computedAttributesView'}}).show()},keys:function(){var i;var result={};var list='fixTime latitude longitude valid accuracy altitude speed course address protocol'.split(' ');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){Ext.isArray(data)||(data=[data]);for(store=0;store<data.length;store++)this.deviceId===data[store].get('deviceId')&&(this.position= data[store],this.updatePosition())},formatValue:function(value){return'number'===typeof id?Number(value.toFixed(2)):value},findAttribute:function(record){return record.get('deviceId')===this.position.get('deviceId')&&record.get('attribute')===this.lookupAttribute},updatePosition:function(){var key;var store=Ext.getStore('Attributes');store.removeAll();for(key in this.position.data)this.position.data.hasOwnProperty(key)&&void 0!==this.keys[key]&&store.add(Ext.create('Traccar.model.Attribute',{priority:this.keys[key].priority, name:this.keys[key].name,value:Traccar.AttributeFormatter.getFormatter(key)(this.position.get(key))}));var attributes=this.position.get('attributes');if(attributes instanceof Object)for(key in attributes)if(attributes.hasOwnProperty(key)&&!this.hideAttributes[key]){this.lookupAttribute=key;var name=Ext.getStore('PositionAttributes').getAttributeName(key,!0);var value=void 0!==this.position.get('attribute.'+key)?Traccar.AttributeFormatter.getAttributeFormatter(key)(this.position.get('attribute.'+key)): Traccar.AttributeFormatter.defaultFormatter(attributes[key]);store.add(Ext.create('Traccar.model.Attribute',{priority:1024,name:name,attribute:key,value:value}))}},selectDevice:function(device){this.deviceId=device.get('id');(device=Ext.getStore('LatestPositions').findRecord('deviceId',this.deviceId,0,!1,!1,!0))?(this.position=device,this.updatePosition()):(this.position=null,Ext.getStore('Attributes').removeAll())},selectPosition:function(position){position instanceof Traccar.model.Position&&(this.deviceId= null,this.position=position,this.updatePosition())},deselectFeature:function(){this.position=this.deviceId=null;Ext.getStore('Attributes').removeAll()},clearReport:function(){this.deviceId||(this.position=null,Ext.getStore('Attributes').removeAll())},onGeocode:function(){var positionId=this.position.getId();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){this.position&& this.position.getId()===positionId&&(this.position.set('address',response.responseText),this.updatePosition())},failure:function(response){Traccar.app.showError(response)}})}}); Ext.define('Traccar.view.State',{extend:Traccar.view.GridPanel,xtype:'stateView',controller:'state',store:'Attributes',stateful:!0,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:!0,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:!0,renderer:function(value,metaData,record){if('alarm'===record.get('attribute'))metaData.tdCls='view-color-red';else{if(record.get('name')===Strings.positionAddress&&!value)return'\x3ca href\x3d"#" onclick\x3d"Ext.fireEvent(\'stategeocode\')" \x3e'+Strings.sharedShowAddress+'\x3c/a\x3e';if(record.get('name')===Strings.positionImage||record.get('name')===Strings.positionAudio)if(metaData=this.getController().position)if(metaData= Ext.getStore('Devices').getById(metaData.get('deviceId')))return'\x3ca target\x3d"_blank" href\x3d"/api/media/'+metaData.get('uniqueId')+'/'+value+'" \x3e'+value+'\x3c/a\x3e'}return value}}]}}); Ext.define('Traccar.view.dialog.ReportConfigController',{extend:Ext.app.ViewController,alias:'controller.reportConfig',onSaveClick:function(button){var callingPanel=this.getView().callingPanel;callingPanel.deviceId=this.lookupReference('deviceField').getValue();callingPanel.groupId=this.lookupReference('groupField').getValue();var eventType=this.lookupReference('eventTypeField').getValue();-1<eventType.indexOf(Traccar.store.ReportEventTypes.allEvents)?eventType=[Traccar.store.ReportEventTypes.allEvents]: 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){combobox='custom'===newValue;this.lookupReference('fromContainer').setHidden(!combobox);this.lookupReference('toContainer').setHidden(!combobox);if(!combobox){combobox=new Date;var to=new Date;switch(newValue){case 'today':to.setDate(to.getDate()+1);break;case 'yesterday':combobox.setDate(to.getDate()- 1);break;case 'thisWeek':newValue=combobox.getDay();newValue=combobox.getDate()-newValue+(0===newValue?-6:1);combobox.setDate(newValue);to.setDate(newValue+7);break;case 'previousWeek':newValue=combobox.getDay();newValue=combobox.getDate()-newValue+(0===newValue?-6:1);combobox.setDate(newValue-7);to.setDate(newValue);break;case 'thisMonth':combobox.setDate(1);to.setDate(1);to.setMonth(combobox.getMonth()+1);break;case 'previousMonth':combobox.setDate(1),combobox.setMonth(combobox.getMonth()-1),to.setDate(1)}combobox.setHours(0, 0,0,0);to.setHours(0,0,0,0);this.lookupReference('fromDateField').setValue(combobox);this.lookupReference('fromTimeField').setValue(combobox);this.lookupReference('toDateField').setValue(to);this.lookupReference('toTimeField').setValue(to)}}});Ext.define('Traccar.view.CustomTimeField',{extend:Ext.form.field.Time,xtype:'customTimeField',constructor:function(config){Traccar.app.getPreference('twelveHourFormat',!1)?config.format=Traccar.Style.timeFormat12:config.format=Traccar.Style.timeFormat24;this.callParent(arguments)}}); Ext.define('Traccar.view.dialog.ReportConfig',{extend:Traccar.view.dialog.Base,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:!0,valueField:'type',displayField:'name',queryMode:'local'},{fieldLabel:Strings.reportChartType,xtype:'combobox',reference:'chartTypeField',store:'ReportChartTypes',hidden:!0,value:'speed',valueField:'key',displayField:'name',queryMode:'local'},{fieldLabel:Strings.reportShowMarkers,xtype:'checkbox',reference:'showMarkersField',inputValue:!0,uncheckedValue:!1, value:!1},{fieldLabel:Strings.reportPeriod,reference:'periodField',xtype:'combobox',store:'ReportPeriods',editable:!1,valueField:'key',displayField:'name',queryMode:'local',listeners:{change:'onPeriodChange'}},{xtype:'fieldcontainer',layout:'vbox',reference:'fromContainer',hidden:!0,fieldLabel:Strings.reportFrom,items:[{xtype:'datefield',reference:'fromDateField',startDay:Traccar.Style.weekStartDay,format:Traccar.Style.dateFormat,value:new Date((new Date).getTime()-18E5)},{xtype:'customTimeField', reference:'fromTimeField',value:new Date((new Date).getTime()-18E5)}]},{xtype:'fieldcontainer',layout:'vbox',reference:'toContainer',hidden:!0,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'}]}); Ext.define('Traccar.view.ReportController',{extend:Ext.app.ViewController,alias:'controller.report',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(!1)}, getGrid:function(){return this.getView().getComponent('grid')},getChart:function(){return this.getView().getComponent('chart')},init:function(){var i;var data=Ext.getStore('PositionAttributes').getData().items;for(i=0;i<data.length;i++){var attribute=data[i];this.routeColumns.push({text:attribute.get('name'),dataIndex:'attribute.'+attribute.get('key'),renderer:Traccar.AttributeFormatter.getAttributeFormatter(attribute.get('key')),hidden:!0})}if(Traccar.app.getVehicleFeaturesDisabled()){for(i=0;i< this.summaryColumns.length;i++)this.summaryColumns[i].dataIndex.match('engineHours|spentFuel')&&(this.summaryColumns[i].hidden=!0);for(i=0;i<this.tripsColumns.length;i++)this.tripsColumns[i].dataIndex.match('spentFuel|driverUniqueId')&&(this.tripsColumns[i].hidden=!0);for(i=0;i<this.stopsColumns.length;i++)this.stopsColumns[i].dataIndex.match('engineHours|spentFuel')&&(this.stopsColumns[i].hidden=!0)}},onConfigureClick:function(){var dialog=Ext.create('Traccar.view.dialog.ReportConfig');dialog.lookupReference('eventTypeField').setHidden('events'!== this.lookupReference('reportTypeField').getValue());dialog.lookupReference('chartTypeField').setHidden('chart'!==this.lookupReference('reportTypeField').getValue());dialog.callingPanel=this;dialog.lookupReference('deviceField').setValue(this.deviceId);dialog.lookupReference('groupField').setValue(this.groupId);void 0!==this.eventType?dialog.lookupReference('eventTypeField').setValue(this.eventType):dialog.lookupReference('eventTypeField').setValue([Traccar.store.ReportEventTypes.allEvents]);void 0!== this.chartType&&dialog.lookupReference('chartTypeField').setValue(this.chartType);void 0!==this.showMarkers&&dialog.lookupReference('showMarkersField').setValue(this.showMarkers);void 0!==this.fromDate&&dialog.lookupReference('fromDateField').setValue(this.fromDate);void 0!==this.fromTime&&dialog.lookupReference('fromTimeField').setValue(this.fromTime);void 0!==this.toDate&&dialog.lookupReference('toDateField').setValue(this.toDate);void 0!==this.toTime&&dialog.lookupReference('toTimeField').setValue(this.toTime); void 0!==this.period&&dialog.lookupReference('periodField').setValue(this.period);dialog.show()},updateButtons:function(){var reportType=this.lookupReference('reportTypeField').getValue();var disabled=this.deviceId&&0!==this.deviceId.length||this.groupId&&0!==this.groupId.length;var time=this.fromDate&&this.fromTime&&this.toDate&&this.toTime;disabled=!reportType||!disabled||!time||this.reportProgress;this.lookupReference('showButton').setDisabled(disabled);this.lookupReference('exportButton').setDisabled('chart'=== reportType||disabled);this.lookupReference('emailButton').setDisabled('chart'===reportType||disabled)},onReportClick:function(button){var reportType;this.getGrid().getSelectionModel().deselectAll();if((reportType=this.lookupReference('reportTypeField').getValue())&&(this.deviceId||this.groupId)){var from=new Date(this.fromDate.getFullYear(),this.fromDate.getMonth(),this.fromDate.getDate(),this.fromTime.getHours(),this.fromTime.getMinutes(),this.fromTime.getSeconds(),this.fromTime.getMilliseconds()); var to=new Date(this.toDate.getFullYear(),this.toDate.getMonth(),this.toDate.getDate(),this.toTime.getHours(),this.toTime.getMinutes(),this.toTime.getSeconds(),this.toTime.getMilliseconds());var daily='daily'===reportType;this.reportProgress=!0;this.updateButtons();'showButton'===button.reference?('chart'===reportType?(button=this.getChart().getStore(),this.getChart().setSeries([])):button=this.getGrid().getStore(),button.showMarkers=this.showMarkers,button.load({scope:this,callback:function(){this.reportProgress= !1;this.updateButtons()},params:{deviceId:this.deviceId,groupId:this.groupId,type:this.eventType,from:from.toISOString(),to:to.toISOString(),daily:daily}})):(reportType=this.getGrid().getStore().getProxy().url,this.excelReport(reportType,{deviceId:this.deviceId,groupId:this.groupId,type:this.eventType,from:Ext.Date.format(from,'c'),to:Ext.Date.format(to,'c'),daily:daily,mail:'emailButton'===button.reference}))}},onClearClick:function(){var reportType=this.lookupReference('reportTypeField').getValue(); this.clearReport(reportType)},clearReport:function(reportType){this.getGrid().getStore().removeAll();'trips'!==reportType&&'events'!==reportType&&'stops'!==reportType||Ext.getStore('ReportRoute').removeAll();'chart'===reportType&&this.getChart().getStore().removeAll()},onSelectionChange:function(selection,selected){0<selected.length&&(selection=selected[0],this.fireEvent('selectreport',selection,!0),selection instanceof Traccar.model.ReportTrip&&this.selectTrip(selection),(selection instanceof Traccar.model.Event|| selection instanceof Traccar.model.ReportStop)&&this.selectPositionRelated(selection))},selectReport:function(object){var reportType=this.lookupReference('reportTypeField').getValue();if(object instanceof Traccar.model.Position)if('route'===reportType)this.getGrid().getSelectionModel().select([object],!1,!0),this.getGrid().getView().focusRow(object);else if('events'===reportType||'stops'===reportType)object=this.getGrid().getStore().findRecord('positionId',object.get('id'),0,!1,!0,!0),this.getGrid().getSelectionModel().select([object], !1,!0),this.getGrid().getView().focusRow(object)},deselectReport:function(object){object&&this.deselectFeature()},deselectFeature:function(){'trips'!==this.lookupReference('reportTypeField').getValue()&&this.getGrid().getSelectionModel().deselectAll()},selectTrip:function(trip){var from=new Date(trip.get('startTime'));var 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){report.get('positionId')&&(report=Ext.getStore('ReportRoute').getById(report.get('positionId')))&&this.fireEvent('selectreport',report,!0)},loadRelatedPositions:function(store,data){var positionIds=[];Ext.getStore('ReportRoute').removeAll();for(store=0;store<data.length;store++){var reportObject=data[store];reportObject.get('positionId')&&positionIds.push(reportObject.get('positionId'))}0<positionIds.length&&Ext.getStore('Positions').load({params:{id:positionIds}, scope:this,callback:function(records,operation,success){success&&(Ext.getStore('ReportRoute').showMarkers=this.showMarkers,Ext.getStore('ReportRoute').add(records),1===records.length&&this.fireEvent('selectreport',records[0],!1))}})},loadRoute:function(store){if('chart'===this.lookupReference('reportTypeField').getValue()){this.getChart().getAxes()[0].setTitle(Ext.getStore('ReportChartTypes').findRecord('key',this.chartType).get('name'));var chartSeries=[];var deviceIds=store.collect('deviceId'); for(store=0;store<deviceIds.length;store++){var deviceStore=Ext.create('Ext.data.ChainedStore',{source:'ReportRoute',filters:[{property:'deviceId',value:deviceIds[store]}]});chartSeries.push({type:'line',store:deviceStore,yField:this.chartType,xField:'fixTime',highlightCfg:{scaling:Traccar.Style.chartMarkerHighlightScaling},colors:[Traccar.app.getReportColor(deviceIds[store])],marker:{type:'circle',radius:Traccar.Style.chartMarkerRadius,fill:Traccar.app.getReportColor(deviceIds[store])}})}this.getChart().setSeries(chartSeries)}}, onChartMarkerClick:function(chart,item){this.fireEvent('selectreport',item.record,!0)},showSingleEvent:function(eventId){this.lookupReference('reportTypeField').setValue('events');Ext.getStore('Events').load({id:eventId,scope:this,callback:function(records,operation,success){success&&(Ext.getStore('ReportEvents').add(records),0<records.length&&(records[0].get('positionId')||(Traccar.app.isMobile()?Traccar.app.showReports(!0):this.getView().expand()),this.getGrid().getSelectionModel().select([records[0]], !1,!0),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:!0,scope:this,callback:function(options,success,response){if(success&&!requestParams.mail)if(options=response.getResponseHeader('Content-Disposition'),options=options.slice(options.indexOf('\x3d')+1,options.length), success=response.getResponseHeader('Content-Type'),response=new Blob([response.responseBytes],{type:success}),'undefined'!==typeof window.navigator.msSaveBlob)window.navigator.msSaveBlob(response,options);else{var url=window.URL||window.webkitURL;var downloadUrl=url.createObjectURL(response);options&&Ext.dom.Helper.append(Ext.getBody(),{tag:'a',href:downloadUrl,download:options}).click();setTimeout(function(){url.revokeObjectURL(downloadUrl)},100)}this.reportProgress=!1;this.updateButtons()}})},onTypeChange:function(combobox, newValue,oldValue){null!==oldValue&&this.clearReport(oldValue);'route'===newValue?(this.getGrid().reconfigure('ReportRoute',this.routeColumns),this.getView().getLayout().setActiveItem('grid')):'events'===newValue?(this.getGrid().reconfigure('ReportEvents',this.eventsColumns),this.getView().getLayout().setActiveItem('grid')):'summary'===newValue||'daily'===newValue?(this.getGrid().reconfigure('ReportSummary',this.summaryColumns),this.getView().getLayout().setActiveItem('grid')):'trips'===newValue? (this.getGrid().reconfigure('ReportTrips',this.tripsColumns),this.getView().getLayout().setActiveItem('grid')):'stops'===newValue?(this.getGrid().reconfigure('ReportStops',this.stopsColumns),this.getView().getLayout().setActiveItem('grid')):'chart'===newValue&&this.getView().getLayout().setActiveItem('chart');this.updateButtons()},onGeocode:function(positionId){var position=Ext.getStore('ReportRoute').getById(positionId);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){return value?Traccar.AttributeFormatter.getFormatter('address')(value):'\x3ca href\x3d"#" onclick\x3d"Ext.fireEvent(\'routegeocode\', '+record.getId()+')" \x3e'+Strings.sharedShowAddress+'\x3c/a\x3e'}}],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.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')}]}); Ext.define('Traccar.view.Report',{extend:Ext.panel.Panel,xtype:'reportView',controller:'report',title:Strings.reportTitle,tools:[{type:'close',tooltip:Strings.sharedHide,handler:'hideReports'}],tbar:{scrollable:!0,items:[{xtype:'tbtext',html:Strings.sharedType},{xtype:'combobox',reference:'reportTypeField',store:'ReportTypes',displayField:'name',valueField:'key',editable:!1,listeners:{change:'onTypeChange'}},'-',{text:Strings.reportConfigure,handler:'onConfigureClick'},'-',{text:Strings.reportShow, reference:'showButton',disabled:!0,handler:'onReportClick'},{text:Strings.reportExport,reference:'exportButton',disabled:!0,handler:'onReportClick'},{text:Strings.reportEmail,reference:'emailButton',disabled:!0,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:!0},store:'ReportRoute',axes:[{title:Strings.reportChart,type:'numeric',position:'left'},{type:'time',position:'bottom',fields:['fixTime']}],listeners:{itemclick:'onChartMarkerClick'},insetPadding:Traccar.Style.chartPadding}]}); 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);Traccar.app.isMobile()&&this.lookupReference('hideEventsButton').setHidden(!1)},onRemoveClick:function(){var event; if(event=this.getView().getSelectionModel().getSelection()[0])Ext.getStore('Events').remove(event),(event=event.get('positionId'))&&!Ext.getStore('Events').findRecord('positionId',event,0,!1,!1,!0)&&Ext.getStore('EventPositions').remove(Ext.getStore('EventPositions').getById(event))},onClearClick:function(){Ext.getStore('Events').removeAll();Ext.getStore('EventPositions').removeAll()},onAddEvent:function(){this.lookupReference('scrollToLastButton').pressed&&this.getView().scrollBy(0,Number.POSITIVE_INFINITY, !0)},onScrollToLastClick:function(button,pressed){if(pressed)this.onAddEvent()},onHideEvents:function(){Traccar.app.showEvents(!1)},deselectEvent:function(object){object&&this.deselectFeature()},deselectFeature:function(){this.getView().getSelectionModel().deselectAll()},onSelectionChange:function(selection,selected){var position;if(selection=0<selected.length?selected[0]:null)(selected=selection.get('positionId'))?(position=Ext.getStore('EventPositions').getById(selected))?this.fireEvent('selectevent', position):Ext.getStore('EventPositions').load({params:{id:selected},scope:this,addRecords:!0,callback:function(records,operation,success){success&&0<records.length&&this.fireEvent('selectevent',records[0])}}):this.fireEvent('selectevent');this.lookupReference('removeEventButton').setDisabled(!selection)}}); Ext.define('Traccar.view.Events',{extend:Traccar.view.GridPanel,xtype:'eventsView',controller:'events',store:'Events',stateful:!0,stateId:'events-grid',title:Strings.reportEvents,sortableColumns:!1,header:!1,tbar:{componentCls:'toolbar-header-style',defaults:{xtype:'button',tooltipType:'title',stateEvents:['toggle'],enableToggle:!0,stateful:{pressed:!0}},items:[{xtype:'tbtext',html:Strings.reportEvents,baseCls:'x-panel-header-title-default'},{xtype:'tbfill'},{glyph:'xf063@FontAwesome',pressed:!0, 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:!0,stateful:!1,enableToggle:!1},{glyph:'xf1f8@FontAwesome',tooltip:Strings.reportClear,handler:'onClearClick',stateful:!1,enableToggle:!1},{glyph:'xf00d@FontAwesome', tooltip:Strings.sharedHide,handler:'onHideEvents',reference:'hideEventsButton',hidden:!0,stateful:!1,enableToggle:!1}]},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')}]}}); 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 self=this;var server=Traccar.app.getServer();var type=Traccar.app.getPreference('map',null);var bingKey=server.get('bingKey');server=new ol.layer.Group({title:Strings.mapLayer,layers:[new ol.layer.Tile({title:Strings.mapCustom,type:'base',visible:'custom'===type,source:new ol.source.XYZ({url:Ext.String.htmlDecode(server.get('mapUrl')), attributions:''})}),new ol.layer.Tile({title:Strings.mapCustomArcgis,type:'base',visible:'customArcgis'===type,source:new ol.source.TileArcGISRest({url:Ext.String.htmlDecode(server.get('mapUrl'))})}),new ol.layer.Tile({title:Strings.mapBingRoad,type:'base',visible:'bingRoad'===type,source:new ol.source.BingMaps({key:bingKey,imagerySet:'Road'})}),new ol.layer.Tile({title:Strings.mapBingAerial,type:'base',visible:'bingAerial'===type,source:new ol.source.BingMaps({key:bingKey,imagerySet:'Aerial'})}), new ol.layer.Tile({title:Strings.mapBingHybrid,type:'base',visible:'bingHybrid'===type,source:new ol.source.BingMaps({key:bingKey,imagerySet:'AerialWithLabels'})}),new ol.layer.Tile({title:Strings.mapCarto,type:'base',visible:'carto'===type,source:new ol.source.XYZ({url:'https://cartodb-basemaps-{a-d}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png',attributions:'\x26copy; \x3ca href\x3d"http://www.openstreetmap.org/copyright"\x3eOpenStreetMap\x3c/a\x3e contributors, \x26copy; \x3ca href\x3d"https://carto.com/attributions"\x3eCARTO\x3c/a\x3e'})}), new ol.layer.Tile({title:Strings.mapAutoNavi,type:'base',visible:'autoNavi'===type||'baidu'===type,source:new ol.source.OSM({url:'https://webrd0{1-4}.is.autonavi.com/appmaptile?lang\x3dzh_cn\x26size\x3d1\x26scale\x3d1\x26style\x3d8\x26x\x3d{x}\x26y\x3d{y}\x26z\x3d{z}'})}),new ol.layer.Tile({title:Strings.mapYandexMap,type:'base',visible:'yandexMap'===type,source:new ol.source.XYZ({url:'https://vec0{1-4}.maps.yandex.net/tiles?l\x3dmap\x26x\x3d{x}\x26y\x3d{y}\x26z\x3d{z}',projection:'EPSG:3395',attributions:'\x26copy; \x3ca href\x3d"https://yandex.com/maps/"\x3eYandex\x3c/a\x3e'})}), new ol.layer.Tile({title:Strings.mapYandexSat,type:'base',visible:'yandexSat'===type,source:new ol.source.XYZ({url:'https://sat0{1-4}.maps.yandex.net/tiles?l\x3dsat\x26x\x3d{x}\x26y\x3d{y}\x26z\x3d{z}',projection:'EPSG:3395',attributions:'\x26copy; \x3ca href\x3d"https://yandex.com/maps/"\x3eYandex\x3c/a\x3e'})}),new ol.layer.Tile({title:Strings.mapWikimedia,type:'base',visible:'wikimedia'===type,source:new ol.source.OSM({url:'https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png'})}),new ol.layer.Tile({title:Strings.mapOsm, type:'base',visible:'osm'===type||!type,source:new ol.source.OSM({})})]});type=Traccar.app.getPreference('latitude',Traccar.Style.mapDefaultLat);bingKey=Traccar.app.getPreference('longitude',Traccar.Style.mapDefaultLon);var zoom=Traccar.app.getPreference('zoom',Traccar.Style.mapDefaultZoom);var maxZoom=Traccar.app.getAttributePreference('web.maxZoom',Traccar.Style.mapMaxZoom);this.mapView=new ol.View({center:ol.proj.fromLonLat([bingKey,type]),zoom:zoom,maxZoom:maxZoom});this.map=new ol.Map({target:this.body.dom.id, layers:[server],view:this.mapView});(server=Traccar.app.getPreference('poiLayer',null))&&this.map.addLayer(new ol.layer.Vector({source:new ol.source.Vector({url:server,format:new ol.format.KML})}));this.body.dom.tabIndex=0;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)}this.map.addControl(new ol.control.LayerSwitcher); var target=this.map.getTarget();'string'===typeof target&&(target=Ext.get(target).dom);this.map.on('pointermove',function(e){this.forEachFeatureAtPixel(e.pixel,function(){return!0})?target.style.cursor='pointer':target.style.cursor=''});this.map.on('click',function(e){var features=self.map.getFeaturesAtPixel(e.pixel,{layerFilter:function(layer){return!layer.get('name')}});if(features)for(e=0;e<features.length;e++)self.fireEvent('selectfeature',features[e]);else self.fireEvent('deselectfeature')})}, listeners:{afterrender:function(){this.initMap()},resize:function(){this.map.updateSize()}}},function(){var projection;proj4.defs('EPSG:3395','+proj\x3dmerc +lon_0\x3d0 +k\x3d1 +x_0\x3d0 +y_0\x3d0 +datum\x3dWGS84 +units\x3dm +no_defs');ol.proj.proj4.register(proj4);(projection=ol.proj.get('EPSG:3395'))&&projection.setExtent([-2.0037508342789244E7,-2.0037508342789244E7,2.0037508342789244E7,2.0037508342789244E7])}); Ext.define('Traccar.DeviceImages',{singleton:!0,getImageSvg:function(color,zoom,angle,category){var i,svg;category=Ext.getStore('DeviceImages').findRecord('key',category||'default',0,!1,!1,!0);(svg=Ext.clone(category.get('svg')))||(svg=this.cloneDocument(category.get('svg')));var width=parseFloat(svg.documentElement.getAttribute('width'));var height=parseFloat(svg.documentElement.getAttribute('height'));var fill=category.get('fillId');Ext.isArray(fill)||(fill=[fill]);for(i=0;i<fill.length;i++)svg.getElementById(fill[i]).style.fill= color;color='rotate('+angle+' '+width/2+' '+height/2+')';svg.getElementById(category.get('rotateId')).setAttribute('transform',color);zoom?(width*=Traccar.Style.mapScaleSelected,height*=Traccar.Style.mapScaleSelected,zoom='scale('+Traccar.Style.mapScaleSelected+') '):(width*=Traccar.Style.mapScaleNormal,height*=Traccar.Style.mapScaleNormal,zoom='scale('+Traccar.Style.mapScaleNormal+') ');category.get('scaleId')!==category.get('rotateId')?svg.getElementById(category.get('scaleId')).setAttribute('transform', zoom):svg.getElementById(category.get('scaleId')).setAttribute('transform',zoom+' '+color);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\x3dutf-8,'+encodeURIComponent((new XMLSerializer).serializeToString(svg.documentElement))},cloneDocument:function(svgDocument){var newDocument=svgDocument.implementation.createDocument(svgDocument.namespaceURI, null,null);svgDocument=newDocument.importNode(svgDocument.documentElement,!0);newDocument.appendChild(svgDocument);return newDocument},getImageIcon:function(color,zoom,angle,category){var image=this.getImageSvg(color,zoom,angle,category);var width=parseFloat(image.documentElement.getAttribute('width'));var height=parseFloat(image.documentElement.getAttribute('height'));image=new ol.style.Icon({imgSize:[width,height],src:this.formatSrc(image)});image.fill=color;image.zoom=zoom;image.angle=angle;image.category= category;return image}}); Ext.define('Traccar.view.map.MapMarkerController',{extend:Ext.app.ViewController,alias:'controller.mapMarker',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:{'#':{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)},getAreaStyle:function(label, color){if(color)var fillColor=ol.color.asArray(color);else fillColor=ol.color.asArray(Traccar.Style.mapGeofenceColor),color=Traccar.Style.mapGeofenceColor;fillColor[3]=Traccar.Style.mapGeofenceOverlayOpacity;fillColor={fill:new ol.style.Fill({color:fillColor}),stroke:new ol.style.Stroke({color:color,width:Traccar.Style.mapGeofenceWidth})};label&&(fillColor.text=new ol.style.Text({text:label,overflow:!0,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(fillColor)},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){Ext.isArray(data)||(data=[data]);for(store=0;store<data.length;store++){var device=data[store];var deviceId=device.get('id');if(deviceId in this.latestMarkers){deviceId= this.latestMarkers[deviceId];var style=deviceId.getStyle();if(style.getImage().fill!==this.getDeviceColor(device)||style.getImage().category!==device.get('category'))this.updateDeviceMarker(style,this.getDeviceColor(device),device.get('category')),deviceId.changed();device=Ext.String.htmlDecode(device.get('name'));style.getText().getText()!==device&&(style.getText().setText(device),deviceId.changed())}}},removeDevice:function(store,data){Ext.isArray(data)||(data=[data]);var markersSource=this.getView().getMarkersSource(); for(store=0;store<data.length;store++){var deviceId=data[store].get('id');this.latestMarkers[deviceId]&&(markersSource.getFeatureById(this.latestMarkers[deviceId].getId())&&markersSource.removeFeature(this.latestMarkers[deviceId]),delete this.latestMarkers[deviceId]);this.accuracyCircles[deviceId]&&(markersSource.getFeatureById(this.accuracyCircles[deviceId].getId())&&markersSource.removeFeature(this.accuracyCircles[deviceId]),delete this.accuracyCircles[deviceId]);this.liveRoutes[deviceId]&&(markersSource.getFeatureById(this.liveRoutes[deviceId].getId())&& markersSource.removeFeature(this.liveRoutes[deviceId]),delete this.liveRoutes[deviceId])}},animateMarker:function(marker$jscomp$0,geometry,course){var start=marker$jscomp$0.getGeometry().getCoordinates();geometry=geometry.getCoordinates();start=new ol.geom.LineString([start,geometry]);var duration=Traccar.Style.mapAnimateMarkerDuration;var timeout=Traccar.Style.mapAnimateMarkerTimeout;var self=this;var updatePosition=function(position,marker){var coordinate=marker.get('line').getCoordinateAt(position/ (duration/timeout));var style=marker.getStyle();marker.setGeometry(new ol.geom.Point(coordinate));position<duration/timeout?setTimeout(updatePosition,timeout,position+1,marker):(style.getImage().angle!==marker.get('nextCourse')&&self.rotateMarker(style,marker.get('nextCourse')),marker.set('animating',!1))};marker$jscomp$0.set('line',start);marker$jscomp$0.set('nextCourse',course);marker$jscomp$0.get('animating')||(marker$jscomp$0.set('animating',!0),updatePosition(1,marker$jscomp$0))},updateLatest:function(store, data){var device;Ext.isArray(data)||(data=[data]);var deviceStore=Ext.getStore('Devices');for(store=0;store<data.length;store++){var position=data[store];if(device=deviceStore.getById(position.get('deviceId')))this.updateAccuracy(position,device),this.updateLatestMarker(position,device),this.updateLiveRoute(position,device)}},updateAccuracy:function(position,device){var feature=this.accuracyCircles[position.get('deviceId')];if(position.get('accuracy')){var center=ol.proj.fromLonLat([position.get('longitude'), position.get('latitude')]);var radius=Ext.getStore('DistanceUnits').convertValue(position.get('accuracy'),Traccar.app.getAttributePreference('distanceUnit'),!0);feature?(feature.getGeometry().setCenter(center),feature.getGeometry().setRadius(radius)):(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,this.isDeviceVisible(device)&& this.getView().getAccuracySource().addFeature(feature))}else feature&&this.getView().getAccuracySource().getFeatureById(feature.getId())&&this.getView().getAccuracySource().removeFeature(feature),delete this.accuracyCircles[position.get('deviceId')]},updateLatestMarker:function(position,device){var geometry=new ol.geom.Point(ol.proj.fromLonLat([position.get('longitude'),position.get('latitude')]));var deviceId=position.get('deviceId');if(deviceId in this.latestMarkers){var marker=this.latestMarkers[deviceId]; this.animateMarker(marker,geometry,position.get('course'))}else marker=new ol.Feature(geometry),marker.set('record',device),position=this.getLatestMarker(this.getDeviceColor(device),position.get('course'),device.get('category')),position.getText().setText(Ext.String.htmlDecode(device.get('name'))),marker.setStyle(position),marker.setId(device.get('id')),this.latestMarkers[deviceId]=marker,this.isDeviceVisible(device)&&this.getView().getMarkersSource().addFeature(marker);marker===this.selectedMarker&& this.lookupReference('deviceFollowButton').pressed&&this.getView().getMapView().setCenter(marker.getGeometry().getCoordinates())},updateLiveRoute:function(position,device){var deviceId=position.get('deviceId');if(deviceId in this.liveRoutes){device=this.liveRoutes[deviceId].getGeometry().getCoordinates();var lastLiveCoordinates=device[device.length-1];position=ol.proj.fromLonLat([position.get('longitude'),position.get('latitude')]);if(lastLiveCoordinates[0]!==position[0]||lastLiveCoordinates[1]!== position[1])device.length>=this.liveRouteLength&&device.shift(),device.push(position),this.liveRoutes[deviceId].getGeometry().setCoordinates(device)}else position=new ol.Feature({geometry:new ol.geom.LineString([ol.proj.fromLonLat([position.get('longitude'),position.get('latitude')])])}),position.setStyle(this.getRouteStyle(deviceId)),position.setId(deviceId),this.liveRoutes[deviceId]=position,this.isDeviceVisible(device)&&this.getView().getMarkersSource().addFeature(position)},loadReport:function(store, data){if(data){this.addReportMarkers(store,data);var routeSource=this.getView().getRouteSource();this.reportRoute=[];for(store=0;store<data.length;store++){var position=data[store];position=ol.proj.fromLonLat([position.get('longitude'),position.get('latitude')]);if(0===store||data[store].get('deviceId')!==data[store-1].get('deviceId'))this.reportRoute.push(new ol.Feature({geometry:new ol.geom.LineString([])})),this.reportRoute[this.reportRoute.length-1].setStyle(this.getRouteStyle(data[store].get('deviceId'))), routeSource.addFeature(this.reportRoute[this.reportRoute.length-1]);this.reportRoute[this.reportRoute.length-1].getGeometry().appendCoordinate(position)}}},addReportMarker:function(position){var geometry=ol.proj.fromLonLat([position.get('longitude'),position.get('latitude')]);geometry=new ol.geom.Point(geometry);geometry=new ol.Feature(geometry);geometry.set('record',position);position=this.getReportMarker(position.get('deviceId'),position.get('course'));geometry.setStyle(position);this.getView().getMarkersSource().addFeature(geometry); return geometry},addReportMarkers:function(store,data){var i;this.clearReport();for(i=0;i<data.length;i++)store.showMarkers&&(this.reportMarkers[data[i].get('id')]=this.addReportMarker(data[i]));this.zoomToAllPositions(data)},clearReport:function(){var key,i;var 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){i=this.getView().getMarkersSource();for(key in this.reportMarkers)this.reportMarkers.hasOwnProperty(key)&& i.removeFeature(this.reportMarkers[key]);this.reportMarkers={}}this.selectedMarker&&!this.selectedMarker.get('event')&&this.selectedMarker.get('record')instanceof Traccar.model.Position&&(this.selectedMarker=null)},clearEvent:function(){this.selectedMarker&&this.selectedMarker.get('event')&&this.selectMarker(null,!1)},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){zoom=Traccar.DeviceImages.getImageIcon(color,zoom,angle,category);return new ol.style.Style({image:zoom,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:-zoom.getSize()[1]/2-Traccar.Style.mapTextOffset,font:Traccar.Style.mapTextFont})})},getLatestMarker:function(color,angle,category){return this.getMarkerStyle(!1, color,angle,category)},getReportMarker:function(deviceId,angle){return this.getMarkerStyle(!1,Traccar.app.getReportColor(deviceId),angle,'arrow')},resizeMarker:function(style,zoom){zoom=Traccar.DeviceImages.getImageIcon(style.getImage().fill,zoom,style.getImage().angle,style.getImage().category);var text=style.getText();text.setOffsetY(-zoom.getSize()[1]/2-Traccar.Style.mapTextOffset);style.setText(text);style.setImage(zoom)},rotateMarker:function(style,angle){style.setImage(Traccar.DeviceImages.getImageIcon(style.getImage().fill, style.getImage().zoom,angle,style.getImage().category))},updateDeviceMarker:function(style,color,category){color=Traccar.DeviceImages.getImageIcon(color,style.getImage().zoom,style.getImage().angle,category);category=style.getText();category.setOffsetY(-color.getSize()[1]/2-Traccar.Style.mapTextOffset);style.setText(category);style.setImage(color)},selectMarker:function(marker,center){this.selectedMarker&&(this.selectedMarker.get('event')?this.getView().getMarkersSource().removeFeature(this.selectedMarker): !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')]):(this.resizeMarker(this.selectedMarker.getStyle(),!1),this.selectedMarker.getStyle().setZIndex(0),this.selectedMarker.changed()));marker&&(this.resizeMarker(marker.getStyle(),!0),marker.getStyle().setZIndex(1),marker.changed(),center&&(this.getView().getMapView().setCenter(marker.getGeometry().getCoordinates()), 0!==this.selectZoom&&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){position instanceof Traccar.model.Position?(Ext.getStore('ReportRoute').showMarkers||(this.reportMarkers[position.get('id')]=this.addReportMarker(position)),this.selectMarker(this.reportMarkers[position.get('id')], center)):this.selectedMarker&&this.selectMarker(null,!1)},selectEvent:function(position){position?(position=this.addReportMarker(position),position.set('event',!0),this.selectMarker(position,!0)):this.selectedMarker&&this.selectedMarker.get('event')&&this.selectMarker(null,!1)},selectFeature:function(feature){(feature=feature.get('record'))&&(feature instanceof Traccar.model.Device?this.fireEvent('selectdevice',feature,!1):this.fireEvent('selectreport',feature,!1))},deselectFeature:function(){this.deselectDevice(); this.fireEvent('deselectfeature')},deselectDevice:function(){this.selectMarker(null,!1)},zoomToAllPositions:function(data){var i,maxx,maxy;for(i=0;i<data.length;i++){var point=ol.proj.fromLonLat([data[i].get('longitude'),data[i].get('latitude')]);if(0===i){var minx=maxx=point[0];var 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)}minx!==maxx||miny!==maxy?this.getView().getMapView().fit([minx,miny,maxx,maxy]): point&&this.getView().getMapView().fit(new ol.geom.Point(point))},updateVisibleDevices:function(store,data){Ext.isArray(data)||(data=[data]);for(store=0;store<data.length;store++){var device=data[store];device.get('id')in this.latestMarkers&&this.updateDeviceVisibility(device)}},isDeviceVisible:function(device){return Ext.getStore('VisibleDevices').contains(device)},updateDeviceVisibility:function(device){var deviceId=device.get('id');var marker=this.latestMarkers[deviceId];var accuracy=this.accuracyCircles[deviceId]; deviceId=this.liveRoutes[deviceId];this.isDeviceVisible(device)?(marker&&!this.getView().getMarkersSource().getFeatureById(marker.getId())&&this.getView().getMarkersSource().addFeature(marker),accuracy&&!this.getView().getAccuracySource().getFeatureById(accuracy.getId())&&this.getView().getAccuracySource().addFeature(accuracy),deviceId&&!this.getView().getLiveRouteSource().getFeatureById(deviceId.getId())&&this.getView().getLiveRouteSource().addFeature(deviceId)):(marker&&this.getView().getMarkersSource().getFeatureById(marker.getId())&& this.getView().getMarkersSource().removeFeature(marker),accuracy&&this.getView().getAccuracySource().getFeatureById(accuracy.getId())&&this.getView().getAccuracySource().removeFeature(accuracy),deviceId&&this.getView().getLiveRouteSource().getFeatureById(deviceId.getId())&&this.getView().getLiveRouteSource().removeFeature(deviceId))},filterDevices:function(){Ext.getStore('Devices').each(this.updateDeviceVisibility,this,!1)}}); Ext.define('Traccar.GeofenceConverter',{singleton:!0,wktToGeometry:function(mapView,wkt){var points=[];if(0===wkt.lastIndexOf('POLYGON',0)){if(wkt=wkt.match(/\([^()]+\)/),null!==wkt&&(wkt=wkt[0].match(/-?\d+\.?\d*/g),null!==wkt)){var geometry=mapView.getProjection();for(mapView=0;mapView<wkt.length;mapView+=2){var lat=Number(wkt[mapView]);var lon=Number(wkt[mapView+1]);points.push(ol.proj.transform([lon,lat],'EPSG:4326',geometry))}geometry=new ol.geom.Polygon([points])}}else if(0===wkt.lastIndexOf('CIRCLE', 0))wkt=wkt.match(/\([^()]+\)/),null!==wkt&&(wkt=wkt[0].match(/-?\d+\.?\d*/g),null!==wkt&&(geometry=mapView.getProjection(),points=ol.proj.transform([Number(wkt[1]),Number(wkt[0])],'EPSG:4326',geometry),mapView=mapView.getResolution(),geometry=ol.proj.getPointResolution(geometry,mapView,points),wkt=Number(wkt[2])/ol.proj.Units.METERS_PER_UNIT.m*(mapView/geometry),geometry=new ol.geom.Circle(points,wkt)));else if(0===wkt.lastIndexOf('LINESTRING',0)&&(wkt=wkt.match(/\([^()]+\)/),null!==wkt&&(wkt=wkt[0].match(/-?\d+\.?\d*/g), null!==wkt))){geometry=mapView.getProjection();for(mapView=0;mapView<wkt.length;mapView+=2)lat=Number(wkt[mapView]),lon=Number(wkt[mapView+1]),points.push(ol.proj.transform([lon,lat],'EPSG:4326',geometry));geometry=new ol.geom.LineString(points)}return geometry},geometryToWkt:function(projection,geometry){if(geometry instanceof ol.geom.Circle){var result=geometry.getCenter();geometry=geometry.getRadius();geometry=[result[0]+geometry,result[1]];result=ol.proj.transform(result,projection,'EPSG:4326'); projection=ol.sphere.getDistance(result,ol.proj.transform(geometry,projection,'EPSG:4326'),6378137);result='CIRCLE ('+(result[1]+' '+result[0]+', ');result+=projection.toFixed(1)+')'}else if(geometry instanceof ol.geom.Polygon){geometry.transform(projection,'EPSG:4326');geometry=geometry.getCoordinates();result='POLYGON((';for(projection=0;projection<geometry[0].length;projection+=1)result+=geometry[0][projection][1]+' '+geometry[0][projection][0]+', ';result=result.substring(0,result.length-2)+'))'}else if(geometry instanceof ol.geom.LineString){geometry.transform(projection,'EPSG:4326');geometry=geometry.getCoordinates();result='LINESTRING (';for(projection=0;projection<geometry.length;projection+=1)result+=geometry[projection][1]+' '+geometry[projection][0]+', ';result=result.substring(0,result.length-2)+')'}return result}}); Ext.define('Traccar.view.map.MapController',{extend:Traccar.view.map.MapMarkerController,alias:'controller.map',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.getBooleanAttributePreference('ui.disableReport')); this.lookupReference('showEventsButton').setVisible(Traccar.app.isMobile()&&!Traccar.app.getBooleanAttributePreference('ui.disableEvents'))},showReports:function(){Traccar.app.showReports(!0)},showEvents:function(){Traccar.app.showEvents(!0)},onFollowClick:function(button,pressed){pressed&&this.selectedMarker&&this.getView().getMapView().setCenter(this.selectedMarker.getGeometry().getCoordinates())},showLiveRoutes:function(button){this.getView().getLiveRouteLayer().setVisible(button.pressed)},getMapState:function(){var zoom= this.getView().getMapView().getProjection();var center=ol.proj.transform(this.getView().getMapView().getCenter(),zoom,'EPSG:4326');zoom=this.getView().getMapView().getZoom();this.fireEvent('mapstate',center[1],center[0],zoom)},updateGeofences:function(){this.getView().getGeofencesSource().clear();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!0},this)},zoomToAllDevices:function(){this.zoomToAllPositions(Ext.getStore('LatestPositions').getData().items)}}); 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)}}); Ext.define('Traccar.view.dialog.UserController',{extend:Traccar.view.dialog.MapPickerController,alias:'controller.user',init:function(){Traccar.app.getUser().get('administrator')&&(this.lookupReference('adminField').setDisabled(!1),this.lookupReference('deviceLimitField').setDisabled(!1),this.lookupReference('userLimitField').setDisabled(!1));if(Traccar.app.getUser().get('administrator')||!this.getView().selfEdit)this.lookupReference('readonlyField').setDisabled(!1),this.lookupReference('disabledField').setDisabled(!1), this.lookupReference('expirationTimeField').setDisabled(!1),this.lookupReference('deviceReadonlyField').setDisabled(!1),this.lookupReference('limitCommandsField').setDisabled(!1)},symbols:'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',generateToken:function(){var i,newToken='';for(i=0;32>i;i++)newToken+=this.symbols.charAt(Math.floor(Math.random()*this.symbols.length));this.lookupReference('tokenField').setValue(newToken)},testNotification:function(){Ext.Ajax.request({url:'api/notifications/test', method:'POST',failure:function(response){Traccar.app.showError(response)}})},onSaveClick:function(button){var dialog=button.up('window').down('form');dialog.updateRecord();dialog=dialog.getRecord();if(dialog===Traccar.app.getUser())dialog.save();else{var store=Ext.getStore('Users');dialog.phantom&&store.add(dialog);store.sync({failure:function(batch){store.rejectChanges();Traccar.app.showError(batch.exceptions[0].getError().response)}})}button.up('window').close()}}); Ext.define('Traccar.view.dialog.User',{extend:Traccar.view.dialog.BaseEdit,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:!1},{xtype:'textfield',name:'password',fieldLabel:Strings.userPassword,inputType:'password',allowBlank:!1}]},{xtype:'fieldset',title:Strings.sharedPreferences, collapsible:!0,collapsed:!0,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:!0,uncheckedValue:!1,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:!0, collapsed:!0,items:[{xtype:'checkboxfield',inputValue:!0,uncheckedValue:!1,name:'disabled',fieldLabel:Strings.sharedDisabled,disabled:!0,reference:'disabledField'},{xtype:'checkboxfield',inputValue:!0,uncheckedValue:!1,name:'administrator',fieldLabel:Strings.userAdmin,disabled:!0,reference:'adminField'},{xtype:'checkboxfield',inputValue:!0,uncheckedValue:!1,name:'readonly',fieldLabel:Strings.serverReadonly,disabled:!0,reference:'readonlyField'},{xtype:'checkboxfield',inputValue:!0,uncheckedValue:!1, name:'deviceReadonly',fieldLabel:Strings.userDeviceReadonly,disabled:!0,reference:'deviceReadonlyField'},{xtype:'checkboxfield',inputValue:!0,uncheckedValue:!1,name:'limitCommands',fieldLabel:Strings.userLimitCommands,disabled:!0,reference:'limitCommandsField'},{xtype:'datefield',name:'expirationTime',fieldLabel:Strings.userExpirationTime,disabled:!0,reference:'expirationTimeField',startDay:Traccar.Style.weekStartDay,format:Traccar.Style.dateFormat},{xtype:'numberfield',name:'deviceLimit',fieldLabel:Strings.userDeviceLimit, disabled:!0,reference:'deviceLimitField'},{xtype:'numberfield',name:'userLimit',fieldLabel:Strings.userUserLimit,disabled:!0,reference:'userLimitField'},{xtype:'unescapedTextField',name:'token',reference:'tokenField',fieldLabel:Strings.userToken,triggers:{generate:{cls:'iconCls: x-fa fa-refresh',handler:'generateToken'}}}]}]},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:!0,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'}]}); Ext.define('Traccar.view.dialog.Server',{extend:Traccar.view.dialog.BaseEdit,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:!0,uncheckedValue:!1,name:'twelveHourFormat',fieldLabel:Strings.settingsTwelveHourFormat},{xtype:'checkboxfield', inputValue:!0,uncheckedValue:!1,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:!0,collapsed:!0,items:[{xtype:'checkboxfield', inputValue:!0,uncheckedValue:!1,name:'registration',fieldLabel:Strings.serverRegistration},{xtype:'checkboxfield',inputValue:!0,uncheckedValue:!1,name:'readonly',fieldLabel:Strings.serverReadonly},{xtype:'checkboxfield',inputValue:!0,uncheckedValue:!1,name:'deviceReadonly',fieldLabel:Strings.userDeviceReadonly},{xtype:'checkboxfield',inputValue:!0,uncheckedValue:!1,name:'limitCommands',fieldLabel:Strings.userLimitCommands}]}]},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'}]}); Ext.define('Traccar.view.permissions.Devices',{extend:Traccar.view.permissions.Base,xtype:'linkDevicesView',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:!0,filter:'string'},{text:Strings.deviceModel,dataIndex:'model', flex:1,minWidth:Traccar.Style.columnWidthNormal,hidden:!0,filter:'string'},{text:Strings.deviceContact,dataIndex:'contact',flex:1,minWidth:Traccar.Style.columnWidthNormal,hidden:!0,filter:'string'},{text:Strings.sharedDisabled,dataIndex:'disabled',flex:1,minWidth:Traccar.Style.columnWidthNormal,renderer:Traccar.AttributeFormatter.getFormatter('disabled'),hidden:!0,filter:'boolean'},{text:Strings.groupDialog,dataIndex:'groupId',flex:1,minWidth:Traccar.Style.columnWidthNormal,hidden:!0,filter:{type:'list', labelField:'name',store:'AllGroups'},renderer:Traccar.AttributeFormatter.getFormatter('groupId')}]}});Ext.define('Traccar.view.permissions.Groups',{extend:Traccar.view.permissions.Base,xtype:'linkGroupsView',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:!0,filter:{type:'list',labelField:'name',store:'AllGroups'},renderer:Traccar.AttributeFormatter.getFormatter('groupId')}]}}); 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'}]}});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'}]}}); Ext.define('Traccar.view.edit.UsersController',{extend:Traccar.view.edit.ToolbarController,alias:'controller.users',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',!1));this.lookupReference('userMaintenancesButton').setHidden(Traccar.app.getVehicleFeaturesDisabled()||Traccar.app.getBooleanAttributePreference('ui.disableMaintenance'))}, onEditClick:function(){var user=this.getView().getSelectionModel().getSelection()[0];var 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=Ext.create('Traccar.model.User');Traccar.app.getUser().get('administrator')&&user.set('deviceLimit',-1);Traccar.app.getUser().get('expirationTime')&&user.set('expirationTime',Traccar.app.getUser().get('expirationTime'));var 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=0===selected.length;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|| 0===selected[0].get('userLimit'));this.callParent(arguments)}}); Ext.define('Traccar.view.edit.Users',{extend:Traccar.view.GridPanel,xtype:'usersView',controller:'users',store:'Users',tbar:{xtype:'editToolbar',scrollable:!0,items:[{disabled:!0,handler:'onGeofencesClick',reference:'userGeofencesButton',glyph:'xf21d@FontAwesome',tooltip:Strings.sharedGeofences,tooltipType:'title'},{disabled:!0,handler:'onDevicesClick',reference:'userDevicesButton',glyph:'xf248@FontAwesome',tooltip:Strings.deviceTitle,tooltipType:'title'},{disabled:!0,handler:'onGroupsClick',reference:'userGroupsButton', glyph:'xf247@FontAwesome',tooltip:Strings.settingsGroups,tooltipType:'title'},{disabled:!0,handler:'onUsersClick',reference:'userUsersButton',glyph:'xf0c0@FontAwesome',tooltip:Strings.settingsUsers,tooltipType:'title'},{disabled:!0,handler:'onNotificationsClick',reference:'userNotificationsButton',glyph:'xf003@FontAwesome',tooltip:Strings.sharedNotifications,tooltipType:'title'},{disabled:!0,handler:'onCalendarsClick',reference:'userCalendarsButton',glyph:'xf073@FontAwesome',tooltip:Strings.sharedCalendars, tooltipType:'title'},{disabled:!0,handler:'onAttributesClick',reference:'userAttributesButton',glyph:'xf0ae@FontAwesome',tooltip:Strings.sharedComputedAttributes,tooltipType:'title'},{disabled:!0,handler:'onDriversClick',reference:'userDriversButton',glyph:'xf084@FontAwesome',tooltip:Strings.sharedDrivers,tooltipType:'title'},{xtype:'button',disabled:!0,handler:'onCommandsClick',reference:'userCommandsButton',glyph:'xf093@FontAwesome',tooltip:Strings.sharedSavedCommands,tooltipType:'title'},{xtype:'button', disabled:!0,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:!0,renderer:Traccar.AttributeFormatter.getFormatter('readonly'),filter:'boolean'},{text:Strings.userDeviceReadonly,dataIndex:'deviceReadonly',renderer:Traccar.AttributeFormatter.getFormatter('deviceReadonly'),hidden:!0,filter:'boolean'},{text:Strings.sharedDisabled,dataIndex:'disabled',renderer:Traccar.AttributeFormatter.getFormatter('disabled'),filter:'boolean'},{text:Strings.userExpirationTime,dataIndex:'expirationTime', hidden:!0,renderer:Traccar.AttributeFormatter.getFormatter('expirationTime'),filter:'date'}]}}); Ext.define('Traccar.view.dialog.Group',{extend:Traccar.view.dialog.BaseEdit,title:Strings.groupDialog,items:{xtype:'form',items:[{xtype:'fieldset',title:Strings.sharedRequired,items:[{xtype:'unescapedTextField',name:'name',fieldLabel:Strings.sharedName,allowBlank:!1}]},{xtype:'fieldset',title:Strings.sharedExtra,collapsible:!0,collapsed:!0,items:[{xtype:'clearableComboBox',name:'groupId',fieldLabel:Strings.groupParent,store:'Groups',queryMode:'local',displayField:'name',valueField:'id'}]}]}}); Ext.define('Traccar.view.edit.GroupsController',{extend:Traccar.view.edit.ToolbarController,alias:'controller.groups',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',!1));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=0===selected.length;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)}}); Ext.define('Traccar.view.edit.Groups',{extend:Traccar.view.GridPanel,xtype:'groupsView',controller:'groups',store:'Groups',tbar:{xtype:'editToolbar',items:[{xtype:'button',disabled:!0,handler:'onGeofencesClick',reference:'toolbarGeofencesButton',glyph:'xf21d@FontAwesome',tooltip:Strings.sharedGeofences,tooltipType:'title'},{xtype:'button',disabled:!0,handler:'onAttributesClick',reference:'toolbarAttributesButton',glyph:'xf0ae@FontAwesome',tooltip:Strings.sharedComputedAttributes,tooltipType:'title'}, {xtype:'button',disabled:!0,handler:'onDriversClick',reference:'toolbarDriversButton',glyph:'xf084@FontAwesome',tooltip:Strings.sharedDrivers,tooltipType:'title'},{xtype:'button',disabled:!0,handler:'onCommandsClick',reference:'toolbarCommandsButton',glyph:'xf093@FontAwesome',tooltip:Strings.sharedSavedCommands,tooltipType:'title'},{xtype:'button',disabled:!0,handler:'onNotificationsClick',reference:'toolbarNotificationsButton',glyph:'xf003@FontAwesome',tooltip:Strings.sharedNotifications,tooltipType:'title'}, {xtype:'button',disabled:!0,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:!0,filter:{type:'list',labelField:'name',store:'AllGroups'},renderer:Traccar.AttributeFormatter.getFormatter('groupId')}]}}); Ext.define('Traccar.view.map.GeofenceMapController',{extend:Ext.app.ViewController,alias:'controller.geofenceMap',config:{listen:{controller:{'*':{mapstate:'setMapState'}}}},onFileChange:function(fileField){var view=this.getView();if(0<fileField.fileInputEl.dom.files.length){var reader=new FileReader;reader.onload=function(){var points=[];var segment=(new DOMParser).parseFromString(reader.result,'text/xml').getElementsByTagName('trkseg')[0];var projection=view.mapView.getProjection();Array.from(segment.getElementsByTagName('trkpt')).forEach(function(point){var lat= Number(point.getAttribute('lat'));point=Number(point.getAttribute('lon'));points.push(ol.proj.transform([point,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){if(0<this.getView().getFeatures().getLength()){var geometry=this.getView().getFeatures().pop().getGeometry(); var 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)}}); Ext.define('Traccar.view.map.GeofenceMap',{extend:Traccar.view.map.BaseMap,xtype:'geofenceMapView',controller:'geofenceMap',bodyBorder:!0,tbar:{items:[{xtype:'combobox',store:'GeofenceTypes',valueField:'key',displayField:'name',editable:!1,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(){this.callParent();var map=this.map;this.features=new ol.Collection;if(this.area){var geometry=Traccar.GeofenceConverter.wktToGeometry(this.mapView,this.area);this.features.push(new ol.Feature(geometry)); this.mapView.fit(geometry)}else this.controller.fireEvent('mapstaterequest');geometry=ol.color.asArray(Traccar.Style.mapGeofenceColor);geometry[3]=Traccar.Style.mapGeofenceOverlayOpacity;(new ol.layer.Vector({source:new ol.source.Vector({features:this.features}),style:new ol.style.Style({fill:new ol.style.Fill({color:geometry}),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})})})})).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(){this.draw&&(this.map.removeInteraction(this.draw),this.draw=null)}}); Ext.define('Traccar.view.dialog.GeofenceController',{extend:Traccar.view.dialog.BaseEditController,alias:'controller.geofence',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){button=button.up('window').down('form').getRecord();Ext.create('Traccar.view.BaseWindow', {title:Strings.sharedArea,items:{xtype:'geofenceMapView',area:button.get('area')}}).show()}}); Ext.define('Traccar.view.dialog.Geofence',{extend:Traccar.view.dialog.BaseEdit,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:!0,collapsed:!0,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:!1,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'}]});Ext.define('Traccar.view.edit.GeofencesController',{extend:Traccar.view.edit.ToolbarController,alias:'controller.geofences',objectModel:'Traccar.model.Geofence',objectDialog:'Traccar.view.dialog.Geofence',removeTitle:Strings.sharedGeofence}); Ext.define('Traccar.view.edit.Geofences',{extend:Traccar.view.GridPanel,xtype:'geofencesView',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:!0,filter:{type:'list',labelField:'name', store:'AllCalendars'},renderer:Traccar.AttributeFormatter.getFormatter('calendarId')}]}});Ext.define('Traccar.view.dialog.Driver',{extend:Traccar.view.dialog.BaseEdit,title:Strings.sharedDriver,items:{xtype:'form',items:[{xtype:'fieldset',title:Strings.sharedRequired,items:[{xtype:'unescapedTextField',name:'name',fieldLabel:Strings.sharedName,allowBlank:!1},{xtype:'unescapedTextField',name:'uniqueId',fieldLabel:Strings.deviceIdentifier,allowBlank:!1}]}]}}); Ext.define('Traccar.view.edit.DriversController',{extend:Traccar.view.edit.ToolbarController,alias:'controller.drivers',objectModel:'Traccar.model.Driver',objectDialog:'Traccar.view.dialog.Driver',removeTitle:Strings.sharedDriver}); Ext.define('Traccar.view.edit.Drivers',{extend:Traccar.view.GridPanel,xtype:'driversView',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'}]}}); 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('alarm'!==value)},onAlarmsLoad:function(view){var attributes=view.up('form').getRecord().get('attributes')||{};attributes.alarms&&(view.suspendEvents(!1),view.setValue(attributes.alarms.split(',')), view.resumeEvents())},onAlarmsChange:function(view,value){var record=view.up('window').down('form').getRecord();view=record.get('attributes')||{};value=value.join();view.alarms!==value&&(view.alarms=value,record.set('attributes',view),record.dirty=!0)}}); Ext.define('Traccar.view.dialog.Notification',{extend:Traccar.view.dialog.BaseEdit,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:!1,allowBlank:!1,listeners:{change:'onTypeChange'}},{xtype:'checkboxfield',inputValue:!0,uncheckedValue:!1,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:!0,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:!0,collapsed:!0,items:[{xtype:'clearableComboBox',reference:'calendarCombo',name:'calendarId',store:'Calendars',queryMode:'local',displayField:'name',valueField:'id',fieldLabel:Strings.sharedCalendar}]}]}});Ext.define('Traccar.view.edit.NotificationsController',{extend:Traccar.view.edit.ToolbarController,alias:'controller.notifications',objectModel:'Traccar.model.Notification',objectDialog:'Traccar.view.dialog.Notification',removeTitle:Strings.sharedNotification}); Ext.define('Traccar.view.edit.Notifications',{extend:Traccar.view.GridPanel,xtype:'notificationsView',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 result='',alarms=value&&value.alarms;if(alarms)for(alarms=alarms.split(','),value=0;value<alarms.length;value++){var key='alarm'+alarms[value].charAt(0).toUpperCase()+alarms[value].slice(1);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='';if(value){var notificators=value.split(/[ ,]+/).filter(Boolean);for(value=0;value<notificators.length;value++)result+=Traccar.app.getNotificatorString(notificators[value])+(value<notificators.length-1?', ':'')}return result}},{text:Strings.sharedCalendar,dataIndex:'calendarId',hidden:!0,filter:{type:'list',labelField:'name',store:'AllCalendars'}, renderer:Traccar.AttributeFormatter.getFormatter('calendarId')}]}});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()}})}}); Ext.define('Traccar.view.Statistics',{extend:Traccar.view.GridPanel,xtype:'statisticsView',controller:'statistics',store:'Statistics',tbar:{scrollable:!0,items:[{xtype:'tbtext',html:Strings.reportFrom},{xtype:'datefield',reference:'fromDateField',startDay:Traccar.Style.weekStartDay,format:Traccar.Style.dateFormat,value:new Date((new Date).getTime()-864E5)},'-',{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'}]}}); Ext.define('Traccar.view.dialog.CalendarController',{extend:Traccar.view.dialog.BaseEditController,alias:'controller.calendar',onFileChange:function(fileField){if(0<fileField.fileInputEl.dom.files.length){var 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])}}}); Ext.define('Traccar.view.dialog.Calendar',{extend:Traccar.view.dialog.BaseEdit,controller:'calendar',title:Strings.sharedCalendar,items:{xtype:'form',items:[{xtype:'fieldset',title:Strings.sharedRequired,items:[{xtype:'unescapedTextField',name:'name',fieldLabel:Strings.sharedName,allowBlank:!1},{xtype:'filefield',name:'file',fieldLabel:Strings.sharedFile,allowBlank:!1,buttonConfig:{glyph:'xf093@FontAwesome',text:'',tooltip:Strings.sharedSelectFile,tooltipType:'title',minWidth:0},listeners:{change:'onFileChange'}}]}, {xtype:'hiddenfield',name:'data',allowBlank:!1,reference:'dataField'}]}});Ext.define('Traccar.view.edit.CalendarsController',{extend:Traccar.view.edit.ToolbarController,alias:'controller.calendars',objectModel:'Traccar.model.Calendar',objectDialog:'Traccar.view.dialog.Calendar',removeTitle:Strings.sharedCalendar}); Ext.define('Traccar.view.edit.Calendars',{extend:Traccar.view.GridPanel,xtype:'calendarsView',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'}]}}); Ext.define('Traccar.view.dialog.SavedCommand',{extend:Traccar.view.dialog.BaseEdit,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:!0,uncheckedValue:!1,fieldLabel:Strings.commandSendSms},{xtype:'combobox',name:'type',reference:'commandType', fieldLabel:Strings.sharedType,store:'AllCommandTypes',queryMode:'local',displayField:'name',valueField:'type',editable:!1,allowBlank:!1,listeners:{change:'onTypeChange'}},{xtype:'fieldcontainer',reference:'parameters'}]}]}],buttons:[{glyph:'xf00c@FontAwesome',reference:'saveButton',tooltip:Strings.sharedSave,tooltipType:'title',minWidth:0,disabled:!0,handler:'onSaveClick'},{glyph:'xf00d@FontAwesome',tooltip:Strings.sharedCancel,tooltipType:'title',minWidth:0,handler:'closeView'}]}); Ext.define('Traccar.view.edit.SavedCommandsController',{extend:Traccar.view.edit.ToolbarController,alias:'controller.savedCommands',objectModel:'Traccar.model.Command',objectDialog:'Traccar.view.dialog.SavedCommand',removeTitle:Strings.sharedSavedCommand}); Ext.define('Traccar.view.edit.SavedCommands',{extend:Traccar.view.GridPanel,xtype:'savedCommandsView',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'}]}}); 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(!0)},onValidityChange:function(form,valid){this.lookupReference('saveButton').setDisabled(!valid)}, updateFieldConfig:function(fieldReference,initialConfig,newConfig){var field=this.lookupReference(fieldReference);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()):(field.setConfig(newConfig),field.validate())},onNameChange:function(combobox,newValue){var config={};if(combobox=combobox.getStore().getById(newValue))void 0!== combobox.get('allowDecimals')?config.allowDecimals=combobox.get('allowDecimals'):config.allowDecimals=!0,config.dataType=combobox.get('dataType'),config.maxValue=combobox.get('maxValue'),config.minValue=combobox.get('minValue');this.updateFieldConfig('startField',this.startConfig,config);this.updateFieldConfig('periodField',this.periodConfig,config)}}); Ext.define('Traccar.view.dialog.Maintenance',{extend:Traccar.view.dialog.BaseEdit,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:!1},{xtype:'combobox',name:'type',reference:'typeComboField',fieldLabel:Strings.sharedType,displayField:'name',valueField:'key',allowBlank:!1,queryMode:'local', store:'MaintenanceTypes',listeners:{change:'onNameChange'}},{xtype:'customNumberField',name:'start',reference:'startField',fieldLabel:Strings.maintenanceStart},{xtype:'customNumberField',name:'period',reference:'periodField',allowBlank:!1,fieldLabel:Strings.maintenancePeriod,validator:function(value){return 0!==this.parseValue(value)?!0:Strings.errorZero}}]}]}}); Ext.define('Traccar.view.edit.MaintenancesController',{extend:Traccar.view.edit.ToolbarController,alias:'controller.maintenances',objectModel:'Traccar.model.Maintenance',objectDialog:'Traccar.view.dialog.Maintenance',removeTitle:Strings.sharedMaintenance}); Ext.define('Traccar.view.edit.Maintenances',{extend:Traccar.view.GridPanel,xtype:'maintenancesView',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')))}}]}}); Ext.define('Traccar.view.SettingsMenuController',{extend:Ext.app.ViewController,alias:'controller.settings',init:function(){var admin=Traccar.app.getUser().get('administrator');var manager=0!==Traccar.app.getUser().get('userLimit');var readonly=Traccar.app.getPreference('readonly',!1);admin&&(this.lookupReference('settingsServerButton').setHidden(!1),this.lookupReference('settingsStatisticsButton').setHidden(!1),this.lookupReference('settingsComputedAttributesButton').setHidden(Traccar.app.getBooleanAttributePreference('ui.disableComputedAttributes'))); (admin||manager)&&this.lookupReference('settingsUsersButton').setHidden(!1);if(admin||!readonly)this.lookupReference('settingsUserButton').setHidden(!1),this.lookupReference('settingsGroupsButton').setHidden(!1),this.lookupReference('settingsGeofencesButton').setHidden(!1),this.lookupReference('settingsNotificationsButton').setHidden(!1),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',!1)),this.lookupReference('settingsMaintenancesButton').setHidden(Traccar.app.getVehicleFeaturesDisabled()||Traccar.app.getBooleanAttributePreference('ui.disableMaintenance'))},onUserClick:function(){var dialog=Ext.create('Traccar.view.dialog.User',{selfEdit:!0});dialog.down('form').loadRecord(Traccar.app.getUser());dialog.lookupReference('testNotificationButton').setHidden(!1); 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()}}); Ext.define('Traccar.view.SettingsMenu',{extend:Ext.button.Button,xtype:'settingsMenu',glyph:'xf013@FontAwesome',tooltip:Strings.settingsTitle,tooltipType:'title',menu:{controller:'settings',items:[{hidden:!0,text:Strings.settingsUser,glyph:'xf007@FontAwesome',handler:'onUserClick',reference:'settingsUserButton'},{hidden:!0,text:Strings.settingsGroups,glyph:'xf247@FontAwesome',handler:'onGroupsClick',reference:'settingsGroupsButton'},{hidden:!0,text:Strings.sharedDrivers,glyph:'xf084@FontAwesome', handler:'onDriversClick',reference:'settingsDriversButton'},{hidden:!0,text:Strings.sharedGeofences,glyph:'xf21d@FontAwesome',handler:'onGeofencesClick',reference:'settingsGeofencesButton'},{hidden:!0,text:Strings.settingsServer,glyph:'xf233@FontAwesome',handler:'onServerClick',reference:'settingsServerButton'},{hidden:!0,text:Strings.settingsUsers,glyph:'xf0c0@FontAwesome',handler:'onUsersClick',reference:'settingsUsersButton'},{hidden:!0,text:Strings.sharedNotifications,glyph:'xf003@FontAwesome', handler:'onNotificationsClick',reference:'settingsNotificationsButton'},{hidden:!0,text:Strings.sharedComputedAttributes,glyph:'xf0ae@FontAwesome',handler:'onComputedAttributesClick',reference:'settingsComputedAttributesButton'},{hidden:!0,text:Strings.statisticsTitle,glyph:'xf080@FontAwesome',handler:'onStatisticsClick',reference:'settingsStatisticsButton'},{hidden:!0,text:Strings.sharedCalendars,glyph:'xf073@FontAwesome',handler:'onCalendarsClick',reference:'settingsCalendarsButton'},{hidden:!0, text:Strings.sharedSavedCommands,glyph:'xf093@FontAwesome',handler:'onCommandsClick',reference:'settingsCommandsButton'},{hidden:!0,text:Strings.sharedMaintenance,glyph:'xf0ad@FontAwesome',handler:'onMaintenancesClick',reference:'settingsMaintenancesButton'},{text:Strings.loginLogout,glyph:'xf08b@FontAwesome',handler:'onLogoutClick'}]}}); Ext.define('Traccar.view.map.Map',{extend:Traccar.view.map.BaseMap,xtype:'mapView',controller:'map',title:Strings.mapTitle,tbar:{componentCls:'toolbar-header-style',defaults:{xtype:'button',tooltipType:'title',stateEvents:['toggle'],enableToggle:!0,stateful:{pressed:!0}},items:[{xtype:'tbtext',html:Strings.mapTitle,baseCls:'x-panel-header-title-default'},{xtype:'tbfill'},{handler:'showReports',reference:'showReportsButton',glyph:'xf0f6@FontAwesome',stateful:!1,enableToggle:!1,tooltip:Strings.reportTitle}, {handler:'showEvents',reference:'showEventsButton',glyph:'xf27b@FontAwesome',stateful:!1,enableToggle:!1,tooltip:Strings.reportEvents},{handler:'updateGeofences',reference:'showGeofencesButton',glyph:'xf21d@FontAwesome',pressed:!0,stateId:'show-geofences-button',tooltip:Strings.sharedGeofences},{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:!1}]},getMarkersSource:function(){return this.markersSource},getAccuracySource:function(){return this.accuracySource},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.map.addLayer(new ol.layer.Vector({name:'accuracyLayer', source:this.accuracySource}));this.markersSource=new ol.source.Vector({});this.map.addLayer(new ol.layer.Vector({source:this.markersSource}))}}); Ext.define('Traccar.view.Main',{extend:Ext.container.Viewport,alias:'widget.main',controller:'mainController',layout:'border',defaults:{header:!1,collapsible:!0,split:!0},items:[{region:'west',layout:'border',width:Traccar.Style.deviceWidth,title:Strings.devicesAndState,titleCollapse:!0,floatable:!1,stateful:!0,stateId:'devices-and-state-panel',defaults:{split:!0,flex:1},items:[{region:'center',xtype:'devicesView'},{region:'south',xtype:'stateView'}]},{region:'south',xtype:'reportView',reference:'reportView', height:Traccar.Style.reportHeight,collapsed:!0,titleCollapse:!0,floatable:!1},{region:'center',xtype:'mapView',collapsible:!1},{region:'east',xtype:'eventsView',reference:'eventsView',width:Traccar.Style.deviceWidth,collapsed:!0,titleCollapse:!0,floatable:!1}]}); Ext.define('Traccar.view.MainMobile',{extend:Ext.container.Viewport,alias:'widget.mainMobile',id:'rootPanel',layout:'card',items:[{layout:'border',defaults:{header:!1,collapsible:!0,split:!0},items:[{region:'east',xtype:'stateView',title:Strings.stateTitle,flex:4,collapsed:!0,collapseMode:'mini',titleCollapse:!0,floatable:!1,stateId:'mobile-state-grid'},{region:'center',xtype:'mapView',collapsible:!1,flex:2},{region:'south',xtype:'devicesView',title:Strings.deviceTitle,flex:1,collapsed:!0,titleCollapse:!0, floatable:!1,stateId:'mobile-devices-grid'}]},{xtype:'reportView'},{xtype:'eventsView'}]}); Ext.define('Traccar.controller.Root',{extend:Ext.app.Controller,alias:'controller.root',init:function(){var i;var chartTypesStore=Ext.getStore('ReportChartTypes');var maintenanceTypesStore=Ext.getStore('MaintenanceTypes');Ext.state.Manager.setProvider(new Ext.state.CookieProvider);var data=Ext.getStore('PositionAttributes').getData().items;for(i=0;i<data.length;i++){var attribute=data[i];Traccar.model.Position.addFields([{name:'attribute.'+attribute.get('key'),attributeKey:attribute.get('key'),calculate:this.calculateAttribute, persist:!1}]);'number'===attribute.get('valueType')&&(chartTypesStore.add({key:'attribute.'+attribute.get('key'),name:attribute.get('name')}),maintenanceTypesStore.add(attribute))}},calculateAttribute:function(data){data=data.attributes[this.attributeKey];return void 0!==data?Traccar.AttributeFormatter.getAttributeConverter(this.attributeKey)(data):data},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;maxWidth>Traccar.Style.windowWidth&&(maxWidth=Traccar.Style.windowWidth);Ext.Msg.show({msg:announcement,buttons:Ext.Msg.OK,closable:!1,modal:!1,maxWidth:maxWidth}).alignTo(Ext.getBody(),'t-t',[0,Traccar.Style.normalPadding])},onServerReturn:function(options,success,response){options={};if(success){Traccar.app.setServer(Ext.decode(response.responseText));(success=Traccar.app.getServer().get('announcement'))&&this.showAnnouncement(success); if(success=Ext.Object.fromQueryString(window.location.search).token)options.token=success;Ext.Ajax.request({scope:this,url:'api/session',method:'GET',params:options,callback:this.onSessionReturn})}else Traccar.app.showError(response)},onSessionReturn:function(options$jscomp$0,success$jscomp$0,response$jscomp$0){var passwordReset;Ext.get('spinner').setVisible(!1);if(success$jscomp$0)Traccar.app.setUser(Ext.decode(response$jscomp$0.responseText)),this.loadApp();else if(this.login=Ext.create('widget.login', {listeners:{scope:this,login:this.onLogin}}),this.login.show(),passwordReset=Ext.Object.fromQueryString(window.location.search).passwordReset){var dialog=Ext.Msg.prompt(Strings.loginReset,Strings.userPassword,function(btn,text){dialog.textField.inputEl.dom.type='text';'ok'===btn&&Ext.Ajax.request({scope:this,method:'POST',url:'api/password/update',params:{token:passwordReset,password:text},callback:function(options,success,response){success?(Traccar.app.showToast(Strings.loginUpdateSuccess),this.removeUrlParameter('passwordReset')): Traccar.app.showError(response.responseText)}})},this);dialog.textField.inputEl.dom.type='password'}},onLogin:function(){this.login.close();this.loadApp()},loadApp:function(){var updateView;window.webkit&&window.webkit.messageHandlers.appInterface&&window.webkit.messageHandlers.appInterface.postMessage('login');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){operation=Ext.getStore('ReportEventTypes');success&&(operation.add({type:Traccar.store.ReportEventTypes.allEvents,name:Strings.eventAll}),operation.loadData(records,!0))}});Ext.getStore('AllNotificators').load();Ext.getStore('Notifications').load();Ext.getStore('ServerAttributes').loadData(Ext.getStore('CommonDeviceAttributes').getData().items, !0);Ext.getStore('ServerAttributes').loadData(Ext.getStore('CommonUserAttributes').getData().items,!0);Ext.getStore('UserAttributes').loadData(Ext.getStore('CommonUserAttributes').getData().items,!0);Ext.getStore('DeviceAttributes').loadData(Ext.getStore('CommonDeviceAttributes').getData().items,!0);Ext.getStore('GroupAttributes').loadData(Ext.getStore('CommonDeviceAttributes').getData().items,!0);Ext.getStore('Devices').load({scope:this,callback:function(){this.asyncUpdate(!0)}});(updateView=Ext.get('update'))&& updateView.remove();(updateView=Ext.get('attribution'))&&updateView.remove();Traccar.app.isMobile()?Ext.create('widget.mainMobile'):Ext.create('widget.main');if(updateView=Ext.Object.fromQueryString(window.location.search).eventId)this.fireEvent('showsingleevent',updateView),this.removeUrlParameter('eventId')},beep:function(){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];Ext.Object.isEmpty(params)?window.history.pushState(null,null,window.location.pathname):window.history.pushState(null,null,window.location.pathname+'?'+Ext.Object.toQueryString(params))},asyncUpdate:function(first){var self=this;var protocol='https:'===window.location.protocol?'wss:':'ws:';var pathname=window.location.pathname.substring(0,window.location.pathname.lastIndexOf('/')+ 1);protocol=new WebSocket(protocol+'//'+window.location.host+pathname+'api/socket');protocol.onclose=function(){Ext.Ajax.request({url:'api/devices',success:function(response){self.updateDevices(Ext.decode(response.responseText))},failure:function(response){401===response.status&&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(!1)}, Traccar.Style.reconnectTimeout)};protocol.onmessage=function(event){event=Ext.decode(event.data);event.devices&&self.updateDevices(event.devices);event.positions&&(self.updatePositions(event.positions,first),first=!1);event.events&&self.updateEvents(event.events)}},updateDevices:function(array){var i,entity;var store=Ext.getStore('Devices');for(i=0;i<array.length;i++)(entity=store.getById(array[i].id))&&entity.set({status:array[i].status,lastUpdate:array[i].lastUpdate,geofenceIds:array[i].geofenceIds}, {dirty:!1})},updatePositions:function(array,first){var i,entity,device;var store=Ext.getStore('LatestPositions');for(i=0;i<array.length;i++)(entity=store.findRecord('deviceId',array[i].deviceId,0,!1,!1,!0))?entity.set(array[i]):store.add(Ext.create('Traccar.model.Position',array[i])),Ext.getStore('Events').findRecord('positionId',array[i].id,0,!1,!1,!0)&&Ext.getStore('EventPositions').add(Ext.create('Traccar.model.Position',array[i]));first&&((array=Ext.Object.fromQueryString(window.location.search).deviceId)&& (device=Ext.getStore('VisibleDevices').findRecord('id',array,0,!1,!0,!0))&&this.fireEvent('selectdevice',device,!0),device||this.zoomToAllDevices())},updateEvents:function(array){var i,device;var store=Ext.getStore('Events');for(i=0;i<array.length;i++)store.insert(0,array[i]),(device=Ext.getStore('Devices').getById(array[i].deviceId))?(this.soundPressed()&&this.beep(),Traccar.app.showToast(array[i].text,device.get('name'))):Traccar.app.showToast(array[i].text)},zoomToAllDevices:function(){var lat= Traccar.app.getPreference('latitude',0);var lon=Traccar.app.getPreference('longitude',0);var zoom=Traccar.app.getPreference('zoom',0);0===lat&&0===lon&&0===zoom&&this.fireEvent('zoomtoalldevices')}}); Ext.define('Traccar.Application',{extend:Ext.app.Application,name:'Traccar',models:'Server User Group Device Position Attribute Command Event Geofence Notification ReportSummary ReportTrip ReportStop Calendar KnownAttribute Driver KnownCommand KnownNotification Maintenance'.split(' '),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'.split(' '),controllers:['Root'], isMobile:function(){return window.matchMedia&&window.matchMedia('(max-width: 768px)').matches},getVehicleFeaturesDisabled:function(){return this.getBooleanAttributePreference('ui.disableVehicleFetures')},getEventString:function(eventType){eventType='event'+eventType.charAt(0).toUpperCase()+eventType.slice(1);return Strings[eventType]||eventType},getNotificatorString:function(eventType){eventType='notificator'+eventType.charAt(0).toUpperCase()+eventType.slice(1);return Strings[eventType]||eventType}, showReports:function(show){var rootPanel=Ext.getCmp('rootPanel');rootPanel&&rootPanel.setActiveItem(show?1:0)},showEvents:function(show){var rootPanel=Ext.getCmp('rootPanel');rootPanel&&rootPanel.setActiveItem(show?2:0)},updateNotificationToken:function(token){var attributes=Ext.clone(this.user.get('attributes'));if(!attributes.notificationTokens||0>attributes.notificationTokens.indexOf(token))attributes.notificationTokens=attributes.notificationTokens?attributes.notificationTokens+(','+token):token, this.user.set('attributes',attributes),this.user.save()},setUser:function(data){this.user=Ext.create('Ext.data.reader.Json',{model:'Traccar.model.User'}).readRecords(data).getRecords()[0]},getUser:function(){return this.user},setServer:function(data){this.server=Ext.create('Ext.data.reader.Json',{model:'Traccar.model.Server'}).readRecords(data).getRecords()[0]},getServer:function(){return this.server},getPreference:function(key,defaultValue){return this.getServer().get('forceSettings')?this.getServer().get(key)|| this.getUser().get(key)||defaultValue:this.getUser().get(key)||this.getServer().get(key)||defaultValue},getAttributePreference:function(key,defaultValue){return this.getServer().get('forceSettings')?this.getServer().get('attributes')[key]||this.getUser().get('attributes')[key]||defaultValue:this.getUser().get('attributes')[key]||this.getServer().get('attributes')[key]||defaultValue},getBooleanAttributePreference:function(key){return'true'===this.getAttributePreference(key,!1).toString()},getReportColor:function(deviceId){var index, device=Ext.getStore('Devices').getById(deviceId);device&&(index=device.get('attributes')['web.reportColor']);if(index)return index;index=0;void 0!==deviceId&&(index=deviceId%Traccar.Style.mapRouteColor.length);return Traccar.Style.mapRouteColor[index]},showError:function(error){Ext.isString(error)?Ext.Msg.alert(Strings.errorTitle,error):error.responseText?Ext.Msg.alert(Strings.errorTitle,Strings.errorGeneral+'\x3cbr\x3e\x3cbr\x3e\x3ctextarea readonly rows\x3d"5" style\x3d"resize: none; width: 100%;"\x3e'+ error.responseText+'\x3c/textarea\x3e'):error.statusText?Ext.Msg.alert(Strings.errorTitle,error.statusText):Ext.Msg.alert(Strings.errorTitle,Strings.errorConnection)},showToast:function(message,title){Ext.toast({html:message,title:title,width:Traccar.Style.toastWidth,align:'br'})}});Ext.application({name:'Traccar',extend:Traccar.Application});