From 4e7c6e216f9bb759d755bc5557ffedeb8e5f880d Mon Sep 17 00:00:00 2001
From: verou <857149855@qq.com>
Date: 星期三, 12 三月 2025 09:40:26 +0800
Subject: [PATCH] feat:po asn btn

---
 rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupList.jsx |  447 +++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 315 insertions(+), 132 deletions(-)

diff --git a/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupList.jsx b/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupList.jsx
index b7ee747..8436018 100644
--- a/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupList.jsx
+++ b/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupList.jsx
@@ -1,156 +1,339 @@
-import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
-import { useNavigate } from 'react-router-dom';
+import React from 'react';
 import {
-    List,
-    DatagridConfigurable,
-    SearchInput,
-    TopToolbar,
-    SelectColumnsButton,
-    EditButton,
-    FilterButton,
-    CreateButton,
-    ExportButton,
-    BulkDeleteButton,
-    WrapperField,
-    useRecordContext,
+    Title,
     useTranslate,
     useNotify,
-    useListContext,
-    FunctionField,
-    TextField,
-    NumberField,
-    DateField,
-    BooleanField,
-    ReferenceField,
-    TextInput,
-    DateTimeInput,
-    DateInput,
-    SelectInput,
-    NumberInput,
-    ReferenceInput,
-    ReferenceArrayInput,
-    AutocompleteInput,
-    DeleteButton,
+    useRedirect,
+    useRefresh,
+    useDelete,
 } from 'react-admin';
-import { Box, Typography, Card, Stack } from '@mui/material';
 import { styled } from '@mui/material/styles';
-import MatnrGroupCreate from "./MatnrGroupCreate";
-import MatnrGroupPanel from "./MatnrGroupPanel";
-import EmptyData from "@/page/components/EmptyData";
-import MyCreateButton from "@/page/components/MyCreateButton";
-import MyExportButton from '@/page/components/MyExportButton';
-import PageDrawer from "@/page/components/PageDrawer";
-import MyField from "@/page/components/MyField";
-import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
-import * as Common from '@/utils/common';
+import {
+    Box,
+    Collapse,
+    IconButton,
+    Table,
+    TableBody,
+    TableCell,
+    TableContainer,
+    TableHead,
+    TableRow,
+    Paper,
+    Card,
+    Typography,
+    TextField,
+    Tooltip,
+    Button,
+    Chip,
+    LinearProgress,
+} from '@mui/material';
+import { Add, Edit, Delete } from '@mui/icons-material';
+import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
+import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
+import RefreshIcon from '@mui/icons-material/Refresh';
+import request from '@/utils/request';
+import MatnrGroupEdit from "./MatnrGroupEdit";
+import * as Icons from '@mui/icons-material';
 
-const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
-    '& .css-1vooibu-MuiSvgIcon-root': {
-        height: '.9em'
+const RESOURCE = 'matnrGroup';
+const TITLE = 'menu.matnrGroup';
+
+const columns = [
+    {
+        id: 'name',
+        label: 'table.field.matnrGroup.name',
+        minWidth: 200,
     },
-    '& .RaDatagrid-row': {
-        cursor: 'auto'
+    {
+        id: 'code',
+        label: 'table.field.matnrGroup.code',
+        minWidth: 80,
     },
-    '& .column-name': {
-    },
-    '& .opt': {
-        width: 200
-    },
+    {
+        id: 'parentId',
+        label: 'table.field.matnrGroup.parentId',
+        minWidth: 100,
+    }
+];
+
+const getIconComponent = (iconStr) => {
+    return Icons[iconStr] || null;
+};
+
+const StyledTableRow = styled(TableRow)(({ theme }) => ({
+    '& .MuiButtonBase-root': {
+        padding: '0px 8px'
+    }
 }));
 
-const filters = [
-    <SearchInput source="condition" alwaysOn />,
-    <DateInput label='common.time.after' source="timeStart" alwaysOn />,
-    <DateInput label='common.time.before' source="timeEnd" alwaysOn />,
+const StyledTableCell = styled(TableCell)(({ theme }) => ({
+    overflow: 'hidden',
+    textOverflow: 'ellipsis',
+    whiteSpace: 'nowrap',
+    maxWidth: 600,
+}));
 
-    <TextInput source="name" label="table.field.matnrGroup.name" />,
-    <TextInput source="code" label="table.field.matnrGroup.code" />,
-    <NumberInput source="parentId" label="table.field.matnrGroup.parentId" />,
+const TreeTableRow = (props) => {
+    const { row, depth = 0, openNodes, setOpenNodes, onEdit, onDelete } = props;
+    const translate = useTranslate();
 
-    <TextInput label="common.field.memo" source="memo" />,
-    <SelectInput
-        label="common.field.status"
-        source="status"
-        choices={[
-            { id: '1', name: 'common.enums.statusTrue' },
-            { id: '0', name: 'common.enums.statusFalse' },
-        ]}
-        resettable
-    />,
-]
+    const toggleNode = (id) => {
+        setOpenNodes(prevState => ({ ...prevState, [id]: !prevState[id] }));
+    };
+
+    const isOpen = openNodes[row.id] || false;
+
+    return (
+        <React.Fragment>
+            <StyledTableRow hover tabIndex={-1} key={row.id}>
+                <StyledTableCell sx={{ padding: 0 }}>
+                    {row.children && (
+                        <IconButton
+                            aria-label="expand row"
+                            size="small"
+                            onClick={() => toggleNode(row.id)}
+                        >
+                            {isOpen ? <KeyboardArrowDownIcon /> : <KeyboardArrowRightIcon />}
+                        </IconButton>
+                    )}
+                </StyledTableCell>
+                {columns.map((column, idx) => {
+                    if (column.id !== 'actions') {
+                        let value = row[column.id];
+                        if (column.id === 'name' && row['type'] === 0) {
+                            value = translate(value);
+                        }
+                        return (
+                            <StyledTableCell
+                                key={column.id}
+                                align={column.align || 'left'}
+                                style={{
+                                    paddingLeft: idx === 0 && (depth * 16 + 16),
+                                    opacity: column.id === 'icon' && .6
+                                }}
+                                onClick={() => toggleNode(row.id)}
+                            >
+                                {column.format ? column.format(value) : value}
+                            </StyledTableCell>
+                        )
+                    }
+                })}
+                <StyledTableCell>
+                    <Tooltip title="Edit">
+                        <IconButton onClick={() => onEdit(row)}>
+                            <Edit />
+                        </IconButton>
+                    </Tooltip>
+                    <Tooltip title="Delete">
+                        <IconButton onClick={() => onDelete(row)}>
+                            <Delete />
+                        </IconButton>
+                    </Tooltip>
+                </StyledTableCell>
+            </StyledTableRow>
+            {row.children && isOpen && (
+                row.children.map((child) => (
+                    <TreeTableRow
+                        key={child.id}
+                        row={child}
+                        depth={depth + 1}
+                        onEdit={onEdit}
+                        onDelete={onDelete}
+                        openNodes={openNodes}
+                        setOpenNodes={setOpenNodes}
+                    />
+                ))
+            )}
+        </React.Fragment>
+    );
+};
 
 const MatnrGroupList = () => {
     const translate = useTranslate();
+    const notify = useNotify();
+    const redirect = useRedirect();
+    const refresh = useRefresh();
+    const [deleteOne] = useDelete();
 
-    const [createDialog, setCreateDialog] = useState(false);
-    const [drawerVal, setDrawerVal] = useState(false);
+    const [treeData, setTreeData] = React.useState(null);
+    const [filter, setFilter] = React.useState("");
+    const [createDialog, setCreateDialog] = React.useState(false);
+    const [editRecord, setEditRecord] = React.useState(null);
+    const [openNodes, setOpenNodes] = React.useState({});
+    const [expandAll, setExpandAll] = React.useState(false);
+
+    const http = async () => {
+        const res = await request.post(RESOURCE + '/tree', {
+            condition: filter
+        });
+        if (res?.data?.code === 200) {
+            setTreeData(res.data.data);
+        } else {
+            notify(res.data.msg);
+        }
+    }
+
+    React.useEffect(() => {
+        http();
+    }, [filter]);
+
+    const handleRefresh = () => {
+        http();
+    };
+
+    const handleAdd = () => {
+        setEditRecord(null);
+        setCreateDialog(true);
+    };
+
+    const handleEdit = (node) => {
+        setEditRecord(node);
+        setCreateDialog(true);
+    };
+
+    const handleDelete = (node) => {
+        if (window.confirm(translate('ra.message.delete_content'))) {
+            deleteOne(
+                RESOURCE,
+                { id: node.id },
+                {
+                    onSuccess: () => {
+                        handleRefresh();
+                        notify('Department deleted successfully', { type: 'info', messageArgs: { _: 'Department deleted successfully' } });
+                    },
+                    onError: (error) => {
+                        notify(`Error: ${error.message}`, { type: 'warning', messageArgs: { _: `Error: ${error.message}` } });
+                    },
+                }
+            );
+        }
+    };
+
+    const toggleExpandAll = () => {
+        setExpandAll(prevExpandAll => {
+            const newExpandAll = !prevExpandAll;
+            const newOpenNodes = {};
+            const updateOpenNodes = (nodes) => {
+                nodes.forEach(node => {
+                    newOpenNodes[node.id] = newExpandAll;
+                    if (node.children) {
+                        updateOpenNodes(node.children);
+                    }
+                });
+            };
+            updateOpenNodes(treeData);
+            setOpenNodes(newOpenNodes);
+            return newExpandAll;
+        });
+    };
 
     return (
-        <Box display="flex">
-            <List
-                sx={{
-                    flexGrow: 1,
-                    transition: (theme) =>
-                        theme.transitions.create(['all'], {
-                            duration: theme.transitions.duration.enteringScreen,
-                        }),
-                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
-                }}
-                title={"menu.matnrGroup"}
-                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
-                filters={filters}
-                sort={{ field: "create_time", order: "desc" }}
-                actions={(
-                    <TopToolbar>
-                        <FilterButton />
-                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
-                        <SelectColumnsButton preferenceKey='matnrGroup' />
-                        <MyExportButton />
-                    </TopToolbar>
-                )}
-                perPage={DEFAULT_PAGE_SIZE}
-            >
-                <StyledDatagrid
-                    preferenceKey='matnrGroup'
-                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
-                    rowClick={(id, resource, record) => false}
-                    expand={() => <MatnrGroupPanel />}
-                    expandSingle={true}
-                    omit={['id', 'createTime', 'createBy', 'memo']}
-                >
-                    <NumberField source="id" />
-                    <TextField source="name" label="table.field.matnrGroup.name" />
-                    <TextField source="code" label="table.field.matnrGroup.code" />
-                    <NumberField source="parentId" label="table.field.matnrGroup.parentId" />
-
-                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
-                        <TextField source="nickname" />
-                    </ReferenceField>
-                    <DateField source="updateTime" label="common.field.updateTime" showTime />
-                    <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}>
-                        <TextField source="nickname" />
-                    </ReferenceField>
-                    <DateField source="createTime" label="common.field.createTime" showTime />
-                    <BooleanField source="statusBool" label="common.field.status" sortable={false} />
-                    <TextField source="memo" label="common.field.memo" sortable={false} />
-                    <WrapperField cellClassName="opt" label="common.field.opt">
-                        <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
-                        <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
-                    </WrapperField>
-                </StyledDatagrid>
-            </List>
-            <MatnrGroupCreate
+        <div>
+            <MatnrGroupEdit
+                editRecord={editRecord}
                 open={createDialog}
                 setOpen={setCreateDialog}
+                callback={() => {
+                    handleRefresh();
+                }}
+                resource={RESOURCE}
             />
-            <PageDrawer
-                title='MatnrGroup Detail'
-                drawerVal={drawerVal}
-                setDrawerVal={setDrawerVal}
-            >
-            </PageDrawer>
-        </Box>
-    )
+            <Title title={TITLE} />
+            <Box sx={{ mt: 2, mr: 3, mb: 1, display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
+                <Box width={300} >
+                    <Button
+                        variant="outlined"
+                        color="primary"
+                        startIcon={expandAll ? <KeyboardArrowDownIcon /> : <KeyboardArrowRightIcon />}
+                        onClick={toggleExpandAll}
+                        sx={{ ml: 1 }}
+                    >
+                        {expandAll ? translate('common.action.collapseAll') : translate('common.action.expandAll')}
+                    </Button>
+                    {/* <TextField
+                        label="Search"
+                        value={filter}
+                        onChange={({ target }) => {
+                            setFilter(target.value)
+                        }}
+                        variant="filled"
+                        size="small"
+                        margin="dense"
+                        fullWidth
+                    /> */}
+                </Box>
+                <Box>
+                    <Button
+                        variant="outlined"
+                        color="primary"
+                        startIcon={<RefreshIcon />}
+                        onClick={handleRefresh}
+                        sx={{ ml: 1 }}
+                    >
+                        {translate('ra.action.refresh')}
+                    </Button>
+                    <Button
+                        variant="outlined"
+                        color="primary"
+                        startIcon={<Add />}
+                        onClick={handleAdd}
+                        sx={{ ml: 1 }}
+                    >
+                        {translate('ra.action.add')}
+                    </Button>
+                </Box>
+            </Box>
+            <Card sx={{
+                position: 'relative',
+            }}>
+                {!treeData && (
+                    <LinearProgress
+                        sx={{
+                            height: "3px",
+                            position: 'absolute',
+                            top: 0,
+                            left: 0,
+                            right: 0,
+                        }}
+                    />
+                )}
+                <TableContainer component={Paper}>
+                    <Table size="small">
+                        <TableHead>
+                            <TableRow>
+                                <StyledTableCell sx={{ padding: 0, width: 60 }} />
+                                {columns.map((column, idx) => (
+                                    <StyledTableCell
+                                        key={idx}
+                                        align={column.align || 'left'}
+                                        style={{
+                                            minWidth: column.minWidth
+                                        }}
+                                    >
+                                        {translate(column.label)}
+                                    </StyledTableCell>
+                                ))}
+                            </TableRow>
+                        </TableHead>
+                        <TableBody>
+                            {treeData && treeData.length > 0 && (
+                                treeData.map((row) => (
+                                    <TreeTableRow
+                                        key={row.id}
+                                        row={row}
+                                        onEdit={handleEdit}
+                                        onDelete={handleDelete}
+                                        openNodes={openNodes}
+                                        setOpenNodes={setOpenNodes}
+                                    />
+                                ))
+                            )}
+                        </TableBody>
+                    </Table>
+                </TableContainer>
+            </Card>
+        </div>
+    );
 }
 
 export default MatnrGroupList;

--
Gitblit v1.9.1