UNPKG

es-grid-template

Version:

es-grid-template

295 lines (263 loc) 9.1 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import customParseFormat from 'dayjs/plugin/customParseFormat'; import React, { Fragment, useState } from 'react'; import 'react-resizable/css/styles.css'; import dayjs from 'dayjs'; import 'dayjs/locale/es'; import 'dayjs/locale/vi'; // import en from "rc-master-ui/es/date-picker/locale/en_US" // import vi from "rc-master-ui/es/date-picker/locale/vi_VN" // import enDr from "rc-master-ui/es/locales/en_US" // import viDr from "rc-master-ui/es/locales/vi_VN" // import type { PickerLocale } from "rc-master-ui/es/date-picker/generatePicker" import "./style.scss"; // import Swal from "sweetalert2" // import withReactContent from "sweetalert2-react-content" // import { Tooltip } from "react-tooltip" import { faker } from '@faker-js/faker'; import useMergedState from "rc-util/es/hooks/useMergedState"; // import InfiniteTable from './table/InfiniteTable' // import GridEdit from './table/GridEdit' import Grid from "./table/Grid"; // import { Group } from 'becoxy-icons' import { Tooltip } from 'react-tooltip'; import ContextMenu from "./ContextMenu"; import { addRowIdArray, // convertFilters, filterDataByColumns, // filterDataByColumns, getAllRowKey, getFixedFields, getInvisibleColumns, groupArrayByColumns } from "./hook/utils"; import GridEdit from "./table/GridEdit"; import { convertToTanStackColumns } from "./hook/useColumns"; dayjs.extend(customParseFormat); // const MySwal = withReactContent(Swal) // const ASCEND = 'ascend' // const DESCEND = 'descend' export const SELECTION_COLUMN = {}; const InternalTable = props => { const { t, // columns: propsColumns, columns, lang, locale, dataSource, editAble, format, groupAble, groupSetting, groupColumns, infiniteScroll, // wrapSettings, // onFilter, expandable, contextMenuItems: propContextMenuItems, contextMenuHidden, contextMenuClick, contextMenuOpen, ...rest } = props; const id = React.useMemo(() => { return faker.string.alpha(20); }, []); const rowKey = 'rowId'; const prefix = 'ui-rc'; const getWindowSize = () => { const { innerWidth, innerHeight } = window; return { innerWidth, innerHeight }; }; const [windowSize, setWindowSize] = useState(getWindowSize()); React.useEffect(() => { const handleWindowResize = () => { setWindowSize(getWindowSize()); }; window.addEventListener('resize', handleWindowResize); return () => { window.removeEventListener('resize', handleWindowResize); }; }, []); // const local = lang && lang === 'en' ? en : vi // const dateRangeLocale = lang && lang === 'en' ? enDr : viDr // const buddhistLocale: PickerLocale = { // ...local, // lang: { // ...local.lang // } // } const menuRef = React.useRef(null); const viewportWidth = windowSize.innerWidth; const viewportHeight = windowSize.innerHeight; const [menuVisible, setMenuVisible] = React.useState(false); const [selectedRowData, setSelectedRowData] = React.useState(null); const [position, setPosition] = React.useState({ x: 0, y: 0, viewportWidth, viewportHeight }); // const [tooltipContent, setTooltipContent] = useState<any>('') const [filterStates, setFilterState] = React.useState(null); const [sorterStates, setSorterStates] = React.useState([]); // const [isFullScreen, setIsFullScreen] = React.useState<boolean>(false) const [expanded, setExpanded] = React.useState({}); const convertData = React.useMemo(() => { if (groupAble && groupSetting && groupSetting.client !== false) { return groupArrayByColumns(dataSource, groupColumns); } return addRowIdArray(dataSource); }, [dataSource, groupAble, groupColumns, groupSetting]); const mergedColumns = React.useMemo(() => { return convertToTanStackColumns({ columns, expanded, setExpanded, expandable, format, editAble }); // return convertToTanStackColumns<RecordType>(columns, expanded, setExpanded, expandable) }, [columns, expanded, expandable, format, editAble]); const columnPinning = React.useMemo(() => { return { left: getFixedFields(columns, 'left'), right: getFixedFields(columns, 'right') }; }, [columns]); // ========================= Keys ========================= const [mergedFilterKeys, setMergedFilterKeys] = useMergedState(getAllRowKey(convertData), { value: undefined }); const mergedData = React.useMemo(() => { return filterDataByColumns(convertData, filterStates, sorterStates, mergedFilterKeys); }, [convertData, filterStates, mergedFilterKeys, sorterStates]); const columnVisibility = React.useMemo(() => { return getInvisibleColumns(columns); }, [columns]); const contextMenuItems = React.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]); // const [columns, setColumns] = React.useState<any[]>([]) // React.useEffect(() => { // setColumns(propsColumns) // }, [propsColumns]) // const triggerFilter = (queries: any[]) => { // if (onFilter) { // onFilter?.(convertFilters(queries)) // } else { // setFilterState(convertFilters(queries)) // const b = filterDataByColumns(convertData, convertFilters(queries), [], []) // setMergedFilterKeys(getAllRowKey(b)) // } // } 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); setPosition(prevState => ({ ...prevState, x: undefined, y: undefined })); document.removeEventListener(`click`, onClickOutside); }); } }; // const TableComponent = infiniteScroll ? InfiniteTable : (groupAble ? Group : editAble ? GridEdit : Grid) const TableComponent = editAble ? GridEdit : Grid; return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(TableComponent, _extends({}, rest, { t: t, id: id, prefix: prefix, originData: convertData, dataSource: mergedData, locale: locale, format: format, columns: mergedColumns, propsColumns: columns, rowKey: rowKey, groupSetting: groupSetting, groupAble: groupAble, groupColumns: groupColumns, isFullScreen: false, columnPinning: columnPinning, columnVisibility: columnVisibility, triggerFilter: setFilterState, triggerSorter: setSorterStates, setMergedFilterKeys: setMergedFilterKeys, mergedFilterKeys: mergedFilterKeys, expanded: expanded, onContextMenu: onContextMenu, contextMenuItems: contextMenuItems, editAble: editAble })), menuVisible && /*#__PURE__*/React.createElement(ContextMenu, { open: menuVisible, pos: position, setOpen: setMenuVisible, menuRef: menuRef, contextMenuItems: contextMenuItems, contextMenuClick: contextMenuClick, rowData: selectedRowData }), /*#__PURE__*/React.createElement(Tooltip, { id: `${id}-tooltip-header-trigger`, style: { zIndex: 1999 } })); }; export default InternalTable;