/** * This plugin allows the end user to configure the pivot component. * * It adds the following methods to the pivot grid: * - showConfigurator: which when called will show the configurator panel * - hideConfigurator: which when called will hide the configurator panel * * The configurator panel will be shown docked to the pivot grid. */Ext.define('Ext.pivot.plugin.Configurator', { alternateClassName: [ 'Mz.pivot.plugin.Configurator' ], extend: 'Ext.plugin.Abstract', requires: [ 'Ext.util.DelayedTask', 'Ext.menu.Menu', 'Ext.menu.CheckItem', 'Ext.util.Collection', 'Ext.pivot.plugin.configurator.Panel' ], alias: [ 'plugin.pivotconfigurator', 'plugin.mzconfigurator' ], /** * Fired on the pivot component before a configurator field is moved. * * Return false if you don't want to move that field. * * @event beforemoveconfigfield * @param {Ext.pivot.plugin.configurator.Panel} panel Configurator panel * @param {Object} config * @param {Ext.pivot.plugin.configurator.Container} config.fromContainer Source container * to move from * @param {Ext.pivot.plugin.configurator.Container} config.toContainer Destination container * to move to * @param {Ext.pivot.plugin.configurator.Field} config.field Field configuration */ /** * Fired on the pivot component before the pivot settings window is shown. * * Return false if you don't want to show the window. * * @event beforeshowpivotsettings * @param {Ext.pivot.plugin.configurator.Panel} panel Configurator panel * @param {Object} config * @param {Ext.pivot.plugin.configurator.window.Settings} config.container Window object where * you can inject additional fields * @param {Object} config.settings Settings that will be loaded into the form */ /** * Fired on the pivot component after the configurator pivot settings window is shown. * * @event showpivotsettings * @param {Ext.pivot.plugin.configurator.Panel} panel Configurator panel * @param {Object} config * @param {Ext.pivot.plugin.configurator.window.Settings} config.container Window object where * you can inject additional fields * @param {Object} config.settings Settings that were loaded into the form */ /** * Fired on the pivot component before settings are applied to the pivot matrix. * * Return false if you don't want to apply the settings to the field. * * @event beforeapplypivotsettings * @param {Ext.pivot.plugin.configurator.Panel} panel Configurator panel * @param {Object} config * @param {Ext.pivot.plugin.configurator.window.Settings} config.container Window object that * contains all pivot matrix settings. * @param {Object} config.settings Settings that will be loaded into the form */ /** * Fired on the pivot component after settings are applied to the pivot matrix. * * @event applypivotsettings * @param {Ext.pivot.plugin.configurator.Panel} panel Configurator panel * @param {Object} config * @param {Ext.pivot.plugin.configurator.window.Settings} config.container Window object * @param {Object} config.settings Settings that were loaded into the form */ /** * Fired on the pivot component before the field settings window is shown. * * Return false if you don't want to show the window. * * @event beforeshowconfigfieldsettings * @param {Ext.pivot.plugin.configurator.Panel} panel Configurator panel * @param {Object} config * @param {Ext.pivot.plugin.configurator.window.FieldSettings} config.container Window object * where you can inject additional fields * @param {Object} config.settings Settings that will be loaded into the form */ /** * Fired on the pivot component after the configurator field settings window is shown. * * @event showconfigfieldsettings * @param {Ext.pivot.plugin.configurator.Panel} panel Configurator panel * @param {Object} config * @param {Ext.pivot.plugin.configurator.window.FieldSettings} config.container Window object * where you can inject additional fields * @param {Object} config.settings Settings that were loaded into the form */ /** * Fired on the pivot component before settings are applied to the configurator field. * * Return false if you don't want to apply the settings to the field. * * @event beforeapplyconfigfieldsettings * @param {Ext.pivot.plugin.configurator.Panel} panel Configurator panel * @param {Object} config * @param {Ext.pivot.plugin.configurator.window.FieldSettings} config.container Window object * that contains all field settings. * @param {Object} config.settings Settings that will be loaded into the form */ /** * Fired on the pivot component after settings are applied to the configurator field. * * @event applyconfigfieldsettings * @param {Ext.pivot.plugin.configurator.Panel} panel Configurator panel * @param {Object} config * @param {Ext.pivot.plugin.configurator.window.FieldSettings} config.container Window object * @param {Object} config.settings Settings that were loaded into the form */ /** * Fired on the pivot component before the configurator field menu is shown. * * Return false if you don't want to show the menu. * * @event beforeshowconfigfieldmenu * @param {Ext.pivot.plugin.configurator.Panel} panel Configurator panel * @param {Object} config * @param {Ext.menu.Menu} config.menu Menu object * @param {Ext.pivot.plugin.configurator.Field} config.field Field configuration * @param {String} config.container Type of container in which the field is located: `all`, * `leftAxis`, `topAxis` or `aggregate`. */ /** * Fired on the pivot component after the configurator field menu is shown. * * @event showconfigfieldmenu * @param {Ext.pivot.plugin.configurator.Panel} panel Configurator panel * @param {Object} config * @param {Ext.menu.Menu} config.menu Menu object * @param {Ext.pivot.plugin.configurator.Field} config.field Field configuration * @param {String} config.container Type of container in which the field is located: `all`, * `leftAxis`, `topAxis` or `aggregate`. */ /** * Fired on the pivot component before the new configuration is applied. * * Return false if you don't want to apply the new configuration to the pivot grid. * * @event beforeconfigchange * @param {Ext.pivot.plugin.configurator.Panel} panel Configurator panel * @param {Object} config Config object used to reconfigure the pivot */ /** * Fired on the pivot component when the configuration changes. * * @event configchange * @param {Ext.pivot.plugin.configurator.Panel} panel Configurator panel * @param {Object} config Config object used to reconfigure the pivot */ /** * Fired on the pivot component when the configurator panel is visible * * @event showconfigpanel * @param {Ext.pivot.plugin.configurator.Panel} panel Configurator panel */ /** * Fired on the pivot component when the configurator panel is hidden * * @event hideconfigpanel * @param {Ext.pivot.plugin.configurator.Panel} panel Configurator panel */ /** * `"both"` (the default) - The plugin is added to both grids * `"top"` - The plugin is added to the containing Panel * `"locked"` - The plugin is added to the locked (left) grid * `"normal"` - The plugin is added to the normal (right) grid * * @private */ lockableScope: 'top', config: { /** * @cfg {Ext.pivot.plugin.configurator.Field[]} fields * * This is the array of fields you want to be used in the configurator. * * If no fields are defined then all fields are fetched from the store model if * a {@link Ext.pivot.matrix.Local Local} matrix is used. * * The fields are indexed by the dataIndex supplied to them which means that you can't have * two fields sharing the same dataIndex. If you want to define two fields that share * the same dataIndex then it's best to use a unique dataIndex for the 2nd field and define * a grouperFn on it. * * The dimensions that are configured on the pivot component but do not exist in this fields * collection * will be added here with a set of default settings. */ fields: [], /** * @cfg {Number} refreshDelay Number of milliseconds to wait for pivot refreshing when * a config change occurred. */ refreshDelay: 300, /** * @cfg {String} dock Docking position for the configurator panel. Possible values: top, * right, bottom, left */ dock: 'right', /** * @cfg {Boolean} collapsible Is the configurator panel collapsible? */ collapsible: true, /** * @private */ configPanel: null }, init: function(cmp) { var me = this; //<debug> // this plugin is only available for the pivot components if (!cmp.isPivotComponent) { Ext.raise('This plugin is only compatible with pivot components'); } //</debug> cmp.showConfigurator = Ext.bind(me.showConfigurator, me); cmp.hideConfigurator = Ext.bind(me.hideConfigurator, me); cmp.on({ afterrender: me.onAfterPivotRendered, single: true, scope: me }); me.callParent([cmp]); }, /** * @private * AbstractComponent calls destroy on all its plugins at destroy time. */ destroy: function() { var me = this, cmp = me.getCmp(); cmp.showConfigurator = cmp.hideConfigurator = null; me.setConfigPanel(Ext.destroy(me.getConfigPanel())); me.setFields(null); me.callParent(); }, /** * Enable the plugin to show the configurator panel. * */ enable: function() { this.disabled = false; this.showConfigurator(); }, /** * Disable the plugin to hide the configurator panel. * */ disable: function() { this.disabled = true; this.hideConfigurator(); }, /** * @private */ showConfigurator: function() { this.renderConfigPanel(); }, /** * @private */ hideConfigurator: function() { var cfgPanel = this.getConfigPanel(); if (cfgPanel) { cfgPanel.disable(); this.getCmp().fireEvent('hideconfigpanel', cfgPanel); } }, /** * @private */ onAfterPivotRendered: function() { var me = this, fields = me.getFields(), matrix = me.getCmp().getMatrix(), fieldsToUpdate = [], duplicates = {}, noFields = false, store, newFields, field, name, length, i, dim, config; if (fields.length === 0 && matrix instanceof Ext.pivot.matrix.Local) { // if no fields were provided then try to extract them from the matrix store noFields = true; store = matrix.store; newFields = store ? store.model.getFields() : []; length = newFields.length; for (i = 0; i < length; i++) { name = newFields[i].getName(); if (!fields.byDataIndex.get(name)) { fields.add({ header: Ext.String.capitalize(name), dataIndex: name }); } } } // extract fields from the existing pivot configuration newFields = Ext.Array.merge( matrix.leftAxis.dimensions.getRange(), matrix.topAxis.dimensions.getRange(), matrix.aggregate.getRange() ); length = newFields.length; for (i = 0; i < length; i++) { dim = newFields[i].getConfig(); delete(dim.matrix); delete(dim.values); delete(dim.id); field = fields.byDataIndex.get(dim.dataIndex); if (!field) { fields.add(dim); } else if (noFields) { if (!duplicates[dim.dataIndex]) { duplicates[dim.dataIndex] = 0; } delete(dim.header); duplicates[dim.dataIndex]++; fieldsToUpdate.push(dim); } } // Some fields defined on the pivot axis already exist in the configurator fields // so we need to update the configurator fields for later usage. // This is important because the dimensions may have labelRenderer/renderer/formatter // defined // This happens only when no fields were defined on the Configurator plugin. length = fieldsToUpdate.length; for (i = 0; i < length; i++) { dim = fieldsToUpdate[i]; if (duplicates[dim.dataIndex] === 1) { field = fields.byDataIndex.get(dim.dataIndex); if (field) { config = field.getConfig(); Ext.merge(config, dim); field.setConfig(config); } } } me.isReady = true; if (me.disabled === true) { me.disable(); } else { me.enable(); } }, /** * Change configurator panel position. * @method setDock * * @param {String} position Possible values: `top`, `right`, `bottom`, `left`. */ /** * Get a reference to the configurator panel * @method getConfigPanel * * @returns {Ext.pivot.plugin.configurator.Panel} */ /** * @private * @param value */ updateDock: function(value) { this.renderConfigPanel(value); }, /** * @private * @param value */ updateCollapsible: function(value) { this.renderConfigPanel(value); }, getFields: function() { var ret = this.fields; if (!ret) { ret = new Ext.util.Collection({ extraKeys: { byDataIndex: 'dataIndex' }, decoder: function(field) { return (field && field.isField) ? field : new Ext.pivot.plugin.configurator.Field(field || {}); } }); this.setFields(ret); } return ret; }, applyFields: function(fields, fieldsCollection) { if (fields == null || (fields && fields.isCollection)) { return fields; } if (fields) { if (!fieldsCollection) { fieldsCollection = this.getFields(); } fieldsCollection.splice(0, fieldsCollection.length, fields); } return fieldsCollection; }, /** * Render the configurator panel as a docked panel to the pivot component * * @private * @param position */ renderConfigPanel: function(position) { var me = this, cmp = me.getCmp(), cfgPanel = me.getConfigPanel(), exists = !Ext.isEmpty(cfgPanel); if (!cmp || !me.isReady || me.disabled) { // nothing to do return; } Ext.destroy(cfgPanel); cfgPanel = cmp.addDocked({ xtype: 'pivotconfigpanel', dock: position || me.getDock(), refreshDelay: me.getRefreshDelay(), pivot: me.getCmp(), fields: me.getFields(), listeners: { afterrender: 'onRenderConfigPanel', single: true, scope: me } })[0]; me.setConfigPanel(cfgPanel); if (exists) { cfgPanel.enable(); } }, onRenderConfigPanel: function(panel) { this.getCmp().fireEvent('showconfigpanel', panel); }});