"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.QuickFilterFormReact = void 0;
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
const debounce_1 = tslib_1.__importDefault(require("lodash/debounce"));
const LayoutRedux = tslib_1.__importStar(require("../../../Redux/ActionsReducers/LayoutRedux"));
const LayoutRedux_1 = require("../../../Redux/ActionsReducers/LayoutRedux");
const react_redux_1 = require("react-redux");
const ObjectFactory_1 = require("../../../Utilities/ObjectFactory");
const OverlayTrigger_1 = tslib_1.__importDefault(require("../../../components/OverlayTrigger"));
const SimpleButton_1 = tslib_1.__importDefault(require("../../../components/SimpleButton"));
const icons_1 = require("../../../components/icons");
const rebass_1 = require("rebass");
const AdaptableInput_1 = tslib_1.__importDefault(require("../AdaptableInput"));
const renderWithAdaptableContext_1 = require("../../renderWithAdaptableContext");
const CheckBox_1 = require("../../../components/CheckBox");
const getDefaultColumnFilterPredicate_1 = require("./getDefaultColumnFilterPredicate");
const Icon_1 = require("../../../components/Icon");
const QuickFilterValues_1 = require("./QuickFilterValues");
const AdaptableIconComponent_1 = require("../AdaptableIconComponent");
const AdaptableDateInlineInput_1 = require("../AdaptableInput/AdaptableDateInlineInput");
class QuickFilterFormComponent extends React.Component {
    constructor(props) {
        super(props);
        this.shouldOpenValuesDropdown = false;
        this._isMounted = false;
        this.debouncedAddFilter = (0, debounce_1.default)((filter) => this.props.onAddColumnFilter(filter), this.props.quickFilterDebounce);
        this.debouncedEditFilter = (0, debounce_1.default)((filter) => this.props.onEditColumnFilter(filter), this.props.quickFilterDebounce);
        this._isMounted = true;
        this.state = {
            transientColumnFilter: props.columnFilter,
        };
    }
    static getDerivedStateFromProps(props, state) {
        return Object.assign(Object.assign({}, state), { transientColumnFilter: props.columnFilter });
    }
    componentWillUnmount() {
        this._isMounted = false;
    }
    isFilterDisabled() {
        return Boolean(this.props.columnFilter.IsSuspended);
    }
    render() {
        /**
         * Transient column filter needs to be used for it to work with the debounced update.
         */
        const { transientColumnFilter } = this.state;
        const predicateDefs = this.props.api.columnFilterApi.getFilterPredicateDefsForColumn(this.props.currentColumn);
        const activePredicateDef = this.props.api.predicateApi.getPredicateDefById(transientColumnFilter === null || transientColumnFilter === void 0 ? void 0 : transientColumnFilter.Predicate.PredicateId);
        if (!this.props.currentColumn || !this.props.currentColumn.filterable) {
            return null;
        }
        let showEvent = 'mouseenter';
        let hideEvent = 'mouseleave';
        if (this.props.quickFilterTrigger === 'click') {
            showEvent = 'click';
            hideEvent = 'blur';
        }
        let showQuickFilterDropdown = true;
        let hideQuickFilterDropdownFunction = this.props.api.optionsApi.getColumnFilterOptions().quickFilterOptions
            .hideQuickFilterDropdown;
        if (hideQuickFilterDropdownFunction) {
            const columnFilterContext = Object.assign({ column: this.props.currentColumn }, this.props.api.internalApi.buildBaseContext());
            showQuickFilterDropdown = !hideQuickFilterDropdownFunction(columnFilterContext);
        }
        let showQuickFilterInput = true;
        let hideQuickFilterInputFunction = this.props.api.optionsApi.getColumnFilterOptions().quickFilterOptions.hideQuickFilterInput;
        if (hideQuickFilterInputFunction) {
            const columnFilterContext = Object.assign({ column: this.props.currentColumn }, this.props.api.internalApi.buildBaseContext());
            showQuickFilterInput = !hideQuickFilterInputFunction(columnFilterContext);
        }
        return (React.createElement(React.Fragment, null,
            showQuickFilterDropdown && (React.createElement(OverlayTrigger_1.default, { className: "ab-QuickFilter", showEvent: showEvent, hideEvent: hideEvent, preventPortalEventPropagation: showEvent === 'click', targetOffset: 10, hideDelay: 50, "data-name": "quick-filter-overlay", render: () => (React.createElement(rebass_1.Flex, { className: "ab-QuickFilter__dropdown", flexDirection: "column", "data-name": "quick-filter", fontSize: 2 },
                    (transientColumnFilter === null || transientColumnFilter === void 0 ? void 0 : transientColumnFilter.Predicate.PredicateId) && (React.createElement(SimpleButton_1.default, { p: 2, variant: "text", onClick: () => this.clearFilter() },
                        React.createElement("span", { style: { width: 20, marginRight: 10 } },
                            React.createElement(icons_1.Icon, { name: "delete" })),
                        "Clear")),
                    predicateDefs.map((p) => (React.createElement(SimpleButton_1.default, { "data-name": transientColumnFilter.Predicate.PredicateId, disabled: this.isFilterDisabled(), key: p.id, p: 2, variant: "text", tone: (transientColumnFilter === null || transientColumnFilter === void 0 ? void 0 : transientColumnFilter.Predicate.PredicateId) === p.id ? 'info' : 'none', onClick: () => this.selectColumnPredicate(p.id) },
                        React.createElement("span", { style: { width: 20, marginRight: 10 } }, this.renderPredicateIcon(p)),
                        p.label))))) },
                React.createElement(SimpleButton_1.default, { "data-name": transientColumnFilter.Predicate.PredicateId, style: {
                        borderRadius: 0,
                        borderColor: 'var(--ab-color-primarydark)',
                    } }, this.renderPredicateIcon(activePredicateDef)))),
            showQuickFilterInput && this.renderLabel(transientColumnFilter, activePredicateDef),
            showQuickFilterInput &&
                this.renderPredicateInput(activePredicateDef, transientColumnFilter)));
    }
    renderLabel(filter, activePredicateDef) {
        if (this.hasValuesPredicate(filter === null || filter === void 0 ? void 0 : filter.Predicate)) {
            return (React.createElement(QuickFilterValues_1.QuickFilterValues, { api: this.props.api, currentColumn: this.props.currentColumn, isFilterDisabled: this.isFilterDisabled(), columnFilter: filter, clearColumnFilter: () => this.clearFilter(), updateColumnFilter: (columnFilter) => this.updateFilter(columnFilter), registerValuesDropdownApi: (api) => {
                    if (api && this.shouldOpenValuesDropdown) {
                        api.show();
                        this.shouldOpenValuesDropdown = false;
                    }
                }, valuesFilterTrigger: this.props.valuesFilterTrigger }));
        }
        return (activePredicateDef &&
            (activePredicateDef === null || activePredicateDef === void 0 ? void 0 : activePredicateDef.inputs) === undefined && (React.createElement(rebass_1.Box, { color: this.isFilterDisabled() ? undefined : 'var(--ab-color-text-on-primary)', disabled: this.isFilterDisabled(), p: 1, alignSelf: "center" }, activePredicateDef.label)));
    }
    renderPredicateIcon(predicateDef) {
        if (!predicateDef || !predicateDef.icon) {
            return React.createElement(icons_1.Icon, { name: "filter" });
        }
        if ('text' in predicateDef.icon) {
            return React.createElement("span", null, predicateDef.icon.text);
        }
        if ((0, Icon_1.isAdaptableIcon)(predicateDef.icon)) {
            return React.createElement(AdaptableIconComponent_1.AdaptableIconComponent, { icon: predicateDef.icon });
        }
    }
    renderPredicateInput(predicateDef, filter) {
        var _a;
        if ((predicateDef === null || predicateDef === void 0 ? void 0 : predicateDef.id) === 'BooleanToggle') {
            // custom tri-state checkbox: 'checked', 'unchecked', 'all'
            return (React.createElement(rebass_1.Flex, { flexDirection: "row", flex: 1, justifyContent: "center", alignItems: "center", style: { position: 'absolute', left: 0, right: 0, bottom: 0, top: 0 } },
                React.createElement(CheckBox_1.CheckBox, { disabled: this.isFilterDisabled(), checked: filter.Predicate.Inputs[0] === 'checked'
                        ? true
                        : filter.Predicate.Inputs[0] === 'unchecked'
                            ? false
                            : // 'all'
                                null, onChange: (checked) => {
                        // sequence: 'checked' -> 'unchecked' -> 'all' -> 'checked'
                        const newCheckedValue = filter.Predicate.Inputs[0] === 'unchecked' && checked === true
                            ? 'all'
                            : checked === true
                                ? 'checked'
                                : 'unchecked';
                        this.changeColumnPredicateInput(newCheckedValue, 0);
                    } })));
        }
        return (_a = predicateDef === null || predicateDef === void 0 ? void 0 : predicateDef.inputs) === null || _a === void 0 ? void 0 : _a.map((predicateInput, index) => {
            var _a, _b, _c, _d, _e, _f;
            const showDatePicker = (_b = (_a = this.props.api.optionsApi) === null || _a === void 0 ? void 0 : _a.getColumnFilterOptions()) === null || _b === void 0 ? void 0 : _b.showDatePicker;
            const value = (_d = (_c = filter.Predicate.Inputs) === null || _c === void 0 ? void 0 : _c[index]) !== null && _d !== void 0 ? _d : '';
            const onKeyDownCapture = (e) => {
                if (e.nativeEvent.key === 'Escape') {
                    e.nativeEvent.preventDefault();
                    e.nativeEvent.stopPropagation();
                    this.clearFilter();
                }
            };
            if (predicateInput.type === 'date' && !showDatePicker) {
                return (React.createElement(AdaptableDateInlineInput_1.AdaptableDateInlineInput, { value: value, key: index, onKeyDownCapture: onKeyDownCapture, onChange: (value) => this.changeColumnPredicateInput(value, index) }));
            }
            return (React.createElement(AdaptableInput_1.default, { disabled: this.isFilterDisabled(), key: index, type: predicateInput.type === 'number' ? 'text' : predicateInput.type, 
                // autoFocus has to be FALSE because if the input receives focus in the init phase,
                // it may scroll the AG Grid header viewport into view and de-synchronize it (relative to the content viewport)
                autoFocus: false, value: (_f = (_e = filter.Predicate.Inputs) === null || _e === void 0 ? void 0 : _e[index]) !== null && _f !== void 0 ? _f : '', onChange: (e) => this.changeColumnPredicateInput(e.target.value, index), onKeyDownCapture: onKeyDownCapture, style: {
                    width: '100%',
                    padding: 'var(--ab-space-1)',
                    borderRadius: 0,
                    borderLeftWidth: 0,
                } }));
        });
    }
    onColumnValuesChange(columnValues) {
        var _a;
        const columnFilter = Object.assign({}, this.props.columnFilter);
        columnFilter.Predicate = {
            PredicateId: columnFilter.Predicate.PredicateId,
            Inputs: columnValues,
        };
        if ((_a = this.props.api.optionsApi.getColumnFilterOptions()) === null || _a === void 0 ? void 0 : _a.autoApplyFilter) {
            this.updateFilter(columnFilter);
        }
        else {
            this.setState({ transientColumnFilter: columnFilter });
        }
    }
    selectColumnPredicate(predicateId) {
        var _a;
        const columnFilter = Object.assign({}, this.props.columnFilter);
        const predicateDef = this.props.api.predicateApi.getPredicateDefById(predicateId);
        columnFilter.Predicate = {
            PredicateId: predicateId,
            Inputs: ((_a = predicateDef.inputs) !== null && _a !== void 0 ? _a : []).map((i) => { var _a; return (_a = i.defaultValue) !== null && _a !== void 0 ? _a : ''; }),
        };
        this.updateFilter(columnFilter);
        if (predicateId === 'Values' || predicateId === 'ExcludeValues') {
            this.shouldOpenValuesDropdown = true;
        }
    }
    updateFilter(filter) {
        this.setState({ transientColumnFilter: filter });
        if (filter.Uuid) {
            this.debouncedEditFilter(filter);
        }
        else {
            this.debouncedAddFilter(filter);
        }
    }
    changeColumnPredicateInput(value, index) {
        const predicateId = this.getPredicateIdForShortcutValue(value);
        if (predicateId) {
            this.selectColumnPredicate(predicateId);
        }
        else {
            const columnFilter = Object.assign({}, this.props.columnFilter);
            columnFilter.Predicate.Inputs = columnFilter.Predicate.Inputs || [];
            columnFilter.Predicate.Inputs[index] = value;
            this.updateFilter(columnFilter);
        }
    }
    getPredicateIdForShortcutValue(value) {
        var _a;
        return (_a = this.props.api.columnFilterApi.internalApi.findPredicateDefByShortcut(value, this.props.currentColumn)) === null || _a === void 0 ? void 0 : _a.id;
    }
    clearFilter() {
        const columnFilter = Object.assign({}, this.props.columnFilter);
        this.props.api.columnFilterApi.clearColumnFilterForColumn(columnFilter.ColumnId);
    }
    hasValuesPredicate(predicate) {
        return this.props.api.predicateApi.internalApi.hasPredicateValues(predicate);
    }
}
function getColumnFilterWithDefault(state, props) {
    const columnFilter = (0, LayoutRedux_1.getColumnFilterSelector)(state).find((cf) => cf.ColumnId == props.currentColumn.columnId);
    if (columnFilter) {
        return columnFilter;
    }
    const columnFilterOptions = props.api.optionsApi.getColumnFilterOptions();
    if (!columnFilter && props.currentColumn.dataType === 'Number') {
        return ObjectFactory_1.ObjectFactory.CreateColumnFilter(props.currentColumn.columnId, (0, getDefaultColumnFilterPredicate_1.getDefaultColumnFilterPredicate)(props.currentColumn, columnFilterOptions.defaultNumericColumnFilter), ['']);
    }
    if (!columnFilter && props.currentColumn.dataType === 'String') {
        return ObjectFactory_1.ObjectFactory.CreateColumnFilter(props.currentColumn.columnId, (0, getDefaultColumnFilterPredicate_1.getDefaultColumnFilterPredicate)(props.currentColumn, columnFilterOptions.defaultStringColumnFilter), ['']);
    }
    if (!columnFilter && props.currentColumn.dataType === 'Date') {
        return ObjectFactory_1.ObjectFactory.CreateColumnFilter(props.currentColumn.columnId, (0, getDefaultColumnFilterPredicate_1.getDefaultColumnFilterPredicate)(props.currentColumn, columnFilterOptions.defaultDateColumnFilter), ['']);
    }
    if (!columnFilter && props.currentColumn.dataType === 'Boolean') {
        return ObjectFactory_1.ObjectFactory.CreateColumnFilter(props.currentColumn.columnId, 'BooleanToggle', ['all']);
    }
    return ObjectFactory_1.ObjectFactory.CreateColumnFilter(props.currentColumn.columnId, null, null);
}
function mapStateToProps(state, ownProps) {
    return {
        currentColumn: ownProps.currentColumn,
        columnFilter: getColumnFilterWithDefault(state, ownProps),
    };
}
function mapDispatchToProps(dispatch) {
    return {
        onAddColumnFilter: (columnFilter) => dispatch(LayoutRedux.LayoutColumnFilterAdd(columnFilter)),
        onEditColumnFilter: (columnFilter) => dispatch(LayoutRedux.LayoutColumnFilterEdit(columnFilter)),
    };
}
const QuickFilterForm = (0, react_redux_1.connect)(mapStateToProps, mapDispatchToProps)(QuickFilterFormComponent);
const QuickFilterFormReact = (columnFilterProps) => {
    var _a, _b, _c;
    return (0, renderWithAdaptableContext_1.renderWithAdaptableContext)(React.createElement(QuickFilterForm, { api: columnFilterProps.Adaptable.api, quickFilterTrigger: (_a = columnFilterProps.Adaptable.adaptableOptions.columnFilterOptions) === null || _a === void 0 ? void 0 : _a.quickFilterOptions.quickFilterTrigger, valuesFilterTrigger: (_b = columnFilterProps.Adaptable.adaptableOptions.columnFilterOptions) === null || _b === void 0 ? void 0 : _b.valuesFilterOptions.valuesFilterTrigger, quickFilterDebounce: (_c = columnFilterProps.Adaptable.adaptableOptions.columnFilterOptions) === null || _c === void 0 ? void 0 : _c.quickFilterOptions.quickFilterDebounce, currentColumn: columnFilterProps.Column, teamSharingActivated: false, embedColumnMenu: columnFilterProps.Adaptable.embedColumnMenu }), columnFilterProps.Adaptable);
};
exports.QuickFilterFormReact = QuickFilterFormReact;
