/**
 * DevExtreme (bundles/__internal/grids/grid_core/filter/m_filter_row.js)
 * Version: 23.2.4 (build 24056-0112)
 * Build date: Sun Feb 25 2024
 *
 * Copyright (c) 2012 - 2024 Developer Express Inc. ALL RIGHTS RESERVED
 * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
 */
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.filterRowModule = void 0;
var _renderer = _interopRequireDefault(require("../../../../core/renderer"));
var _common = require("../../../../core/utils/common");
var _extend = require("../../../../core/utils/extend");
var _iterator = require("../../../../core/utils/iterator");
var _size = require("../../../../core/utils/size");
var _type = require("../../../../core/utils/type");
var _events_engine = _interopRequireDefault(require("../../../../events/core/events_engine"));
var _index = require("../../../../events/utils/index");
var _message = _interopRequireDefault(require("../../../../localization/message"));
var _editor = _interopRequireDefault(require("../../../../ui/editor/editor"));
var _menu = _interopRequireDefault(require("../../../../ui/menu"));
var _ui = _interopRequireDefault(require("../../../../ui/overlay/ui.overlay"));
var _accessibility = require("../../../../ui/shared/accessibility");
var _m_modules = _interopRequireDefault(require("../m_modules"));
var _m_utils = _interopRequireDefault(require("../m_utils"));

function _interopRequireDefault(obj) {
    return obj && obj.__esModule ? obj : {
        default: obj
    }
}

function _extends() {
    _extends = Object.assign ? Object.assign.bind() : function(target) {
        for (var i = 1; i < arguments.length; i++) {
            var source = arguments[i];
            for (var key in source) {
                if (Object.prototype.hasOwnProperty.call(source, key)) {
                    target[key] = source[key]
                }
            }
        }
        return target
    };
    return _extends.apply(this, arguments)
}

function _inheritsLoose(subClass, superClass) {
    subClass.prototype = Object.create(superClass.prototype);
    subClass.prototype.constructor = subClass;
    _setPrototypeOf(subClass, superClass)
}

function _setPrototypeOf(o, p) {
    _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function(o, p) {
        o.__proto__ = p;
        return o
    };
    return _setPrototypeOf(o, p)
}
const OPERATION_ICONS = {
    "=": "filter-operation-equals",
    "<>": "filter-operation-not-equals",
    "<": "filter-operation-less",
    "<=": "filter-operation-less-equal",
    ">": "filter-operation-greater",
    ">=": "filter-operation-greater-equal",
    default: "filter-operation-default",
    notcontains: "filter-operation-not-contains",
    contains: "filter-operation-contains",
    startswith: "filter-operation-starts-with",
    endswith: "filter-operation-ends-with",
    between: "filter-operation-between"
};
const OPERATION_DESCRIPTORS = {
    "=": "equal",
    "<>": "notEqual",
    "<": "lessThan",
    "<=": "lessThanOrEqual",
    ">": "greaterThan",
    ">=": "greaterThanOrEqual",
    startswith: "startsWith",
    contains: "contains",
    notcontains: "notContains",
    endswith: "endsWith",
    between: "between"
};
const FILTERING_TIMEOUT = 700;
const CORRECT_FILTER_RANGE_OVERLAY_WIDTH = 1;
const FILTER_ROW_CLASS = "filter-row";
const FILTER_RANGE_OVERLAY_CLASS = "filter-range-overlay";
const FILTER_RANGE_START_CLASS = "filter-range-start";
const FILTER_RANGE_END_CLASS = "filter-range-end";
const MENU_CLASS = "dx-menu";
const EDITOR_WITH_MENU_CLASS = "dx-editor-with-menu";
const EDITOR_CONTAINER_CLASS = "dx-editor-container";
const EDITOR_CELL_CLASS = "dx-editor-cell";
const FILTER_MENU = "dx-filter-menu";
const APPLY_BUTTON_CLASS = "dx-apply-button";
const HIGHLIGHT_OUTLINE_CLASS = "dx-highlight-outline";
const FOCUSED_CLASS = "dx-focused";
const CELL_FOCUS_DISABLED_CLASS = "dx-cell-focus-disabled";
const FILTER_RANGE_CONTENT_CLASS = "dx-filter-range-content";
const FILTER_MODIFIED_CLASS = "dx-filter-modified";
const EDITORS_INPUT_SELECTOR = "input:not([type='hidden'])";
const BETWEEN_OPERATION_DATA_TYPES = ["date", "datetime", "number"];
const ARIA_SEARCH_BOX = _message.default.format("dxDataGrid-ariaSearchBox");

function isOnClickApplyFilterMode(that) {
    return "onClick" === that.option("filterRow.applyFilter")
}
const getEditorInstance = function($editorContainer) {
    const $editor = $editorContainer && $editorContainer.children();
    const componentNames = $editor && $editor.data("dxComponents");
    const editor = componentNames && componentNames.length && $editor.data(componentNames[0]);
    if (editor instanceof _editor.default) {
        return editor
    }
    return null
};
const getRangeTextByFilterValue = function(that, column) {
    let result = "";
    let rangeEnd = "";
    const filterValue = getColumnFilterValue(that, column);
    const formatOptions = _m_utils.default.getFormatOptionsByColumn(column, "filterRow");
    if (Array.isArray(filterValue)) {
        result = _m_utils.default.formatValue(filterValue[0], formatOptions);
        rangeEnd = _m_utils.default.formatValue(filterValue[1], formatOptions);
        if ("" !== rangeEnd) {
            result += " - ".concat(rangeEnd)
        }
    } else if ((0, _type.isDefined)(filterValue)) {
        result = _m_utils.default.formatValue(filterValue, formatOptions)
    }
    return result
};

function getColumnFilterValue(that, column) {
    if (column) {
        return isOnClickApplyFilterMode(that) && void 0 !== column.bufferedFilterValue ? column.bufferedFilterValue : column.filterValue
    }
}
const getColumnSelectedFilterOperation = function(that, column) {
    if (column) {
        return isOnClickApplyFilterMode(that) && void 0 !== column.bufferedSelectedFilterOperation ? column.bufferedSelectedFilterOperation : column.selectedFilterOperation
    }
};
const isValidFilterValue = function(filterValue, column) {
    if (column && BETWEEN_OPERATION_DATA_TYPES.includes(column.dataType) && Array.isArray(filterValue)) {
        return false
    }
    return void 0 !== filterValue
};
const getFilterValue = function(that, columnIndex, $editorContainer) {
    const column = that._columnsController.columnOption(columnIndex);
    const filterValue = getColumnFilterValue(that, column);
    const isFilterRange = $editorContainer.closest(".".concat(that.addWidgetPrefix("filter-range-overlay"))).length;
    const isRangeStart = $editorContainer.hasClass(that.addWidgetPrefix("filter-range-start"));
    if (filterValue && Array.isArray(filterValue) && "between" === getColumnSelectedFilterOperation(that, column)) {
        if (isRangeStart) {
            return filterValue[0]
        }
        return filterValue[1]
    }
    return !isFilterRange && isValidFilterValue(filterValue, column) ? filterValue : null
};
const normalizeFilterValue = function(that, filterValue, column, $editorContainer) {
    if ("between" === getColumnSelectedFilterOperation(that, column)) {
        const columnFilterValue = getColumnFilterValue(that, column);
        if ($editorContainer.hasClass(that.addWidgetPrefix("filter-range-start"))) {
            return [filterValue, Array.isArray(columnFilterValue) ? columnFilterValue[1] : void 0]
        }
        return [Array.isArray(columnFilterValue) ? columnFilterValue[0] : columnFilterValue, filterValue]
    }
    return filterValue
};
const updateFilterValue = function(that, options) {
    const value = "" === options.value ? null : options.value;
    const $editorContainer = options.container;
    const column = that._columnsController.columnOption(options.column.index);
    const filterValue = getFilterValue(that, column.index, $editorContainer);
    if (!(0, _type.isDefined)(filterValue) && !(0, _type.isDefined)(value)) {
        return
    }
    that._applyFilterViewController.setHighLight($editorContainer, filterValue !== value);
    const columnOptionName = isOnClickApplyFilterMode(that) ? "bufferedFilterValue" : "filterValue";
    const normalizedValue = normalizeFilterValue(that, value, column, $editorContainer);
    const isBetween = "between" === getColumnSelectedFilterOperation(that, column);
    const notFireEvent = options.notFireEvent || isBetween && Array.isArray(normalizedValue) && normalizedValue.includes(void 0);
    that._columnsController.columnOption(column.index, columnOptionName, normalizedValue, notFireEvent)
};
const columnHeadersView = Base => function(_Base) {
    _inheritsLoose(ColumnHeadersViewFilterRowExtender, _Base);

    function ColumnHeadersViewFilterRowExtender() {
        return _Base.apply(this, arguments) || this
    }
    var _proto = ColumnHeadersViewFilterRowExtender.prototype;
    _proto._updateEditorValue = function(column, $editorContainer) {
        const editor = getEditorInstance($editorContainer);
        editor && editor.option("value", getFilterValue(this, column.index, $editorContainer))
    };
    _proto._columnOptionChanged = function(e) {
        var _a;
        const that = this;
        const {
            optionNames: optionNames
        } = e;
        let $cell;
        let $editorContainer;
        let $editorRangeElements;
        let $menu;
        if (_m_utils.default.checkChanges(optionNames, ["filterValue", "bufferedFilterValue", "selectedFilterOperation", "bufferedSelectedFilterOperation", "filterValues", "filterType"]) && void 0 !== e.columnIndex) {
            const visibleIndex = that._columnsController.getVisibleIndex(e.columnIndex);
            const column = that._columnsController.columnOption(e.columnIndex);
            $cell = null !== (_a = that._getCellElement(that.element().find(".".concat(that.addWidgetPrefix("filter-row"))).index(), visibleIndex)) && void 0 !== _a ? _a : (0, _renderer.default)();
            $editorContainer = $cell.find(".".concat("dx-editor-container")).first();
            if (optionNames.filterValue || optionNames.bufferedFilterValue) {
                that._updateEditorValue(column, $editorContainer);
                const overlayInstance = $cell.find(".".concat(that.addWidgetPrefix("filter-range-overlay"))).data("dxOverlay");
                if (overlayInstance) {
                    $editorRangeElements = overlayInstance.$content().find(".".concat("dx-editor-container"));
                    that._updateEditorValue(column, $editorRangeElements.first());
                    that._updateEditorValue(column, $editorRangeElements.last())
                }
                if (!overlayInstance || !overlayInstance.option("visible")) {
                    that._updateFilterRangeContent($cell, getRangeTextByFilterValue(that, column))
                }
            }
            if (optionNames.selectedFilterOperation || optionNames.bufferedSelectedFilterOperation) {
                if (visibleIndex >= 0 && column) {
                    $menu = $cell.find(".".concat("dx-menu"));
                    if ($menu.length) {
                        that._updateFilterOperationChooser($menu, column, $editorContainer);
                        if ("between" === getColumnSelectedFilterOperation(that, column)) {
                            that._renderFilterRangeContent($cell, column)
                        } else if ($editorContainer.find(".".concat("dx-filter-range-content")).length) {
                            that._renderEditor($editorContainer, that._getEditorOptions($editorContainer, column));
                            that._hideFilterRange()
                        }
                    }
                }
            }
            return
        }
        _Base.prototype._columnOptionChanged.call(this, e)
    };
    _proto._renderCore = function() {
        this._filterRangeOverlayInstance = null;
        return _Base.prototype._renderCore.apply(this, arguments)
    };
    _proto._resizeCore = function() {
        var _a;
        _Base.prototype._resizeCore.apply(this, arguments);
        null === (_a = this._filterRangeOverlayInstance) || void 0 === _a ? void 0 : _a.repaint()
    };
    _proto.isFilterRowVisible = function() {
        return this._isElementVisible(this.option("filterRow"))
    };
    _proto.isVisible = function() {
        return _Base.prototype.isVisible.call(this) || this.isFilterRowVisible()
    };
    _proto.init = function() {
        _Base.prototype.init.call(this);
        this._applyFilterViewController = this.getController("applyFilter")
    };
    _proto._initFilterRangeOverlay = function($cell, column) {
        const that = this;
        const sharedData = {};
        const $editorContainer = $cell.find(".dx-editor-container");
        const filterRangeOverlayClass = that.addWidgetPrefix("filter-range-overlay");
        const $overlay = (0, _renderer.default)("<div>").addClass(filterRangeOverlayClass).appendTo($cell);
        return that._createComponent($overlay, _ui.default, {
            height: "auto",
            shading: false,
            showTitle: false,
            focusStateEnabled: false,
            hideOnOutsideClick: true,
            wrapperAttr: {
                class: filterRangeOverlayClass
            },
            animation: false,
            position: {
                my: "top",
                at: "top",
                of: $editorContainer.length && $editorContainer || $cell,
                offset: "0 -1"
            },
            contentTemplate(contentElement) {
                let editorOptions;
                let $editor = (0, _renderer.default)("<div>").addClass("".concat("dx-editor-container", " ").concat(that.addWidgetPrefix("filter-range-start"))).appendTo(contentElement);
                column = that._columnsController.columnOption(column.index);
                editorOptions = that._getEditorOptions($editor, column);
                editorOptions.sharedData = sharedData;
                that._renderEditor($editor, editorOptions);
                _events_engine.default.on($editor.find(EDITORS_INPUT_SELECTOR), "keydown", e => {
                    let $prevElement = $cell.find("[tabindex]").not(e.target).first();
                    if ("tab" === (0, _index.normalizeKeyName)(e) && e.shiftKey) {
                        e.preventDefault();
                        that._hideFilterRange();
                        if (!$prevElement.length) {
                            $prevElement = $cell.prev().find("[tabindex]").last()
                        }
                        _events_engine.default.trigger($prevElement, "focus")
                    }
                });
                $editor = (0, _renderer.default)("<div>").addClass("".concat("dx-editor-container", " ").concat(that.addWidgetPrefix("filter-range-end"))).appendTo(contentElement);
                editorOptions = that._getEditorOptions($editor, column);
                editorOptions.sharedData = sharedData;
                that._renderEditor($editor, editorOptions);
                _events_engine.default.on($editor.find(EDITORS_INPUT_SELECTOR), "keydown", e => {
                    if ("tab" === (0, _index.normalizeKeyName)(e) && !e.shiftKey) {
                        e.preventDefault();
                        that._hideFilterRange();
                        _events_engine.default.trigger($cell.next().find("[tabindex]").first(), "focus")
                    }
                });
                return (0, _renderer.default)(contentElement).addClass(that.getWidgetContainerClass())
            },
            onShown(e) {
                const $editor = e.component.$content().find(".".concat("dx-editor-container")).first();
                _events_engine.default.trigger($editor.find(EDITORS_INPUT_SELECTOR), "focus")
            },
            onHidden() {
                column = that._columnsController.columnOption(column.index);
                $cell.find(".".concat("dx-menu")).parent().addClass("dx-editor-with-menu");
                if ("between" === getColumnSelectedFilterOperation(that, column)) {
                    that._updateFilterRangeContent($cell, getRangeTextByFilterValue(that, column));
                    that.component.updateDimensions()
                }
            }
        })
    };
    _proto._updateFilterRangeOverlay = function(options) {
        const overlayInstance = this._filterRangeOverlayInstance;
        overlayInstance && overlayInstance.option(options)
    };
    _proto._showFilterRange = function($cell, column) {
        const that = this;
        const $overlay = $cell.children(".".concat(that.addWidgetPrefix("filter-range-overlay")));
        let overlayInstance = $overlay.length && $overlay.data("dxOverlay");
        if (!overlayInstance && column) {
            overlayInstance = that._initFilterRangeOverlay($cell, column)
        }
        if (!overlayInstance.option("visible")) {
            that._filterRangeOverlayInstance && that._filterRangeOverlayInstance.hide();
            that._filterRangeOverlayInstance = overlayInstance;
            that._updateFilterRangeOverlay({
                width: (0, _size.getOuterWidth)($cell, true) + 1
            });
            that._filterRangeOverlayInstance && that._filterRangeOverlayInstance.show()
        }
    };
    _proto._hideFilterRange = function() {
        const overlayInstance = this._filterRangeOverlayInstance;
        overlayInstance && overlayInstance.hide()
    };
    _proto.getFilterRangeOverlayInstance = function() {
        return this._filterRangeOverlayInstance
    };
    _proto._createRow = function(row) {
        const $row = _Base.prototype._createRow.call(this, row);
        if ("filter" === row.rowType) {
            $row.addClass(this.addWidgetPrefix("filter-row"));
            if (!this.option("useLegacyKeyboardNavigation")) {
                _events_engine.default.on($row, "keydown", event => (0, _accessibility.selectView)("filterRow", this, event))
            }
        }
        return $row
    };
    _proto._getRows = function() {
        const result = _Base.prototype._getRows.call(this);
        if (this.isFilterRowVisible()) {
            result.push({
                rowType: "filter"
            })
        }
        return result
    };
    _proto._renderFilterCell = function(cell, options) {
        const that = this;
        const {
            column: column
        } = options;
        const $cell = (0, _renderer.default)(cell);
        if (that.component.option("showColumnHeaders")) {
            that.setAria("describedby", column.headerId, $cell)
        }
        that.setAria("label", _message.default.format("dxDataGrid-ariaFilterCell"), $cell);
        $cell.addClass("dx-editor-cell");
        const $container = (0, _renderer.default)("<div>").appendTo($cell);
        const $editorContainer = (0, _renderer.default)("<div>").addClass("dx-editor-container").appendTo($container);
        if ("between" === getColumnSelectedFilterOperation(that, column)) {
            that._renderFilterRangeContent($cell, column)
        } else {
            const editorOptions = that._getEditorOptions($editorContainer, column);
            that._renderEditor($editorContainer, editorOptions)
        }
        const {
            alignment: alignment
        } = column;
        if (alignment && "center" !== alignment) {
            $cell.find(EDITORS_INPUT_SELECTOR).first().css("textAlign", column.alignment)
        }
        if (column.filterOperations && column.filterOperations.length) {
            that._renderFilterOperationChooser($container, column, $editorContainer)
        }
    };
    _proto._renderCellContent = function($cell, options) {
        const that = this;
        const {
            column: column
        } = options;
        if ("filter" === options.rowType) {
            if (column.command) {
                $cell.html("&nbsp;")
            } else if (column.allowFiltering) {
                that.renderTemplate($cell, that._renderFilterCell.bind(that), options).done(() => {
                    that._updateCell($cell, options)
                });
                return
            }
        }
        _Base.prototype._renderCellContent.apply(this, arguments)
    };
    _proto._getEditorOptions = function($editorContainer, column) {
        const that = this;
        const accessibilityOptions = {
            editorOptions: {
                inputAttr: that._getFilterInputAccessibilityAttributes(column)
            }
        };
        const result = (0, _extend.extend)(accessibilityOptions, column, {
            value: getFilterValue(that, column.index, $editorContainer),
            parentType: "filterRow",
            showAllText: that.option("filterRow.showAllText"),
            updateValueTimeout: "onClick" === that.option("filterRow.applyFilter") ? 0 : 700,
            width: null,
            setValue(value, notFireEvent) {
                updateFilterValue(that, {
                    column: column,
                    value: value,
                    container: $editorContainer,
                    notFireEvent: notFireEvent
                })
            }
        });
        if ("between" === getColumnSelectedFilterOperation(that, column)) {
            if ($editorContainer.hasClass(that.addWidgetPrefix("filter-range-start"))) {
                result.placeholder = that.option("filterRow.betweenStartText")
            } else {
                result.placeholder = that.option("filterRow.betweenEndText")
            }
        }
        return result
    };
    _proto._getFilterInputAccessibilityAttributes = function(column) {
        const columnAriaLabel = _message.default.format("dxDataGrid-ariaFilterCell");
        if (this.component.option("showColumnHeaders")) {
            return {
                "aria-label": columnAriaLabel,
                "aria-describedby": column.headerId
            }
        }
        return {
            "aria-label": columnAriaLabel
        }
    };
    _proto._renderEditor = function($editorContainer, options) {
        $editorContainer.empty();
        const $element = (0, _renderer.default)("<div>").appendTo($editorContainer);
        const editorController = this.getController("editorFactory");
        const dataSource = this.getController("data").dataSource();
        const filterRowController = this.getController("applyFilter");
        if (options.lookup && this.option("syncLookupFilterValues")) {
            filterRowController.setCurrentColumnForFiltering(options);
            const filter = this.getController("data").getCombinedFilter();
            filterRowController.setCurrentColumnForFiltering(null);
            const lookupDataSource = _m_utils.default.getWrappedLookupDataSource(options, dataSource, filter);
            const lookupOptions = _extends(_extends({}, options), {
                lookup: _extends(_extends({}, options.lookup), {
                    dataSource: lookupDataSource
                })
            });
            return editorController.createEditor($element, lookupOptions)
        }
        return editorController.createEditor($element, options)
    };
    _proto._renderFilterRangeContent = function($cell, column) {
        const that = this;
        const $editorContainer = $cell.find(".".concat("dx-editor-container")).first();
        $editorContainer.empty();
        const $filterRangeContent = (0, _renderer.default)("<div>").addClass("dx-filter-range-content").attr("tabindex", this.option("tabIndex"));
        _events_engine.default.on($filterRangeContent, "focusin", () => {
            that._showFilterRange($cell, column)
        });
        $filterRangeContent.appendTo($editorContainer);
        that._updateFilterRangeContent($cell, getRangeTextByFilterValue(that, column))
    };
    _proto._updateFilterRangeContent = function($cell, value) {
        const $filterRangeContent = $cell.find(".".concat("dx-filter-range-content"));
        if ($filterRangeContent.length) {
            if ("" === value) {
                $filterRangeContent.html("&nbsp;")
            } else {
                $filterRangeContent.text(value)
            }
        }
    };
    _proto._updateFilterOperationChooser = function($menu, column, $editorContainer) {
        const that = this;
        let isCellWasFocused;
        const restoreFocus = function() {
            const menu = _menu.default.getInstance($menu);
            menu && menu.option("focusedElement", null);
            isCellWasFocused && that._focusEditor($editorContainer)
        };
        that._createComponent($menu, _menu.default, {
            integrationOptions: {},
            activeStateEnabled: false,
            selectionMode: "single",
            cssClass: "".concat(that.getWidgetContainerClass(), " ").concat("dx-cell-focus-disabled", " ").concat(FILTER_MENU),
            showFirstSubmenuMode: "onHover",
            hideSubmenuOnMouseLeave: true,
            items: [{
                disabled: !(column.filterOperations && column.filterOperations.length),
                icon: OPERATION_ICONS[getColumnSelectedFilterOperation(that, column) || "default"],
                selectable: false,
                items: that._getFilterOperationMenuItems(column)
            }],
            onItemRendered: _ref => {
                let {
                    itemElement: itemElement
                } = _ref;
                this.setAria("label", ARIA_SEARCH_BOX, (0, _renderer.default)(itemElement))
            },
            onItemClick(properties) {
                const selectedFilterOperation = properties.itemData.name;
                const columnSelectedFilterOperation = getColumnSelectedFilterOperation(that, column);
                let notFocusEditor = false;
                const isOnClickMode = isOnClickApplyFilterMode(that);
                const options = {};
                if (properties.itemData.items || selectedFilterOperation && selectedFilterOperation === columnSelectedFilterOperation) {
                    return
                }
                if (selectedFilterOperation) {
                    options[isOnClickMode ? "bufferedSelectedFilterOperation" : "selectedFilterOperation"] = selectedFilterOperation;
                    if ("between" === selectedFilterOperation || "between" === columnSelectedFilterOperation) {
                        notFocusEditor = "between" === selectedFilterOperation;
                        options[isOnClickMode ? "bufferedFilterValue" : "filterValue"] = null
                    }
                } else {
                    options[isOnClickMode ? "bufferedFilterValue" : "filterValue"] = null;
                    options[isOnClickMode ? "bufferedSelectedFilterOperation" : "selectedFilterOperation"] = column.defaultSelectedFilterOperation || null
                }
                that._columnsController.columnOption(column.index, options);
                that._applyFilterViewController.setHighLight($editorContainer, true);
                if (!selectedFilterOperation) {
                    const editor = getEditorInstance($editorContainer);
                    if (editor && "dxDateBox" === editor.NAME && !editor.option("isValid")) {
                        editor.clear();
                        editor.option("isValid", true)
                    }
                }
                if (!notFocusEditor) {
                    that._focusEditor($editorContainer)
                } else {
                    that._showFilterRange($editorContainer.closest(".".concat("dx-editor-cell")), column)
                }
            },
            onSubmenuShowing() {
                isCellWasFocused = that._isEditorFocused($editorContainer);
                that.getController("editorFactory").loseFocus()
            },
            onSubmenuHiding() {
                _events_engine.default.trigger($menu, "blur");
                restoreFocus()
            },
            onContentReady(e) {
                _events_engine.default.on($menu, "blur", () => {
                    const menu = e.component;
                    menu._hideSubmenuAfterTimeout();
                    restoreFocus()
                })
            },
            rtlEnabled: that.option("rtlEnabled")
        })
    };
    _proto._isEditorFocused = function($container) {
        return $container.hasClass("dx-focused") || $container.parents(".".concat("dx-focused")).length
    };
    _proto._focusEditor = function($container) {
        this.getController("editorFactory").focus($container);
        _events_engine.default.trigger($container.find(EDITORS_INPUT_SELECTOR), "focus")
    };
    _proto._renderFilterOperationChooser = function($container, column, $editorContainer) {
        const that = this;
        let $menu;
        if (that.option("filterRow.showOperationChooser")) {
            $container.addClass("dx-editor-with-menu");
            $menu = (0, _renderer.default)("<div>").prependTo($container);
            that._updateFilterOperationChooser($menu, column, $editorContainer)
        }
    };
    _proto._getFilterOperationMenuItems = function(column) {
        const that = this;
        let result = [{}];
        const filterRowOptions = that.option("filterRow");
        const operationDescriptions = filterRowOptions && filterRowOptions.operationDescriptions || {};
        if (column.filterOperations && column.filterOperations.length) {
            const availableFilterOperations = column.filterOperations.filter(value => (0, _type.isDefined)(OPERATION_DESCRIPTORS[value]));
            result = (0, _iterator.map)(availableFilterOperations, value => {
                const descriptionName = OPERATION_DESCRIPTORS[value];
                return {
                    name: value,
                    selected: (getColumnSelectedFilterOperation(that, column) || column.defaultFilterOperation) === value,
                    text: operationDescriptions[descriptionName],
                    icon: OPERATION_ICONS[value]
                }
            });
            result.push({
                name: null,
                text: filterRowOptions && filterRowOptions.resetOperationText,
                icon: OPERATION_ICONS.default
            })
        }
        return result
    };
    _proto._handleDataChanged = function(e) {
        var _a, _b, _c, _d, _e, _f;
        const dataSource = null === (_b = null === (_a = this._dataController) || void 0 === _a ? void 0 : _a.dataSource) || void 0 === _b ? void 0 : _b.call(_a);
        const lastLoadOptions = null === (_c = null === dataSource || void 0 === dataSource ? void 0 : dataSource.lastLoadOptions) || void 0 === _c ? void 0 : _c.call(dataSource);
        _Base.prototype._handleDataChanged.apply(this, arguments);
        if ((null === (_d = e.operationTypes) || void 0 === _d ? void 0 : _d.filtering) || (null === (_e = e.operationTypes) || void 0 === _e ? void 0 : _e.fullReload)) {
            this.updateLookupDataSource((null === (_f = e.operationTypes) || void 0 === _f ? void 0 : _f.filtering) || (null === lastLoadOptions || void 0 === lastLoadOptions ? void 0 : lastLoadOptions.filter))
        }
    };
    _proto.updateLookupDataSource = function(filterChanged) {
        if (!this.option("syncLookupFilterValues")) {
            return
        }
        if (!this.element()) {
            return
        }
        const columns = this._columnsController.getVisibleColumns();
        const dataSource = this._dataController.dataSource();
        const applyFilterViewController = this._applyFilterViewController;
        const rowIndex = this.element().find(".".concat(this.addWidgetPrefix("filter-row"))).index();
        if (-1 === rowIndex) {
            return
        }
        columns.forEach((column, index) => {
            if (!column.lookup || column.calculateCellValue !== column.defaultCalculateCellValue) {
                return
            }
            const $cell = this._getCellElement(rowIndex, index);
            const editor = getEditorInstance(null === $cell || void 0 === $cell ? void 0 : $cell.find(".dx-editor-container"));
            if (editor) {
                applyFilterViewController.setCurrentColumnForFiltering(column);
                const filter = this._dataController.getCombinedFilter() || null;
                applyFilterViewController.setCurrentColumnForFiltering(null);
                const editorDataSource = editor.option("dataSource");
                const shouldUpdateFilter = !filterChanged || !(0, _common.equalByValue)(editorDataSource.__dataGridSourceFilter || null, filter);
                if (shouldUpdateFilter) {
                    const lookupDataSource = _m_utils.default.getWrappedLookupDataSource(column, dataSource, filter);
                    editor.option("dataSource", lookupDataSource)
                }
            }
        })
    };
    _proto.optionChanged = function(args) {
        switch (args.name) {
            case "filterRow":
            case "showColumnLines":
                this._invalidate(true, true);
                args.handled = true;
                break;
            case "syncLookupFilterValues":
                if (args.value) {
                    this.updateLookupDataSource()
                } else {
                    this.render()
                }
                args.handled = true;
                break;
            default:
                _Base.prototype.optionChanged.call(this, args)
        }
    };
    return ColumnHeadersViewFilterRowExtender
}(Base);
const data = Base => function(_Base2) {
    _inheritsLoose(DataControllerFilterRowExtender, _Base2);

    function DataControllerFilterRowExtender() {
        return _Base2.apply(this, arguments) || this
    }
    var _proto2 = DataControllerFilterRowExtender.prototype;
    _proto2.skipCalculateColumnFilters = function() {
        return false
    };
    _proto2._calculateAdditionalFilter = function() {
        if (this.skipCalculateColumnFilters()) {
            return _Base2.prototype._calculateAdditionalFilter.call(this)
        }
        const filters = [_Base2.prototype._calculateAdditionalFilter.call(this)];
        const columns = this._columnsController.getVisibleColumns(null, true);
        const filterRowController = this.getController("applyFilter");
        (0, _iterator.each)(columns, (function() {
            var _a;
            const shouldSkip = (null === (_a = filterRowController.getCurrentColumnForFiltering()) || void 0 === _a ? void 0 : _a.index) === this.index;
            if (this.allowFiltering && this.calculateFilterExpression && (0, _type.isDefined)(this.filterValue) && !shouldSkip) {
                const filter = this.createFilterExpression(this.filterValue, this.selectedFilterOperation || this.defaultFilterOperation, "filterRow");
                filters.push(filter)
            }
        }));
        return _m_utils.default.combineFilters(filters)
    };
    return DataControllerFilterRowExtender
}(Base);
let ApplyFilterViewController = function(_modules$ViewControll) {
    _inheritsLoose(ApplyFilterViewController, _modules$ViewControll);

    function ApplyFilterViewController() {
        return _modules$ViewControll.apply(this, arguments) || this
    }
    var _proto3 = ApplyFilterViewController.prototype;
    _proto3._getHeaderPanel = function() {
        if (!this._headerPanel) {
            this._headerPanel = this.getView("headerPanel")
        }
        return this._headerPanel
    };
    _proto3.setHighLight = function($element, value) {
        if (isOnClickApplyFilterMode(this)) {
            $element && $element.toggleClass("dx-highlight-outline", value) && $element.closest(".".concat("dx-editor-cell")).toggleClass("dx-filter-modified", value);
            this._getHeaderPanel().enableApplyButton(value)
        }
    };
    _proto3.applyFilter = function() {
        const columnsController = this.getController("columns");
        const columns = columnsController.getColumns();
        columnsController.beginUpdate();
        for (let i = 0; i < columns.length; i++) {
            const column = columns[i];
            if (void 0 !== column.bufferedFilterValue) {
                columnsController.columnOption(i, "filterValue", column.bufferedFilterValue);
                column.bufferedFilterValue = void 0
            }
            if (void 0 !== column.bufferedSelectedFilterOperation) {
                columnsController.columnOption(i, "selectedFilterOperation", column.bufferedSelectedFilterOperation);
                column.bufferedSelectedFilterOperation = void 0
            }
        }
        columnsController.endUpdate();
        this.removeHighLights()
    };
    _proto3.removeHighLights = function() {
        if (isOnClickApplyFilterMode(this)) {
            const columnHeadersViewElement = this.getView("columnHeadersView").element();
            columnHeadersViewElement.find(".".concat(this.addWidgetPrefix("filter-row"), " .").concat("dx-highlight-outline")).removeClass("dx-highlight-outline");
            columnHeadersViewElement.find(".".concat(this.addWidgetPrefix("filter-row"), " .").concat("dx-filter-modified")).removeClass("dx-filter-modified");
            this._getHeaderPanel().enableApplyButton(false)
        }
    };
    _proto3.setCurrentColumnForFiltering = function(column) {
        this._currentColumn = column
    };
    _proto3.getCurrentColumnForFiltering = function() {
        return this._currentColumn
    };
    return ApplyFilterViewController
}(_m_modules.default.ViewController);
const columnsResizer = Base => function(_Base3) {
    _inheritsLoose(FilterRowColumnsResizerExtender, _Base3);

    function FilterRowColumnsResizerExtender() {
        return _Base3.apply(this, arguments) || this
    }
    var _proto4 = FilterRowColumnsResizerExtender.prototype;
    _proto4._startResizing = function() {
        const that = this;
        _Base3.prototype._startResizing.apply(that, arguments);
        if (that.isResizing()) {
            const overlayInstance = that._columnHeadersView.getFilterRangeOverlayInstance();
            if (overlayInstance) {
                const cellIndex = overlayInstance.$element().closest("td").index();
                if (cellIndex === that._targetPoint.columnIndex || cellIndex === that._targetPoint.columnIndex + 1) {
                    overlayInstance.$content().hide()
                }
            }
        }
    };
    _proto4._endResizing = function() {
        const that = this;
        let $cell;
        if (that.isResizing()) {
            const overlayInstance = that._columnHeadersView.getFilterRangeOverlayInstance();
            if (overlayInstance) {
                $cell = overlayInstance.$element().closest("td");
                that._columnHeadersView._updateFilterRangeOverlay({
                    width: (0, _size.getOuterWidth)($cell, true) + 1
                });
                overlayInstance.$content().show()
            }
        }
        _Base3.prototype._endResizing.apply(that, arguments)
    };
    return FilterRowColumnsResizerExtender
}(Base);
const editing = Base => function(_Base4) {
    _inheritsLoose(FilterRowEditingController, _Base4);

    function FilterRowEditingController() {
        return _Base4.apply(this, arguments) || this
    }
    var _proto5 = FilterRowEditingController.prototype;
    _proto5.updateFieldValue = function(options) {
        if (options.column.lookup) {
            this._needUpdateLookupDataSource = true
        }
        return _Base4.prototype.updateFieldValue.apply(this, arguments)
    };
    _proto5._afterSaveEditData = function(cancel) {
        var _a;
        if (this._needUpdateLookupDataSource && !cancel) {
            null === (_a = this.getView("columnHeadersView")) || void 0 === _a ? void 0 : _a.updateLookupDataSource()
        }
        this._needUpdateLookupDataSource = false;
        return _Base4.prototype._afterSaveEditData.apply(this, arguments)
    };
    _proto5._afterCancelEditData = function() {
        this._needUpdateLookupDataSource = false;
        return _Base4.prototype._afterCancelEditData.apply(this, arguments)
    };
    return FilterRowEditingController
}(Base);
const headerPanel = Base => function(_Base5) {
    _inheritsLoose(FilterRowHeaderPanel, _Base5);

    function FilterRowHeaderPanel() {
        return _Base5.apply(this, arguments) || this
    }
    var _proto6 = FilterRowHeaderPanel.prototype;
    _proto6._getToolbarItems = function() {
        const items = _Base5.prototype._getToolbarItems.call(this);
        const filterItem = this._prepareFilterItem();
        return filterItem.concat(items)
    };
    _proto6._prepareFilterItem = function() {
        const that = this;
        const filterItem = [];
        if (that._isShowApplyFilterButton()) {
            const hintText = that.option("filterRow.applyFilterText");
            const columns = that._columnsController.getColumns();
            const disabled = !columns.filter(column => void 0 !== column.bufferedFilterValue).length;
            const onInitialized = function(e) {
                (0, _renderer.default)(e.element).addClass(that._getToolbarButtonClass("dx-apply-button"))
            };
            const onClickHandler = function() {
                that._applyFilterViewController.applyFilter()
            };
            const toolbarItem = {
                widget: "dxButton",
                options: {
                    icon: "apply-filter",
                    disabled: disabled,
                    onClick: onClickHandler,
                    hint: hintText,
                    text: hintText,
                    onInitialized: onInitialized
                },
                showText: "inMenu",
                name: "applyFilterButton",
                location: "after",
                locateInMenu: "auto",
                sortIndex: 10
            };
            filterItem.push(toolbarItem)
        }
        return filterItem
    };
    _proto6._isShowApplyFilterButton = function() {
        const filterRowOptions = this.option("filterRow");
        return !!(null === filterRowOptions || void 0 === filterRowOptions ? void 0 : filterRowOptions.visible) && "onClick" === filterRowOptions.applyFilter
    };
    _proto6.init = function() {
        _Base5.prototype.init.call(this);
        this._dataController = this.getController("data");
        this._applyFilterViewController = this.getController("applyFilter")
    };
    _proto6.enableApplyButton = function(value) {
        this.setToolbarItemDisabled("applyFilterButton", !value)
    };
    _proto6.isVisible = function() {
        return _Base5.prototype.isVisible.call(this) || this._isShowApplyFilterButton()
    };
    _proto6.optionChanged = function(args) {
        if ("filterRow" === args.name) {
            this._invalidate();
            args.handled = true
        } else {
            _Base5.prototype.optionChanged.call(this, args)
        }
    };
    return FilterRowHeaderPanel
}(Base);
const filterRowModule = {
    defaultOptions: () => ({
        syncLookupFilterValues: true,
        filterRow: {
            visible: false,
            showOperationChooser: true,
            showAllText: _message.default.format("dxDataGrid-filterRowShowAllText"),
            resetOperationText: _message.default.format("dxDataGrid-filterRowResetOperationText"),
            applyFilter: "auto",
            applyFilterText: _message.default.format("dxDataGrid-applyFilterText"),
            operationDescriptions: {
                equal: _message.default.format("dxDataGrid-filterRowOperationEquals"),
                notEqual: _message.default.format("dxDataGrid-filterRowOperationNotEquals"),
                lessThan: _message.default.format("dxDataGrid-filterRowOperationLess"),
                lessThanOrEqual: _message.default.format("dxDataGrid-filterRowOperationLessOrEquals"),
                greaterThan: _message.default.format("dxDataGrid-filterRowOperationGreater"),
                greaterThanOrEqual: _message.default.format("dxDataGrid-filterRowOperationGreaterOrEquals"),
                startsWith: _message.default.format("dxDataGrid-filterRowOperationStartsWith"),
                contains: _message.default.format("dxDataGrid-filterRowOperationContains"),
                notContains: _message.default.format("dxDataGrid-filterRowOperationNotContains"),
                endsWith: _message.default.format("dxDataGrid-filterRowOperationEndsWith"),
                between: _message.default.format("dxDataGrid-filterRowOperationBetween"),
                isBlank: _message.default.format("dxFilterBuilder-filterOperationIsBlank"),
                isNotBlank: _message.default.format("dxFilterBuilder-filterOperationIsNotBlank")
            },
            betweenStartText: _message.default.format("dxDataGrid-filterRowOperationBetweenStartText"),
            betweenEndText: _message.default.format("dxDataGrid-filterRowOperationBetweenEndText")
        }
    }),
    controllers: {
        applyFilter: ApplyFilterViewController
    },
    extenders: {
        controllers: {
            data: data,
            columnsResizer: columnsResizer,
            editing: editing
        },
        views: {
            columnHeadersView: columnHeadersView,
            headerPanel: headerPanel
        }
    }
};
exports.filterRowModule = filterRowModule;
