diff --git a/js/MDM.js b/js/MDM.js index 0dc25fa..77199ce 100755 --- a/js/MDM.js +++ b/js/MDM.js @@ -16,6 +16,12 @@ Zarafa.plugins.mdm.MDM = Ext.extend(Zarafa.core.Plugin, { constructor : function(config) { config = config || {}; Zarafa.plugins.mdm.MDM.superclass.constructor.call(this, config); + + // Module information for MDM which will use in shadow store. + Zarafa.core.ModuleNames["IPM.MDM"] = { + list: 'pluginmdmmodule', + item: 'pluginmdmmodule' + } }, /** @@ -28,6 +34,7 @@ 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.mdmdevicecontentpanel'); + Zarafa.core.data.SharedComponentType.addProperty('mdm.dialog.mdmmanagesharedfoldercontentpanel'); Zarafa.plugins.mdm.MDM.superclass.initPlugin.apply(this, arguments); }, @@ -44,6 +51,9 @@ Zarafa.plugins.mdm.MDM = Ext.extend(Zarafa.core.Plugin, { case Zarafa.core.data.SharedComponentType['mdm.dialog.mdmdevicecontentpanel']: bid = 1; break; + case Zarafa.core.data.SharedComponentType['mdm.dialog.mdmmanagesharedfoldercontentpanel']: + bid = 1; + break; } return bid; }, @@ -57,7 +67,16 @@ Zarafa.plugins.mdm.MDM = Ext.extend(Zarafa.core.Plugin, { */ getSharedComponent : function (type, record) { - return Zarafa.plugins.mdm.dialogs.MDMDeviceContentPanel; + var component; + switch (type) { + case Zarafa.core.data.SharedComponentType['mdm.dialog.mdmdevicecontentpanel']: + component = Zarafa.plugins.mdm.dialogs.MDMDeviceContentPanel; + break; + case Zarafa.core.data.SharedComponentType['mdm.dialog.mdmmanagesharedfoldercontentpanel']: + component = Zarafa.plugins.mdm.dialogs.MDMManageSharedFolderContentPanel; + break; + } + return component; }, diff --git a/js/data/JsonDeviceFolderReader.js b/js/data/JsonDeviceFolderReader.js new file mode 100644 index 0000000..04ece92 --- /dev/null +++ b/js/data/JsonDeviceFolderReader.js @@ -0,0 +1,41 @@ +Ext.namespace('Zarafa.plugins.mdm.data'); + +/** + * @class Zarafa.plugins.mdm.data.JsonDeviceFolderReader + * @extends Zarafa.core.data.JsonReader + * + * This extension of the {@link Zarafa.core.data.JsonReader} supports + * {@link Zarafa.plugins.mdm.data.MDMDeviceStore stores} which can hold different type of + * {@link Zarafa.plugins.mdm.data.MDMDeviceRecord records}. + */ +Zarafa.plugins.mdm.data.JsonDeviceFolderReader = Ext.extend(Zarafa.core.data.JsonReader, { + + /** + * @cfg {Zarafa.core.data.RecordCustomObjectType} customObjectType The custom object type + * which represents the {@link Ext.data.Record records} which should be created using + * {@link Zarafa.core.data.RecordFactory#createRecordObjectByCustomType}. + */ + customObjectType: Zarafa.core.data.RecordCustomObjectType.MDM_Device_Folder, + + /** + * @constructor + * @param {Object} meta Metadata configuration options. + * @param {Object} recordType (optional) Optional Record type matches the type + * which must be read from response. If no type is given, it will use the + * record type for the {@link Zarafa.core.data.RecordCustomObjectType#ZARAFA_RECIPIENT}. + */ + constructor: function (meta, recordType) + { + meta = Ext.applyIf(meta || {}, { + id: 'folderid', + idProperty: 'folderid', + dynamicRecord: false + }); + + if (!Ext.isDefined(recordType)) { + recordType = Zarafa.core.data.RecordFactory.getRecordClassByCustomType(meta.customObjectType || this.customObjectType); + } + + Zarafa.plugins.mdm.data.JsonDeviceFolderReader.superclass.constructor.call(this, meta, recordType); + } +}); diff --git a/js/data/JsonDeviceReader.js b/js/data/JsonDeviceReader.js index 6f2b2c6..906310e 100644 --- a/js/data/JsonDeviceReader.js +++ b/js/data/JsonDeviceReader.js @@ -5,28 +5,21 @@ Ext.namespace('Zarafa.plugins.mdm.data'); * @extends Zarafa.core.data.JsonReader */ Zarafa.plugins.mdm.data.JsonCertificateReader = Ext.extend(Zarafa.core.data.JsonReader, { - /** - * @cfg {Zarafa.core.data.RecordCustomObjectType} customObjectType The custom object type - * which represents the {@link Ext.data.Record records} which should be created using - * {@link Zarafa.core.data.RecordFactory#createRecordObjectByCustomType}. - */ - customObjectType : Zarafa.core.data.RecordCustomObjectType.ZARAFA_MDM, - /** - * @constructor - * @param {Object} meta Metadata configuration options. - * @param {Object} recordType (optional) Optional Record type matches the type - * which must be read from response. If no type is given, it will use the - * record type for the {@link Zarafa.core.data.RecordCustomObjectType#ZARAFA_MDM}. - */ - constructor : function(meta, recordType) - { - meta = Ext.applyIf(meta || {}, { - dynamicRecord : false - }); + /** + * @constructor + * @param {Object} meta Metadata configuration options. + * @param {Object} recordType (optional) Optional Record type matches the type + * which must be read from response. If no type is given, it will use the + * record type for the {@link Zarafa.core.mapi.ObjectType#MAPI_MDM}. + */ + constructor: function (meta, recordType) + { + meta = Ext.applyIf(meta || {}, { + dynamicRecord: false + }); + recordType = Zarafa.core.data.RecordFactory.getRecordClassByMessageClass('IPM.MDM'); - recordType = Zarafa.core.data.RecordFactory.getRecordClassByCustomType(Zarafa.core.data.RecordCustomObjectType.ZARAFA_MDM); - - Zarafa.plugins.mdm.data.JsonCertificateReader.superclass.constructor.call(this, meta, recordType); - } + Zarafa.plugins.mdm.data.JsonCertificateReader.superclass.constructor.call(this, meta, recordType); + } }); diff --git a/js/data/MDMDeviceFolderRecord.js b/js/data/MDMDeviceFolderRecord.js new file mode 100644 index 0000000..f1fc2cf --- /dev/null +++ b/js/data/MDMDeviceFolderRecord.js @@ -0,0 +1,21 @@ +Ext.namespace('Zarafa.plugins.mdm'); + +/** + * @class Zarafa.plugins.mdm.data.MDMDeviceFolderRecordFields + * + * Array of default fields for the {@link Zarafa.plugins.mdm.data.MDMDeviceFolderRecord} object. + * These fields will always be added, regardless of the exact type of + * {@link Zarafa.plugins.mdm.data.MDMDeviceFolderRecord record}. + */ +Zarafa.plugins.mdm.data.MDMDeviceFolderRecordFields = [ + {name: 'store', type: 'string'}, + {name: 'folderid', type: 'string'}, + {name: 'name', type: 'string'}, + {name: 'type', type: 'int'}, + {name: 'flags', type: 'int'}, + {name: 'entryid', type: 'string'} +]; + +Zarafa.core.data.RecordCustomObjectType.addProperty('MDM_Device_Folder'); +Zarafa.core.data.RecordFactory.addFieldToCustomType(Zarafa.core.data.RecordCustomObjectType.MDM_Device_Folder, Zarafa.plugins.mdm.data.MDMDeviceFolderRecordFields); +Zarafa.core.data.RecordFactory.setBaseClassToCustomType(Zarafa.core.data.RecordCustomObjectType.MDM_Device_Folder, Zarafa.core.data.MAPIRecord); diff --git a/js/data/MDMDeviceFolderStore.js b/js/data/MDMDeviceFolderStore.js new file mode 100644 index 0000000..3981838 --- /dev/null +++ b/js/data/MDMDeviceFolderStore.js @@ -0,0 +1,33 @@ +Ext.namespace('Zarafa.plugins.mdm.data'); + +/** + * @class Zarafa.plugins.mdm.data.MDMDeviceFolderStore + * @extends Zarafa.core.data.MAPISubStore + * @xtype mdm.devicefolderstore + * Store specific for MDM Plugin which creates {@link Zarafa.plugins.mdm.MDMDeviceFolderStore record}. + */ +Zarafa.plugins.mdm.data.MDMDeviceFolderStore = Ext.extend(Zarafa.core.data.MAPISubStore, { + /** + * @constructor + * @param config Configuration object + */ + constructor: function (config) + { + config = config || {}; + + Ext.applyIf(config, { + autoLoad: true, + remoteSort: false, + reader: new Zarafa.plugins.mdm.data.JsonDeviceFolderReader(), + writer: new Zarafa.core.data.JsonWriter(), + proxy: new Zarafa.core.data.IPMProxy({ + listModuleName: 'pluginmdmmodule', + itemModuleName: 'pluginmdmmodule' + }) + }); + + Zarafa.plugins.mdm.data.MDMDeviceFolderStore.superclass.constructor.call(this, config); + } +}); + +Ext.reg('mdm.devicefolderstore', Zarafa.plugins.mdm.data.MDMDeviceFolderStore); \ No newline at end of file diff --git a/js/data/MDMDeviceProxy.js b/js/data/MDMDeviceProxy.js new file mode 100644 index 0000000..781dd44 --- /dev/null +++ b/js/data/MDMDeviceProxy.js @@ -0,0 +1,54 @@ +Ext.namespace('Zarafa.plugins.mdm.data'); + +/** + * @class Zarafa.plugins.mdm.data.MDMDeviceProxy + * @extends Zarafa.core.data.MAPIProxy + */ +Zarafa.plugins.mdm.data.MDMDeviceProxy = Ext.extend(Zarafa.core.data.MAPIProxy, { + + /** + * @constructor + * @param {Object} config Configuration object + */ + constructor: function (config) + { + config = config || {}; + Ext.applyIf(config, { + listModuleName: 'pluginmdmmodule', + itemModuleName: 'pluginmdmmodule' + }); + + Zarafa.plugins.mdm.data.MDMDeviceProxy.superclass.constructor.call(this, config); + }, + + /** + * This will create a {@link Zarafa.core.data.ProxyResponseHandler ProxyResponseHandler} object + * which will be used by the {@link Zarafa.core.data.ResponseRouter ResponseRouter} when the + * response for the given request has returned. + * + * @param {String} modulename The modulename which is being accessed with this request + * @param {Zarafa.core.Actions} serverAction The action to perform on the server. + * @param {Ext.data.Api.action} action name of the action to perform. + * @param {Ext.data.Record[]} records list of records to operate on. + * @param {Object} parameters object containing user parameters such as range (pagination) information, sorting information, etc. + * @param {Ext.data.DataReader} reader data reader. Converts raw JavaScript objects (in our case) to instances of {@link Ext.data.Record} + * @param {Function} callback call back function to call when the request has finished successfully. + * @param {Object} scope scope for the call back function. + * @param {Object} args arguments object. This will be passed to the call back function on successful read. + * @return {Object} An instance of the {@link Zarafa.plugins.mdm.data.MDMDeviceResponseHandler ProxyResponseHandler} + * which should be used for this request. + * @private + */ + getResponseHandlerForRequest: function (modulename, serverAction, action, records, parameters, reader, callback, scope, args) + { + return new Zarafa.plugins.mdm.data.MDMDeviceResponseHandler({ + proxy: this, + action: action, + reader: reader, + sendRecords: records, + options: args, + callback: callback, + scope: scope + }); + } +}); diff --git a/js/data/MDMDeviceRecord.js b/js/data/MDMDeviceRecord.js index 64c22a9..e73ae49 100644 --- a/js/data/MDMDeviceRecord.js +++ b/js/data/MDMDeviceRecord.js @@ -1,5 +1,10 @@ Ext.namespace('Zarafa.plugins.mdm'); +/** + * @class Zarafa.plugins.mdm.data.MDMDeviceRecordFields Array of {@link Ext.data.Field field} configurations for the + * {@link Zarafa.plugins.mdm.data.MDMDeviceRecord record} object. + * @private + */ Zarafa.plugins.mdm.data.MDMDeviceRecordFields = [ {name: 'entryid', type: 'string'}, {name: 'devicetype', type: 'string'}, @@ -12,30 +17,22 @@ Zarafa.plugins.mdm.data.MDMDeviceRecordFields = [ {name: 'lastupdatetime', type: 'date', dateFormat: 'timestamp'}, {name: 'wipestatus', type: 'string'}, {name: 'policyname', type: 'string'}, - {name: 'totalfolders', type: 'string'}, + {name: 'sharedfolders', type: 'string'}, {name: 'shortfolderids', type: 'string'}, - {name: 'synchronizedfolders', type: 'string'}, - {name: 'emailsfolder', type: 'string'}, - {name: 'contactsfolder', type: 'string'}, - {name: 'tasksfolder', type: 'string'}, - {name: 'calendarsfolder', type: 'string'}, - {name: 'notesfolder', type: 'string'}, + {name: 'synchronizedfolders', type: 'string', defaultValue:'0'}, + {name: 'emailsfolder', type: 'string', defaultValue:'0'}, + {name: 'contactsfolder', type: 'string', defaultValue:'0'}, + {name: 'tasksfolder', type: 'string', defaultValue:'0'}, + {name: 'calendarsfolder', type: 'string', defaultValue:'0'}, + {name: 'notesfolder', type: 'string', defaultValue:'0'}, {name: 'koeversion', type: 'string'}, {name: 'koebuild', type: 'string'}, - {name: 'koebuilddate', type: 'date', dateFormat: 'timestamp'} + {name: 'koebuilddate', type: 'date', dateFormat: 'timestamp'}, + {name: 'message_class', type: 'string', defaultValue:"IPM.MDM"} ]; -/** - * - */ + Zarafa.plugins.mdm.data.MDMDeviceRecord = Ext.extend(Zarafa.core.data.IPMRecord, {}); -Zarafa.core.data.RecordCustomObjectType.addProperty('ZARAFA_MDM'); -Zarafa.core.data.RecordFactory.addFieldToCustomType(Zarafa.core.data.RecordCustomObjectType.ZARAFA_MDM, Zarafa.plugins.mdm.data.MDMDeviceRecordFields); - -Zarafa.core.data.RecordFactory.addListenerToCustomType(Zarafa.core.data.RecordCustomObjectType.ZARAFA_MDM, 'createphantom', function(record) -{ - // Phantom records must always be marked as opened (they contain the full set of data) - record.afterOpen(); -}); - -Zarafa.core.data.RecordFactory.setBaseClassToCustomType(Zarafa.core.data.RecordCustomObjectType.ZARAFA_MDM, Zarafa.plugins.mdm.data.MDMDeviceRecord); +Zarafa.core.data.RecordFactory.addFieldToMessageClass('IPM.MDM', Zarafa.plugins.mdm.data.MDMDeviceRecordFields); +Zarafa.core.data.RecordFactory.setBaseClassToMessageClass('IPM.MDM', Zarafa.plugins.mdm.data.MDMDeviceRecord); +Zarafa.core.data.RecordFactory.setSubStoreToMessageClass('IPM.MDM', 'sharedfolders', Zarafa.plugins.mdm.data.MDMDeviceFolderStore); diff --git a/js/data/MDMDeviceResponseHandler.js b/js/data/MDMDeviceResponseHandler.js new file mode 100644 index 0000000..d627d3b --- /dev/null +++ b/js/data/MDMDeviceResponseHandler.js @@ -0,0 +1,41 @@ +Ext.namespace('Zarafa.plugins.mdm.data'); + +/** + * @class Zarafa.plugins.mdm.data.MDMDeviceResponseHandler + * @extends Zarafa.core.data.ProxyResponseHandler + * + * A Simple implementation for a {@link Zarafa.plugins.mdm.data.MDMDeviceResponseHandler ResponseHandler}. + * This one can only be used by {@link Ext.data.DataProxy proxies} which wish to handle a Response + * to their Request. + * + * This implementation limits itself to firing an {@link Ext.data.DataProxy#exception exception} + * on error, and calling a callback function when all processing has been completed. + */ +Zarafa.plugins.mdm.data.MDMDeviceResponseHandler = Ext.extend(Zarafa.core.data.ProxyResponseHandler, { + + /** + * Handles the list response. Gathers the stores from the response data, converts each entry + * into a {@link Zarafa.core.MAPIStore MAPIStore} and pushes them into the collectedItems. + * @param {Object} data The response object belonging to the given command. + * @return {Boolean} False when action could not be handled successfully. This will + * not cancel the transaction itself, but rather causes the 'success' argument for the + * {@link #done} function to be false. + */ + doOpen: function(response) + { + this.receivedRecords = this.readRecordsFromResponse(response, 'item'); + }, + + /** + * Handles the list response. Gathers the stores from the response data, converts each entry + * into a {@link Zarafa.core.MAPIStore MAPIStore} and pushes them into the collectedItems. + * @param {Object} data The response object belonging to the given command. + * @return {Boolean} False when action could not be handled successfully. This will + * not cancel the transaction itself, but rather causes the 'success' argument for the + * {@link #done} function to be false. + */ + doList: function(response) + { + this.receivedRecords = this.readRecordsFromResponse(response, 'item'); + } +}); diff --git a/js/data/MDMDeviceStore.js b/js/data/MDMDeviceStore.js index a9f7ea1..fad7075 100644 --- a/js/data/MDMDeviceStore.js +++ b/js/data/MDMDeviceStore.js @@ -20,10 +20,7 @@ Zarafa.plugins.mdm.data.MDMDeviceStore = Ext.extend(Zarafa.core.data.ListModuleS remoteSort: false, reader : new Zarafa.plugins.mdm.data.JsonCertificateReader(), writer : new Zarafa.core.data.JsonWriter(), - proxy : new Zarafa.core.data.IPMProxy({ - listModuleName: 'pluginmdmmodule', - itemModuleName: 'pluginmdmmodule' - }) + proxy : new Zarafa.plugins.mdm.data.MDMDeviceProxy() }); Zarafa.plugins.mdm.data.MDMDeviceStore.superclass.constructor.call(this, config); diff --git a/js/data/MDMHierarchyTreeLoader.js b/js/data/MDMHierarchyTreeLoader.js new file mode 100644 index 0000000..8eb159c --- /dev/null +++ b/js/data/MDMHierarchyTreeLoader.js @@ -0,0 +1,57 @@ +Ext.namespace('Zarafa.hierarchy.data'); + +/** + * @class Zarafa.plugins.mdm.data.MDMHierarchyTreeLoader + * @extends Zarafa.hierarchy.data.HierarchyTreeLoader + * + * A Special treeloader to be used by the {@link Zarafa.plugins.mdm.data.MDMHierarchyTreeLoader MDMHierarchyTree}. + * This wil dynamically load the child nodes for a given node by obtaining the subfolders of + * the folder related to the given node. + */ +Zarafa.plugins.mdm.data.MDMHierarchyTreeLoader = Ext.extend(Zarafa.hierarchy.data.HierarchyTreeLoader, { + + /** + * @constructor + * @param {Object} config Configuration object + */ + constructor : function(config) + { + Zarafa.plugins.mdm.data.MDMHierarchyTreeLoader.superclass.constructor.call(this, config); + }, + + /** + * Add extra attributes for a new {@link Zarafa.hierarchy.ui.FolderNode folderNode} which is about + * to be created. This will check the {@link Zarafa.hierarchy.ui.FolderNode#folder folder} to + * see what properties must be set. + * + * Override to provide (@link Zarafa.plugins.mdm.ui.MDMFolderNodeUI MDMFolderNodeUI} to ui provider + * @param {Object} attr The attributes which will be used to create the node + * @return {Zarafa.hierarchy.ui.FolderNode} The created node + */ + createNode : function(attr) + { + var folder = attr.folder; + + if (folder) { + if (attr.nodeType === 'rootfolder') { + attr.extendedDisplayName = this.tree.hasFilter(); + } + + // To uniquely identify the favorites tree nodes we append the "favorites-" key word with node id + // when the node is created. + attr.id = folder.isFavoritesFolder() ? "favorites-" + folder.get('entryid') : folder.get('entryid'); + if (folder.isFavoritesRootFolder()) { + attr.leaf = folder.get('assoc_content_count') === 0; + } else { + attr.leaf = !folder.get('has_subfolder'); + } + + attr.uiProvider = Zarafa.plugins.mdm.ui.MDMFolderNodeUI; + attr.expanded = this.tree.isFolderOpened(folder); + attr.allowDrag = !folder.isDefaultFolder(); + } + + // call parent of parent because of parent class will change ui provider + return Zarafa.hierarchy.data.HierarchyTreeLoader.superclass.createNode.apply(this, arguments); + } +}); diff --git a/js/data/MDMRecord.js b/js/data/MDMRecord.js deleted file mode 100644 index e69de29..0000000 diff --git a/js/dialogs/MDMDeviceContentPanel.js b/js/dialogs/MDMDeviceContentPanel.js index 30d7709..497ac7e 100644 --- a/js/dialogs/MDMDeviceContentPanel.js +++ b/js/dialogs/MDMDeviceContentPanel.js @@ -2,12 +2,12 @@ Ext.namespace('Zarafa.plugins.mdm.dialogs'); /** * @class Zarafa.plugins.mdm.dialogs.MDMDeviceContentPanel - * @extends Zarafa.core.ui.ContentPanel + * @extends Zarafa.core.ui.RecordContentPanel * @xtype mdmplugin.devicecontentpanel * * The content panel which is use to show device detail panel. */ -Zarafa.plugins.mdm.dialogs.MDMDeviceContentPanel = Ext.extend(Zarafa.core.ui.ContentPanel, { +Zarafa.plugins.mdm.dialogs.MDMDeviceContentPanel = Ext.extend(Zarafa.core.ui.RecordContentPanel, { /** * @constructor @@ -16,19 +16,24 @@ Zarafa.plugins.mdm.dialogs.MDMDeviceContentPanel = Ext.extend(Zarafa.core.ui.Con constructor: function (config) { config = config || {}; - var isKOE = config.record && config.record.get('koeversion') ? true : false; + var isKOE = config.record && config.record.get('koeversion') ? true : false; Ext.applyIf(config, { xtype: 'mdmplugin.devicecontentpanel', modal: true, title: dgettext('plugin_mdm', config.record.get('devicetype')), - layout : 'fit', - stateful : false, - width : isKOE ? 440 : 405, - height : isKOE ? 395 : 360, + recordComponentPluginConfig: Ext.applyIf(config.recordComponentPluginConfig || {}, { + allowWrite: true, + useShadowStore: true + }), + layout: 'fit', + stateful: false, + showLoadMask: false, + width: isKOE ? 440 : 405, + height: isKOE ? 450 : 420, items: [{ xtype: 'mdmplugin.mdmdevicepanel', record: config.record, - isKoe : isKOE, + isKoe: isKOE, buttons: [{ text: _('Ok'), handler: this.onOk, diff --git a/js/dialogs/MDMDeviceGeneralTab.js b/js/dialogs/MDMDeviceGeneralTab.js index e26daf9..e46b0c6 100644 --- a/js/dialogs/MDMDeviceGeneralTab.js +++ b/js/dialogs/MDMDeviceGeneralTab.js @@ -12,7 +12,7 @@ Zarafa.plugins.mdm.dialogs.MDMDeviceGeneralTab = Ext.extend(Ext.form.FormPanel, /** * @cfg {Boolean} isKoe True if device has Kopano Outlook Extension information. */ - isKoe : false, + isKoe: false, /** * @constructor @@ -54,7 +54,7 @@ Zarafa.plugins.mdm.dialogs.MDMDeviceGeneralTab = Ext.extend(Ext.form.FormPanel, createDeviceInfoPanel: function (config) { return { - cls : 'mdm-device-panel', + cls: 'mdm-device-panel', defaultType: 'displayfield', defaults: { disabled: true @@ -89,7 +89,7 @@ Zarafa.plugins.mdm.dialogs.MDMDeviceGeneralTab = Ext.extend(Ext.form.FormPanel, createFolderInfoPanel: function () { return { - cls : 'mdm-device-panel mdm-field-sep', + cls: 'mdm-device-panel mdm-field-sep', defaultType: 'displayfield', items: [{ cls: 'mdm-display-name', @@ -104,7 +104,7 @@ Zarafa.plugins.mdm.dialogs.MDMDeviceGeneralTab = Ext.extend(Ext.form.FormPanel, xtype: 'fieldset', layout: 'form', labelWidth: 140, - cls : 'mdm-synchronize-panel', + cls: 'mdm-synchronize-panel', defaultType: 'displayfield', defaults: { labelSeparator: '', @@ -126,7 +126,48 @@ Zarafa.plugins.mdm.dialogs.MDMDeviceGeneralTab = Ext.extend(Ext.form.FormPanel, }, { fieldLabel: _('Tasks'), name: 'tasksfolder' - }] + }, + this.createSharedFolderInfoPanel() + ] + }] + }; + }, + + /** + * Function which is use to create shared folders panel + * @returns {Object} Configuration object for the panel which shows folders properties + */ + createSharedFolderInfoPanel: function () + { + return { + xtype: 'panel', + border: false, + cls: 'mdm-synchronize-shared-panel', + height: 50, + disabled: false, + layout: { + type: 'hbox', + align: 'stretch', + pack: 'start' + }, + items: [{ + layout: 'form', + border: false, + items: [{ + xtype: 'displayfield', + fieldLabel: 'Shared Folders', + disabled: true, + name : 'sharedfolders' + }], + flex: 1 + }, { + xtype: 'button', + text: dgettext('plugin_mdm', 'Managed shared Folders'), + cls: 'mdm-managesharedfolder-button', + listeners: { + click: this.onClickManageSharedFolder, + scope: this + } }] }; }, @@ -142,13 +183,25 @@ Zarafa.plugins.mdm.dialogs.MDMDeviceGeneralTab = Ext.extend(Ext.form.FormPanel, /** * 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 + * Which is use to set 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)); + }, + + /** + * Function which handles the click event of manage shared folder button. + * It will open {@link Zarafa.plugins.mdm.dialogs.MDMManageSharedFolderContentPanel dialog} + */ + onClickManageSharedFolder: function () + { + Zarafa.core.data.UIFactory.openLayerComponent(Zarafa.core.data.SharedComponentType['mdm.dialog.mdmmanagesharedfoldercontentpanel'], undefined, { + manager: Ext.WindowMgr, + record: this.dialog.record + }); } }); diff --git a/js/dialogs/MDMManageSharedFolderContentPanel.js b/js/dialogs/MDMManageSharedFolderContentPanel.js new file mode 100644 index 0000000..b77d673 --- /dev/null +++ b/js/dialogs/MDMManageSharedFolderContentPanel.js @@ -0,0 +1,36 @@ +Ext.namespace('Zarafa.plugins.mdm.dialogs'); + +/** + * @class Zarafa.plugins.mdm.dialogs.MDMManageSharedFolderContentPanel + * @extends Zarafa.core.ui.ContentPanel + * @xtype zarafa.managesharedfoldercontentpanel + * + * This will display a {@link Zarafa.plugins.mdm.dialogs.MDMManageSharedFolderPanel contentpanel} + * to show {@link Zarafa.core.data.IPFRecord folders} which are shared with device. + */ +Zarafa.plugins.mdm.dialogs.MDMManageSharedFolderContentPanel = Ext.extend(Zarafa.core.ui.ContentPanel, { + + /** + * @constructor + * @param config Configuration structure + */ + constructor: function (config) { + config = config || {}; + + Ext.applyIf(config, + { + xtype: 'mdm.managesharedfoldercontentpanel', + layout: 'fit', + title: dgettext('plugin_mdm','Manage Shared Folder'), + width: 300, + height: 350, + items: [{ + xtype: 'mdm.managesharedfolderpanel' + }] + }); + + Zarafa.plugins.mdm.dialogs.MDMManageSharedFolderContentPanel.superclass.constructor.call(this, config); + } +}); + +Ext.reg('mdm.managesharedfoldercontentpanel', Zarafa.plugins.mdm.dialogs.MDMManageSharedFolderContentPanel); diff --git a/js/dialogs/MDMManageSharedFolderPanel.js b/js/dialogs/MDMManageSharedFolderPanel.js new file mode 100644 index 0000000..b7dd667 --- /dev/null +++ b/js/dialogs/MDMManageSharedFolderPanel.js @@ -0,0 +1,132 @@ +Ext.namespace('Zarafa.plugins.mdm.dialogs'); + +/** + * @class Zarafa.plugins.mdm.dialogs.MDMManageSharedFolderPanel + * @extends Ext.Panel + * @xtype mdm.managesharedfolderpanel + * + * Panel for users to show the {@link Zarafa.core.data.IPFRecord folders} which are shared with device + */ +Zarafa.plugins.mdm.dialogs.MDMManageSharedFolderPanel = Ext.extend(Ext.Panel, { + + /** + * @constructor + * @param {Object} config Configuration structure + */ + constructor: function (config) + { + config = config || {}; + + Ext.applyIf(config, { + xtype: 'mdm.managesharedfolderpanel', + layout: { + type: 'fit', + align: 'stretch' + }, + border: false, + header: false, + items: [ + this.createTreePanel() + ], + buttonAlign: 'right', + buttons: [{ + text: _('Apply'), + ref: '../okButton', + cls: 'zarafa-action', + scope: this + }, { + text: _('Cancel'), + ref: '../cancelButton', + handler: this.onCancel, + scope: this + }] + }); + + Zarafa.plugins.mdm.dialogs.MDMManageSharedFolderPanel.superclass.constructor.call(this, config); + }, + + /** + * Creates a {@link Zarafa.hierarchy.ui.Tree treepanel} + * which contains all the {@link Zarafa.hierarchy.data.MAPIFolderRecord folders} + * on which search get perform. + * @return {Object} Configuration object for the tree panel. + * @private + */ + createTreePanel: function () + { + return { + xtype: 'panel', + layout : 'form', + defaults: { + cls : 'mdm-create-tree-panel-item' + }, + border: false, + flex: 1, + items: [{ + xtype: 'displayfield', + hideLabel : true, + value: dgettext('plugin_mdm','Select folders to sync on your device') + }, { + xtype: 'mdm.hierarchytree', + autoScroll : true, + nodeConfig : { + checked : false + }, + multiSelect: true, + hideShowAllFolders: true, + border: true, + treeSorter: true, + bbarConfig: { + hidden: true + }, + enableDD: false, + anchor: '100% 90%', + ref: '../hierarchyTree' + }] + }; + }, + + /** + * Initialize the events + * @private + */ + initEvents: function () + { + Zarafa.plugins.mdm.dialogs.MDMManageSharedFolderPanel.superclass.initEvents.apply(this, arguments); + this.mon(this.hierarchyTree, 'load', this.onTreeNodeLoad, this); + }, + + /** + * Fired when the {@link Zarafa.hierarchy.ui.Tree Tree} fires the {@link Zarafa.hierarchy.ui.Tree#load load} + * event. This function will try to select those {@link Ext.tree.TreeNode TreeNode} in + * {@link Zarafa.hierarchy.ui.Tree Tree} which was shared with respective device. When the given node is not loaded yet, it will try again + * later when the event is fired again. + * + * @private + */ + onTreeNodeLoad: function () + { + var subStore = this.dialog.record.getSubStore('sharedfolders'); + var folders = subStore.getRange(); + folders.forEach(function (folder) { + var node = this.hierarchyTree.getNodeById(folder.get('entryid')); + if (Ext.isDefined(node)) { + if(node.hasChildNodes()){ + node.expand(); + } + node.getUI().toggleCheck(true) + } + }, this); + }, + + /** + * Action handler when the user presses the "Cancel" button. + * This will close the panel. + */ + onCancel: function () + { + this.dialog.close(); + } +}); + +Ext.reg('mdm.managesharedfolderpanel', Zarafa.plugins.mdm.dialogs.MDMManageSharedFolderPanel); \ No newline at end of file diff --git a/js/settings/MDMSettingsWidget.js b/js/settings/MDMSettingsWidget.js index 899fea4..566ab12 100644 --- a/js/settings/MDMSettingsWidget.js +++ b/js/settings/MDMSettingsWidget.js @@ -207,6 +207,7 @@ Zarafa.plugins.mdm.settings.MDMSettingsWidget = Ext.extend(Zarafa.settings.ui.Se onRowDblClick : function (grid, rowIndex) { var record = grid.getStore().getAt(rowIndex); + record.opened = false; Zarafa.core.data.UIFactory.openLayerComponent(Zarafa.core.data.SharedComponentType['mdm.dialog.mdmdevicecontentpanel'], undefined, { manager : Ext.WindowMgr, record : record diff --git a/js/ui/MDMFolderNodeUI.js b/js/ui/MDMFolderNodeUI.js new file mode 100644 index 0000000..07681ff --- /dev/null +++ b/js/ui/MDMFolderNodeUI.js @@ -0,0 +1,151 @@ +Ext.namespace('Zarafa.plugins.mdm.ui'); + + +/** + * @class Zarafa.plugins.mdm.ui.MDMFolderNodeUI + * @extends Zarafa.hierarchy.ui.FolderNodeUI + * + * {@link Zarafa.hierarchy.ui.FolderNodeUI} has limitation that it can add + * (@link Ext.form.Checkbox check box} preceded to calendar item only. + * So, It will add (@link Ext.form.Checkbox check box} preceded to all context items. + */ +Zarafa.plugins.mdm.ui.MDMFolderNodeUI = Ext.extend(Zarafa.hierarchy.ui.FolderNodeUI, { + + /** + * Function will render {@link Zarafa.hierachy.ui.FolderNode FolderNode} based on modified template for + * our custom needs. + * @param {Zarafa.hierarchy.ui.FolderNode} node tree node. + * @param {Object} config config object of {@link Zarafa.hierarchy.ui.FolderNode FolderNode}. + * @param {Ext.Element} targetNode element in which {@link Zarafa.hierarchy.ui.FolderNode FolderNode} will be rendered. + * @param {Boolean} bulkRender + */ + renderElements : function(node, config, targetNode, bulkRender) + { + // add some indent caching, this helps performance when rendering a large tree + this.indentMarkup = node.parentNode ? node.parentNode.ui.getChildIndent() : ''; + + var scheme; + var cb = Ext.isBoolean(config.checked); + var isCalenderNode = config.folder.isCalendarFolder(); + var calendarSVGIcon = ''; + + if (isCalenderNode) { + var calendarContextModel = node.getOwnerTree().model; + + // We started providing color choosing facility to all the calendar tree-nodes. + // CalendarContextModel is responsible for this facility. + // There is no CalendarContextModel available in the case where that particular + // calendar-tree-node doesn't belongs to MultiSelectHierarchyTree. + // So, simply made that ContextModel available to current HierarchyTree. + if (!calendarContextModel) { + var calendarContext = container.getContextByName('calendar'); + calendarContextModel = calendarContext.getModel(); + node.getOwnerTree().model = calendarContextModel; + } + + scheme = calendarContextModel.getColorScheme(config.folder.get('entryid')); + + // Get the scheme base only if we are able to get scheme successfully, + // otherwise let it be undefined instead of a JS fatal error. + if(scheme && scheme.base) { + calendarSVGIcon = '' ; + } + } + + var icon = '', + nel, + href = config.href ? config.href : Ext.isGecko ? "" : "#", + buf = '