123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409 |
- import * as React from "react";
- import { useState } from "react";
- import {
- FolderRegular,
- DocumentRegular,
- DocumentPdfRegular,
- VideoRegular,
- ChevronDown16Filled,
- TextField16Regular,
- Calendar16Regular,
- SelectAllOn16Regular,
- CommentAdd16Regular,
- MoreHorizontal16Filled,
- NumberCircle116Regular,
- Add16Filled
- } from "@fluentui/react-icons";
- import {
- DataGridBody,
- DataGridRow,
- DataGrid,
- DataGridHeader,
- DataGridHeaderCell,
- DataGridCell,
- TableCellLayout,
- createTableColumn,
- Button,
- Menu,
- MenuTrigger,
- MenuList,
- MenuItem,
- MenuPopover,
- Tooltip,
- MenuDivider,
- Input,
- Select,
- } from "@fluentui/react-components";
- import { DatePicker } from "@fluentui/react-datepicker-compat";
- const List = (editType) => {
- // const defaultSelectedItems = React.useMemo(() => new Set([1]), []);
- //数据类型常量
- const DATA_TYPE = {
- 文本: "文本",
- 数字: "数字",
- 日期: "日期",
- 选项: "选项"
- }
- /**
- * 列头下拉菜单
- * @param {*} dataType 表现类型
- */
- const HeaderMenuList = (props) => {
- return (
- <Menu>
- <MenuTrigger disableButtonEnhancement>
- <Button
- appearance="subtle"
- icon={<ChevronDown16Filled />}
- ></Button>
- </MenuTrigger>
- <MenuPopover>
- <MenuList>
- {props.dataType == DATA_TYPE.数字 && <MenuItem onClick={() => {
- ascendingData(props.columnId);
- }}>从小到大 </MenuItem>}
- {props.dataType == DATA_TYPE.数字 && <MenuItem onClick={() => {
- descendingData(props.columnId);
- }}>从大到小</MenuItem>}
- {(props.dataType == DATA_TYPE.文本 || props.dataType == DATA_TYPE.选项) && <MenuItem onClick={() => {
- ascendingData(props.columnId);
- }}>A到Z </MenuItem>}
- {(props.dataType == DATA_TYPE.文本 || props.dataType == DATA_TYPE.选项) && <MenuItem onClick={() => {
- descendingData(props.columnId);
- }}>Z到A </MenuItem>}
- {(props.dataType == DATA_TYPE.日期) && <MenuItem onClick={() => {
- ascendingData(props.columnId);
- }}>从旧到新 </MenuItem>}
- {(props.dataType == DATA_TYPE.日期) && <MenuItem onClick={() => {
- descendingData(props.columnId);
- }}>从新到旧 </MenuItem>}
- <MenuDivider />
- <MenuItem>筛选方式</MenuItem>
- <MenuDivider />
- <MenuItem>按“{props.columnId}”分组</MenuItem>
- <MenuDivider />
- <MenuItem><HeaderMenuColumnSet dataType={props.dataType} /></MenuItem>
- <MenuDivider />
- <MenuItem><HeaderMenuAmount dataType={props.dataType} /></MenuItem>
- </MenuList>
- </MenuPopover>
- </Menu>
- );
- }
- const [dataSortType, setDataSortType] = useState(({
- sortColumn: "序号",
- sortDirection: "ascending",
- }));
- const ascendingData = (columnId) => {
- setDataSortType(({
- sortColumn: columnId,
- sortDirection: "ascending",
- }));
- }
- const descendingData = (columnId) => {
- setDataSortType(({
- sortColumn: columnId,
- sortDirection: "descending",
- }));
- }
- /**
- * 列设置的二级菜单
- * @returns
- */
- const HeaderMenuColumnSet = (props) => {
- return (
- <Menu>
- <MenuTrigger disableButtonEnhancement>
- <MenuItem>列设置</MenuItem>
- </MenuTrigger>
- <MenuPopover>
- <MenuList>
- <MenuItem>编辑</MenuItem>
- <MenuItem>隐藏此列</MenuItem>
- <MenuItem>设置此列的格式</MenuItem>
- <MenuItem>向左移动</MenuItem>
- <MenuItem>向右移动</MenuItem>
- <MenuItem>显示/隐藏列</MenuItem>
- <MenuItem>加宽列</MenuItem>
- <MenuItem>窄列</MenuItem>
- <MenuItem>固定到筛选器窗口</MenuItem>
- <MenuItem>添加列</MenuItem>
- </MenuList>
- </MenuPopover>
- </Menu>
- );
- }
- /**
- * 列头“合计”二级菜单
- */
- const HeaderMenuAmount = (props) => {
- return (
- <Menu>
- <MenuTrigger disableButtonEnhancement>
- <MenuItem>合计</MenuItem>
- </MenuTrigger>
- <MenuPopover>
- <MenuList>
- <MenuItem>无</MenuItem>
- <MenuItem>计数</MenuItem>
- {props.dataType == DATA_TYPE.数字 && <MenuItem>平均值</MenuItem>}
- {props.dataType == DATA_TYPE.数字 && <MenuItem>最大值</MenuItem>}
- {props.dataType == DATA_TYPE.数字 && <MenuItem>最小值</MenuItem>}
- {props.dataType == DATA_TYPE.数字 && <MenuItem>求和</MenuItem>}
- {props.dataType == DATA_TYPE.数字 && <MenuItem>标准偏差</MenuItem>}
- {props.dataType == DATA_TYPE.数字 && <MenuItem>方差</MenuItem>}
- </MenuList>
- </MenuPopover>
- </Menu>
- );
- }
- /**
- * 鼠标移动到姓名列上时,显示两个按钮
- * @param item 包含姓名标签的对象
- * @returns 返回 JSX 元素
- */
- const ChangeBtnShowType = (props) => {
- const [showButton, setShowButton] = useState(false);
- const handleMouseEnter = () => {
- setShowButton(true);
- };
- const handleMouseLeave = () => {
- setShowButton(false);
- };
- return (
- <div
- style={{
- width: "100%",
- display: "flex",
- justifyContent: "space-between",
- alignItems: "center",
- }}
- onMouseEnter={handleMouseEnter}
- onMouseLeave={handleMouseLeave}
- >
- {editType.edit == "true" ? <Input type="text" style={{ width: "calc(100% - 70px)" }} defaultValue={props.cellData} /> : props.cellData}
- {showButton && (
- <div>
- <Tooltip content="更多操作" positioning="below">
- <Button
- appearance="subtle"
- icon={<MoreHorizontal16Filled />}
- onClick={() => {
- alert("更多操作");
- }}
- ></Button>
- </Tooltip>
- <Tooltip content="添加注释" positioning="below">
- <Button appearance="subtle" icon={<CommentAdd16Regular />}></Button>
- </Tooltip>
- </div>
- )}
- </div>
- );
- };
- const tableData = [
- {
- 序号: { label: 1 },
- 姓名: { label: "陈丹" },
- 性别: { label: "女" },
- 年龄: { label: "18岁" },
- 最后在线时间: { label: "2024-11-03" },
- },
- {
- 序号: { label: 2 },
- 姓名: { label: "蔡青松" },
- 性别: { label: "男", },
- 年龄: { label: "30岁" },
- 最后在线时间: { label: "2024-11-04" },
- },
- {
- 序号: { label: 3 },
- 姓名: { label: "杨东明" },
- 性别: { label: "男" },
- 年龄: { label: "25岁" },
- 最后在线时间: { label: "2024-11-05" },
- },
- {
- 序号: { label: 4 },
- 姓名: { label: "吴瑞强" },
- 性别: { label: "男" },
- 年龄: { label: "25岁" },
- 最后在线时间: { label: "2024-11-06" },
- },
- ]
- const [newTableData, setTabeData] = useState(tableData);
- /**
- * 新增空行
- */
- const AddNewRow = () => {
- setTabeData(newTableData.concat([{
- 序号: { label: newTableData.length + 1 },
- 姓名: { label: "" },
- 性别: { label: "" },
- 年龄: { label: "" },
- 最后在线时间: { label: "" },
- }]));
- }
- return (
- <DataGrid
- items={newTableData}
- columns={[
- createTableColumn({
- columnId: "姓名",
- compare: (a, b) => {
- return a.姓名.label.localeCompare(b.姓名.label);
- },
- renderHeaderCell: () => {
- return (
- <TableCellLayout media={<TextField16Regular />}>
- 姓名
- <HeaderMenuList dataType={DATA_TYPE.文本} title="姓名" columnId="姓名" />
- </TableCellLayout>
- );
- },
- renderCell: (item) => {
- return <ChangeBtnShowType cellData={item.姓名.label} />
- },
- }),
- createTableColumn({
- columnId: "序号",
- fixed: true,
- compare: (a, b) => {
- return a.序号.label - b.序号.label;
- },
- renderHeaderCell: () => {
- return (
- <TableCellLayout media={<NumberCircle116Regular />}>
- 序号
- <HeaderMenuList dataType={DATA_TYPE.数字} title="序号" columnId="序号" />
- </TableCellLayout>
- );
- },
- renderCell: (item) => {
- return editType.edit == "true" ? <Input type="number" defaultValue={item.序号.label} style={{ width: "100%" }} /> : item.序号.label;
- },
- }),
- createTableColumn({
- columnId: "性别",
- compare: (a, b) => {
- return a.性别.label.localeCompare(b.性别.label);
- },
- renderHeaderCell: () => {
- return (
- <TableCellLayout media={<SelectAllOn16Regular />}>
- 性别
- <HeaderMenuList dataType={DATA_TYPE.选项} title="性别" columnId="性别" />
- </TableCellLayout>
- );
- },
- renderCell: (item) => {
- return editType.edit == "true" ? <Select style={{ width: "calc(100% - 70px)" }}>
- <option value="男" selected={item.性别.label == "男"}>男</option>
- <option value="女" selected={item.性别.label == "女"}>女</option>
- </Select> : item.性别.label;
- },
- }),
- createTableColumn({
- columnId: "年龄",
- compare: (a, b) => {
- return a.年龄.timestamp - b.年龄.timestamp;
- },
- renderHeaderCell: () => {
- return (
- <TableCellLayout media={<TextField16Regular />}>
- 年龄
- <HeaderMenuList dataType={DATA_TYPE.文本} title="年龄" columnId="年龄" />
- </TableCellLayout>
- );
- },
- renderCell: (item) => {
- return item.年龄.label;
- },
- }),
- createTableColumn({
- columnId: "最后在线时间",
- compare: (a, b) => {
- return new Date(a.最后在线时间.label) - new Date(b.最后在线时间.label);
- },
- renderHeaderCell: () => {
- return (
- <TableCellLayout media={<Calendar16Regular />}>
- 最后在线时间
- <HeaderMenuList dataType={DATA_TYPE.日期} title="最后在线时间" columnId="最后在线时间" />
- </TableCellLayout>
- );
- },
- renderCell: (item) => {
- return editType.edit == "true" ? <Input type="date" defaultValue={item.最后在线时间.label} /> : item.最后在线时间.label;
- },
- }),
- ]}
- selectionMode="multiselect"
- sortable
- sortState={dataSortType}
- subtleSelection
- resizableColumns
- // defaultSelectedItems={defaultSelectedItems}
- style={{ minWidth: "550px" }}
- >
- <DataGridHeader>
- <DataGridRow>
- {({ renderHeaderCell }) => (
- <DataGridHeaderCell>{renderHeaderCell()}</DataGridHeaderCell>
- )}
- </DataGridRow>
- </DataGridHeader>
- <DataGridBody>
- {({ item, rowId }) => (
- <DataGridRow
- key={rowId}
- selectionCell={{ radioIndicator: { "aria-label": "Select row" } }}
- >
- {({ renderCell }) => (
- <DataGridCell>{renderCell(item)}</DataGridCell>
- )}
- </DataGridRow>
- )}
- </DataGridBody>
- <Button
- appearance="subtle"
- icon={<Add16Filled />}
- style={{ color: "#ca5010" }}
- onClick={() => {
- AddNewRow();
- }}
- >添加新项目</Button>
- </DataGrid>
- );
- };
- export default List;
|