/** * This class is used for creating a configurator field component. * * @private */Ext.define('Ext.pivot.plugin.configurator.Column', { extend: 'Ext.Component', requires: [ 'Ext.menu.Menu', 'Ext.menu.CheckItem', 'Ext.menu.Item', 'Ext.menu.Separator', 'Ext.pivot.plugin.configurator.Field', 'Ext.pivot.plugin.configurator.window.FilterLabel', 'Ext.pivot.plugin.configurator.window.FilterValue', 'Ext.pivot.plugin.configurator.window.FilterTop', 'Ext.pivot.plugin.configurator.window.FieldSettings' ], alias: 'widget.pivotconfigfield', childEls: ['textCol', 'filterCol', 'sortCol', 'customCol'], tabIndex: 0, focusable: true, isConfiguratorField: true, /* eslint-disable max-len, indent */ renderTpl: '<div id="{id}-configCol" role="button" class="' + Ext.baseCSSPrefix + 'pivot-grid-config-column-inner" >' + '<span id="{id}-customCol" role="presentation" data-ref="customCol" class="' + Ext.baseCSSPrefix + 'pivot-grid-config-column-btn-customize ' + Ext.baseCSSPrefix + 'border-box ' + Ext.baseCSSPrefix + 'pivot-grid-config-column-btn ' + Ext.baseCSSPrefix + 'pivot-grid-config-column-btn-image"></span>' + '<span id="{id}-sortCol" role="presentation" data-ref="sortCol" class="' + Ext.baseCSSPrefix + 'border-box ' + Ext.baseCSSPrefix + 'pivot-grid-config-column-btn"></span>' + '<span id="{id}-filterCol" role="presentation" data-ref="filterCol" class="' + Ext.baseCSSPrefix + 'border-box ' + Ext.baseCSSPrefix + 'pivot-grid-config-column-btn"></span>' + '<span id="{id}-textCol" role="presentation" data-ref="textCol" data-qtip="{header}" class="' + Ext.baseCSSPrefix + 'pivot-grid-config-column-text ' + Ext.baseCSSPrefix + 'column-header-text ' + Ext.baseCSSPrefix + 'border-box">' + '{header}' + '</span>' + '</div>', /* eslint-enable max-len, indent */ header: ' ', minWidth: 80, sortAscText: 'Sort A to Z', sortDescText: 'Sort Z to A', sortClearText: 'Disable sorting', clearFilterText: 'Clear filter from "{0}"', labelFiltersText: 'Label filters', valueFiltersText: 'Value filters', equalsText: 'Equals...', doesNotEqualText: 'Does not equal...', beginsWithText: 'Begins with...', doesNotBeginWithText: 'Does not begin with...', endsWithText: 'Ends with...', doesNotEndWithText: 'Does not end with...', containsText: 'Contains...', doesNotContainText: 'Does not contain...', greaterThanText: 'Greater than...', greaterThanOrEqualToText: 'Greater than or equal to...', lessThanText: 'Less than...', lessThanOrEqualToText: 'Less than or equal to...', betweenText: 'Between...', notBetweenText: 'Not between...', top10Text: 'Top 10...', equalsLText: 'equals', doesNotEqualLText: 'does not equal', beginsWithLText: 'begins with', doesNotBeginWithLText: 'does not begin with', endsWithLText: 'ends with', doesNotEndWithLText: 'does not end with', containsLText: 'contains', doesNotContainLText: 'does not contain', greaterThanLText: 'is greater than', greaterThanOrEqualToLText: 'is greater than or equal to', lessThanLText: 'is less than', lessThanOrEqualToLText: 'is less than or equal to', betweenLText: 'is between', notBetweenLText: 'is not between', top10LText: 'Top 10...', topOrderTopText: 'Top', topOrderBottomText: 'Bottom', topTypeItemsText: 'Items', topTypePercentText: 'Percent', topTypeSumText: 'Sum', baseCls: Ext.baseCSSPrefix + 'pivot-grid-config-column', btnIconCls: Ext.baseCSSPrefix + 'pivot-grid-config-column-btn-image', setFilterIconCls: Ext.baseCSSPrefix + 'pivot-grid-config-column-btn-filter-set', clearFilterIconCls: Ext.baseCSSPrefix + 'pivot-grid-config-column-btn-filter-clear', ascSortIconCls: Ext.baseCSSPrefix + 'pivot-grid-config-column-btn-sort-asc', descSortIconCls: Ext.baseCSSPrefix + 'pivot-grid-config-column-btn-sort-desc', clearSortIconCls: Ext.baseCSSPrefix + 'pivot-grid-config-column-btn-sort-clear', overCls: Ext.baseCSSPrefix + 'pivot-grid-config-column-over', cls: Ext.baseCSSPrefix + 'unselectable', config: { /** * @cfg {String} fieldType * * Defines in which area this configurator field exists. * * Possible values: * * - `all` = the field is located in the "all fields" area; * - `aggregate` = the field is located in the "values" area; * - `leftAxis` = the field is located in the "row values" area; * - `topAxis` = the field is located in the "column values" area; * */ fieldType: 'all', /** * @cfg {Ext.pivot.plugin.configurator.Field} field * * Reference to the configured dimension on this configurator field. */ field: null }, destroy: function() { this.setField(null); this.callParent(); }, initRenderData: function() { var dim = this.getField(); return Ext.apply(this.callParent(arguments), { header: this.getFieldType() === 'aggregate' ? dim.getFieldText() : dim.getHeader(), dimension: dim }); }, afterRender: function() { var me = this, dim = me.getField(), settings = dim.getSettings(); me.callParent(); if (Ext.Array.indexOf(['leftAxis', 'topAxis'], me.getFieldType()) >= 0) { if (!Ext.isDefined(dim.sortable) || dim.sortable) { me.addSortCls(dim.direction); } if (dim.filter) { me.addFilterCls(); } } // the custom style we configure it on the textCol since that one is one level deeper me.textCol.setStyle(settings.getStyle()); // but the custom class we configure it on the component itself since it's more flexible // this way me.addCls(settings.getCls()); }, getMenuConfig: function() { var fieldType = this.getFieldType(); if (fieldType === 'leftAxis' || fieldType === 'topAxis') { return this.getColMenuConfig(); } }, addSortCls: function(direction) { var me = this; if (!me.sortCol) { return; } if (direction === 'ASC' || !direction) { me.sortCol.addCls(me.ascSortIconCls); me.sortCol.removeCls(me.descSortIconCls); } else { me.sortCol.addCls(me.descSortIconCls); me.sortCol.removeCls(me.ascSortIconCls); } me.sortCol.addCls(me.btnIconCls); }, removeSortCls: function(direction) { var me = this; if (!me.sortCol) { return; } if (direction === 'ASC') { me.sortCol.removeCls(me.ascSortIconCls); } else { me.sortCol.removeCls(me.descSortIconCls); } me.sortCol.removeCls(me.btnIconCls); }, addFilterCls: function() { var me = this; if (me.filterCol && !me.filterCol.hasCls(me.setFilterIconCls)) { me.filterCol.addCls(me.setFilterIconCls); me.filterCol.addCls(me.btnIconCls); } }, removeFilterCls: function() { var me = this; if (me.filterCol) { me.filterCol.removeCls(me.setFilterIconCls); me.filterCol.removeCls(me.btnIconCls); } }, getColMenuConfig: function() { var me = this, items = [], labelItems, valueItems, commonItems, i, filter = me.getField().filter; // check if the dimension is sortable items.push({ text: me.sortAscText, direction: 'ASC', iconCls: me.ascSortIconCls, handler: me.sortMe }, { text: me.sortDescText, direction: 'DESC', iconCls: me.descSortIconCls, handler: me.sortMe }, { text: me.sortClearText, direction: '', disabled: me.getField().sortable === false, iconCls: me.clearSortIconCls, handler: me.sortMe }, { xtype: 'menuseparator' }); commonItems = [{ text: me.equalsText, operator: '=' }, { text: me.doesNotEqualText, operator: '!=' }, { xtype: 'menuseparator' }, { text: me.greaterThanText, operator: '>' }, { text: me.greaterThanOrEqualToText, operator: '>=' }, { text: me.lessThanText, operator: '<' }, { text: me.lessThanOrEqualToText, operator: '<=' }, { xtype: 'menuseparator' }, { text: me.betweenText, operator: 'between' }, { text: me.notBetweenText, operator: 'not between' }]; labelItems = Ext.clone(commonItems); Ext.Array.insert(labelItems, 3, [{ text: me.beginsWithText, operator: 'begins' }, { text: me.doesNotBeginWithText, operator: 'not begins' }, { text: me.endsWithText, operator: 'ends' }, { text: me.doesNotEndWithText, operator: 'not ends' }, { xtype: 'menuseparator' }, { text: me.containsText, operator: 'contains' }, { text: me.doesNotContainText, operator: 'not contains' }, { xtype: 'menuseparator' }]); for (i = 0; i < labelItems.length; i++) { labelItems[i].checked = (filter && filter.type === 'label' && filter.operator === labelItems[i].operator); } valueItems = Ext.clone(commonItems); valueItems.push({ xtype: 'menuseparator' }, { text: me.top10Text, operator: 'top10' }); for (i = 0; i < valueItems.length; i++) { valueItems[i].checked = (filter && filter.type === 'value' && filter.operator === valueItems[i].operator); } items.push({ text: Ext.String.format(me.clearFilterText, me.header), iconCls: me.clearFilterIconCls, disabled: !filter, handler: me.onRemoveFilter }, { text: me.labelFiltersText, menu: { defaults: { handler: me.onShowFilter, scope: me, xtype: 'menucheckitem', group: 'filterlabel', type: 'label' }, items: labelItems } }, { text: me.valueFiltersText, menu: { defaults: { handler: me.onShowFilter, scope: me, xtype: 'menucheckitem', group: 'filtervalue', type: 'value' }, items: valueItems } }); return { defaults: { scope: me }, items: items }; }, sortMe: function(btn) { var me = this, field = me.getField(); if (Ext.isEmpty(btn.direction)) { // disable sorting field.setSortable(false); me.removeSortCls(field.getDirection()); } else { field.setSortable(true); me.addSortCls(btn.direction); field.setDirection(btn.direction); } me.applyChanges(); }, onShowFilter: function(btn) { var me = this, panel = me.up('pivotconfigpanel'), dataAgg = [], winCfg = {}, filter = me.getField().getFilter(), values = { type: btn.type, operator: btn.operator, value: (filter ? filter.value : ''), from: (filter ? (Ext.isArray(filter.value) ? filter.value[0] : '') : ''), to: (filter ? (Ext.isArray(filter.value) ? filter.value[1] : '') : ''), caseSensitive: (filter ? filter.caseSensitive : false), topSort: (filter ? filter.topSort : false) }, items = panel.getAggregateContainer().items, len = items.getCount(), win, winClass, data, i, field; for (i = 0; i < len; i++) { field = items.getAt(i).getField(); dataAgg.push([field.getHeader(), field.getId()]); } if (btn.type === 'label' || (btn.type === 'value' && btn.operator !== 'top10')) { data = [ [me.equalsLText, '='], [me.doesNotEqualLText, '!='], [me.greaterThanLText, '>'], [me.greaterThanOrEqualToLText, '>='], [me.lessThanLText, '<'], [me.lessThanOrEqualToLText, '<='], [me.betweenLText, 'between'], [me.notBetweenLText, 'not between'] ]; if (btn.type === 'label') { Ext.Array.insert(data, 3, [ [me.beginsWithLText, 'begins'], [me.doesNotBeginWithLText, 'not begins'], [me.endsWithLText, 'ends'], [me.doesNotEndWithLText, 'not ends'], [me.containsLText, 'contains'], [me.doesNotContainLText, 'not contains'] ]); winClass = 'Ext.pivot.plugin.configurator.window.FilterLabel'; } else { winClass = 'Ext.pivot.plugin.configurator.window.FilterValue'; Ext.apply(values, { dimensionId: (filter ? filter.dimensionId : '') }); winCfg.storeAgg = new Ext.data.ArrayStore({ fields: ['text', 'value'], data: dataAgg }); } winCfg.store = new Ext.data.ArrayStore({ fields: ['text', 'value'], data: data }); } else { winClass = 'Ext.pivot.plugin.configurator.window.FilterTop'; data = []; Ext.apply(winCfg, { storeTopOrder: new Ext.data.ArrayStore({ fields: ['text', 'value'], data: [ [me.topOrderTopText, 'top'], [me.topOrderBottomText, 'bottom'] ] }), storeTopType: new Ext.data.ArrayStore({ fields: ['text', 'value'], data: [ [me.topTypeItemsText, 'items'], [me.topTypePercentText, 'percent'], [me.topTypeSumText, 'sum'] ] }), storeAgg: new Ext.data.ArrayStore({ fields: ['text', 'value'], data: dataAgg }) }); Ext.apply(values, { operator: 'top10', dimensionId: (filter ? filter.dimensionId : ''), topType: (filter ? filter.topType : 'items'), topOrder: (filter ? filter.topOrder : 'top') }); } win = Ext.create(winClass, Ext.apply(winCfg || {}, { title: me.header, listeners: { applysettings: Ext.bind(me.onApplyFilterSettings, me) } })); win.loadSettings(values); win.show(); }, onApplyFilterSettings: function(win, filter) { var me = this; win.close(); me.addFilterCls(); me.getField().setFilter(filter); me.applyChanges(); }, onRemoveFilter: function() { var me = this; me.removeFilterCls(); me.getField().setFilter(null); me.applyChanges(); }, /** * This is used for firing the 'configchange' event * */ applyChanges: function() { if (this.ownerCt) { this.ownerCt.applyChanges(this); } }});