import { GridCellEditStopReasons, GridRenderCellParams, useGridApiContext } from "@mui/x-data-grid" import React, { memo, useMemo, useRef, useState } from "react" import { TreeCellNode } from "./types" import { removeUndefine } from "../../../utils" import { Box, Popper } from "@mui/material" import { SimpleTreeView, TreeItem2 } from "@mui/x-tree-view" import RefreshIcon from "../../../ui-utils/RefreshIcon" import ClearIcon from "@mui/icons-material/Clear" import { CustomIcon } from "../../../ui-utils" const buildIndex = (nodes: TreeCellNode[], dict?: Record) => { const d = dict || {} nodes.forEach(n => { d[n.nodeId] = n n.children && buildIndex(n.children, d) }) return d } function filterTreeNodes(treeNodes: TreeCellNode[], filterString?: string): TreeCellNode[] { if (!filterString) return treeNodes const filterTreeNode = (treeNode: TreeCellNode) => { if (treeNode.title.indexOf(filterString) !== -1) return treeNode if (!treeNode.children || treeNode.children.length === 0) return undefined const children = filterTreeNodes(treeNode.children, filterString) if (children && children.length > 0) { return { ...treeNode, children } } return undefined } return treeNodes.map(filterTreeNode).filter(removeUndefine) } const rendTreeCellNode = (node: TreeCellNode) => { const childrenNodes = node.children ? rendTreeCellNodes(node.children) : null return ( {childrenNodes} ) } const rendTreeCellNodes = (nodes: TreeCellNode[]) => { return nodes.map(rendTreeCellNode) } export const TreeSelectCell = memo( ({ cellParams, rootNodes, isLoading, refreshHandler, enableClear, }: { // eslint-disable-next-line @typescript-eslint/no-explicit-any cellParams: GridRenderCellParams[]> rootNodes: TreeCellNode[] isLoading?: boolean refreshHandler?: () => void enableClear?: boolean }) => { const { id, field } = cellParams const nodeIndex = React.useMemo(() => buildIndex(rootNodes), [rootNodes]) const divRef = useRef(null) const apiRef = useGridApiContext() const [showPops, setShowPops] = useState(false) const [filterString, setFilterString] = useState("") const filteredTreeNodes = useMemo(() => filterTreeNodes(rootNodes, filterString), [rootNodes, filterString]) const onNodeSelect = (_event: React.SyntheticEvent, nodeId: string) => { const node = nodeIndex[nodeId] if (node.canBeChoosed) { apiRef.current.setEditCellValue({ id, field, value: node.value === undefined ? node.nodeId : node.value }) if (!node.disableAutoSelect) { setShowPops(false) apiRef.current.publishEvent("cellEditStop", { ...cellParams, reason: GridCellEditStopReasons.cellFocusOut, }) } } } const onClear = () => { apiRef.current.setEditCellValue({ id, field, value: "" }) setShowPops(false) apiRef.current.publishEvent("cellEditStop", { ...cellParams, reason: GridCellEditStopReasons.cellFocusOut, }) } React.useEffect(() => { setShowPops(true) }, []) const refreshButton = isLoading !== undefined && refreshHandler !== undefined ? ( ) : null const clearButton = enableClear ? } handler={onClear} /> : null return (
请选择 {refreshButton} {clearButton}
过滤: setFilterString(e.target.value)}>
{rendTreeCellNodes(filteredTreeNodes)}
) }, )