"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var react_1 = tslib_1.__importDefault(require("react"));
var react_dom_1 = require("react-dom");
var Item_1 = require("./Item");
var combo_1 = require("../../store/combo");
var helper_1 = require("../../utils/helper");
var Sortable = require("sortablejs");
var tpl_1 = require("../../utils/tpl");
;
var ComboControl = /** @class */ (function (_super) {
    tslib_1.__extends(ComboControl, _super);
    function ComboControl(props) {
        var _this = _super.call(this, props) || this;
        _this.subForms = [];
        _this.keys = [];
        _this.handleChange = _this.handleChange.bind(_this);
        _this.handleSingleFormChange = _this.handleSingleFormChange.bind(_this);
        _this.handleSingleFormInit = _this.handleSingleFormInit.bind(_this);
        _this.handleAction = _this.handleAction.bind(_this);
        _this.addItem = _this.addItem.bind(_this);
        _this.removeItem = _this.removeItem.bind(_this);
        _this.dragTipRef = _this.dragTipRef.bind(_this);
        _this.defaultValue = tslib_1.__assign({}, props.scaffold);
        return _this;
    }
    ComboControl.prototype.componentWillMount = function () {
        var _a = this.props, store = _a.store, value = _a.value, minLength = _a.minLength, maxLength = _a.maxLength;
        store.config({
            minLength: minLength,
            maxLength: maxLength,
            length: this.getValueAsArray().length
        });
    };
    ComboControl.prototype.componentWillReceiveProps = function (nextProps) {
        var props = this.props;
        if (helper_1.anyChanged(['minLength', 'maxLength', 'value'], props, nextProps)) {
            var store = nextProps.store, minLength = nextProps.minLength, maxLength = nextProps.maxLength;
            store.config({
                minLength: minLength,
                maxLength: maxLength,
                length: this.getValueAsArray(nextProps).length
            });
        }
    };
    ComboControl.prototype.getValueAsArray = function (props) {
        if (props === void 0) { props = this.props; }
        var flat = props.flat, joinValues = props.joinValues, delimiter = props.delimiter;
        var value = props.value;
        if (joinValues && flat && typeof value === 'string') {
            value = value.split(delimiter || ',');
        }
        else if (!Array.isArray(value)) {
            value = [];
        }
        else {
            value = value.concat();
        }
        return value;
    };
    ComboControl.prototype.addItem = function () {
        var _a = this.props, flat = _a.flat, joinValues = _a.joinValues, delimiter = _a.delimiter, scaffold = _a.scaffold, disabled = _a.disabled;
        if (disabled) {
            return;
        }
        var value = this.getValueAsArray();
        value.push(flat ? scaffold || '' : tslib_1.__assign({}, scaffold));
        this.keys.push(helper_1.guid());
        if (flat && joinValues) {
            value = value.join(delimiter || ',');
        }
        this.props.onChange(value);
    };
    ComboControl.prototype.removeItem = function (key) {
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var _a, flat, joinValues, delimiter, disabled, deleteApi, deleteConfirmText, data, env, value, ctx, confirmed, result;
            return tslib_1.__generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        _a = this.props, flat = _a.flat, joinValues = _a.joinValues, delimiter = _a.delimiter, disabled = _a.disabled, deleteApi = _a.deleteApi, deleteConfirmText = _a.deleteConfirmText, data = _a.data, env = _a.env;
                        if (disabled) {
                            return [2 /*return*/];
                        }
                        value = this.getValueAsArray();
                        if (!deleteApi) return [3 /*break*/, 3];
                        ctx = helper_1.createObject(data, value[key]);
                        return [4 /*yield*/, env.confirm(deleteConfirmText ? tpl_1.filter(deleteConfirmText, ctx) : '确认要删除？')];
                    case 1:
                        confirmed = _b.sent();
                        if (!confirmed) { // 如果不确认，则跳过！
                            return [2 /*return*/];
                        }
                        return [4 /*yield*/, env.fetcher(deleteApi, ctx)];
                    case 2:
                        result = _b.sent();
                        if (!result.ok) {
                            env.notify('error', '删除失败');
                            return [2 /*return*/];
                        }
                        _b.label = 3;
                    case 3:
                        value.splice(key, 1);
                        this.keys.splice(key, 1);
                        if (flat && joinValues) {
                            value = value.join(delimiter || ',');
                        }
                        this.props.onChange(value);
                        return [2 /*return*/];
                }
            });
        });
    };
    ComboControl.prototype.handleChange = function (index, values) {
        var _a = this.props, formItem = _a.formItem, flat = _a.flat, store = _a.store, joinValues = _a.joinValues, delimiter = _a.delimiter, disabled = _a.disabled;
        if (disabled) {
            return;
        }
        var value = this.getValueAsArray();
        value[index] = flat ? values.flat : tslib_1.__assign({}, values);
        if (flat && joinValues) {
            value = value.join(delimiter || ',');
        }
        this.props.onChange(value);
        if (formItem && formItem.validated) {
            this.subForms.forEach(function (item) { return item.validate(); });
        }
        store.forms.forEach(function (item) { return item.items.forEach(function (item) { return item.unique && item.syncOptions(); }); });
    };
    ComboControl.prototype.handleSingleFormChange = function (values) {
        this.props.onChange(tslib_1.__assign({}, values));
    };
    ComboControl.prototype.handleSingleFormInit = function (values) {
        this.props.syncDefaultValue !== false && this.props.setPrinstineValue && this.props.setPrinstineValue(tslib_1.__assign({}, values));
    };
    ComboControl.prototype.handleAction = function (action) {
        var onAction = this.props.onAction;
        if (action.actionType === 'delete') {
            action.index !== void 0 && this.removeItem(action.index);
            return;
        }
        onAction && onAction.apply(null, arguments);
    };
    ComboControl.prototype.validate = function () {
        var _a = this.props, value = _a.value, minLength = _a.minLength, maxLength = _a.maxLength;
        if (minLength && (!Array.isArray(value) || value.length < minLength)) {
            return "\u7EC4\u5408\u8868\u5355\u6210\u5458\u6570\u91CF\u4E0D\u591F\uFF0C\u4F4E\u4E8E\u6700\u5C0F\u7684\u8BBE\u5B9A" + minLength + "\u4E2A\uFF0C\u8BF7\u6DFB\u52A0\u66F4\u591A\u7684\u6210\u5458\u3002";
        }
        else if (maxLength && Array.isArray(value) && value.length > maxLength) {
            return "\u7EC4\u5408\u8868\u5355\u6210\u5458\u6570\u91CF\u8D85\u51FA\uFF0C\u8D85\u51FA\u6700\u5927\u7684\u8BBE\u5B9A" + maxLength + "\u4E2A\uFF0C\u8BF7\u5220\u9664\u591A\u4F59\u7684\u6210\u5458\u3002";
        }
        else if (this.subForms.length) {
            return Promise
                .all(this.subForms.map(function (item) { return item.validate(); }))
                .then(function (values) {
                if (~values.indexOf(false)) {
                    return '子表单验证失败，请仔细检查';
                }
                return;
            });
        }
    };
    ComboControl.prototype.dragTipRef = function (ref) {
        if (!this.dragTip && ref) {
            this.initDragging();
        }
        else if (this.dragTip && !ref) {
            this.destroyDragging();
        }
        this.dragTip = ref;
    };
    ComboControl.prototype.initDragging = function () {
        var _this = this;
        var ns = this.props.classPrefix;
        var dom = react_dom_1.findDOMNode(this);
        this.sortable = new Sortable(dom.querySelector("." + ns + "Combo-items"), {
            group: 'combo',
            handle: "." + ns + "Combo-itemDrager",
            ghostClass: ns + "Combo-item--dragging",
            onEnd: function (e) {
                // 没有移动
                if (e.newIndex === e.oldIndex) {
                    return;
                }
                // 换回来
                var parent = e.to;
                if (e.oldIndex < parent.childNodes.length - 1) {
                    parent.insertBefore(e.item, parent.childNodes[e.oldIndex]);
                }
                else {
                    parent.appendChild(e.item);
                }
                var value = _this.props.value;
                if (!Array.isArray(value)) {
                    return;
                }
                var newValue = value.concat();
                newValue.splice(e.newIndex, 0, newValue.splice(e.oldIndex, 1)[0]);
                _this.keys.splice(e.newIndex, 0, _this.keys.splice(e.oldIndex, 1)[0]);
                _this.props.onChange(newValue);
            }
        });
    };
    ComboControl.prototype.destroyDragging = function () {
        this.sortable && this.sortable.destroy();
    };
    ComboControl.prototype.formRef = function (ref, index) {
        if (index === void 0) { index = 0; }
        if (ref) {
            while (ref && ref.getWrappedInstance) {
                ref = ref.getWrappedInstance();
            }
            this.subForms[index] = ref;
        }
        else {
            this.subForms.splice(index, 1);
        }
    };
    ComboControl.prototype.formatValue = function (value, index) {
        var _a = this.props, flat = _a.flat, data = _a.data, canAccessSuperData = _a.canAccessSuperData;
        if (flat) {
            value = {
                flat: value
            };
        }
        value = value || this.defaultValue;
        return canAccessSuperData
            ? helper_1.createObject(helper_1.createObject(data, { index: index, __index: index }), value)
            : helper_1.createObject({ index: index, __index: index }, value);
    };
    ComboControl.prototype.renderMultipe = function () {
        var _this = this;
        var _a = this.props, ns = _a.classPrefix, cx = _a.classnames, formClassName = _a.formClassName, render = _a.render, controls = _a.controls, multiLine = _a.multiLine, addButtonClassName = _a.addButtonClassName, disabled = _a.disabled, store = _a.store, flat = _a.flat, subFormMode = _a.subFormMode, draggable = _a.draggable, draggableTip = _a.draggableTip, addButtonText = _a.addButtonText, addable = _a.addable, removable = _a.removable, itemRemovableOn = _a.itemRemovableOn, delimiter = _a.delimiter, canAccessSuperData = _a.canAccessSuperData, addIcon = _a.addIcon, dragIcon = _a.dragIcon, deleteIcon = _a.deleteIcon, noBorder = _a.noBorder;
        var value = this.props.value;
        if (flat && typeof value === 'string') {
            value = value.split(delimiter || ',');
        }
        var finnalRemovable = store.removable !== false // minLength ?
            && !disabled // 控件自身是否禁用
            && removable !== false; // 是否可以删除
        return (react_1.default.createElement("div", { className: cx("Combo Combo--multi", multiLine ? "Combo--ver" : "Combo--hor", noBorder ? "Combo--noBorder" : '') },
            react_1.default.createElement("div", { className: cx("Combo-items") }, Array.isArray(value) ? value.map(function (value, index, thelist) {
                var toolbar = [];
                if (!disabled && draggable && thelist.length > 1) {
                    toolbar.push(react_1.default.createElement("a", { key: "drag", className: cx("Combo-toolbarBtn Combo-itemDrager"), "data-tooltip": "\u62D6\u62FD\u6392\u5E8F", "data-position": "bottom" },
                        react_1.default.createElement("i", { className: dragIcon })));
                }
                if (finnalRemovable
                    && ( // 表达式判断单条是否可删除
                    !itemRemovableOn
                        || tpl_1.evalExpression(itemRemovableOn, value) !== false)) {
                    toolbar.push(react_1.default.createElement("a", { onClick: _this.removeItem.bind(_this, index), key: "remove", className: cx("Combo-toolbarBtn " + (!store.removable ? 'is-disabled' : '')), "data-tooltip": "\u5220\u9664", "data-position": "bottom" },
                        react_1.default.createElement("i", { className: deleteIcon })));
                }
                var finnalControls = flat ? [tslib_1.__assign({}, controls[0], { name: 'flat' })] : controls;
                return (react_1.default.createElement("div", { className: cx("Combo-item"), key: _this.keys[index] || (_this.keys[index] = helper_1.guid()) },
                    react_1.default.createElement("div", { className: cx("Combo-itemInner") }, render("multiple/" + index, {
                        type: 'form',
                        controls: finnalControls,
                        wrapperComponent: 'div',
                        wrapWithPanel: false,
                        mode: multiLine ? subFormMode : 'row',
                        className: cx("Combo-form", formClassName)
                    }, {
                        index: index,
                        disabled: disabled,
                        data: _this.formatValue(value, index),
                        onChange: _this.handleChange.bind(_this, index),
                        onAction: _this.handleAction,
                        ref: function (ref) { return _this.formRef(ref, index); },
                        canAccessSuperData: canAccessSuperData
                    })),
                    toolbar.length ? (react_1.default.createElement("div", { className: cx("Combo-itemToolbar") }, toolbar)) : null));
            }) : null),
            !disabled ? (react_1.default.createElement("div", { className: cx("Combo-toolbar") },
                store.addable && addable !== false ? (react_1.default.createElement("button", { type: "button", onClick: this.addItem, className: cx("Button Combo-addBtn", addButtonClassName), "data-tooltip": "\u65B0\u589E\u4E00\u6761\u6570\u636E" },
                    addIcon ? (react_1.default.createElement("i", { className: cx("Button-icon", addIcon) })) : null,
                    react_1.default.createElement("span", null, addButtonText || '新增'))) : null,
                draggable ? (react_1.default.createElement("span", { className: cx("Combo-dragableTip"), ref: this.dragTipRef }, Array.isArray(value) && value.length > 1 ? draggableTip : '')) : null)) : null));
    };
    ComboControl.prototype.renderSingle = function () {
        var _this = this;
        var _a = this.props, controls = _a.controls, cx = _a.classnames, render = _a.render, value = _a.value, multiLine = _a.multiLine, formClassName = _a.formClassName, canAccessSuperData = _a.canAccessSuperData, noBorder = _a.noBorder, disabled = _a.disabled;
        return (react_1.default.createElement("div", { className: cx("Combo Combo--single", multiLine ? "Combo--ver" : "Combo--hor", noBorder ? "Combo--noBorder" : '') },
            react_1.default.createElement("div", { className: cx("Combo-item") },
                react_1.default.createElement("div", { className: cx("Combo-itemInner") }, render('single', {
                    type: 'form',
                    controls: controls,
                    wrapperComponent: 'div',
                    wrapWithPanel: false,
                    mode: multiLine ? 'normal' : 'row',
                    className: cx("Combo-form", formClassName)
                }, {
                    disabled: disabled,
                    data: helper_1.isObject(value) ? value : this.defaultValue,
                    onChange: this.handleSingleFormChange,
                    ref: function (ref) { return _this.formRef(ref); },
                    onInit: this.handleSingleFormInit,
                    canAccessSuperData: canAccessSuperData
                })))));
    };
    ComboControl.prototype.render = function () {
        var _a = this.props, multiple = _a.multiple, className = _a.className, ns = _a.classPrefix, cx = _a.classnames;
        return (react_1.default.createElement("div", { className: cx("ComboControl", className) }, multiple ? this.renderMultipe() : this.renderSingle()));
    };
    ComboControl.defaultProps = {
        minLength: 0,
        maxLength: 0,
        multiple: false,
        multiLine: false,
        addButtonClassName: '',
        formClassName: '',
        subFormMode: 'normal',
        draggableTip: '可拖拽排序',
        addButtonText: '新增',
        canAccessSuperData: false,
        addIcon: 'fa fa-plus',
        dragIcon: 'glyphicon glyphicon-sort',
        deleteIcon: 'glyphicon glyphicon-remove'
    };
    ComboControl.propsList = [
        "minLength",
        "maxLength",
        "multiple",
        "multiLine",
        "addButtonClassName",
        "subFormMode",
        "draggableTip",
        "addButtonText",
        "draggable",
        "scaffold",
        "canAccessSuperData",
        "addIcon",
        "dragIcon",
        "deleteIcon",
        "noBorder"
    ];
    return ComboControl;
}(react_1.default.Component));
exports.default = ComboControl;
var ComboControlRenderer = /** @class */ (function (_super) {
    tslib_1.__extends(ComboControlRenderer, _super);
    function ComboControlRenderer() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    ComboControlRenderer = tslib_1.__decorate([
        Item_1.FormItem({
            type: 'combo',
            storeType: combo_1.ComboStore.name
        })
    ], ComboControlRenderer);
    return ComboControlRenderer;
}(ComboControl));
exports.ComboControlRenderer = ComboControlRenderer;
;
//# sourceMappingURL=./renderers/Form/Combo.js.map
