/** * 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 when the end-user does a `longpress` event * on the column headers. */Ext.define('Ext.pivot.plugin.Configurator', { extend: 'Ext.plugin.Abstract', requires: [ 'Ext.util.Collection', 'Ext.pivot.plugin.configurator.Panel' ], alias: 'plugin.pivotconfigurator', /** * 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 container is shown. * * Return false if you don't want to show the container. * * @event beforeshowpivotsettings * @param {Ext.pivot.plugin.configurator.Panel} panel Configurator panel * @param {Object} config * @param {Ext.pivot.plugin.configurator.window.Settings} config.container Form panel container 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 container 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 Form panel container 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 pivot matrix. * * @event beforeapplypivotsettings * @param {Ext.pivot.plugin.configurator.Panel} panel Configurator panel * @param {Object} config * @param {Ext.pivot.plugin.configurator.Settings} config.container Form panel container 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.Settings} config.container Form panel container where you can inject * additional fields * @param {Object} config.settings Settings that were loaded into the form */ /** * Fired on the pivot component before the field settings container is shown. * * Return false if you don't want to show the field settings container. * * @event beforeshowconfigfieldsettings * @param {Ext.pivot.plugin.configurator.Panel} panel Configurator panel * @param {Object} config * @param {Ext.pivot.plugin.configurator.Form} config.container Form panel container 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 container is shown. * * @event showconfigfieldsettings * @param {Ext.pivot.plugin.configurator.Panel} panel Configurator panel * @param {Object} config * @param {Ext.pivot.plugin.configurator.Form} config.container Form panel container 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.Form} config.container Form panel container 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.Form} config.container Form panel container that contains all field settings * @param {Object} config.settings Settings that were loaded into the form */ /** * 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 disabled * * @event hideconfigpanel * @param {Ext.pivot.plugin.configurator.Panel} panel Configurator panel */ 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} width * * The width of the configurator panel. */ width: 400, /** * @cfg {Object} panel * * Configuration object used to instantiate the configurator panel. */ panel: { lazy: true, $value: { xtype: 'pivotconfigpanel', hidden: true, floated: true, modal: true, hideOnMaskTap: true, right: 0, height: '100%' } }, /** * @private */ pivot: null }, init: function (pivot) { this.setPivot(pivot); }, /** * @private * AbstractComponent calls destroy on all its plugins at destroy time. */ destroy: function () { this.setConfig({ pivot: null, panel: null }); this.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(); }, applyPanel: function (panel, oldPanel) { if (panel) { panel = panel.isInstance ? panel : Ext.create(panel); } return panel; }, updatePanel: function (panel, oldPanel) { var me = this, pivot = this.getPivot(); Ext.destroy(oldPanel, me.panelListeners); if (panel) { me.panelListeners = panel.on({ hiddenchange: 'onPanelHiddenChange', close: 'hideConfigurator', scope: me, destroyable: true }); panel.setConfig({ pivot: pivot, fields: me.getFields() }); pivot.add(panel); } }, onPanelHiddenChange: function (panel, hidden) { this.getPivot().fireEvent(hidden ? 'hideconfigpanel' : 'showconfigpanel', panel); }, updatePivot: function (pivot, oldPivot) { var me = this; Ext.destroy(me.pivotListeners); if (oldPivot) { oldPivot.showConfigurator = oldPivot.hideConfigurator = null; } if (pivot) { //<debug> // this plugin is only available for the pivot components if (!pivot.isPivotComponent) { Ext.raise('This plugin is only compatible with pivot components'); } //</debug> pivot.showConfigurator = Ext.bind(me.showConfigurator, me); pivot.hideConfigurator = Ext.bind(me.hideConfigurator, me); if (pivot.initialized) { me.onPivotInitialized(); } else { pivot.on({ initialize: 'onPivotInitialized', single: true, scope: me }); } } }, getWidth: function () { var pivot = this.getPivot(), viewport = Ext.Viewport, maxWidth = 100; if (pivot && pivot.element) { maxWidth = pivot.element.getWidth(); } if (viewport) { maxWidth = Math.min(maxWidth, viewport.element.getHeight(), viewport.element.getWidth()); } return Ext.Number.constrain(this._width, 100, maxWidth); }, /** * @private */ onPivotInitialized: function () { var me = this, pivot = me.getPivot(), fields = me.getFields(), matrix = pivot.getMatrix(), header = pivot.getHeaderContainer && pivot.getHeaderContainer(), 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; me.doneSetup = false; if (header) { me.pivotListeners = header.renderElement.on({ longpress: 'showConfigurator', scope: this }); } }, /** * @private */ hideConfigurator: function () { var panel = this.getPanel(); if (panel) { panel.hide(); } }, /** * @private */ showConfigurator: function () { var panel = this.getPanel(); if (panel) { panel.setWidth(this.getWidth()); panel.show(); } }, 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; }, deprecated: { '6.5': { configs: { panelWrapper: null, panelWrap: null } } } });