diff options
Diffstat (limited to 'web')
-rw-r--r-- | web/app/Application.js | 6 | ||||
-rw-r--r-- | web/app/model/KnownCommand.js | 35 | ||||
-rw-r--r-- | web/app/store/CommandTypes.js | 19 | ||||
-rw-r--r-- | web/app/store/KnownCommands.js | 234 | ||||
-rw-r--r-- | web/app/store/TimeUnits.js | 24 | ||||
-rw-r--r-- | web/app/view/CustomNumberField.js | 85 | ||||
-rw-r--r-- | web/app/view/dialog/Command.js | 88 | ||||
-rw-r--r-- | web/app/view/dialog/CommandController.js | 126 | ||||
-rw-r--r-- | web/l10n/en.json | 11 |
9 files changed, 427 insertions, 201 deletions
diff --git a/web/app/Application.js b/web/app/Application.js index e0f0aa45..dddca840 100644 --- a/web/app/Application.js +++ b/web/app/Application.js @@ -41,7 +41,8 @@ Ext.define('Traccar.Application', { 'ReportStop', 'Calendar', 'KnownAttribute', - 'Driver' + 'Driver', + 'KnownCommand' ], stores: [ @@ -95,7 +96,8 @@ Ext.define('Traccar.Application', { 'PositionAttributes', 'AttributeValueTypes', 'Drivers', - 'AllDrivers' + 'AllDrivers', + 'KnownCommands' ], controllers: [ diff --git a/web/app/model/KnownCommand.js b/web/app/model/KnownCommand.js new file mode 100644 index 00000000..08213020 --- /dev/null +++ b/web/app/model/KnownCommand.js @@ -0,0 +1,35 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +Ext.define('Traccar.model.KnownCommand', { + extend: 'Ext.data.Model', + idProperty: 'type', + + fields: [{ + name: 'type', + type: 'string' + }, { + name: 'name', + convert: function (v, rec) { + var name = Strings['command' + rec.get('type').charAt(0).toUpperCase() + rec.get('type').slice(1)]; + return name ? name : rec.get('type'); + }, + depends: ['type'] + }, { + name: 'parameters' + }] +}); diff --git a/web/app/store/CommandTypes.js b/web/app/store/CommandTypes.js index a14dd58e..f14cb596 100644 --- a/web/app/store/CommandTypes.js +++ b/web/app/store/CommandTypes.js @@ -18,28 +18,11 @@ Ext.define('Traccar.store.CommandTypes', { extend: 'Ext.data.Store', - fields: ['type', 'name'], + model: 'Traccar.model.KnownCommand', proxy: { type: 'rest', url: 'api/commandtypes', - reader: { - type: 'json', - getData: function (data) { - Ext.each(data, function (entry) { - var nameKey, name; - entry.name = entry.type; - if (typeof entry.type !== 'undefined') { - nameKey = 'command' + entry.type.charAt(0).toUpperCase() + entry.type.slice(1); - name = Strings[nameKey]; - if (typeof name !== 'undefined') { - entry.name = name; - } - } - }); - return data; - } - }, listeners: { 'exception': function (proxy, response) { Traccar.app.showError(response); diff --git a/web/app/store/KnownCommands.js b/web/app/store/KnownCommands.js new file mode 100644 index 00000000..8bf2e24e --- /dev/null +++ b/web/app/store/KnownCommands.js @@ -0,0 +1,234 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +Ext.define('Traccar.store.KnownCommands', { + extend: 'Ext.data.Store', + model: 'Traccar.model.KnownCommand', + + data: [{ + type: 'custom', + parameters: [{ + key: 'data', + name: Strings.commandData, + valueType: 'string' + }] + }, { + type: 'positionPeriodic', + parameters: [{ + key: 'frequency', + name: Strings.commandFrequency, + valueType: 'number', + allowDecimals: false, + minValue: 0, + dataType: 'frequency' + }] + }, { + type: 'setTimezone', + parameters: [{ + key: 'timezoneName', + 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: 'sendUssd', + parameters: [{ + key: 'phone', + name: Strings.commandPhone, + valueType: 'string' + }] + }, { + type: 'sosNumber', + parameters: [{ + key: 'index', + name: Strings.commandIndex, + valueType: 'number', + allowDecimals: false, + minValue: 0 + }, { + key: 'phone', + name: Strings.commandPhone, + valueType: 'string' + }] + }, { + type: 'silenceTime', + parameters: [{ + key: 'data', + name: Strings.commandData, + valueType: 'string' + }] + }, { + type: 'setPhonebook', + parameters: [{ + key: 'data', + name: Strings.commandData, + valueType: 'string' + }] + }, { + type: 'voiceMessage', + parameters: [{ + key: 'data', + name: Strings.commandData, + valueType: 'string' + }] + }, { + type: 'outputControl', + parameters: [{ + key: 'index', + name: Strings.commandIndex, + valueType: 'number', + allowDecimals: false, + minValue: 0 + }, { + key: 'data', + name: Strings.commandData, + valueType: 'string' + }] + }, { + type: 'voiceMonitoring', + parameters: [{ + key: 'enable', + name: Strings.commandEnable, + valueType: 'boolean' + }] + }, { + type: 'setAgps', + parameters: [{ + key: 'enable', + name: Strings.commandEnable, + valueType: 'boolean' + }] + }, { + type: 'setIndicator', + parameters: [{ + key: 'data', + name: Strings.commandData, + valueType: 'string' + }] + }, { + type: 'configuration', + parameters: [{ + key: 'data', + name: Strings.commandData, + valueType: 'string' + }] + }, { + type: 'setConnection', + parameters: [{ + key: 'server', + name: Strings.commandServer, + valueType: 'string' + }, { + key: 'port', + name: Strings.commandPort, + valueType: 'number', + allowDecimals: false, + minValue: 1, + maxValue: 65535 + }] + }, { + type: 'setOdometer', + parameters: [{ + key: 'data', + name: Strings.commandData, + valueType: 'string' + }] + }, { + type: 'modePowerSaving', + parameters: [{ + key: 'enable', + name: Strings.commandEnable, + valueType: 'boolean' + }] + }, { + type: 'modeDeepSleep', + parameters: [{ + key: 'enable', + name: Strings.commandEnable, + valueType: 'boolean' + }] + }, { + type: 'movementAlarm', + parameters: [{ + key: 'radius', + name: Strings.commandRadius, + valueType: 'number', + allowDecimals: false, + minValue: 0 + }] + }, { + type: 'alarmBattery', + parameters: [{ + key: 'enable', + name: Strings.commandEnable, + valueType: 'boolean' + }] + }, { + type: 'alarmSos', + parameters: [{ + key: 'enable', + name: Strings.commandEnable, + valueType: 'boolean' + }] + }, { + type: 'alarmRemove', + parameters: [{ + key: 'enable', + name: Strings.commandEnable, + valueType: 'boolean' + }] + }, { + type: 'alarmClock', + parameters: [{ + key: 'data', + name: Strings.commandData, + valueType: 'string' + }] + }, { + type: 'alarmSpeed', + parameters: [{ + key: 'data', + name: Strings.commandData, + valueType: 'string' + }] + }, { + type: 'alarmFall', + parameters: [{ + key: 'enable', + name: Strings.commandEnable, + valueType: 'boolean' + }] + }, { + type: 'alarmVibration', + parameters: [{ + key: 'data', + name: Strings.commandData, + valueType: 'string' + }] + }] +}); diff --git a/web/app/store/TimeUnits.js b/web/app/store/TimeUnits.js index efcf1d66..0d16c4bb 100644 --- a/web/app/store/TimeUnits.js +++ b/web/app/store/TimeUnits.js @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,16 +17,28 @@ Ext.define('Traccar.store.TimeUnits', { extend: 'Ext.data.Store', - fields: ['name', 'factor'], + fields: ['key', 'name', 'factor'], data: [{ - name: Strings.sharedSecond, + key: 's', + name: Strings.sharedSecondAbbreviation, factor: 1 }, { - name: Strings.sharedMinute, + key: 'm', + name: Strings.sharedMinuteAbbreviation, factor: 60 }, { - name: Strings.sharedHour, + key: 'h', + name: Strings.sharedHourAbbreviation, factor: 3600 - }] + }], + + convertValue: function (value, unit, back) { + var model; + if (!unit) { + unit = 'kn'; + } + model = this.findRecord('key', unit); + return back ? value * model.get('factor') : value / model.get('factor'); + } }); diff --git a/web/app/view/CustomNumberField.js b/web/app/view/CustomNumberField.js index 887e5c9c..e8fe5f79 100644 --- a/web/app/view/CustomNumberField.js +++ b/web/app/view/CustomNumberField.js @@ -20,30 +20,79 @@ Ext.define('Traccar.view.CustomNumberField', { xtype: 'customNumberField', beforeEl: '<div style="width:100%;display:inline-table;">', - unitEl: '<div style="display:table-cell;padding-left:10px;vertical-align:middle;">', + unitEl: '<div id="numberUnitEl" style="display:table-cell;padding-left:10px;vertical-align:middle;width:1px;white-space:nowrap;">', constructor: function (config) { - var unit; - if (config.dataType === 'speed') { - unit = Traccar.app.getPreference('speedUnit', 'kn'); - config.beforeSubTpl = this.beforeEl; - config.afterSubTpl = this.unitEl + Ext.getStore('SpeedUnits').findRecord('key', unit).get('name') + '</div></div>'; + 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.getPreference('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.getPreference('distanceUnit', 'km'); + }; + unitName = Ext.getStore('DistanceUnits').findRecord('key', config.units.getValue()).get('name'); + break; + case 'frequency': + if (!config.listeners) { + config.listeners = {}; + } + config.listeners.afterrender = function () { + if (!this.units) { + this.units = Ext.create({ + xtype: 'combobox', + renderTo: 'numberUnitEl', + store: 'TimeUnits', + displayField: 'name', + valueField: 'key', + editable: false, + numberField: this, + value: 's', + width: '70px', + listeners: { + select: function () { + this.numberField.step = this.getStore().convertValue(1, this.getValue(), true); + } + } + }); + } + }; + break; + default: + break; + } + config.afterBodyEl = this.unitEl + unitName + '</div></div>'; config.rawToValue = function (rawValue) { - return Ext.getStore('SpeedUnits').convertValue(rawValue, Traccar.app.getPreference('speedUnit', 'kn'), true); + if (this.units) { + return this.units.getStore().convertValue(rawValue, this.units.getValue(), true); + } else { + return this.parseValue(rawValue); + } }; config.valueToRaw = function (value) { - return Ext.getStore('SpeedUnits').convertValue(value, Traccar.app.getPreference('speedUnit', 'kn')); - }; - } else if (config.dataType === 'distance') { - config.beforeSubTpl = this.beforeEl; - unit = Traccar.app.getPreference('distanceUnit', 'km'); - config.afterSubTpl = this.unitEl + Ext.getStore('DistanceUnits').findRecord('key', unit).get('name') + '</div></div>'; - config.rawToValue = function (rawValue) { - return Ext.getStore('DistanceUnits').convertValue(rawValue, Traccar.app.getPreference('distanceUnit', 'km'), true); - }; - config.valueToRaw = function (value) { - return Ext.getStore('DistanceUnits').convertValue(value, Traccar.app.getPreference('distanceUnit', 'km')); + if (this.units) { + return this.units.getStore().convertValue(value, this.units.getValue(), false); + } else { + return this.parseValue(value); + } }; + if (config.units) { + config.step = config.units.getStore().convertValue(1, config.units.getValue(), true); + } } this.callParent(arguments); } diff --git a/web/app/view/dialog/Command.js b/web/app/view/dialog/Command.js index ec98b29f..ce5b75b8 100644 --- a/web/app/view/dialog/Command.js +++ b/web/app/view/dialog/Command.js @@ -27,6 +27,9 @@ Ext.define('Traccar.view.dialog.Command', { items: { xtype: 'form', + listeners: { + validitychange: 'onValidityChange' + }, items: [{ xtype: 'checkboxfield', name: 'textChannel', @@ -51,94 +54,13 @@ Ext.define('Traccar.view.dialog.Command', { } }, { xtype: 'fieldcontainer', - reference: 'paramPositionPeriodic', - name: 'attributes', - hidden: true, - - items: [{ - xtype: 'numberfield', - fieldLabel: Strings.commandFrequency, - name: 'frequency' - }, { - xtype: 'combobox', - fieldLabel: Strings.commandUnit, - name: 'unit', - store: 'TimeUnits', - displayField: 'name', - valueField: 'factor' - }] - }, { - xtype: 'fieldcontainer', - reference: 'paramOutputControl', - name: 'attributes', - hidden: true, - - items: [{ - xtype: 'numberfield', - fieldLabel: Strings.commandIndex, - name: 'index', - allowBlank: false - }, { - xtype: 'textfield', - fieldLabel: Strings.commandData, - name: 'data' - }] - }, { - xtype: 'fieldcontainer', - reference: 'paramSendSmsUssd', - name: 'attributes', - hidden: true, - - items: [{ - xtype: 'textfield', - fieldLabel: Strings.commandPhone, - name: 'phone' - }, { - xtype: 'textfield', - reference: 'paramSmsMessage', - fieldLabel: Strings.commandMessage, - name: 'message', - hidden: true - }] - }, { - xtype: 'fieldcontainer', - reference: 'paramSetTimezone', - name: 'attributes', - hidden: true, - - items: [{ - xtype: 'numberfield', - fieldLabel: Strings.commandTimezone, - name: 'timezone', - minValue: -12, - step: 0.5, - maxValue: +14 - }] - }, { - xtype: 'fieldcontainer', - reference: 'paramSetIndicator', - name: 'attributes', - hidden: true, - - items: [{ - xtype: 'numberfield', - fieldLabel: Strings.commandData, - name: 'data', - minValue: 0, - maxValue: 99 - }] - }, { - xtype: 'textfield', - reference: 'paramCustom', - fieldLabel: Strings.commandCustom, - name: 'customCommand', - hidden: true, - allowBlank: false + reference: 'parameters' }] }, buttons: [{ text: Strings.commandSend, + reference: 'sendButton', handler: 'onSendClick' }, { text: Strings.sharedCancel, diff --git a/web/app/view/dialog/CommandController.js b/web/app/view/dialog/CommandController.js index 3fdc7b0c..0687f670 100644 --- a/web/app/view/dialog/CommandController.js +++ b/web/app/view/dialog/CommandController.js @@ -19,88 +19,68 @@ Ext.define('Traccar.view.dialog.CommandController', { extend: 'Ext.app.ViewController', alias: 'controller.command', + defaultFieldConfig: { + allowBlank: false + }, + onSelect: function (selected) { - this.lookupReference('paramPositionPeriodic').setHidden( - selected.getValue() !== 'positionPeriodic'); - this.lookupReference('paramOutputControl').setHidden( - selected.getValue() !== 'outputControl'); - this.lookupReference('paramSendSmsUssd').setHidden( - selected.getValue() !== 'sendSms' && selected.getValue() !== 'sendUssd'); - this.lookupReference('paramSmsMessage').setHidden( - selected.getValue() !== 'sendSms'); - this.lookupReference('paramSetTimezone').setHidden( - selected.getValue() !== 'setTimezone'); - this.lookupReference('paramSetIndicator').setHidden( - selected.getValue() !== 'setIndicator'); - this.lookupReference('paramCustom').setHidden( - selected.getValue() !== 'custom'); + var i, config, command, parameters, parameter; + this.lookupReference('parameters').removeAll(); + command = Ext.getStore('KnownCommands').getById(selected.getValue()); + if (command && command.get('parameters')) { + parameters = command.get('parameters'); + for (i = 0; i < parameters.length; i++) { + parameter = new Traccar.model.KnownAttribute(parameters[i]); + config = Ext.clone(this.defaultFieldConfig); + config.key = parameter.get('key'); + config.fieldLabel = parameter.get('name'); + switch (parameter.get('valueType')) { + case 'number': + config.xtype = 'customNumberField'; + if (parameter.get('allowDecimals') !== undefined) { + config.allowDecimals = parameter.get('allowDecimals'); + } else { + config.allowDecimals = true; + } + config.dataType = parameter.get('dataType'); + config.maxValue = parameter.get('maxValue'); + config.minValue = parameter.get('minValue'); + break; + case 'boolean': + config.xtype = 'checkboxfield'; + config.inputValue = true; + config.uncheckedValue = false; + break; + default: + if (parameter.get('dataType') === 'timezone') { + config.xtype = 'combobox'; + config.queryMode = 'local'; + config.displayField = 'key'; + config.editable = false; + config.store = 'AllTimezones'; + } else { + config.xtype = 'textfield'; + } + } + this.lookupReference('parameters').add(config); + } + } }, onSendClick: function (button) { - var attributes, value, record, form, index, phone; + var i, record, form, parameters, attributes = {}; form = button.up('window').down('form'); form.updateRecord(); record = form.getRecord(); + parameters = this.lookupReference('parameters').items.items; - switch (record.get('type')) { - case 'positionPeriodic': - attributes = this.lookupReference('paramPositionPeriodic'); - value = attributes.down('numberfield[name="frequency"]').getValue(); - value *= attributes.down('combobox[name="unit"]').getValue(); - record.set('attributes', { - frequency: value - }); - break; - case 'outputControl': - attributes = this.lookupReference('paramOutputControl'); - index = attributes.down('numberfield[name="index"]').getValue(); - value = attributes.down('textfield[name="data"]').getValue(); - record.set('attributes', { - index: index, - data: value - }); - break; - case 'sendUssd': - attributes = this.lookupReference('paramSendSmsUssd'); - phone = attributes.down('textfield[name="phone"]').getValue(); - record.set('attributes', { - phone: phone - }); - break; - case 'sendSms': - attributes = this.lookupReference('paramSendSmsUssd'); - phone = attributes.down('textfield[name="phone"]').getValue(); - value = attributes.down('textfield[name="message"]').getValue(); - record.set('attributes', { - phone: phone, - message: value - }); - break; - case 'setTimezone': - attributes = this.lookupReference('paramSetTimezone'); - value = attributes.down('numberfield[name="timezone"]').getValue(); - record.set('attributes', { - timezone: value * 3600 - }); - break; - case 'setIndicator': - attributes = this.lookupReference('paramSetIndicator'); - value = attributes.down('numberfield[name="data"]').getValue(); - record.set('attributes', { - data: value - }); - break; - case 'custom': - value = this.lookupReference('paramCustom').getValue(); - record.set('attributes', { - data: value - }); - break; - default: - break; + for (i = 0; i < parameters.length; i++) { + attributes[parameters[i].key] = parameters[i].getValue(); } + record.set('attributes', attributes); + Ext.Ajax.request({ scope: this, url: 'api/commands', @@ -109,6 +89,10 @@ Ext.define('Traccar.view.dialog.CommandController', { }); }, + onValidityChange: function (form, valid) { + this.lookupReference('sendButton').setDisabled(!valid); + }, + onTextChannelChange: function (checkbox, newValue) { var typesStore = this.lookupReference('commandType').getStore(); typesStore.getProxy().setExtraParam('textChannel', newValue); diff --git a/web/l10n/en.json b/web/l10n/en.json index 3229064f..4ef3d380 100644 --- a/web/l10n/en.json +++ b/web/l10n/en.json @@ -39,6 +39,7 @@ "sharedDistance": "Distance", "sharedHourAbbreviation": "h", "sharedMinuteAbbreviation": "m", + "sharedSecondAbbreviation": "s", "sharedVoltAbbreviation": "V", "sharedLiterAbbreviation": "l", "sharedLiterPerHourAbbreviation": "l/h", @@ -273,11 +274,15 @@ "commandAlarmFall": "Fail Alarm", "commandAlarmVibration": "Vibration Alarm", "commandFrequency": "Frequency", - "commandIndex": "Index", + "commandTimezone": "Timezone Offset", + "commandMessage": "Message", + "commandRadius": "Radius", + "commandEnable": "Enable", "commandData": "Data", + "commandIndex": "Index", "commandPhone": "Phone Number", - "commandMessage": "Message", - "commandTimezone": "Timezone Offset", + "commandServer": "Server", + "commandPort": "Port", "eventAll": "All Events", "eventDeviceOnline": "Device is online", "eventDeviceUnknown": "Device status is unknown", |