"use strict"; exports.__esModule = true; require("core-js/modules/es.array.push.js"); var _base = require("../base"); var _pluginHooks = _interopRequireDefault(require("../../pluginHooks")); var _freezeColumn = _interopRequireDefault(require("./contextMenuItem/freezeColumn")); var _unfreezeColumn = _interopRequireDefault(require("./contextMenuItem/unfreezeColumn")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } _pluginHooks.default.getSingleton().register('beforeColumnFreeze'); _pluginHooks.default.getSingleton().register('afterColumnFreeze'); _pluginHooks.default.getSingleton().register('beforeColumnUnfreeze'); _pluginHooks.default.getSingleton().register('afterColumnUnfreeze'); const PLUGIN_KEY = 'manualColumnFreeze'; exports.PLUGIN_KEY = PLUGIN_KEY; const PLUGIN_PRIORITY = 110; exports.PLUGIN_PRIORITY = PLUGIN_PRIORITY; const privatePool = new WeakMap(); /* eslint-disable jsdoc/require-description-complete-sentence */ /** * @plugin ManualColumnFreeze * @class ManualColumnFreeze * * @description * This plugin allows to manually "freeze" and "unfreeze" a column using an entry in the Context Menu or using API. * You can turn it on by setting a {@link Options#manualColumnFreeze} property to `true`. * * @example * ```js * // Enables the plugin * manualColumnFreeze: true, * ``` */ class ManualColumnFreeze extends _base.BasePlugin { static get PLUGIN_KEY() { return PLUGIN_KEY; } static get PLUGIN_PRIORITY() { return PLUGIN_PRIORITY; } constructor(hotInstance) { super(hotInstance); privatePool.set(this, { afterFirstUse: false }); } /** * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit} * hook and if it returns `true` then the {@link ManualColumnFreeze#enablePlugin} method is called. * * @returns {boolean} */ isEnabled() { return !!this.hot.getSettings()[PLUGIN_KEY]; } /** * Enables the plugin functionality for this Handsontable instance. */ enablePlugin() { if (this.enabled) { return; } this.addHook('afterContextMenuDefaultOptions', options => this.addContextMenuEntry(options)); this.addHook('beforeColumnMove', (columns, finalIndex) => this.onBeforeColumnMove(columns, finalIndex)); super.enablePlugin(); } /** * Disables the plugin functionality for this Handsontable instance. */ disablePlugin() { const priv = privatePool.get(this); priv.afterFirstUse = false; super.disablePlugin(); } /** * Updates the plugin's state. * * This method is executed when [`updateSettings()`](@/api/core.md#updatesettings) is invoked with any of the following configuration options: * - [`manualColumnFreeze`](@/api/options.md#manualcolumnfreeze) */ updatePlugin() { this.disablePlugin(); this.enablePlugin(); super.updatePlugin(); } /** * Freezes the specified column (adds it to fixed columns). * * `freezeColumn()` doesn't re-render the table, * so you need to call the `render()` method afterward. * * @param {number} column Visual column index. */ freezeColumn(column) { const priv = privatePool.get(this); const settings = this.hot.getSettings(); // columns are already fixed (frozen) const freezePerformed = settings.fixedColumnsStart < this.hot.countCols() && column > settings.fixedColumnsStart - 1; if (!priv.afterFirstUse) { priv.afterFirstUse = true; } const beforeColumnFreezeHook = this.hot.runHooks('beforeColumnFreeze', column, freezePerformed); if (beforeColumnFreezeHook === false) { return; } if (freezePerformed) { this.hot.columnIndexMapper.moveIndexes(column, settings.fixedColumnsStart); // Since 12.0.0, the "fixedColumnsLeft" is replaced with the "fixedColumnsStart" option. // However, keeping the old name still in effect. When both option names are used together, // the error is thrown. To prevent that, the plugin needs to modify the original option key // to bypass the validation. settings._fixedColumnsStart += 1; } this.hot.runHooks('afterColumnFreeze', column, freezePerformed); } /** * Unfreezes the given column (remove it from fixed columns and bring to it's previous position). * * @param {number} column Visual column index. */ unfreezeColumn(column) { const priv = privatePool.get(this); const settings = this.hot.getSettings(); // columns are not fixed (not frozen) const unfreezePerformed = settings.fixedColumnsStart > 0 && column <= settings.fixedColumnsStart - 1; if (!priv.afterFirstUse) { priv.afterFirstUse = true; } const beforeColumnUnfreezeHook = this.hot.runHooks('beforeColumnUnfreeze', column, unfreezePerformed); if (beforeColumnUnfreezeHook === false) { return; } if (unfreezePerformed) { // Since 12.0.0, the "fixedColumnsLeft" is replaced with the "fixedColumnsStart" option. // However, keeping the old name still in effect. When both option names are used together, // the error is thrown. To prevent that, the plugin needs to modify the original option key // to bypass the validation. settings._fixedColumnsStart -= 1; this.hot.columnIndexMapper.moveIndexes(column, settings.fixedColumnsStart); } this.hot.runHooks('afterColumnUnfreeze', column, unfreezePerformed); } /** * Adds the manualColumnFreeze context menu entries. * * @private * @param {object} options Context menu options. */ addContextMenuEntry(options) { options.items.push({ name: '---------' }, (0, _freezeColumn.default)(this), (0, _unfreezeColumn.default)(this)); } /** * Prevents moving the columns from/to fixed area. * * @private * @param {Array} columns Array of visual column indexes to be moved. * @param {number} finalIndex Visual column index, being a start index for the moved columns. Points to where the elements will be placed after the moving action. * @returns {boolean|undefined} */ onBeforeColumnMove(columns, finalIndex) { const priv = privatePool.get(this); if (priv.afterFirstUse) { const freezeLine = this.hot.getSettings().fixedColumnsStart; // Moving any column before the "freeze line" isn't possible. if (finalIndex < freezeLine) { return false; } // Moving frozen column isn't possible. if (columns.some(column => column < freezeLine)) { return false; } } } } exports.ManualColumnFreeze = ManualColumnFreeze;