UNPKG

amis

Version:

一种MIS页面生成工具

481 lines (480 loc) 25.1 kB
"use strict"; /** * @file Tree * @description 树形组件 * @author fex */ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var react_1 = tslib_1.__importDefault(require("react")); var helper_1 = require("../utils/helper"); var Checkboxes_1 = require("./Checkboxes"); var theme_1 = require("../theme"); var Options_1 = require("../renderers/Form/Options"); var icons_1 = require("./icons"); var TreeSelector = /** @class */ (function (_super) { tslib_1.__extends(TreeSelector, _super); function TreeSelector() { return _super !== null && _super.apply(this, arguments) || this; } TreeSelector.prototype.componentWillMount = function () { var props = this.props; this.setState({ value: Checkboxes_1.value2array(props.value, { joinValues: props.joinValues, extractValue: props.extractValue, multiple: props.multiple, delimiter: props.delimiter, valueField: props.valueField, options: props.data }), unfolded: this.syncUnFolded(props), editItem: null, addItem: null, addingItem: null, editingItem: null, addTop: false // 添加一级 }); }; TreeSelector.prototype.componentWillReceiveProps = function (nextProps) { var toUpdate = {}; if (this.props.value !== nextProps.value || this.props.data !== nextProps.data) { toUpdate.value = Checkboxes_1.value2array(nextProps.value, { joinValues: nextProps.joinValues, extractValue: nextProps.extractValue, multiple: nextProps.multiple, delimiter: nextProps.delimiter, valueField: nextProps.valueField, options: nextProps.data }); } if (this.props.data !== nextProps.data) { toUpdate.unfolded = this.syncUnFolded(nextProps); } this.setState(toUpdate); }; TreeSelector.prototype.syncUnFolded = function (props) { // 初始化树节点的展开状态 var unfolded = {}; var _a = this.props, foldedField = _a.foldedField, unfoldedField = _a.unfoldedField; helper_1.eachTree(props.data, function (node, index, level) { if (node.children && node.children.length) { var ret = true; if (unfoldedField && typeof node[unfoldedField] !== 'undefined') { ret = !!node[unfoldedField]; } else if (foldedField && typeof node[foldedField] !== 'undefined') { ret = !node[foldedField]; } else { ret = !!props.initiallyOpen; if (!ret && level <= props.unfoldedLevel) { ret = true; } } unfolded[node[props.valueField]] = ret; } }); return unfolded; }; TreeSelector.prototype.toggleUnfolded = function (node) { var _a; this.setState({ addItem: null, unfolded: tslib_1.__assign(tslib_1.__assign({}, this.state.unfolded), (_a = {}, _a[node[this.props.valueField]] = !this.state.unfolded[node[this.props.valueField]], _a)) }); }; TreeSelector.prototype.clearSelect = function () { var _this = this; this.setState({ value: [] }, function () { var _a = _this.props, joinValues = _a.joinValues, rootValue = _a.rootValue, onChange = _a.onChange; onChange(joinValues ? rootValue : []); }); }; TreeSelector.prototype.handleSelect = function (node, value) { var _this = this; this.setState({ value: [node] }, function () { var _a = _this.props, joinValues = _a.joinValues, valueField = _a.valueField, onChange = _a.onChange; onChange(joinValues ? node[valueField] : node); }); }; TreeSelector.prototype.handleCheck = function (item, checked) { var _this = this; var props = this.props; var value = this.state.value.concat(); var idx = value.indexOf(item); var onlyChildren = this.props.onlyChildren; if (checked) { ~idx || value.push(item); if (!props.cascade) { var children = item.children ? item.children.concat([]) : []; if (onlyChildren) { // 父级选中的时候,子节点也都选中,但是自己不选中 !~idx && children.length && value.shift(); while (children.length) { var child = children.shift(); var index = value.indexOf(child); if (child.children) { children.push.apply(children, child.children); } else { ~index || value.push(child); } } } else { // 只要父节点选择了,子节点就不需要了,全部去掉勾选. withChildren时相反 while (children.length) { var child = children.shift(); var index = value.indexOf(child); if (~index) { value.splice(index, 1); } if (props.withChildren) { value.push(child); } if (child.children && child.children.length) { children.push.apply(children, child.children); } } } } } else if (!checked) { ~idx && value.splice(idx, 1); if (!props.cascade && (props.withChildren || onlyChildren)) { var children = item.children ? item.children.concat([]) : []; while (children.length) { var child = children.shift(); var index = value.indexOf(child); if (~index) { value.splice(index, 1); } if (child.children && child.children.length) { children.push.apply(children, child.children); } } } } this.setState({ value: value }, function () { var _a = _this.props, joinValues = _a.joinValues, extractValue = _a.extractValue, valueField = _a.valueField, delimiter = _a.delimiter, onChange = _a.onChange; onChange(joinValues ? value.map(function (item) { return item[valueField]; }).join(delimiter) : extractValue ? value.map(function (item) { return item[valueField]; }) : value); }); }; TreeSelector.prototype.handleAdd = function (item, isFolder) { var _a; var _b = this.props, addMode = _b.addMode, openAddDialog = _b.openAddDialog, valueField = _b.valueField; var unfolded = this.state.unfolded; if (addMode === 'dialog') { openAddDialog && openAddDialog(item ? item : null); } else if (addMode === 'normal') { // item 为 null 时为添加一级 if (item) { // 添加时,默认折叠的文件夹需要展开 if (isFolder && !unfolded[item[valueField]]) { unfolded = tslib_1.__assign(tslib_1.__assign({}, unfolded), (_a = {}, _a[item[valueField]] = !unfolded[item[valueField]], _a)); } this.setState({ addItem: item, editItem: null, unfolded: unfolded }); } else { this.setState({ addTop: true, editItem: null, addItem: null }); } } }; TreeSelector.prototype.handleEdit = function (item) { var _a = this.props, editMode = _a.editMode, openEditDialog = _a.openEditDialog; var addItem = this.state.addItem; if (editMode === 'dialog') { openEditDialog && openEditDialog(item); addItem && this.setState({ addItem: null }); } else if (editMode === 'normal') { this.setState({ editItem: item, addItem: null }); } }; TreeSelector.prototype.handleRemove = function (item) { var onRemove = this.props.onRemove; onRemove && onRemove(item); }; TreeSelector.prototype.handleConfirmOnAdd = function () { var onAdd = this.props.onAdd; var _a = this.state, parent = _a.addItem, addingItem = _a.addingItem; onAdd && onAdd(tslib_1.__assign(tslib_1.__assign({}, addingItem), { parent: parent })); this.setState({ addingItem: null, addItem: null, addTop: false }); }; TreeSelector.prototype.handleCancelOnAdd = function () { this.setState({ addItem: null, addTop: false }); }; TreeSelector.prototype.handleConfirmOnEdit = function () { var onEdit = this.props.onEdit; var _a = this.state, editingItem = _a.editingItem, prevItem = _a.editItem; onEdit && onEdit(tslib_1.__assign(tslib_1.__assign({}, editingItem), { prev: prevItem })); this.setState({ editingItem: null, editItem: null }); }; TreeSelector.prototype.handleCancelOnEdit = function () { this.setState({ editItem: null }); }; TreeSelector.prototype.handleChangeOnAdd = function (value) { this.setState({ addingItem: { label: value } }); }; TreeSelector.prototype.handleChangeOnEdit = function (item, value) { var editItem = this.state.editItem; this.setState({ editingItem: tslib_1.__assign(tslib_1.__assign({}, item), { label: value || editItem['label'] }) }); }; TreeSelector.prototype.renderList = function (list, value, uncheckable) { var _this = this; var _a = this.props, itemClassName = _a.itemClassName, showIcon = _a.showIcon, showRadio = _a.showRadio, multiple = _a.multiple, disabled = _a.disabled, _b = _a.nameField, nameField = _b === void 0 ? '' : _b, _c = _a.valueField, valueField = _c === void 0 ? '' : _c, _d = _a.iconField, iconField = _d === void 0 ? '' : _d, _e = _a.disabledField, disabledField = _e === void 0 ? '' : _e, cascade = _a.cascade, selfDisabledAffectChildren = _a.selfDisabledAffectChildren, onlyChildren = _a.onlyChildren, cx = _a.classnames, highlightTxt = _a.highlightTxt, data = _a.data, maxLength = _a.maxLength, minLength = _a.minLength, addable = _a.addable, editable = _a.editable, removable = _a.removable; var _f = this.state, addItem = _f.addItem, editItem = _f.editItem, unfolded = _f.unfolded, addTop = _f.addTop, stateValue = _f.value; var childrenChecked = 0; var ret = list.map(function (item, key) { if (!helper_1.isVisible(item, data)) { return null; } var checked = !!~value.indexOf(item); var selfDisabled = item[disabledField]; var selfChecked = !!uncheckable || checked; var childrenItems = null; var tmpChildrenChecked = false; if (item.children && item.children.length) { childrenItems = _this.renderList(item.children, value, cascade ? false : uncheckable || (selfDisabledAffectChildren ? selfDisabled : false) || (multiple && checked)); tmpChildrenChecked = !!childrenItems.childrenChecked; if (!selfChecked && onlyChildren && item.children.length === childrenItems.childrenChecked) { selfChecked = true; } childrenItems = childrenItems.dom; } if (tmpChildrenChecked || checked) { childrenChecked++; } var nodeDisabled = !!uncheckable || !!disabled || selfDisabled; if (!nodeDisabled && ((maxLength && !selfChecked && stateValue.length >= maxLength) || (minLength && selfChecked && stateValue.length <= minLength))) { nodeDisabled = true; } var checkbox = multiple ? (react_1.default.createElement("label", { className: cx("Checkbox Checkbox--checkbox Checkbox--sm") }, react_1.default.createElement("input", { type: "checkbox", disabled: nodeDisabled, checked: selfChecked, onChange: function (e) { return _this.handleCheck(item, e.currentTarget.checked); } }), react_1.default.createElement("i", null))) : showRadio ? (react_1.default.createElement("label", { className: cx("Checkbox Checkbox--radio Checkbox--sm") }, react_1.default.createElement("input", { type: "radio", disabled: nodeDisabled, checked: checked, onChange: function () { return _this.handleSelect(item); } }), react_1.default.createElement("i", null))) : null; var isLeaf = !item.children || !item.children.length; return (react_1.default.createElement("li", { key: key, className: cx("Tree-item " + (itemClassName || ''), { 'Tree-item--isLeaf': isLeaf }) }, !editItem || helper_1.isObject(editItem) && editItem[valueField] !== item[valueField] ? (react_1.default.createElement("a", null, !isLeaf ? (react_1.default.createElement("i", { onClick: function () { return _this.toggleUnfolded(item); }, className: cx('Tree-itemArrow', { 'is-folded': !unfolded[item[valueField]], }) })) : null, showIcon ? (react_1.default.createElement("i", { className: cx("Tree-itemIcon " + (item[iconField] || (childrenItems ? 'Tree-folderIcon' : 'Tree-leafIcon'))) })) : null, checkbox, react_1.default.createElement("span", { className: cx('Tree-itemText', { 'is-children-checked': multiple && !cascade && tmpChildrenChecked && !nodeDisabled, 'is-checked': checked, 'is-disabled': nodeDisabled, }), onClick: function () { return !nodeDisabled && (multiple ? _this.handleCheck(item, !selfChecked) : _this.handleSelect(item)); } }, highlightTxt ? Options_1.highlight(item[nameField], highlightTxt) : item[nameField]), !nodeDisabled && !addTop && !addItem && !editItem ? (react_1.default.createElement("span", { className: cx('Tree-item-icons') }, addable ? react_1.default.createElement(icons_1.Icon, { icon: "plus", className: "icon", onClick: function () { return _this.handleAdd(item, !isLeaf); } }) : null, removable ? react_1.default.createElement(icons_1.Icon, { icon: "minus", className: "icon", onClick: function () { return _this.handleRemove(item); } }) : null, editable ? react_1.default.createElement(icons_1.Icon, { icon: "pencil", className: "icon", onClick: function () { return _this.handleEdit(item); } }) : null)) : null)) : (react_1.default.createElement("div", { className: cx('Tree-item--isEdit') }, react_1.default.createElement("input", { defaultValue: item['label'], onChange: function (e) { return _this.handleChangeOnEdit(item, e.currentTarget.value); } }), react_1.default.createElement(icons_1.Icon, { icon: "check", className: "icon", onClick: _this.handleConfirmOnEdit }), react_1.default.createElement(icons_1.Icon, { icon: "close", className: "icon", onClick: _this.handleCancelOnEdit }))), ((childrenItems && unfolded[item[valueField]]) || addItem && (addItem[valueField] === item[valueField])) ? (react_1.default.createElement("ul", { className: cx('Tree-sublist') }, addItem && addItem[valueField] === item[valueField] ? (react_1.default.createElement("li", null, react_1.default.createElement("input", { onChange: function (e) { return _this.handleChangeOnAdd(e.currentTarget.value); } }), react_1.default.createElement(icons_1.Icon, { icon: "check", className: "icon", onClick: _this.handleConfirmOnAdd }), react_1.default.createElement(icons_1.Icon, { icon: "close", className: "icon", onClick: _this.handleCancelOnAdd }))) : null, childrenItems)) : null)); }); return { dom: ret, childrenChecked: childrenChecked }; }; TreeSelector.prototype.render = function () { var _this = this; var _a = this.props, className = _a.className, placeholder = _a.placeholder, hideRoot = _a.hideRoot, rootLabel = _a.rootLabel, showIcon = _a.showIcon, cx = _a.classnames, addable = _a.addable; var data = this.props.data; var _b = this.state, value = _b.value, addTop = _b.addTop; return (react_1.default.createElement("div", { className: cx("Tree " + (className || '')) }, data && data.length ? (react_1.default.createElement("ul", { className: cx('Tree-list') }, hideRoot ? (this.renderList(data, value, false).dom) : (react_1.default.createElement("li", { className: cx('Tree-item Tree-rootItem') }, react_1.default.createElement("a", null, showIcon ? react_1.default.createElement("i", { className: cx('Tree-itemIcon Tree-rootIcon') }) : null, react_1.default.createElement("label", { className: cx('Tree-itemLabel', { 'is-checked': !value || !value.length }) }, react_1.default.createElement("span", { className: cx('Tree-itemText'), onClick: this.clearSelect }, rootLabel))), addable ? (react_1.default.createElement("div", { className: cx('Tree-addTop') }, !addTop ? (react_1.default.createElement("p", { onClick: function () { return _this.handleAdd(null, false); } }, react_1.default.createElement(icons_1.Icon, { icon: "plus", className: "icon" }), react_1.default.createElement("span", null, "\u6DFB\u52A0\u4E00\u7EA7"))) : null, addTop ? (react_1.default.createElement("div", { className: cx('Tree-addTop-input') }, react_1.default.createElement("input", { onChange: function (e) { return _this.handleChangeOnAdd(e.currentTarget.value); } }), react_1.default.createElement(icons_1.Icon, { icon: "check", className: "icon", onClick: this.handleConfirmOnAdd }), react_1.default.createElement(icons_1.Icon, { icon: "close", className: "icon", onClick: this.handleCancelOnAdd }))) : null)) : null, react_1.default.createElement("ul", { className: cx('Tree-sublist') }, this.renderList(data, value, false).dom))))) : (react_1.default.createElement("div", { className: cx('Tree-placeholder') }, placeholder)))); }; var _a, _b, _c, _d, _e; TreeSelector.defaultProps = { showIcon: true, initiallyOpen: true, unfoldedLevel: 0, showRadio: false, multiple: false, disabled: false, withChildren: false, onlyChildren: false, nameField: 'name', valueField: 'value', iconField: 'icon', unfoldedField: 'unfolded', foldedField: 'foled', disabledField: 'disabled', joinValues: true, extractValue: false, delimiter: ',', hideRoot: true, rootLabel: '顶级', rootValue: 0, cascade: false, selfDisabledAffectChildren: true }; tslib_1.__decorate([ helper_1.autobind, tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", [Object]), tslib_1.__metadata("design:returntype", void 0) ], TreeSelector.prototype, "toggleUnfolded", null); tslib_1.__decorate([ helper_1.autobind, tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", []), tslib_1.__metadata("design:returntype", void 0) ], TreeSelector.prototype, "clearSelect", null); tslib_1.__decorate([ helper_1.autobind, tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", [Object, Object]), tslib_1.__metadata("design:returntype", void 0) ], TreeSelector.prototype, "handleSelect", null); tslib_1.__decorate([ helper_1.autobind, tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", [Object, Boolean]), tslib_1.__metadata("design:returntype", void 0) ], TreeSelector.prototype, "handleCheck", null); tslib_1.__decorate([ helper_1.autobind, tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", [typeof (_a = typeof Checkboxes_1.Option !== "undefined" && Checkboxes_1.Option) === "function" ? _a : Object, Boolean]), tslib_1.__metadata("design:returntype", void 0) ], TreeSelector.prototype, "handleAdd", null); tslib_1.__decorate([ helper_1.autobind, tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", [typeof (_b = typeof Checkboxes_1.Option !== "undefined" && Checkboxes_1.Option) === "function" ? _b : Object]), tslib_1.__metadata("design:returntype", void 0) ], TreeSelector.prototype, "handleEdit", null); tslib_1.__decorate([ helper_1.autobind, tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", [typeof (_c = typeof Checkboxes_1.Option !== "undefined" && Checkboxes_1.Option) === "function" ? _c : Object]), tslib_1.__metadata("design:returntype", void 0) ], TreeSelector.prototype, "handleRemove", null); tslib_1.__decorate([ helper_1.autobind, tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", []), tslib_1.__metadata("design:returntype", void 0) ], TreeSelector.prototype, "handleConfirmOnAdd", null); tslib_1.__decorate([ helper_1.autobind, tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", []), tslib_1.__metadata("design:returntype", void 0) ], TreeSelector.prototype, "handleCancelOnAdd", null); tslib_1.__decorate([ helper_1.autobind, tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", []), tslib_1.__metadata("design:returntype", void 0) ], TreeSelector.prototype, "handleConfirmOnEdit", null); tslib_1.__decorate([ helper_1.autobind, tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", []), tslib_1.__metadata("design:returntype", void 0) ], TreeSelector.prototype, "handleCancelOnEdit", null); tslib_1.__decorate([ helper_1.autobind, tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", [String]), tslib_1.__metadata("design:returntype", void 0) ], TreeSelector.prototype, "handleChangeOnAdd", null); tslib_1.__decorate([ helper_1.autobind, tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", [typeof (_d = typeof Checkboxes_1.Option !== "undefined" && Checkboxes_1.Option) === "function" ? _d : Object, String]), tslib_1.__metadata("design:returntype", void 0) ], TreeSelector.prototype, "handleChangeOnEdit", null); tslib_1.__decorate([ helper_1.autobind, tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", [typeof (_e = typeof Checkboxes_1.Options !== "undefined" && Checkboxes_1.Options) === "function" ? _e : Object, Array, Boolean]), tslib_1.__metadata("design:returntype", Object) ], TreeSelector.prototype, "renderList", null); return TreeSelector; }(react_1.default.Component)); exports.TreeSelector = TreeSelector; exports.default = theme_1.themeable(TreeSelector); //# sourceMappingURL=./components/Tree.js.map