UNPKG

es-grid-template

Version:

es-grid-template

529 lines (513 loc) 18.9 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _react = _interopRequireWildcard(require("react")); var _antdStyle = require("antd-style"); var _reactNumericComponent = require("react-numeric-component"); var _rcMasterUi = require("rc-master-ui"); require("dayjs/locale/es"); require("dayjs/locale/vi"); var _ContextMenu = _interopRequireDefault(require("./ContextMenu")); var _classnames = _interopRequireDefault(require("classnames")); var _hooks = require("./hooks"); var _columns = require("./hooks/columns"); var _pagination = _interopRequireDefault(require("rc-master-ui/es/pagination")); var _LoadingSpinner = _interopRequireDefault(require("./LoadingSpinner")); var _ColumnsChoose = require("./ColumnsChoose"); var _useMergedState = _interopRequireDefault(require("rc-util/lib/hooks/useMergedState")); var _AdvanceFilter = _interopRequireDefault(require("./AdvanceFilter")); var _reactTooltip = require("react-tooltip"); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } // import Table from "../../core/table" // import {ConfigProvider} from "antd"; const convertFilters = filters => { const result = []; filters.forEach(({ key, column, filteredKeys, operator }) => { if (!filteredKeys || filteredKeys.length === 0) { return; } if (column?.typeFilter === "DateRange" && filteredKeys.length === 2) { result.push({ key, field: column?.dataIndex, value: filteredKeys[0], predicate: "and", operator: "greaterthanorequal" }, { key, field: column?.dataIndex, value: filteredKeys[1], predicate: "and", operator: "lessthanorequal" }); } else if (column?.typeFilter === "NumberRange") { if ((filteredKeys[0] || filteredKeys[0] === 0) && !filteredKeys[1]) { result.push({ key, field: column?.dataIndex, value: filteredKeys[0], predicate: "and", operator: "greaterthanorequal" }); } if ((filteredKeys[1] || filteredKeys[1] === 0) && !filteredKeys[0]) { result.push({ key, field: column?.dataIndex, value: filteredKeys[1], predicate: "and", operator: "lessthanorequal" }); } if ((filteredKeys[0] || filteredKeys[0] === 0) && (filteredKeys[1] || filteredKeys[1] === 0)) { result.push({ key, field: column?.dataIndex, value: filteredKeys[0], predicate: "and", operator: "greaterthanorequal" }, { key, field: column?.dataIndex, value: filteredKeys[1], predicate: "and", operator: "lessthanorequal" }); } } else if (column?.typeFilter === 'Checkbox') { filteredKeys.forEach(value => { result.push({ key, field: column?.dataIndex, value, predicate: "or", operator }); }); } else { result.push({ key, field: column?.dataIndex, value: filteredKeys[0], predicate: 'and', operator }); } }); return result; }; const useStyle = (0, _antdStyle.createStyles)(({ css }) => { const antCls = 'ui-rc'; return { customTable: css` ${antCls}-table { ${antCls}-table-container { ${antCls}-table-body, ${antCls}-table-content { scrollbar-width: thin; scrollbar-color: #eaeaea transparent; scrollbar-gutter: stable; } } } ` }; }); // type OnChange = NonNullable<TableProps<any>['onChange']>; const EMPTY_LIST = []; const TableGrid = props => { const { id, columns, tableRef, dataSource, locale, expandable, rowHoverable, title, format, virtual = true, t, lang, contextMenuOpen, className, contextMenuItems: propContextMenuItems, contextMenuHidden, contextMenuClick, recordDoubleClick, toolbarItems, showColumnChoose, showAdvanceFilter, onFilter, triggerFilter, selectionSettings, rowSelection, rowSelected, rowKey = 'id', pagination, scroll, onFilterClick, dataSourceFilter: propDataSourceFilter, loading, triggerChangeColumns, triggerGroupColumns, summary, showToolbar, onSorter, bottomToolbar, groupSetting, groupAble, getRowKey, groupColumns, groupToolbar, showEmptyText, setIsFilter, ...rest } = props; const { styles } = useStyle(); const { mode, type, checkboxOnly, hideSelectAll, columnWidth, selectedRowKeys, defaultSelectedRowKeys } = selectionSettings || {}; const clickRef = _react.default.useRef(null); const menuRef = _react.default.useRef(null); const viewportWidth = window.innerWidth; const viewportHeight = window.innerHeight; const [menuVisible, setMenuVisible] = _react.default.useState(false); const [selectedRowData, setSelectedRowData] = _react.default.useState(null); const [position, setPosition] = _react.default.useState({ x: 0, y: 0, viewportWidth, viewportHeight }); const [filterStates, setFilterState] = _react.default.useState(null); // const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>(defaultSelected); // ========================= Keys ========================= const [mergedSelectedKeys, setMergedSelectedKeys] = (0, _useMergedState.default)(selectedRowKeys || defaultSelectedRowKeys || EMPTY_LIST, { value: selectedRowKeys }); // Reset if rowSelection reset _react.default.useEffect(() => { if (!selectionSettings) { setMergedSelectedKeys(EMPTY_LIST); } }, [!!selectionSettings]); const contextMenuItems = _react.default.useMemo(() => { if (typeof contextMenuHidden === "function" && propContextMenuItems && selectedRowData) { const hiddenItems = contextMenuHidden({ rowInfo: { rowData: selectedRowData } }); return propContextMenuItems.filter(item => !hiddenItems.includes(item?.key)); } if (contextMenuHidden && typeof contextMenuHidden !== 'function' && propContextMenuItems) { return propContextMenuItems.filter(item => !contextMenuHidden.includes(item?.key)); } return propContextMenuItems; }, [propContextMenuItems, contextMenuHidden, selectedRowData]); _react.default.useLayoutEffect(() => { setMenuVisible(false); }, []); const onContextMenu = data => event => { event.preventDefault(); // Ngăn chặn menu mặc định của trình duyệt setSelectedRowData(data); contextMenuOpen?.({ rowInfo: { rowData: data }, event }); setMenuVisible(true); // Đợi DOM cập nhật và lấy kích thước menu setTimeout(() => { const menuElement = menuRef.current; // Lấy menu từ DOM const menuWidth = menuElement?.offsetWidth || 200; // Mặc định 200px nếu chưa render const menuHeight = menuElement?.offsetHeight; // Mặc định 450px nếu chưa render // Điều chỉnh vị trí menu let x = event.clientX; let y = event.clientY; if (x + menuWidth > viewportWidth) { x = x - menuWidth - 10; // Cách cạnh phải 10px } if (y + menuHeight > viewportHeight) { if (y < menuHeight) { y = 10; } else { y = y - 10 - menuHeight; // Cách cạnh dưới 10px } } setPosition(prevState => ({ ...prevState, x, y })); }, 100); if (!menuVisible) { document.addEventListener(`click`, function onClickOutside(e) { const element = e.target; const menuContainer = document.querySelector(".popup-context-menu"); const isInsideContainer = element.closest(".popup-context-menu") && menuContainer; if (isInsideContainer) { return; } setMenuVisible(false); document.removeEventListener(`click`, onClickOutside); }); } }; const handleRowClick = () => () => { // const key = getRowKey(record, index); if (checkboxOnly !== true) { if (type === 'single') {} } }; const handleRowDoubleClick = (record, index) => e => { if (clickRef.current) { clearTimeout(clickRef.current); clickRef.current = null; } recordDoubleClick?.({ e, rowIndex: index, rowData: record }); }; const onSelectChange = (keys, selectedRows, info, selectedRow) => { if (info.type === 'all') { setMergedSelectedKeys(keys); rowSelected?.({ selected: selectedRows, type: 'rowSelected', rowData: {} }); } else { if (selectionSettings?.type === 'multiple') { setMergedSelectedKeys(keys); rowSelected?.({ selected: selectedRows, type: 'rowSelected', rowData: selectedRow }); } else { // @ts-ignore setMergedSelectedKeys(keys); rowSelected?.({ selected: selectedRows, type: 'rowSelected', rowData: selectedRow }); } } }; const handleChange = sorter => { onSorter?.(sorter); }; const handleOnFilter = queries => { if (onFilter) { onFilter?.(convertFilters(queries)); } else { setFilterState(convertFilters(queries)); if (queries && queries.length > 0) { setIsFilter?.(true); } else { setIsFilter?.(false); } } }; return /*#__PURE__*/_react.default.createElement(_react.Fragment, null, /*#__PURE__*/_react.default.createElement(_ContextMenu.default, { open: menuVisible, pos: position, setOpen: setMenuVisible, menuRef: menuRef, contextMenuItems: contextMenuItems, contextMenuClick: contextMenuClick, rowData: selectedRowData }), /*#__PURE__*/_react.default.createElement(_rcMasterUi.Table, (0, _extends2.default)({ ref: tableRef }, rest, { tableLayout: 'fixed', locale: { ...locale, emptyText: showEmptyText !== false ? /*#__PURE__*/_react.default.createElement(_rcMasterUi.Empty, { image: _rcMasterUi.Empty.PRESENTED_IMAGE_SIMPLE, description: locale?.emptyText }) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null) }, loading: { spinning: columns && columns.length === 0 || loading === true, indicator: /*#__PURE__*/_react.default.createElement(_LoadingSpinner.default, null) } // dataSource={columns && columns.length > 0 ? filterDataByColumns3(dataSource, filterStates) : []} , dataSource: columns && columns.length > 0 ? (0, _hooks.filterDataByColumns4)(dataSource, filterStates) : [], className: (0, _classnames.default)(className, { 'table-none-column-select': selectionSettings?.mode === undefined && selectionSettings?.type !== 'multiple' }, styles.customTable), bordered: true, virtual: virtual, columns: columns, rowKey: rowKey, rowHoverable: rowHoverable, size: "small", scroll: scroll ? scroll : { y: 500 }, onRow: (data, index) => { return { onDoubleClick: handleRowDoubleClick(data, index), onClick: handleRowClick(), onContextMenu: onContextMenu(data) }; }, rowSelection: columns && columns.length === 0 ? undefined : { ...selectionSettings, // type: selectionSettings?.mode, type: mode, columnWidth: columnWidth ?? 50, onChange: onSelectChange, // selectedRowKeys: mode === 'checkbox' && type === 'single' ? selectedRowKeys : undefined, selectedRowKeys: mergedSelectedKeys, // defaultSelectedRowKeys: selectionSettings?.defaultSelectedRowKeys, defaultSelectedRowKeys, preserveSelectedRowKeys: true, hideSelectAll: !type || type === 'single' || mode === 'radio' ? true : hideSelectAll ?? type !== 'multiple' } // onScroll={(event) => { // console.log('event', event) // }} , onFilter: val => { handleOnFilter(val); // triggerFilter?.(convertFilters(val)) // onFilter?.(convertFilters(val)) }, onChange: (paging, filters, sorter) => handleChange(sorter), title: showToolbar === false ? undefined : () => { return /*#__PURE__*/_react.default.createElement(_react.Fragment, null, /*#__PURE__*/_react.default.createElement("div", null, title?.(dataSource)), /*#__PURE__*/_react.default.createElement("div", { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: '.75rem' } }, groupAble && groupToolbar?.(), toolbarItems && toolbarItems?.length > 0 && /*#__PURE__*/_react.default.createElement("div", { style: { flex: 1, overflow: 'hidden' } }, /*#__PURE__*/_react.default.createElement(_rcMasterUi.Toolbar // @ts-ignore // style={{width: pagination && pagination.onChange && pagination?.position && pagination?.position[0] === 'topRight' ? `calc(100% - 650px - ${groupAble ? 50 : 0}px` : `calc(100% - 25px - ${groupAble ? 50 : 0}px`}} , { items: (toolbarItems ?? []).filter(it => it.position !== 'Bottom'), mode: 'scroll' })), /*#__PURE__*/_react.default.createElement("div", { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: '.75rem' } }, pagination && pagination.onChange && pagination?.position && pagination?.position[0] === 'topRight' && /*#__PURE__*/_react.default.createElement(_pagination.default, (0, _extends2.default)({ showSizeChanger: true, responsive: true, size: 'small', rootClassName: 'top-pagination' // @ts-ignore , showTotal: (total, range) => `${range[0]}-${range[1]} / ${total} ${t ? t(pagination?.locale?.items ?? 'items') : 'items'}` }, pagination)), showColumnChoose && /*#__PURE__*/_react.default.createElement(_ColumnsChoose.ColumnsChoose, { columns: columns, t: t, columnsGroup: groupColumns, triggerChangeColumns: triggerChangeColumns }), showAdvanceFilter && /*#__PURE__*/_react.default.createElement(_AdvanceFilter.default, { columns: columns, t: t // columnsGroup={groupColumns} // triggerChangeColumns={triggerChangeColumns} })))); }, expandable: { ...expandable }, summary: () => { if (typeof summary === 'function') { return summary(dataSource); } if (!summary) { return undefined; } return /*#__PURE__*/_react.default.createElement(_rcMasterUi.Table.Summary, { fixed: true }, /*#__PURE__*/_react.default.createElement(_rcMasterUi.Table.Summary.Row, null, (0, _columns.flatColumns)(!!mode ? [_rcMasterUi.Table.SELECTION_COLUMN, ...columns] : [...columns]).filter(col => col.hidden !== true).map((col, index) => { // const cellFormat: IFormat | undefined = col.format ? typeof col.format === 'function' ? col.format({}) : col.format : format const colFormat = typeof col.format === 'function' ? col.format({}) : col.format; const cellFormat = (0, _hooks.getFormat)(colFormat, format); const thousandSeparator = cellFormat?.thousandSeparator; const decimalSeparator = cellFormat?.decimalSeparator; // const dec = (col.format?.decimalScale || col.format?.decimalScale === 0) ? col.format?.decimalScale : format?.decimalScale const dec = cellFormat?.decimalScale; const sumValue = col.type === 'number' ? (0, _hooks.sumDataByField)((0, _hooks.filterDataByColumns4)(dataSource, filterStates), col?.key) : 0; const value = !(0, _hooks.isEmpty)(sumValue) ? dec || dec === 0 ? parseFloat(Number(sumValue).toFixed(dec)).toString() : sumValue.toString() : '0'; const cellValue = col.type === 'number' && col.isSummary !== false ? value : ''; const numericFormatProps = { thousandSeparator: (0, _hooks.checkThousandSeparator)(thousandSeparator, decimalSeparator), decimalSeparator: (0, _hooks.checkDecimalSeparator)(thousandSeparator, decimalSeparator), allowNegative: cellFormat?.allowNegative ?? false, prefix: cellFormat?.prefix, suffix: cellFormat?.suffix, decimalScale: dec, fixedDecimalScale: cellFormat?.fixedDecimalScale ?? false }; return /*#__PURE__*/_react.default.createElement(_rcMasterUi.Table.Summary.Cell, { key: col.key, index: index, align: col.align ?? 'right', className: 'ui-rc-table-cell-ellipsis' }, col.summaryTemplate ? col.summaryTemplate(cellValue, col.key) : (0, _reactNumericComponent.numericFormatter)(cellValue, numericFormatProps)); }))); }, pagination: !pagination || pagination && pagination?.onChange ? false : { showTotal: (total, range) => `${range[0]}-${range[1]} / ${total} items`, ...pagination } })), /*#__PURE__*/_react.default.createElement("div", null), pagination && pagination.onChange && !pagination.position && /*#__PURE__*/_react.default.createElement(_pagination.default // style={{padding: '0.75rem 1rem'}} , (0, _extends2.default)({ rootClassName: 'pagination-template', showSizeChanger: true, responsive: true, size: 'small' // @ts-ignore , showTotal: (total, range) => `${range[0]}-${range[1]} / ${total} ${t ? t(pagination?.locale?.items ?? 'items') : 'items'}` }, pagination)), bottomToolbar?.(), /*#__PURE__*/_react.default.createElement(_reactTooltip.Tooltip, { id: `${id}-tooltip-header`, style: { zIndex: 1999 } })); }; var _default = exports.default = TableGrid;