UNPKG

manage-table

Version:

<p align="center"> <img width="400px" src="https://github.com/tnfe/manage-table/blob/master/img/logo.png?raw=true" /> </p>

535 lines (522 loc) 25.2 kB
import { jsxs, jsx, Fragment } from 'react/jsx-runtime'; import React, { useState, useEffect, useImperativeHandle, useRef } from 'react'; import { Tag, Checkbox, Divider, Select, Button, Card, Table, Modal } from 'antd'; import { MoreOutlined, CloseOutlined, DoubleLeftOutlined } from '@ant-design/icons'; import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd'; /*! ***************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; } function __spreadArray(to, from) { for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) to[j] = from[i]; return to; } var ManageTable = 'ManageTable'; var getLSShowCol = function (lsName) { var values = localStorage.getItem(ManageTable + '_' + lsName); if (values) { try { var res = JSON.parse(values); return Array.isArray(res) ? res : []; } catch (error) { return []; } } return []; }; var setLSShowCol = function (lsName, values) { localStorage.setItem(ManageTable + '_' + lsName, JSON.stringify(values)); }; var computeKey = function (dataIndex) { if (Array.isArray(dataIndex)) { return dataIndex.join('.'); } return dataIndex; }; var computeColumns = function (lsName, columns, defaultShowKeys) { if (defaultShowKeys === void 0) { defaultShowKeys = []; } var lssShowCol = getLSShowCol(lsName); var preLsChecked = lssShowCol.length > 0 ? lssShowCol : defaultShowKeys; var fixedColumns = columns.filter(function (column) { return !!column.fixed; }).map(function (column) { return ({ key: column.dataIndex, position: column.fixed, }); }); var groupRecordList = []; var single = []; var computedColumns = []; var action; var map = {}; var saveShowKeys = []; // 函数判断是否展示 var isShow = function (item) { if (preLsChecked.length !== 0) { return preLsChecked.includes(computeKey(item.dataIndex)); } return !!item.show; }; var resolveInfo = function (info, records) { // 如果是操作列 if (info.dataIndex === 'action') { var show_1 = info.show, rest_1 = __rest(info, ["show"]); action = rest_1; return; } var computedShow = isShow(info); var dataIndex = computeKey(info.dataIndex); records.push({ dataIndex: dataIndex, title: info.title, show: computedShow, originShow: info.show === true, }); var show = info.show, rest = __rest(info, ["show"]); map[dataIndex] = rest; if (computedShow) { saveShowKeys.push(dataIndex); } }; var doCollectGroup = function () { var useGroup = columns.some(function (item) { return !!item.group; }); if (useGroup) { var groupIndexMap_1 = {}; columns.forEach(function (item) { if (item.dataIndex === 'action') { var show = item.show, rest = __rest(item, ["show"]); action = rest; return; } var groupName = item.group || '其他'; if (groupIndexMap_1[groupName] === undefined) { groupIndexMap_1[groupName] = groupRecordList.length; groupRecordList.push({ title: groupName, records: [], }); } resolveInfo(item, groupRecordList[groupIndexMap_1[groupName]].records); }); } else { columns.forEach(function (item) { resolveInfo(item, single); }); groupRecordList.push({ records: single, }); } }; doCollectGroup(); var computedShowKeys = preLsChecked.length > 0 ? preLsChecked : saveShowKeys; // 排序处理 computedShowKeys.forEach(function (item) { if (map[item]) { computedColumns.push(map[item]); } }); // 如果存在操作列 if (action) { computedColumns.push(action); } var toReturn = { groupRecordList: groupRecordList, computedColumns: computedColumns, computedShowKeys: computedShowKeys, fixedColumns: fixedColumns, }; return toReturn; }; var stSelectableItem = { display: 'inline-block', width: '208px' }; var GroupSet = React.forwardRef(function (props, ref) { var _a = useState([]), bigOptions = _a[0], setBigOptions = _a[1]; // 所有选项 var _b = React.useState(true), indeterminate = _b[0], setIndeterminate = _b[1]; // 是否全选 var _c = useState(0), totalCount = _c[0], setTotalCount = _c[1]; var _d = useState([]), checkedList = _d[0], setCheckedList = _d[1]; // 选中的对象 useEffect(function () { var options = []; var checkeds = []; // 遍历可选项 props.records.forEach(function (item) { options.push({ label: item.title, value: item.dataIndex, originShow: item.originShow, }); if (item.show) { checkeds.push(item.dataIndex); } }); // 初始化状态 setTotalCount(props.records.length); setBigOptions(options); setCheckedList(checkeds); setIndeterminate(checkeds.length !== totalCount && checkeds.length !== 0); }, [props.records]); useImperativeHandle(ref, function () { return { clearCheck: function () { var ckds = []; props.records.forEach(function (item) { if (props.fixedShowKeys.includes(item.dataIndex)) { ckds.push(item.dataIndex); } }); setIndeterminate(ckds.length !== 0); setCheckedList(ckds); }, selectAll: function () { var ckds = props.records.map(function (item) { return item.dataIndex; }); setCheckedList(ckds); setIndeterminate(false); }, removeCheck: function (key) { var list = checkedList.slice(); var index = list.indexOf(key); if (index !== -1) { list.splice(index, 1); } setCheckedList(list); }, addCheck: function (key) { var ckds = bigOptions.map(function (item) { return item.value; }); if (!ckds.includes(key)) { return; } var list = checkedList.slice(); if (list.includes(key)) { return; } list.push(key); setCheckedList(list); }, }; }); var changeAllChecked = function (event) { var checked = event.target.checked; if (checked) { setIndeterminate(false); var ckds = props.records.map(function (item) { return item.dataIndex; }); setCheckedList(ckds); props.handleSaveChange(props.groupIndex, ckds); } else { var ckds_1 = []; props.records.forEach(function (item) { if (props.fixedShowKeys.includes(item.dataIndex)) { ckds_1.push(item.dataIndex); } }); setIndeterminate(ckds_1.length !== 0); setCheckedList(ckds_1); props.handleSaveChange(props.groupIndex, []); } }; // 单选操作 var handleChange = function (values) { var single = ''; for (var i = 0; i < checkedList.length || i < values.length; i++) { if (values[i] !== checkedList[i]) { single = checkedList[i] || values[i]; break; } } setCheckedList(values); setIndeterminate(values.length !== totalCount); setIndeterminate(values.length !== totalCount && values.length !== 0); props.handleSaveChange(props.groupIndex, single); }; var cardTitle = props.title ? (jsxs("span", { children: [jsx(Tag, __assign({ color: "#3c71f8" }, { children: props.title }), void 0), jsxs(Checkbox, __assign({ indeterminate: indeterminate, onChange: changeAllChecked, checked: checkedList.length === totalCount, style: { marginLeft: '18px' } }, { children: [checkedList.length, "/", totalCount] }), void 0)] }, void 0)) : null; return (jsxs(Fragment, { children: [cardTitle, jsx("p", {}, void 0), jsx(Checkbox.Group, __assign({ value: checkedList, onChange: handleChange }, { children: bigOptions.map(function (item) { return (jsx("span", __assign({ style: stSelectableItem }, { children: jsx(Checkbox, __assign({ disabled: props.fixedShowKeys.includes(item.value), value: item.value }, { children: item.label }), void 0) }), item.value)); }) }), void 0), jsx(Divider, {}, void 0)] }, void 0)); }); var GroupSet$1 = React.memo(GroupSet); var stCloseIcon = { float: 'right', lineHeight: '28px' }; var stChooseItem = { lineHeight: '28px' }; var getItemStyle = function (isDragging, draggableStyle) { return (__assign({ // some basic styles to make the items look a bit nicer padding: '0 12px', userSelect: 'none', border: '1px solid #d9d9d9', // change background colour if dragging background: isDragging ? '#69c0ff' : 'white', height: '28px', margin: '1px' }, draggableStyle)); }; var getListStyle = function (isDraggingOver) { return ({ background: isDraggingOver ? '#e6f7fe' : 'white', width: '100%', }); }; var reorder = function (list, startIndex, endIndex) { var result = Array.from(list); var removed = result.splice(startIndex, 1)[0]; result.splice(endIndex, 0, removed); return result; }; var DragList = function (props) { var onDragEnd = function (result, provided) { var _a; var items = reorder(props.list, result.source.index, ((_a = result.destination) === null || _a === void 0 ? void 0 : _a.index) || 0); props.onChange(items); }; return (jsx(DragDropContext, __assign({ onDragEnd: onDragEnd }, { children: jsx(Droppable, __assign({ droppableId: 'droppable' }, { children: function (provided, snapshot) { return (jsxs("div", __assign({}, provided.droppableProps, { ref: provided.innerRef, style: getListStyle(snapshot.isDraggingOver) }, { children: [props.list.map(function (item, index) { if (!props.fixedColumns.includes(item.dataIndex)) { return (jsx(Draggable, __assign({ draggableId: item.dataIndex, index: index }, { children: function (provided, snapshot) { return (jsx("div", __assign({ ref: provided.innerRef }, provided.draggableProps, provided.dragHandleProps, { style: getItemStyle(snapshot.isDragging, provided.draggableProps.style) }, { children: jsxs("div", __assign({ style: stChooseItem }, { children: [jsx(MoreOutlined, {}, void 0), item.title, jsx(CloseOutlined, { style: stCloseIcon, onClick: function () { return props.removeItem(item.dataIndex); } }, void 0)] }), item.dataIndex) }), void 0)); } }), item.dataIndex)); } return null; }), provided.placeholder] }), void 0)); } }), void 0) }), void 0)); }; var DragList$1 = React.memo(DragList); var stCardLeft = { height: '70vh', width: '60%', display: 'inline-block', verticalAlign: 'top' }; var stCardRight = { height: '70vh', width: '32%', display: 'inline-block', verticalAlign: 'top' }; var stCardBody = { height: '90%', overflowY: 'auto' }; var stSetting = { height: '80%' }; var stBlank = { width: '3%', height: '100%', lineHeight: 'calc(80vh - 160px)', verticalAlign: 'top', textAlign: 'center', fontSize: '22px', display: 'inline-block', cursor: 'pointer', }; // 暂存数据 var saveMap = {}; var SettingContent = function (props) { var _a = useState([]), bigOptions = _a[0], setBigOptions = _a[1]; // 所有选项 var _b = useState([]), allOptions = _b[0], setAllOptions = _b[1]; // 所有选项 var _c = React.useState(true), indeterminate = _c[0], setIndeterminate = _c[1]; // 是否全选 var _d = useState(props.computedShowKeys), checkedList = _d[0], setCheckedList = _d[1]; // 选中的对象 var _e = useState(0), totalCount = _e[0], setTotalCount = _e[1]; // 准备数据阶段 useEffect(function () { var options = []; var alloptions = []; var total = 0; // 遍历可选项 var map = {}; props.choose.forEach(function (item) { var records = []; item.records.forEach(function (record) { map[record.dataIndex] = { title: record.title, dataIndex: record.dataIndex, }; alloptions.push({ label: record.title, value: record.dataIndex }); records.push(record); total++; }); options.push({ records: records, title: item.title, ref: React.createRef() }); }); // 初始化状态 saveMap = map; setTotalCount(total); setAllOptions(alloptions); setBigOptions(options); setIndeterminate(checkedList.length !== total); }, [props.choose]); // 全局选中操作 var changeAllChecked = function (event) { var checked = event.target.checked; setIndeterminate(false); if (checked) { setCheckedList(Object.keys(saveMap)); // 子组全选 bigOptions.forEach(function (bigOption) { bigOption.ref.current.selectAll(); }); } else { setCheckedList(props.fixedShowKeys); // 子组全部清除选中 bigOptions.forEach(function (bigOption) { bigOption.ref.current.clearCheck(); }); } }; // 删除选中的元素 var unClickedColKey = function (key) { if (props.fixedShowKeys.includes(key)) { return; } var now = checkedList === null || checkedList === void 0 ? void 0 : checkedList.slice(); var index = now === null || now === void 0 ? void 0 : now.indexOf(key); if (index !== -1) { var bigOption = bigOptions.find(function (bigOption) { return bigOption.records.find(function (record) { return record.dataIndex === key; }); }); if (bigOption !== undefined) { now === null || now === void 0 ? void 0 : now.splice(index, 1); setCheckedList(now); setIndeterminate(true); bigOption.ref.current.removeCheck(key); } } }; // 清除全部选中 var clearLockColumn = function () { setCheckedList(props.fixedShowKeys); setIndeterminate(props.fixedShowKeys.length !== 0); bigOptions.forEach(function (bigOption) { bigOption.ref.current.clearCheck(); }); }; // 响应子组件的change事件 var handleSaveChange = function (index, checkeds) { var list = checkedList.slice(); var group = bigOptions[index].records.map(function (item) { return item.dataIndex; }); if (Array.isArray(checkeds)) { if (checkeds.length === 0) { group.forEach(function (item) { if (props.fixedShowKeys.includes(item)) { return; } var indx = list.indexOf(item); if (indx !== -1) { list.splice(indx, 1); } }); } else { group.forEach(function (item) { if (props.fixedShowKeys.includes(item)) { return; } if (!list.includes(item)) { list.push(item); } }); } } else { if (props.fixedShowKeys.includes(checkeds)) { return; } var indx = list.indexOf(checkeds); if (indx === -1) { list.push(checkeds); } else { list.splice(indx, 1); } } setCheckedList(list); var cha = list.length; setIndeterminate(cha !== 0 && cha !== totalCount); }; var onChangeSort = function (list) { var result = list.map(function (value) { return value.dataIndex; }); setCheckedList(result); }; var onReset = function () { props.onOk([]); }; var onSelectChange = function (key) { // 选择左侧区域 bigOptions.forEach(function (group) { var _a; (_a = group.ref.current) === null || _a === void 0 ? void 0 : _a.addCheck(key); }); var newList = checkedList.slice(); if (!newList.includes(key)) { // 选中右侧区域 newList.push(key); setCheckedList(newList); } }; var cardTitle = (jsxs("span", { children: ["\u53EF\u9009\u5B57\u6BB5", jsxs(Checkbox, __assign({ indeterminate: indeterminate, onChange: changeAllChecked, checked: checkedList.length === totalCount, style: { marginLeft: '18px' } }, { children: [checkedList.length, "/", totalCount] }), void 0), jsx(Select, { style: { width: '260px', marginLeft: '18px' }, showSearch: true, placeholder: "\u641C\u7D22\u5B57\u6BB5\u53EF\u5FEB\u901F\u52FE\u9009", onChange: onSelectChange, filterOption: function (input, option) { var _a; var label = String((_a = option === null || option === void 0 ? void 0 : option.label) !== null && _a !== void 0 ? _a : ''); return label.toLowerCase().includes(input.toLowerCase()); }, options: allOptions }, void 0)] }, void 0)); var dragList = []; checkedList.forEach(function (key) { if (saveMap[key]) { dragList.push(saveMap[key]); } }); var chooseList = (jsx("div", { children: jsx(DragList$1, { fixedColumns: props.fixedColumns, list: dragList, onChange: onChangeSort, removeItem: unClickedColKey }, void 0) }, void 0)); var footer = (jsxs("div", __assign({ style: { textAlign: 'right' } }, { children: [jsx(Button, __assign({ style: { marginRight: '20px' }, onClick: function () { return props.onCancel(); } }, { children: "\u53D6\u6D88" }), "cancel"), jsx(Button, __assign({ style: { marginRight: '20px' }, onClick: onReset }, { children: "\u6062\u590D\u9ED8\u8BA4\u663E\u793A\u5B57\u6BB5" }), "reset"), jsx(Button, __assign({ type: "primary", onClick: function () { return props.onOk(checkedList); } }, { children: "\u786E\u5B9A" }), "ok")] }), void 0)); return (jsxs("div", __assign({ style: stSetting }, { children: [jsx(Card, __assign({ title: cardTitle, style: stCardLeft, bodyStyle: stCardBody }, { children: bigOptions.map(function (bigOption, index) { return (jsx(GroupSet$1, { ref: bigOption.ref, records: bigOption.records, title: bigOption.title, groupIndex: index, fixedShowKeys: props.fixedShowKeys, handleSaveChange: handleSaveChange }, index)); }) }), void 0), jsx("div", __assign({ style: stBlank }, { children: jsx(DoubleLeftOutlined, { onClick: clearLockColumn }, void 0) }), void 0), jsx(Card, __assign({ bodyStyle: stCardBody, style: stCardRight, title: "\u53EF\u6392\u5E8F\u5B57\u6BB5 " + checkedList.filter(function (item) { return !props.fixedColumns.includes(item); }).length }, { children: chooseList }), void 0), jsx(Divider, {}, void 0), footer] }), void 0)); }; var SettingContent$1 = React.memo(SettingContent); var DefaultSetting = function (props) { return (jsx("div", __assign({ style: { textAlign: "left" } }, { children: jsx(Button, __assign({ type: "primary", onClick: props.handleClick }, { children: "\u8BBE\u7F6E" }), void 0) }), void 0)); }; // 主入口 var ManageTable$1 = React.forwardRef(function (props, ref) { var name = props.name, setTitle = props.setTitle, width = props.width, height = props.height, SettingComp = props.SettingComp, tableProps = __rest(props, ["name", "setTitle", "width", "height", "SettingComp"]); var init = useRef(false); var initConfig = computeColumns(name, props.columns, props.defaultShowKeys); var _a = useState(false), shouldShowModal = _a[0], setShouldShowModal = _a[1]; // 展示设置弹窗 var _b = useState(initConfig), config = _b[0], setConfig = _b[1]; // 展示设置弹窗 useEffect(function () { if (init.current) { setConfig(computeColumns(name, props.columns, props.defaultShowKeys)); } init.current = true; }, [props.columns, name]); // 向外暴露方法 useImperativeHandle(ref, function () { return { getShowKeys: function () { return config.computedShowKeys; }, showModal: function () { setShouldShowModal(true); }, hideModal: function () { setShouldShowModal(false); setConfig(computeColumns(name, props.columns)); }, }; }); //保存变更 var handleOk = function (keys, fixedColumns) { var _a; // Left-fixed columns need to be on the left, right-fixed columns need to be on the right. var left = keys.filter(function (key) { return fixedColumns.find(function (column) { return column.key === key && column.position === 'left'; }); }); var right = keys.filter(function (key) { return fixedColumns.find(function (column) { return column.key === key && column.position === 'right'; }); }); var rest = keys.filter(function (key) { return !fixedColumns.find(function (column) { return column.key === key; }); }); var newkeys = __spreadArray(__spreadArray(__spreadArray([], left), rest), right); setLSShowCol(name, newkeys); setShouldShowModal(false); setConfig(computeColumns(name, props.columns)); (_a = props.onKeysSelected) === null || _a === void 0 ? void 0 : _a.call(props, newkeys); }; return (jsxs("div", { children: [SettingComp ? (SettingComp) : (jsx(DefaultSetting, { handleClick: function () { setShouldShowModal(true); } }, void 0)), jsx(Table, __assign({}, tableProps, { columns: config.computedColumns }), void 0), jsx(Modal, __assign({ destroyOnClose: true, visible: shouldShowModal, width: width || '80%', style: { height: height || '80vh' }, title: setTitle || '设置显示字段', onCancel: function () { return setShouldShowModal(false); }, footer: false }, { children: jsx(SettingContent$1, { fixedColumns: config.fixedColumns.map(function (column) { return column.key; }), choose: config.groupRecordList, computedShowKeys: config.computedShowKeys, fixedShowKeys: props.fixedShowKeys || [], defaultShowKeys: props.defaultShowKeys || [], onCancel: function () { return setShouldShowModal(false); }, onOk: function (keys) { return handleOk(keys, config.fixedColumns); } }, void 0) }), void 0)] }, void 0)); }); var ManageTable$2 = React.memo(ManageTable$1); export default ManageTable$2;