From b1e0b39c8e257a2aa4b7fadc91c750d07509547d Mon Sep 17 00:00:00 2001 From: csoni Date: Tue, 6 Dec 2016 11:22:40 +0530 Subject: [PATCH] Pop-up webapp dialog with additional device info On server side prepare device information data from z-push webservice response. On client side prepare dialog to show addition device information on row double click. --- js/MDM.js | 31 ++++ js/data/MDMDeviceRecord.js | 20 ++- js/dialogs/MDMDeviceDetailsContentPanel.js | 38 +++++ js/dialogs/MDMDeviceDetailsPanel.js | 184 +++++++++++++++++++++ js/settings/MDMSettingsWidget.js | 21 ++- manifest.xml | 2 + php/class.pluginmdmmodule.php | 142 ++++++++++++++-- php/zpushprops.php | 26 +++ 8 files changed, 440 insertions(+), 24 deletions(-) create mode 100644 js/dialogs/MDMDeviceDetailsContentPanel.js create mode 100644 js/dialogs/MDMDeviceDetailsPanel.js create mode 100644 php/zpushprops.php diff --git a/js/MDM.js b/js/MDM.js index 767baf0..b75bdb9 100755 --- a/js/MDM.js +++ b/js/MDM.js @@ -27,9 +27,40 @@ Zarafa.plugins.mdm.MDM = Ext.extend(Zarafa.core.Plugin, { { this.registerInsertionPoint('context.settings.categories', this.createSettingCategory, this); this.registerInsertionPoint('settings.versioninformation', this.createVersionInfo, this); + Zarafa.core.data.SharedComponentType.addProperty('mdm.dialog.mdmdevicedetails'); Zarafa.plugins.mdm.MDM.superclass.initPlugin.apply(this, arguments); }, + /** + * Bid for the type of shared component and the given record. + * @param {Zarafa.core.data.SharedComponentType} type Type of component a context can bid for. + * @param {Ext.data.Record} record Optionally passed record. + * @returns {Number} + */ + bidSharedComponent : function (type, record) + { + var bid = -1; + switch (type) { + case Zarafa.core.data.SharedComponentType['mdm.dialog.mdmdevicedetails']: + bid = 1; + break; + } + return bid; + }, + + /** + * Will return the reference to the shared component. + * Based on the type of component requested a component is returned. + * @param {Zarafa.core.data.SharedComponentType} type Type of component a context can bid for. + * @param {Ext.data.Record} record Optionally passed record. + * @return {Zarafa.plugins.mdm.dialogs.MDMDeviceDetailsContentPanel} Component + */ + getSharedComponent : function (type, record) + { + return Zarafa.plugins.mdm.dialogs.MDMDeviceDetailsContentPanel; + }, + + /** * Creates a category in settings for Z-Push * @return {mdmsettingscategory} diff --git a/js/data/MDMDeviceRecord.js b/js/data/MDMDeviceRecord.js index b017348..0240c02 100644 --- a/js/data/MDMDeviceRecord.js +++ b/js/data/MDMDeviceRecord.js @@ -2,19 +2,23 @@ Ext.namespace('Zarafa.plugins.mdm'); Zarafa.plugins.mdm.data.MDMDeviceRecordFields = [ {name: 'entryid', type: 'string'}, - {name: 'changed', type: 'boolean'}, + {name: 'devicetype', type: 'string'}, {name: 'deviceos', type: 'string'}, {name: 'devicefriendlyname', type: 'string'}, - {name: 'deviceinfo', type: 'string'}, - {name: 'devicetype', type: 'string'}, - {name: 'devicemodel', type: 'string'}, - {name: 'domain', type: 'string'}, - {name: 'hierarchyuuid', type: 'string'}, - // ignoredmessages + {name: 'useragent', type: 'string'}, + {name: 'asversion', type: 'string'}, {name: 'firstsynctime', type: 'date', dateFormat: 'timestamp'}, + {name: 'lastsynctime', type: 'date', dateFormat: 'timestamp'}, {name: 'lastupdatetime', type: 'date', dateFormat: 'timestamp'}, {name: 'wipestatus', type: 'string'}, - {name: 'useragent', type: 'string'} + {name: 'policyname', type: 'string'}, + {name: 'totalfolders', type: 'string'}, + {name: 'shortfolderids', type: 'string'}, + {name: 'synchronizedfolders', type: 'string'}, + {name: 'synchronizeddata', type: 'string'}, + {name: 'koeversion', type: 'string'}, + {name: 'koebuild', type: 'string'}, + {name: 'koebuilddate', type: 'date', dateFormat: 'timestamp'} ]; /** diff --git a/js/dialogs/MDMDeviceDetailsContentPanel.js b/js/dialogs/MDMDeviceDetailsContentPanel.js new file mode 100644 index 0000000..66f7174 --- /dev/null +++ b/js/dialogs/MDMDeviceDetailsContentPanel.js @@ -0,0 +1,38 @@ +Ext.namespace('Zarafa.plugins.mdm.dialogs'); + +/** + * @class Zarafa.plugins.mdm.dialogs.MDMDeviceDetailsContentPanel + * @extends Zarafa.core.ui.ContentPanel + * @xtype mdmplugin.devicedetailscontentpanel + * + * The content panel which is use to show device detail panel. + */ +Zarafa.plugins.mdm.dialogs.MDMDeviceDetailsContentPanel = Ext.extend(Zarafa.core.ui.ContentPanel, { + + /** + * @constructor + * @param config Configuration structure + */ + constructor: function (config) { + config = config || {}; + + Ext.applyIf(config, { + + xtype: 'mdmplugin.devicedetailscontentpanel', + layout : 'fit', + modal : true, + width : 435, + minWidth : 435, + autoHeight: true, + title : dgettext('plugin_mdm', config.record.get('devicetype')), + items : [{ + xtype: 'mdmplugin.devicedetailspanel', + record : config.record + }] + }); + + Zarafa.plugins.mdm.dialogs.MDMDeviceDetailsContentPanel.superclass.constructor.call(this, config); + } +}); + +Ext.reg('mdmplugin.devicedetailscontentpanel', Zarafa.plugins.mdm.dialogs.MDMDeviceDetailsContentPanel); \ No newline at end of file diff --git a/js/dialogs/MDMDeviceDetailsPanel.js b/js/dialogs/MDMDeviceDetailsPanel.js new file mode 100644 index 0000000..40ac908 --- /dev/null +++ b/js/dialogs/MDMDeviceDetailsPanel.js @@ -0,0 +1,184 @@ +Ext.namespace('Zarafa.plugins.mdm.dialogs'); + +/** + * @class Zarafa.plugins.mdm.dialogs.MDMDeviceDetailsPanel + * @extends Ext.form.FormPanel + * @xtype mdmplugin.devicedetailspanel + * + * This dialog panel will provide detail information of device. + */ +Zarafa.plugins.mdm.dialogs.MDMDeviceDetailsPanel = Ext.extend(Ext.form.FormPanel, { + + /** + * @cfg {Zarafa.plugins.mdm.data.MDMDeviceRecord} record The device record which + * is being display by this panel. + */ + record : null, + + /** + * @constructor + * @param config Configuration structure + */ + constructor : function (config) { + config = config || {}; + + Ext.applyIf(config, { + xtype : 'mdmplugin.devicedetailspanel', + layout : 'form', + autoScroll : true, + autoResize : true, + height : 500, + defaultType : 'textfield', + defaults : { + width : 300, + readOnly : true + }, + items : this.createPanelItems(config), + listeners : { + afterlayout : this.onAfterLayout, + scope : this + } + }); + + Zarafa.plugins.mdm.dialogs.MDMDeviceDetailsPanel.superclass.constructor.call(this, config); + }, + + + /** + * Function will create panel items for {@link Zarafa.plugins.mdm.dialogs.MDMDeviceDetailsPanel MDMDeviceDetailsPanel}. + * @param config Configuration structure + * @return {Array} array of items that should be added to panel. + */ + createPanelItems : function (config) + { + var items = [{ + fieldLabel : dgettext('plugin_mdm', 'Device Id'), + name : "entryid" + }, { + fieldLabel : dgettext('plugin_mdm', 'Device Type'), + name : "devicetype" + }, { + fieldLabel : dgettext('plugin_mdm', 'Device OS'), + name : "deviceos" + }, { + fieldLabel : dgettext('plugin_mdm', 'Device Friendly Name'), + name : "devicefriendlyname" + }, { + fieldLabel : dgettext('plugin_mdm', 'User Agent'), + name : "useragent" + }, { + fieldLabel : dgettext('plugin_mdm', 'ActiveSync Version'), + name : "asversion" + }, { + fieldLabel : dgettext('plugin_mdm', 'Z-Push Version'), + value : container.getSettingsModel().get('zarafa/v1/plugins/mdm/zpush-server-version', true) + }, { + xtype : "label", + width : 100, + text : dgettext('plugin_mdm', 'First sync') + ':' + }, { + xtype : 'zarafa.datetimefield', + name : "firstsynctime" + }, { + xtype : "label", + width : 100, + text : dgettext('plugin_mdm', 'Last sync') + ':' + }, { + xtype : 'zarafa.datetimefield', + name : "lastsynctime" + }, { + xtype : "label", + width : 100, + text : dgettext('plugin_mdm', 'Last Update Time') + ':' + }, { + xtype : 'zarafa.datetimefield', + name : "lastupdatetime" + }, { + fieldLabel : dgettext('plugin_mdm', 'Total folders'), + name : "totalfolders" + }, { + fieldLabel : dgettext('plugin_mdm', 'Short folder Ids'), + name : "shortfolderids" + }, { + fieldLabel : dgettext('plugin_mdm', 'Synchronized folders'), + name : "synchronizedfolders" + }, { + xtype : 'textarea', + fieldLabel : dgettext('plugin_mdm', 'Synchronized data'), + autoHeight : true, + name : "synchronizeddata" + }, { + fieldLabel : dgettext('plugin_mdm', 'Status'), + listeners : { + afterrender : this.onAfterRenderStatus, + scope : this + } + }, { + fieldLabel : dgettext('plugin_mdm', 'Policy name'), + name : "policyname" + }]; + + // KOE information + if (config.record && config.record.get('koeversion')) { + items.push(this.createKOEItems()); + } + return items; + }, + + /** + * Function will create Kopano Outlook Extension panel items for + * {@link Zarafa.plugins.mdm.dialogs.MDMDeviceDetailsPanel MDMDeviceDetailsPanel}. + * @return {Array} array of items that should be added to panel. + */ + createKOEItems : function () + { + return [{ + xtype : 'fieldset', + checkboxToggle : false, + title : dgettext('plugin_mdm', 'Kopano Outlook Extension'), + layout : 'form', + width : 405, + defaultType : 'textfield', + defaults : { + readOnly : true, + width : 285 + }, + items : [{ + fieldLabel : dgettext('plugin_mdm', 'Version'), + name : "koeversion" + }, { + fieldLabel : dgettext('plugin_mdm', 'Build'), + name : "koebuild" + },{ + xtype : "label", + width : 100, + text : dgettext('plugin_mdm', 'Build Date') + ':' + }, { + xtype : 'zarafa.datetimefield', + name : "koebuilddate" + }] + }] + }, + + /** + * Function which handles the after layout event of {@link Zarafa.plugins.mdm.dialogs.MDMDeviceDetailsPanel panel} + * Which is use to set record values into form fields. + */ + onAfterLayout : function () + { + this.getForm().loadRecord(this.record); + }, + + /** + * Function which handles the after render event of status field. + * Which is use to set the the display name for the given Provisioning Status into given field + * @param {Ext.form.TextField} statusField text field + */ + onAfterRenderStatus : function (statusField) + { + var status = parseInt(this.record.get("wipestatus")); + statusField.setValue(Zarafa.plugins.mdm.data.ProvisioningStatus.getDisplayName(status)); + } +}); + +Ext.reg('mdmplugin.devicedetailspanel', Zarafa.plugins.mdm.dialogs.MDMDeviceDetailsPanel); \ No newline at end of file diff --git a/js/settings/MDMSettingsWidget.js b/js/settings/MDMSettingsWidget.js index c9ee557..9e10ef9 100644 --- a/js/settings/MDMSettingsWidget.js +++ b/js/settings/MDMSettingsWidget.js @@ -87,7 +87,11 @@ Zarafa.plugins.mdm.settings.MDMSettingsWidget = Ext.extend(Zarafa.settings.ui.Se ref : '../../../refresh', handler : this.onRefresh, scope : this - }] + }], + listeners : { + rowdblclick: this.onRowDblClick, + scope : this + } }] }] }); @@ -192,6 +196,21 @@ Zarafa.plugins.mdm.settings.MDMSettingsWidget = Ext.extend(Zarafa.settings.ui.Se onRefresh : function() { this.deviceGrid.getStore().load(); + }, + + /** + * Function is called if a row in the grid gets double clicked. + * Which is use to show a dialog with detail device information + * @param {Ext.grid.GridPanel} grid The Grid on which the user double-clicked + * @param {Number} rowIndex The Row number on which was double-clicked. + */ + onRowDblClick : function (grid, rowIndex) + { + var record = grid.getStore().getAt(rowIndex); + Zarafa.core.data.UIFactory.openLayerComponent(Zarafa.core.data.SharedComponentType['mdm.dialog.mdmdevicedetails'], undefined, { + manager : Ext.WindowMgr, + record : record + }); } }); diff --git a/manifest.xml b/manifest.xml index bfc7f34..3643704 100755 --- a/manifest.xml +++ b/manifest.xml @@ -33,6 +33,8 @@ js/data/ProvisioningStatus.js js/settings/MDMSettingsWidget.js js/settings/MDMSettingsCategory.js + js/dialogs/MDMDeviceDetailsContentPanel.js + js/dialogs/MDMDeviceDetailsPanel.js js/ui/Renderers.js diff --git a/php/class.pluginmdmmodule.php b/php/class.pluginmdmmodule.php index 11ff1e9..6135eed 100755 --- a/php/class.pluginmdmmodule.php +++ b/php/class.pluginmdmmodule.php @@ -1,6 +1,7 @@ getDevices(); foreach($rawData as $device){ - $device = $device->data; - $item = array(); - $item['entryid'] = $device['deviceid']; - $item['changed'] = $device['changed']; - $item['deviceos'] = $device['deviceos']; - $item['devicefriendlyname'] = $device['devicefriendlyname']; - $item['devicetype'] = $device['devicetype']; - $item['devicemodel'] = $device['devicemodel']; - $item['hierarchyuuid'] = $device['hierarchyuuid']; - $item['firstsynctime'] = $device['firstsynctime']; - $item['lastupdatetime'] = $device['lastupdatetime']; - $item['wipestatus'] = $device['wipestatus']; - $item['useragent'] = $device['useragent']; - $item['domain'] = $device['domain']; - array_push($items, array('props' => $item)); + array_push($items, array('props' => $this->getDeviceProps($device->data))); } $data['page']['start'] = 0; $data['page']['rowcount'] = count($rawData); @@ -205,5 +197,125 @@ class PluginMDMModule extends Module } } } + + + /** + * Function which is use to get device properties. + * + * @param array $device array of device properties + * @return array + */ + function getDeviceProps($device) + { + $item = array(); + $propsList = ['devicetype', 'deviceos', 'devicefriendlyname', 'useragent', 'asversion', 'firstsynctime', + 'lastsynctime', 'lastupdatetime', 'wipestatus', 'policyname', 'koeversion', 'koebuild', 'koebuilddate']; + + $item['entryid'] = $device['deviceid']; + foreach ($propsList as $prop) { + if (isset($device[$prop])) { + $item[$prop] = $device[$prop]; + } + } + + $item = array_merge($item, $this->getSyncFoldersProps($device)); + return $item; + } + + /** + * Function which is use to gather some statistics about synchronized folders. + * @param array $device array of device props + * @return array $syncFoldersProps has list of properties related to synchronized folders + */ + function getSyncFoldersProps($device) + { + $contentData = $device['contentdata']; + $folders = array_keys($contentData); + $synchedFolderTypes = array(); + $synchronizedData = ''; + $synchronizedFolders = 0; + $hierarchyCache = isset($device['hierarchycache']) ? $device['hierarchycache'] : false; + + foreach ($folders as $folderid) { + if (isset($contentData[$folderid][self::FOLDERUUID]) || isset($device['hierarchyuuid'])) { + $type = $contentData[$folderid][self::FOLDERTYPE]; + $name = "unknown"; + if ($hierarchyCache) { + if (array_key_exists($folderid, $hierarchyCache->cacheById)) { + $folder = $hierarchyCache->cacheById[$folderid]; + } else { + $folder = $hierarchyCache->cacheByIdOld[$folderid]; + } + if ($folder) { + $name = $folder->displayname; + } + } + + $folderType = $this->getSyncFolderType($type, $name); + + if (!isset($synchedFolderTypes[$folderType])) { + $synchedFolderTypes[$folderType] = 0; + } + $synchedFolderTypes[$folderType]++; + } + } + + foreach ($synchedFolderTypes as $key => $value) { + $synchronizedData = $synchronizedData . $key; + $synchronizedFolders += $value; + if ($value > 1) { + $synchronizedData = $synchronizedData . "(" . $value . ") "; + } else { + $synchronizedData = $synchronizedData . " "; + } + } + + $syncFoldersProps = array(); + $syncFoldersProps["totalfolders"] = count($folders); + $syncFoldersProps["shortfolderids"] = $device['hasfolderidmapping'] ? dgettext('plugin_mdm', "Yes") : dgettext('plugin_mdm', "No") ; + $syncFoldersProps['synchronizedfolders'] = $synchronizedFolders; + $syncFoldersProps['synchronizeddata'] = $synchronizedData; + + return $syncFoldersProps; + } + + + /** + * Function which is use to get general type like Mail,Calendar,Contacts,etc. from folder type. + * @param int $type foldertype for a folder already known to the mobile + * @param string $name folder name + * @return string general folder type + */ + function getSyncFolderType($type, $name) + { + $folderType = ''; + switch ($type) { + case SYNC_FOLDER_TYPE_APPOINTMENT: + case SYNC_FOLDER_TYPE_USER_APPOINTMENT: + if (KOE_GAB_NAME != "" && $name == KOE_GAB_NAME) { + $folderType = "GAB"; + + } else { + $folderType = "Calendars"; + } + break; + case SYNC_FOLDER_TYPE_CONTACT: + case SYNC_FOLDER_TYPE_USER_CONTACT: + $folderType = "Contacts"; + break; + case SYNC_FOLDER_TYPE_TASK: + case SYNC_FOLDER_TYPE_USER_TASK: + $folderType = "Tasks"; + break; + case SYNC_FOLDER_TYPE_NOTE: + case SYNC_FOLDER_TYPE_USER_NOTE: + $folderType = "Notes"; + break; + default: + $folderType = "Emails"; + break; + } + return $folderType; + } }; ?> diff --git a/php/zpushprops.php b/php/zpushprops.php new file mode 100644 index 0000000..70d31cb --- /dev/null +++ b/php/zpushprops.php @@ -0,0 +1,26 @@ + \ No newline at end of file