aboutsummaryrefslogtreecommitdiff
path: root/web/app
diff options
context:
space:
mode:
authorAnton Tananaev <anton.tananaev@gmail.com>2017-09-05 21:41:29 +1200
committerGitHub <noreply@github.com>2017-09-05 21:41:29 +1200
commit6a87e86cee0cdbcc196166f3f1b330903364931b (patch)
treebf86c8ddb2b5d0edca73175be5e1ec2b69f33633 /web/app
parentca6b408cc068c1e21641d1464350beb1daef872e (diff)
parentb86c09cd3266b2bac9a7a8dbf848ed14fff1e6d7 (diff)
downloadtrackermap-web-6a87e86cee0cdbcc196166f3f1b330903364931b.tar.gz
trackermap-web-6a87e86cee0cdbcc196166f3f1b330903364931b.tar.bz2
trackermap-web-6a87e86cee0cdbcc196166f3f1b330903364931b.zip
Merge pull request #571 from Abyss777/improve_commands
Improve commands
Diffstat (limited to 'web/app')
-rw-r--r--web/app/Application.js6
-rw-r--r--web/app/model/KnownCommand.js35
-rw-r--r--web/app/store/CommandTypes.js19
-rw-r--r--web/app/store/KnownCommands.js234
-rw-r--r--web/app/store/TimeUnits.js24
-rw-r--r--web/app/view/CustomNumberField.js85
-rw-r--r--web/app/view/dialog/Command.js88
-rw-r--r--web/app/view/dialog/CommandController.js126
8 files changed, 419 insertions, 198 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);