aboutsummaryrefslogtreecommitdiff
path: root/web/app/view/edit
diff options
context:
space:
mode:
Diffstat (limited to 'web/app/view/edit')
-rw-r--r--web/app/view/edit/AttributeAliases.js65
-rw-r--r--web/app/view/edit/AttributeAliasesController.js79
-rw-r--r--web/app/view/edit/Attributes.js50
-rw-r--r--web/app/view/edit/AttributesController.js75
-rw-r--r--web/app/view/edit/Calendars.js49
-rw-r--r--web/app/view/edit/CalendarsController.js32
-rw-r--r--web/app/view/edit/Devices.js164
-rw-r--r--web/app/view/edit/DevicesController.js135
-rw-r--r--web/app/view/edit/Geofences.js51
-rw-r--r--web/app/view/edit/GeofencesController.js30
-rw-r--r--web/app/view/edit/Groups.js57
-rw-r--r--web/app/view/edit/GroupsController.js55
-rw-r--r--web/app/view/edit/Toolbar.js49
-rw-r--r--web/app/view/edit/ToolbarController.js70
-rw-r--r--web/app/view/edit/Users.js118
-rw-r--r--web/app/view/edit/UsersController.js168
16 files changed, 1247 insertions, 0 deletions
diff --git a/web/app/view/edit/AttributeAliases.js b/web/app/view/edit/AttributeAliases.js
new file mode 100644
index 0000000..6e11016
--- /dev/null
+++ b/web/app/view/edit/AttributeAliases.js
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@traccar.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+Ext.define('Traccar.view.edit.AttributeAliases', {
+ extend: 'Ext.grid.Panel',
+ xtype: 'attributeAliasesView',
+
+ requires: [
+ 'Traccar.view.edit.AttributeAliasesController',
+ 'Traccar.view.edit.Toolbar'
+ ],
+
+ controller: 'attributeAliases',
+
+ tbar: {
+ xtype: 'editToolbar',
+ items: ['-', {
+ xtype: 'tbtext',
+ html: Strings.sharedDevice
+ }, {
+ xtype: 'combobox',
+ reference: 'deviceField',
+ store: 'Devices',
+ displayField: 'name',
+ valueField: 'id',
+ editable: false,
+ listeners: {
+ change: 'onDeviceChange'
+ }
+ }]
+ },
+
+ listeners: {
+ selectionchange: 'onSelectionChange'
+ },
+
+ columns: {
+ defaults: {
+ flex: 1,
+ minWidth: Traccar.Style.columnWidthNormal
+ },
+ items: [{
+ text: Strings.sharedAttribute,
+ dataIndex: 'attribute'
+ }, {
+ text: Strings.sharedAlias,
+ dataIndex: 'alias'
+ }]
+ }
+});
diff --git a/web/app/view/edit/AttributeAliasesController.js b/web/app/view/edit/AttributeAliasesController.js
new file mode 100644
index 0000000..fc2b57f
--- /dev/null
+++ b/web/app/view/edit/AttributeAliasesController.js
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@traccar.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+Ext.define('Traccar.view.edit.AttributeAliasesController', {
+ extend: 'Traccar.view.edit.ToolbarController',
+ alias: 'controller.attributeAliases',
+
+ requires: [
+ 'Traccar.view.dialog.AttributeAlias',
+ 'Traccar.model.AttributeAlias'
+ ],
+
+ objectModel: 'Traccar.model.AttributeAlias',
+ objectDialog: 'Traccar.view.dialog.AttributeAlias',
+ removeTitle: Strings.sharedAttributeAlias,
+
+ init: function () {
+ var manager = Traccar.app.getUser().get('admin') || Traccar.app.getUser().get('userLimit') > 0;
+ this.lookupReference('deviceField').setStore(manager ? 'AllDevices' : 'Devices');
+ this.lookupReference('toolbarAddButton').setDisabled(true);
+ this.lookupReference('toolbarEditButton').setDisabled(true);
+ this.lookupReference('toolbarRemoveButton').setDisabled(true);
+ this.getView().setStore(Ext.create('Ext.data.ChainedStore', {
+ storeId: 'EditorAttributeAliases',
+ source: 'AttributeAliases'
+ }));
+ this.getView().getStore().filter('deviceId', 0);
+ },
+
+ onAddClick: function () {
+ var attributeAlias, dialog, deviceId;
+ attributeAlias = Ext.create('Traccar.model.AttributeAlias');
+ attributeAlias.store = Ext.getStore('AttributeAliases');
+ deviceId = this.lookupReference('deviceField').getValue();
+ attributeAlias.set('deviceId', deviceId);
+ dialog = Ext.create('Traccar.view.dialog.AttributeAlias');
+ dialog.down('form').loadRecord(attributeAlias);
+ dialog.show();
+ },
+
+ onSelectionChange: function (selected) {
+ var disabled = !this.lookupReference('deviceField').getValue();
+ this.lookupReference('toolbarAddButton').setDisabled(disabled);
+ disabled = selected.length === 0 || !this.lookupReference('deviceField').getValue();
+ this.lookupReference('toolbarEditButton').setDisabled(disabled);
+ this.lookupReference('toolbarRemoveButton').setDisabled(disabled);
+ },
+
+ onDeviceChange: function (combobox, newValue, oldValue) {
+ var manager = Traccar.app.getUser().get('admin') || Traccar.app.getUser().get('userLimit') > 0;
+ this.onSelectionChange('');
+ if (newValue !== null) {
+ this.getView().getStore().filter('deviceId', newValue);
+ if (manager && this.getView().getStore().getCount() === 0) {
+ Ext.getStore('AttributeAliases').getProxy().setExtraParam('deviceId', newValue);
+ Ext.getStore('AttributeAliases').load({
+ addRecords: true
+ });
+ }
+ } else {
+ this.getView().getStore().filter('deviceId', 0);
+ }
+ }
+});
diff --git a/web/app/view/edit/Attributes.js b/web/app/view/edit/Attributes.js
new file mode 100644
index 0000000..93e5a3a
--- /dev/null
+++ b/web/app/view/edit/Attributes.js
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+Ext.define('Traccar.view.edit.Attributes', {
+ extend: 'Ext.grid.Panel',
+ xtype: 'attributesView',
+
+ requires: [
+ 'Traccar.view.edit.AttributesController',
+ 'Traccar.view.edit.Toolbar'
+ ],
+
+ controller: 'attributes',
+
+ tbar: {
+ xtype: 'editToolbar'
+ },
+
+ listeners: {
+ selectionchange: 'onSelectionChange'
+ },
+
+ columns: {
+ defaults: {
+ flex: 1,
+ minWidth: Traccar.Style.columnWidthNormal
+ },
+ items: [{
+ text: Strings.sharedName,
+ dataIndex: 'name'
+ }, {
+ text: Strings.stateValue,
+ dataIndex: 'value'
+ }]
+ }
+});
diff --git a/web/app/view/edit/AttributesController.js b/web/app/view/edit/AttributesController.js
new file mode 100644
index 0000000..1ae32c7
--- /dev/null
+++ b/web/app/view/edit/AttributesController.js
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+Ext.define('Traccar.view.edit.AttributesController', {
+ extend: 'Traccar.view.edit.ToolbarController',
+ alias: 'controller.attributes',
+
+ requires: [
+ 'Traccar.view.dialog.Attribute',
+ 'Traccar.store.Attributes',
+ 'Traccar.model.Attribute'
+ ],
+
+ objectModel: 'Traccar.model.Attribute',
+ objectDialog: 'Traccar.view.dialog.Attribute',
+ removeTitle: Strings.stateName,
+
+ init: function () {
+ var store, propertyName, i = 0, attributes;
+ store = Ext.create('Traccar.store.Attributes');
+ store.setProxy(Ext.create('Ext.data.proxy.Memory'));
+ if (typeof this.getView().record.get('attributes') === 'undefined') {
+ this.getView().record.set('attributes', {});
+ }
+ attributes = this.getView().record.get('attributes');
+ for (propertyName in attributes) {
+ if (attributes.hasOwnProperty(propertyName)) {
+ store.add(Ext.create('Traccar.model.Attribute', {
+ priority: i++,
+ name: propertyName,
+ value: this.getView().record.get('attributes')[propertyName]
+ }));
+ }
+ }
+ store.addListener('add', function (store, records, index, eOpts) {
+ var i;
+ for (i = 0; i < records.length; i++) {
+ this.getView().record.get('attributes')[records[i].get('name')] = records[i].get('value');
+ }
+ this.getView().record.dirty = true;
+ }, this);
+ store.addListener('update', function (store, record, operation, modifiedFieldNames, details, eOpts) {
+ if (operation === Ext.data.Model.EDIT) {
+ if (record.modified.name !== record.get('name')) {
+ delete this.getView().record.get('attributes')[record.modified.name];
+ }
+ this.getView().record.get('attributes')[record.get('name')] = record.get('value');
+ this.getView().record.dirty = true;
+ }
+ }, this);
+ store.addListener('remove', function (store, records, index, isMove, eOpts) {
+ var i;
+ for (i = 0; i < records.length; i++) {
+ delete this.getView().record.get('attributes')[records[i].get('name')];
+ }
+ this.getView().record.dirty = true;
+ }, this);
+
+ this.getView().setStore(store);
+ }
+});
diff --git a/web/app/view/edit/Calendars.js b/web/app/view/edit/Calendars.js
new file mode 100644
index 0000000..92ffa06
--- /dev/null
+++ b/web/app/view/edit/Calendars.js
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@traccar.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+Ext.define('Traccar.view.edit.Calendars', {
+ extend: 'Ext.grid.Panel',
+ xtype: 'calendarsView',
+
+ requires: [
+ 'Traccar.view.edit.CalendarsController',
+ 'Traccar.view.edit.Toolbar'
+ ],
+
+ controller: 'calendars',
+ store: 'Calendars',
+
+ tbar: {
+ xtype: 'editToolbar'
+ },
+
+ listeners: {
+ selectionchange: 'onSelectionChange'
+ },
+
+ columns: {
+ defaults: {
+ flex: 1,
+ minWidth: Traccar.Style.columnWidthNormal
+ },
+ items: [{
+ text: Strings.sharedName,
+ dataIndex: 'name'
+ }]
+ }
+});
diff --git a/web/app/view/edit/CalendarsController.js b/web/app/view/edit/CalendarsController.js
new file mode 100644
index 0000000..f582227
--- /dev/null
+++ b/web/app/view/edit/CalendarsController.js
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@traccar.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+Ext.define('Traccar.view.edit.CalendarsController', {
+ extend: 'Traccar.view.edit.ToolbarController',
+ alias: 'controller.calendars',
+
+ requires: [
+ 'Traccar.view.dialog.Calendar',
+ 'Traccar.model.Calendar'
+ ],
+
+ objectModel: 'Traccar.model.Calendar',
+ objectDialog: 'Traccar.view.dialog.Calendar',
+ removeTitle: Strings.sharedCalendar
+
+});
diff --git a/web/app/view/edit/Devices.js b/web/app/view/edit/Devices.js
new file mode 100644
index 0000000..d4970eb
--- /dev/null
+++ b/web/app/view/edit/Devices.js
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+Ext.define('Traccar.view.edit.Devices', {
+ extend: 'Ext.grid.Panel',
+ xtype: 'devicesView',
+
+ requires: [
+ 'Ext.grid.filters.Filters',
+ 'Traccar.view.edit.DevicesController'
+ ],
+
+ controller: 'devices',
+
+ plugins: 'gridfilters',
+
+ store: 'VisibleDevices',
+
+ stateful: true,
+ stateId: 'devices-grid',
+
+ tbar: {
+ componentCls: 'toolbar-header-style',
+ items: [{
+ xtype: 'tbtext',
+ html: Strings.deviceTitle,
+ baseCls: 'x-panel-header-title-default'
+ }, {
+ xtype: 'tbfill'
+ }, {
+ xtype: 'button',
+ disabled: true,
+ handler: 'onAddClick',
+ reference: 'toolbarAddButton',
+ glyph: 'xf067@FontAwesome',
+ tooltip: Strings.sharedAdd,
+ tooltipType: 'title'
+ }, {
+ xtype: 'button',
+ disabled: true,
+ handler: 'onEditClick',
+ reference: 'toolbarEditButton',
+ glyph: 'xf040@FontAwesome',
+ tooltip: Strings.sharedEdit,
+ tooltipType: 'title'
+ }, {
+ xtype: 'button',
+ disabled: true,
+ handler: 'onRemoveClick',
+ reference: 'toolbarRemoveButton',
+ glyph: 'xf00d@FontAwesome',
+ tooltip: Strings.sharedRemove,
+ tooltipType: 'title'
+ }, {
+ xtype: 'button',
+ disabled: true,
+ handler: 'onGeofencesClick',
+ reference: 'toolbarGeofencesButton',
+ glyph: 'xf21d@FontAwesome',
+ tooltip: Strings.sharedGeofences,
+ tooltipType: 'title'
+ }, {
+ disabled: true,
+ handler: 'onCommandClick',
+ reference: 'deviceCommandButton',
+ glyph: 'xf093@FontAwesome',
+ tooltip: Strings.deviceCommand,
+ tooltipType: 'title'
+ }]
+ },
+
+ listeners: {
+ selectionchange: 'onSelectionChange'
+ },
+
+ columns: {
+ defaults: {
+ flex: 2,
+ minWidth: Traccar.Style.columnWidthNormal
+ },
+ items: [{
+ text: Strings.sharedName,
+ dataIndex: 'name',
+ filter: 'string'
+ }, {
+ text: Strings.deviceIdentifier,
+ dataIndex: 'uniqueId',
+ hidden: true
+ }, {
+ text: Strings.sharedPhone,
+ dataIndex: 'phone',
+ hidden: true
+ }, {
+ text: Strings.deviceModel,
+ dataIndex: 'model',
+ hidden: true
+ }, {
+ text: Strings.deviceContact,
+ dataIndex: 'contact',
+ hidden: true
+ }, {
+ text: Strings.groupDialog,
+ dataIndex: 'groupId',
+ hidden: true,
+ filter: {
+ type: 'list',
+ labelField: 'name',
+ store: 'Groups'
+ },
+ renderer: function (value) {
+ var group;
+ if (value !== 0) {
+ group = Ext.getStore('Groups').getById(value);
+ return group ? group.get('name') : value;
+ }
+ }
+ }, {
+ text: Strings.deviceLastUpdate,
+ dataIndex: 'lastUpdate',
+ renderer: function (value) {
+ if (value) {
+ if (Traccar.app.getPreference('twelveHourFormat', false)) {
+ return Ext.Date.format(value, Traccar.Style.dateTimeFormat12);
+ } else {
+ return Ext.Date.format(value, Traccar.Style.dateTimeFormat24);
+ }
+ }
+ }
+ }, {
+ text: Strings.deviceStatus,
+ dataIndex: 'status',
+ flex: 1,
+ filter: {
+ type: 'list',
+ labelField: 'name',
+ store: 'DeviceStatuses'
+ },
+ renderer: function (value, metaData) {
+ var status;
+ if (value) {
+ status = Ext.getStore('DeviceStatuses').getById(value);
+ if (status) {
+ metaData.tdCls = status.get('color');
+ return status.get('name');
+ }
+ }
+ }
+ }]
+ }
+});
diff --git a/web/app/view/edit/DevicesController.js b/web/app/view/edit/DevicesController.js
new file mode 100644
index 0000000..895f0fb
--- /dev/null
+++ b/web/app/view/edit/DevicesController.js
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+Ext.define('Traccar.view.edit.DevicesController', {
+ extend: 'Traccar.view.edit.ToolbarController',
+ alias: 'controller.devices',
+
+ requires: [
+ 'Traccar.view.dialog.Command',
+ 'Traccar.view.dialog.Device',
+ 'Traccar.view.permissions.DeviceGeofences',
+ 'Traccar.view.BaseWindow',
+ 'Traccar.model.Device',
+ 'Traccar.model.Command'
+ ],
+
+ config: {
+ listen: {
+ controller: {
+ '*': {
+ selectreport: 'selectReport'
+ },
+ 'map': {
+ selectdevice: 'selectDevice',
+ deselectfeature: 'deselectFeature'
+ }
+ },
+ store: {
+ '#Devices': {
+ update: 'onUpdateDevice'
+ }
+ }
+ }
+ },
+
+ objectModel: 'Traccar.model.Device',
+ objectDialog: 'Traccar.view.dialog.Device',
+ removeTitle: Strings.sharedDevice,
+
+ init: function () {
+ var readonly, deviceReadonly;
+ deviceReadonly = Traccar.app.getPreference('deviceReadonly', false) && !Traccar.app.getUser().get('admin');
+ readonly = Traccar.app.getPreference('readonly', false) && !Traccar.app.getUser().get('admin');
+ this.lookupReference('toolbarAddButton').setDisabled(readonly || deviceReadonly);
+ },
+
+ onGeofencesClick: function () {
+ var device = this.getView().getSelectionModel().getSelection()[0];
+ Ext.create('Traccar.view.BaseWindow', {
+ title: Strings.sharedGeofences,
+ items: {
+ xtype: 'deviceGeofencesView',
+ baseObjectName: 'deviceId',
+ linkObjectName: 'geofenceId',
+ storeName: 'Geofences',
+ urlApi: 'api/devices/geofences',
+ baseObject: device.getId()
+ }
+ }).show();
+ },
+
+ onCommandClick: function () {
+ var device, deviceId, command, dialog, typesStore, online;
+ device = this.getView().getSelectionModel().getSelection()[0];
+ online = device.get('status') === 'online';
+ deviceId = device.get('id');
+
+ command = Ext.create('Traccar.model.Command');
+ command.set('deviceId', deviceId);
+ command.set('textChannel', !online);
+
+ dialog = Ext.create('Traccar.view.dialog.Command');
+
+ typesStore = dialog.lookupReference('commandType').getStore();
+ typesStore.getProxy().setExtraParam('deviceId', deviceId);
+
+ dialog.down('form').loadRecord(command);
+ dialog.lookupReference('textChannelCheckBox').setDisabled(!online);
+ dialog.show();
+ },
+
+ updateButtons: function (selected) {
+ var readonly, deviceReadonly, empty;
+ deviceReadonly = Traccar.app.getPreference('deviceReadonly', false) && !Traccar.app.getUser().get('admin');
+ readonly = Traccar.app.getPreference('readonly', false) && !Traccar.app.getUser().get('admin');
+ empty = selected.getCount() === 0;
+ this.lookupReference('toolbarEditButton').setDisabled(empty || readonly || deviceReadonly);
+ this.lookupReference('toolbarRemoveButton').setDisabled(empty || readonly || deviceReadonly);
+ this.lookupReference('toolbarGeofencesButton').setDisabled(empty || readonly);
+ this.lookupReference('deviceCommandButton').setDisabled(empty || readonly);
+ },
+
+ onSelectionChange: function (selected) {
+ this.updateButtons(selected);
+ if (selected.getCount() > 0) {
+ this.fireEvent('selectdevice', selected.getLastSelected(), true);
+ } else {
+ this.fireEvent('deselectfeature');
+ }
+ },
+
+ selectDevice: function (device, center) {
+ this.getView().getSelectionModel().select([device], false, true);
+ this.updateButtons(this.getView().getSelectionModel());
+ this.getView().getView().focusRow(device);
+ },
+
+ selectReport: function (position) {
+ if (position !== undefined) {
+ this.deselectFeature();
+ }
+ },
+
+ onUpdateDevice: function (store, data) {
+ this.updateButtons(this.getView().getSelectionModel());
+ },
+
+ deselectFeature: function () {
+ this.getView().getSelectionModel().deselectAll();
+ }
+});
diff --git a/web/app/view/edit/Geofences.js b/web/app/view/edit/Geofences.js
new file mode 100644
index 0000000..8ca9c31
--- /dev/null
+++ b/web/app/view/edit/Geofences.js
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2016 Anton Tananaev (anton@traccar.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+Ext.define('Traccar.view.edit.Geofences', {
+ extend: 'Ext.grid.Panel',
+ xtype: 'geofencesView',
+
+ requires: [
+ 'Traccar.view.edit.GeofencesController',
+ 'Traccar.view.edit.Toolbar'
+ ],
+
+ controller: 'geofences',
+ store: 'Geofences',
+
+ tbar: {
+ xtype: 'editToolbar'
+ },
+
+ listeners: {
+ selectionchange: 'onSelectionChange'
+ },
+
+ columns: {
+ defaults: {
+ flex: 1,
+ minWidth: Traccar.Style.columnWidthNormal
+ },
+ items: [{
+ text: Strings.sharedName,
+ dataIndex: 'name'
+ }, {
+ text: Strings.sharedDescription,
+ dataIndex: 'description'
+ }]
+ }
+});
diff --git a/web/app/view/edit/GeofencesController.js b/web/app/view/edit/GeofencesController.js
new file mode 100644
index 0000000..73d367a
--- /dev/null
+++ b/web/app/view/edit/GeofencesController.js
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+Ext.define('Traccar.view.edit.GeofencesController', {
+ extend: 'Traccar.view.edit.ToolbarController',
+ alias: 'controller.geofences',
+
+ requires: [
+ 'Traccar.view.dialog.Geofence',
+ 'Traccar.model.Geofence'
+ ],
+
+ objectModel: 'Traccar.model.Geofence',
+ objectDialog: 'Traccar.view.dialog.Geofence',
+ removeTitle: Strings.sharedGeofence
+});
diff --git a/web/app/view/edit/Groups.js b/web/app/view/edit/Groups.js
new file mode 100644
index 0000000..43ae877
--- /dev/null
+++ b/web/app/view/edit/Groups.js
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+Ext.define('Traccar.view.edit.Groups', {
+ extend: 'Ext.grid.Panel',
+ xtype: 'groupsView',
+
+ requires: [
+ 'Traccar.view.edit.GroupsController',
+ 'Traccar.view.edit.Toolbar'
+ ],
+
+ controller: 'groups',
+ store: 'Groups',
+
+ tbar: {
+ xtype: 'editToolbar',
+ items: [{
+ xtype: 'button',
+ disabled: true,
+ handler: 'onGeofencesClick',
+ reference: 'toolbarGeofencesButton',
+ glyph: 'xf21d@FontAwesome',
+ tooltip: Strings.sharedGeofences,
+ tooltipType: 'title'
+ }]
+ },
+
+ listeners: {
+ selectionchange: 'onSelectionChange'
+ },
+
+ columns: {
+ defaults: {
+ flex: 1,
+ minWidth: Traccar.Style.columnWidthNormal
+ },
+ items: [{
+ text: Strings.sharedName,
+ dataIndex: 'name'
+ }]
+ }
+});
diff --git a/web/app/view/edit/GroupsController.js b/web/app/view/edit/GroupsController.js
new file mode 100644
index 0000000..36154b4
--- /dev/null
+++ b/web/app/view/edit/GroupsController.js
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+Ext.define('Traccar.view.edit.GroupsController', {
+ extend: 'Traccar.view.edit.ToolbarController',
+ alias: 'controller.groups',
+
+ requires: [
+ 'Traccar.view.dialog.Group',
+ 'Traccar.view.permissions.GroupGeofences',
+ 'Traccar.view.BaseWindow',
+ 'Traccar.model.Group'
+ ],
+
+ objectModel: 'Traccar.model.Group',
+ objectDialog: 'Traccar.view.dialog.Group',
+ removeTitle: Strings.groupDialog,
+
+ onGeofencesClick: function () {
+ var admin, group;
+ admin = Traccar.app.getUser().get('admin');
+ group = this.getView().getSelectionModel().getSelection()[0];
+ Ext.create('Traccar.view.BaseWindow', {
+ title: Strings.sharedGeofences,
+ items: {
+ xtype: 'groupGeofencesView',
+ baseObjectName: 'groupId',
+ linkObjectName: 'geofenceId',
+ storeName: admin ? 'AllGeofences' : 'Geofences',
+ urlApi: 'api/groups/geofences',
+ baseObject: group.getId()
+ }
+ }).show();
+ },
+
+ onSelectionChange: function (selected) {
+ var disabled = selected.length > 0;
+ this.lookupReference('toolbarGeofencesButton').setDisabled(disabled);
+ this.callParent(arguments);
+ }
+});
diff --git a/web/app/view/edit/Toolbar.js b/web/app/view/edit/Toolbar.js
new file mode 100644
index 0000000..6999030
--- /dev/null
+++ b/web/app/view/edit/Toolbar.js
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+Ext.define('Traccar.view.edit.Toolbar', {
+ extend: 'Ext.toolbar.Toolbar',
+ xtype: 'editToolbar',
+
+ initComponent: function () {
+ this.callParent(arguments);
+ this.add(0, [{
+ xtype: 'button',
+ handler: 'onAddClick',
+ reference: 'toolbarAddButton',
+ glyph: 'xf067@FontAwesome',
+ tooltip: Strings.sharedAdd,
+ tooltipType: 'title'
+ }, {
+ xtype: 'button',
+ disabled: true,
+ handler: 'onEditClick',
+ reference: 'toolbarEditButton',
+ glyph: 'xf040@FontAwesome',
+ tooltip: Strings.sharedEdit,
+ tooltipType: 'title'
+ }, {
+ xtype: 'button',
+ disabled: true,
+ handler: 'onRemoveClick',
+ reference: 'toolbarRemoveButton',
+ glyph: 'xf00d@FontAwesome',
+ tooltip: Strings.sharedRemove,
+ tooltipType: 'title'
+ }]);
+ }
+});
diff --git a/web/app/view/edit/ToolbarController.js b/web/app/view/edit/ToolbarController.js
new file mode 100644
index 0000000..fdbaa7e
--- /dev/null
+++ b/web/app/view/edit/ToolbarController.js
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+Ext.define('Traccar.view.edit.ToolbarController', {
+ extend: 'Ext.app.ViewController',
+ alias: 'controller.toolbarController',
+
+ onAddClick: function () {
+ var dialog, objectInstance = Ext.create(this.objectModel);
+ objectInstance.store = this.getView().getStore();
+ if (objectInstance.store instanceof Ext.data.ChainedStore) {
+ objectInstance.store = objectInstance.store.getSource();
+ }
+ dialog = Ext.create(this.objectDialog);
+ dialog.down('form').loadRecord(objectInstance);
+ dialog.show();
+ },
+
+ onEditClick: function () {
+ var dialog, objectInstance = this.getView().getSelectionModel().getSelection()[0];
+ dialog = Ext.create(this.objectDialog);
+ dialog.down('form').loadRecord(objectInstance);
+ dialog.show();
+ },
+
+ onRemoveClick: function () {
+ var objectInstance = this.getView().getSelectionModel().getSelection()[0];
+ Ext.Msg.show({
+ title: this.removeTitle,
+ message: Strings.sharedRemoveConfirm,
+ buttons: Ext.Msg.YESNO,
+ buttonText: {
+ yes: Strings.sharedRemove,
+ no: Strings.sharedCancel
+ },
+ fn: function (btn) {
+ var store = objectInstance.store;
+ if (btn === 'yes') {
+ store.remove(objectInstance);
+ store.sync({
+ failure: function (batch) {
+ store.rejectChanges();
+ Traccar.app.showError(batch.exceptions[0].getError().response);
+ }
+ });
+ }
+ }
+ });
+ },
+
+ onSelectionChange: function (selected) {
+ var disabled = selected.length > 0;
+ this.lookupReference('toolbarEditButton').setDisabled(disabled);
+ this.lookupReference('toolbarRemoveButton').setDisabled(disabled);
+ }
+});
diff --git a/web/app/view/edit/Users.js b/web/app/view/edit/Users.js
new file mode 100644
index 0000000..312ebe2
--- /dev/null
+++ b/web/app/view/edit/Users.js
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@traccar.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+Ext.define('Traccar.view.edit.Users', {
+ extend: 'Ext.grid.Panel',
+ xtype: 'usersView',
+
+ requires: [
+ 'Ext.grid.filters.Filters',
+ 'Traccar.view.edit.UsersController',
+ 'Traccar.view.edit.Toolbar'
+ ],
+
+ controller: 'users',
+ store: 'Users',
+
+ plugins: 'gridfilters',
+
+ tbar: {
+ xtype: 'editToolbar',
+ items: [{
+ disabled: true,
+ handler: 'onGeofencesClick',
+ reference: 'userGeofencesButton',
+ glyph: 'xf21d@FontAwesome',
+ tooltip: Strings.sharedGeofences,
+ tooltipType: 'title'
+ }, {
+ disabled: true,
+ handler: 'onDevicesClick',
+ reference: 'userDevicesButton',
+ glyph: 'xf248@FontAwesome',
+ tooltip: Strings.deviceTitle,
+ tooltipType: 'title'
+ }, {
+ disabled: true,
+ handler: 'onGroupsClick',
+ reference: 'userGroupsButton',
+ glyph: 'xf247@FontAwesome',
+ tooltip: Strings.settingsGroups,
+ tooltipType: 'title'
+ }, {
+ disabled: true,
+ handler: 'onUsersClick',
+ reference: 'userUsersButton',
+ glyph: 'xf0c0@FontAwesome',
+ tooltip: Strings.settingsUsers,
+ tooltipType: 'title'
+ }, {
+ disabled: true,
+ handler: 'onNotificationsClick',
+ reference: 'userNotificationsButton',
+ glyph: 'xf003@FontAwesome',
+ tooltip: Strings.sharedNotifications,
+ tooltipType: 'title'
+ }, {
+ disabled: true,
+ handler: 'onCalendarsClick',
+ reference: 'userCalendarsButton',
+ glyph: 'xf073@FontAwesome',
+ tooltip: Strings.sharedCalendars,
+ tooltipType: 'title'
+ }]
+ },
+
+ listeners: {
+ selectionchange: 'onSelectionChange'
+ },
+
+ columns: {
+ defaults: {
+ flex: 1,
+ minWidth: Traccar.Style.columnWidthNormal
+ },
+ items: [{
+ text: Strings.sharedName,
+ dataIndex: 'name'
+ }, {
+ text: Strings.userEmail,
+ dataIndex: 'email',
+ filter: 'string'
+ }, {
+ text: Strings.userAdmin,
+ dataIndex: 'admin'
+ }, {
+ text: Strings.serverReadonly,
+ dataIndex: 'readonly',
+ hidden: true
+ }, {
+ text: Strings.userDeviceReadonly,
+ dataIndex: 'deviceReadonly',
+ hidden: true
+ }, {
+ text: Strings.userDisabled,
+ dataIndex: 'disabled'
+ }, {
+ text: Strings.userExpirationTime,
+ dataIndex: 'expirationTime',
+ hidden: true,
+ renderer: Traccar.AttributeFormatter.getFormatter('expirationTime')
+ }]
+ }
+});
diff --git a/web/app/view/edit/UsersController.js b/web/app/view/edit/UsersController.js
new file mode 100644
index 0000000..88f39fb
--- /dev/null
+++ b/web/app/view/edit/UsersController.js
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@traccar.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+Ext.define('Traccar.view.edit.UsersController', {
+ extend: 'Traccar.view.edit.ToolbarController',
+ alias: 'controller.users',
+
+ requires: [
+ 'Traccar.view.dialog.User',
+ 'Traccar.view.permissions.UserDevices',
+ 'Traccar.view.permissions.UserGroups',
+ 'Traccar.view.permissions.UserGeofences',
+ 'Traccar.view.permissions.UserCalendars',
+ 'Traccar.view.permissions.UserUsers',
+ 'Traccar.view.Notifications',
+ 'Traccar.view.BaseWindow',
+ 'Traccar.model.User'
+ ],
+
+ objectModel: 'Traccar.model.User',
+ objectDialog: 'Traccar.view.dialog.User',
+ removeTitle: Strings.settingsUser,
+
+ init: function () {
+ Ext.getStore('Users').load();
+ this.lookupReference('userUsersButton').setHidden(!Traccar.app.getUser().get('admin'));
+ },
+
+ onEditClick: function () {
+ var dialog, user = this.getView().getSelectionModel().getSelection()[0];
+ dialog = Ext.create('Traccar.view.dialog.User', {
+ selfEdit: user.get('id') === Traccar.app.getUser().get('id')
+ });
+ dialog.down('form').loadRecord(user);
+ dialog.show();
+ },
+
+ onAddClick: function () {
+ var user, dialog;
+ user = Ext.create('Traccar.model.User');
+ if (Traccar.app.getUser().get('admin')) {
+ user.set('deviceLimit', -1);
+ }
+ if (Traccar.app.getUser().get('expirationTime')) {
+ user.set('expirationTime', Traccar.app.getUser().get('expirationTime'));
+ }
+ dialog = Ext.create('Traccar.view.dialog.User');
+ dialog.down('form').loadRecord(user);
+ dialog.show();
+ },
+
+ onDevicesClick: function () {
+ var user = this.getView().getSelectionModel().getSelection()[0];
+ Ext.create('Traccar.view.BaseWindow', {
+ title: Strings.deviceTitle,
+ items: {
+ xtype: 'userDevicesView',
+ baseObjectName: 'userId',
+ linkObjectName: 'deviceId',
+ storeName: 'AllDevices',
+ linkStoreName: 'Devices',
+ urlApi: 'api/permissions/devices',
+ baseObject: user.getId()
+ }
+ }).show();
+ },
+
+ onGroupsClick: function () {
+ var user = this.getView().getSelectionModel().getSelection()[0];
+ Ext.create('Traccar.view.BaseWindow', {
+ title: Strings.settingsGroups,
+ items: {
+ xtype: 'userGroupsView',
+ baseObjectName: 'userId',
+ linkObjectName: 'groupId',
+ storeName: 'AllGroups',
+ linkStoreName: 'Groups',
+ urlApi: 'api/permissions/groups',
+ baseObject: user.getId()
+ }
+ }).show();
+ },
+
+ onGeofencesClick: function () {
+ var user = this.getView().getSelectionModel().getSelection()[0];
+ Ext.create('Traccar.view.BaseWindow', {
+ title: Strings.sharedGeofences,
+ items: {
+ xtype: 'userGeofencesView',
+ baseObjectName: 'userId',
+ linkObjectName: 'geofenceId',
+ storeName: 'AllGeofences',
+ linkStoreName: 'Geofences',
+ urlApi: 'api/permissions/geofences',
+ baseObject: user.getId()
+ }
+ }).show();
+ },
+
+ onNotificationsClick: function () {
+ var user = this.getView().getSelectionModel().getSelection()[0];
+ Ext.create('Traccar.view.BaseWindow', {
+ title: Strings.sharedNotifications,
+ modal: false,
+ items: {
+ xtype: 'notificationsView',
+ user: user
+ }
+ }).show();
+ },
+
+ onCalendarsClick: function () {
+ var user = this.getView().getSelectionModel().getSelection()[0];
+ Ext.create('Traccar.view.BaseWindow', {
+ title: Strings.sharedCalendars,
+ items: {
+ xtype: 'userCalendarsView',
+ baseObjectName: 'userId',
+ linkObjectName: 'calendarId',
+ storeName: 'AllCalendars',
+ linkStoreName: 'Calendars',
+ urlApi: 'api/permissions/calendars',
+ baseObject: user.getId()
+ }
+ }).show();
+ },
+
+ onUsersClick: function () {
+ var user = this.getView().getSelectionModel().getSelection()[0];
+ Ext.create('Traccar.view.BaseWindow', {
+ title: Strings.settingsUsers,
+ items: {
+ xtype: 'userUsersView',
+ baseObjectName: 'userId',
+ linkObjectName: 'managedUserId',
+ storeName: 'Users',
+ urlApi: 'api/permissions/users',
+ baseObject: user.getId()
+ }
+ }).show();
+ },
+
+ onSelectionChange: function (selection, selected) {
+ var disabled = selected.length === 0;
+ this.lookupReference('userDevicesButton').setDisabled(disabled);
+ this.lookupReference('userGroupsButton').setDisabled(disabled);
+ this.lookupReference('userGeofencesButton').setDisabled(disabled);
+ this.lookupReference('userNotificationsButton').setDisabled(disabled);
+ this.lookupReference('userCalendarsButton').setDisabled(disabled);
+ this.lookupReference('userUsersButton').setDisabled(disabled || selected[0].get('userLimit') === 0);
+ this.callParent(arguments);
+ }
+});