| | |
| | | import React, { useState, useRef, useEffect, useMemo } from "react"; |
| | | import { Box, Card, CardContent, LinearProgress, TextField, Button, Typography } from "@mui/material"; |
| | | import * as Icons from '@mui/icons-material'; |
| | | import { List, useTranslate, useListContext, Title, } from "react-admin"; |
| | | import { |
| | | Box, |
| | | Card, |
| | | CardContent, |
| | | LinearProgress, |
| | | TextField, |
| | | Button, |
| | | Typography, |
| | | } from "@mui/material"; |
| | | import * as Icons from "@mui/icons-material"; |
| | | import { |
| | | List, |
| | | useTranslate, |
| | | useListContext, |
| | | Title, |
| | | useGetList, |
| | | useNotify, |
| | | } from "react-admin"; |
| | | import WhMatListAside from "./WhMatListAside"; |
| | | import { RichTreeView } from "@mui/x-tree-view/RichTreeView"; |
| | | import { TreeItem2 } from "@mui/x-tree-view/TreeItem2"; |
| | | import request from '@/utils/request'; |
| | | import { Add, Edit, Delete, Padding, Save } 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 { useTreeItem2Utils } from '@mui/x-tree-view/hooks'; |
| | | import request from "@/utils/request"; |
| | | import { Add, Edit, Delete, Padding, Save } 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 { useTreeItem2Utils } from "@mui/x-tree-view/hooks"; |
| | | import WhMatCreate from "./whMatCreate"; |
| | | |
| | | // const RESOURCE = 'dept'; |
| | | const TITLE = 'menu.whMat'; |
| | | const TITLE = "menu.whMat"; |
| | | |
| | | const WhMatListContent = () => { |
| | | const translate = useTranslate(); |
| | | const [searchVal, setSearchVal] = useState(''); |
| | | const [createDialog, setCreateDialog] = React.useState(false); |
| | | const [editRecord, setEditRecord] = React.useState(null); |
| | | const treeData = [ |
| | | const translate = useTranslate(); |
| | | const [searchVal, setSearchVal] = useState(""); |
| | | const [createDialog, setCreateDialog] = React.useState(false); |
| | | const [editRecord, setEditRecord] = React.useState(null); |
| | | const treeData = [ |
| | | { |
| | | id: "19", |
| | | label: "半成品", |
| | | secondaryLabel: "RM001", |
| | | editable: true, |
| | | children: [ |
| | | { |
| | | id: '19', |
| | | label: '半成品', |
| | | secondaryLabel: 'RM001', |
| | | editable: true, |
| | | children: [ |
| | | { |
| | | id: 'grid-community', primaryText: '半成品', |
| | | secondaryText: 'RM001', label: '@mui/x-data-grid', editable: true, children: [ |
| | | { |
| | | id: 'grid-community22', primaryText: '半成品', |
| | | secondaryText: 'RM001', label: '@mui/x-data-grid', editable: true |
| | | },] |
| | | }, |
| | | { |
| | | id: 'grid-pro', primaryText: '半成品', |
| | | secondaryText: 'RM001', label: '@mui/x-data-grid-pro', editable: true |
| | | }, |
| | | { |
| | | id: 'grid-premium', primaryText: '半成品', |
| | | secondaryText: 'RM001', label: '@mui/x-data-grid-premium', editable: true |
| | | }, |
| | | ], |
| | | id: "grid-community", |
| | | primaryText: "半成品", |
| | | secondaryText: "RM001", |
| | | label: "@mui/x-data-grid", |
| | | editable: true, |
| | | children: [ |
| | | { |
| | | id: "grid-community22", |
| | | primaryText: "半成品", |
| | | secondaryText: "RM001", |
| | | label: "@mui/x-data-grid", |
| | | editable: true, |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | id: '18', |
| | | label: '原材料', |
| | | primaryText: '半成品', |
| | | secondaryText: 'RM001', |
| | | id: "grid-pro", |
| | | primaryText: "半成品", |
| | | secondaryText: "RM001", |
| | | label: "@mui/x-data-grid-pro", |
| | | editable: true, |
| | | }, |
| | | { |
| | | id: 'charts', |
| | | label: 'Charts', |
| | | primaryText: '半成品', |
| | | secondaryText: 'RM001', |
| | | children: [{ |
| | | id: 'charts-community', primaryText: '半成品', |
| | | secondaryText: 'RM001', label: '@mui/x-charts' |
| | | }], |
| | | id: "grid-premium", |
| | | primaryText: "半成品", |
| | | secondaryText: "RM001", |
| | | label: "@mui/x-data-grid-premium", |
| | | editable: true, |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | id: "18", |
| | | label: "原材料", |
| | | primaryText: "半成品", |
| | | secondaryText: "RM001", |
| | | }, |
| | | { |
| | | id: "charts", |
| | | label: "Charts", |
| | | primaryText: "半成品", |
| | | secondaryText: "RM001", |
| | | children: [ |
| | | { |
| | | id: 'tree-view', |
| | | label: 'Tree View', |
| | | primaryText: '半成品', |
| | | secondaryLabel: 'RM001', |
| | | children: [{ |
| | | id: 'tree-view-community', primaryText: '半成品', |
| | | secondaryText: 'RM001', label: '@mui/x-tree-view' |
| | | }], |
| | | id: "charts-community", |
| | | primaryText: "半成品", |
| | | secondaryText: "RM001", |
| | | label: "@mui/x-charts", |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | id: "tree-view", |
| | | label: "Tree View", |
| | | primaryText: "半成品", |
| | | secondaryLabel: "RM001", |
| | | children: [ |
| | | { |
| | | id: 'tree-view2', |
| | | label: 'Tree View3', |
| | | primaryText: '半成品', |
| | | secondaryText: 'RM001', |
| | | children: [{ |
| | | id: 'tree-view-community1', primaryText: '半成品', |
| | | secondaryText: 'RM001', label: '@mui/x-tree-view' |
| | | }], |
| | | id: "tree-view-community", |
| | | primaryText: "半成品", |
| | | secondaryText: "RM001", |
| | | label: "@mui/x-tree-view", |
| | | }, |
| | | ]; |
| | | const handleNodeSelect = (event, nodeId) => { |
| | | console.log('Selected Node ID:', nodeId); |
| | | // 在这里可以根据 nodeId 更新主内容区域 |
| | | }; |
| | | const handleSearch = () => { |
| | | console.log('Search Input:', selectedOption); |
| | | }; |
| | | ], |
| | | }, |
| | | { |
| | | id: "tree-view2", |
| | | label: "Tree View3", |
| | | primaryText: "半成品", |
| | | secondaryText: "RM001", |
| | | children: [ |
| | | { |
| | | id: "tree-view-community1", |
| | | primaryText: "半成品", |
| | | secondaryText: "RM001", |
| | | label: "@mui/x-tree-view", |
| | | }, |
| | | ], |
| | | }, |
| | | ]; |
| | | |
| | | const notify = useNotify(); |
| | | const handleNodeSelect = (event, nodeId) => { |
| | | console.log("Selected Node ID:", nodeId); |
| | | // 在这里可以根据 nodeId 更新主内容区域 |
| | | }; |
| | | const handleSearch = () => { |
| | | console.log("Search Input:", selectedOption); |
| | | }; |
| | | |
| | | const CustomCheckbox = React.forwardRef(function CustomCheckbox(props, ref) { |
| | | return <input type="checkbox" ref={ref} {...props} />; |
| | | }); |
| | | function CustomLabel({ children, className, secondaryLabel }) { |
| | | return ( |
| | | <Box display={"flex"} alignItems={"end"}> |
| | | <Typography fontWeight={500}>{children}</Typography> |
| | | <Box width={10}></Box> |
| | | {secondaryLabel && ( |
| | | <Typography variant="caption" color="secondary"> |
| | | {secondaryLabel} |
| | | </Typography> |
| | | )} |
| | | </Box> |
| | | ); |
| | | const handleInput = (value) => { |
| | | setSearchVal(value); |
| | | }; |
| | | |
| | | const CustomCheckbox = React.forwardRef(function CustomCheckbox(props, ref) { |
| | | return <input type="checkbox" ref={ref} {...props} />; |
| | | }); |
| | | |
| | | const getMatnrList = async () => { |
| | | const { |
| | | data: { code, data, msg }, |
| | | } = await request.post("/matnr/list", {}); |
| | | if (code === 200) { |
| | | console.log(data); |
| | | } else { |
| | | notify(msg); |
| | | } |
| | | const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { |
| | | const { publicAPI } = useTreeItem2Utils({ |
| | | itemId: props.itemId, |
| | | children: props.children, |
| | | }); |
| | | }; |
| | | |
| | | const item = publicAPI.getItem(props.itemId); |
| | | React.useEffect(() => { |
| | | getMatnrList(); |
| | | }, []); |
| | | |
| | | return ( |
| | | <TreeItem2 |
| | | {...props} |
| | | ref={ref} |
| | | slots={{ |
| | | label: CustomLabel, |
| | | }} |
| | | slotProps={{ |
| | | label: { secondaryLabel: item?.secondaryLabel || '' }, |
| | | }} |
| | | |
| | | /> |
| | | ); |
| | | function CustomLabel({ children, className, secondaryLabel }) { |
| | | return ( |
| | | <Box display={"flex"} alignItems={"end"}> |
| | | <Typography fontWeight={500}>{children}</Typography> |
| | | <Box width={10}></Box> |
| | | {secondaryLabel && ( |
| | | <Typography variant="caption" color="secondary"> |
| | | {secondaryLabel} |
| | | </Typography> |
| | | )} |
| | | </Box> |
| | | ); |
| | | } |
| | | const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { |
| | | const { publicAPI } = useTreeItem2Utils({ |
| | | itemId: props.itemId, |
| | | children: props.children, |
| | | }); |
| | | |
| | | const isLoading = false; |
| | | |
| | | React.useEffect(() => { |
| | | request.post('/matnrGroup/tree', {}) |
| | | .then(res => { |
| | | if (res?.data?.code === 200) { |
| | | let data = res.data.data; |
| | | console.log(data); |
| | | |
| | | } else { |
| | | notify(res.data.msg); |
| | | } |
| | | }) |
| | | .catch(error => { |
| | | notify('Error fetching tree data'); |
| | | }); |
| | | }, [searchVal]) |
| | | |
| | | const handleAdd = () => { |
| | | setCreateDialog(true); |
| | | }; |
| | | const item = publicAPI.getItem(props.itemId); |
| | | |
| | | return ( |
| | | <> |
| | | <Box sx={{ mt: 1, mr: 3, display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}> |
| | | <WhMatCreate |
| | | editRecord={editRecord} |
| | | open={createDialog} |
| | | setOpen={setCreateDialog} |
| | | /> |
| | | <Box |
| | | width={300} |
| | | mb={1} |
| | | > |
| | | <TextField |
| | | label={translate('ra.action.search')} |
| | | value={searchVal} |
| | | onChange={(e) => handleInput(e.target.value)} |
| | | /> |
| | | </Box> |
| | | <Box> |
| | | <Button |
| | | variant="outlined" |
| | | color="primary" |
| | | startIcon={<Add />} |
| | | onClick={handleAdd} |
| | | > |
| | | {translate('ra.action.add')} |
| | | </Button> |
| | | <Button |
| | | variant="outlined" |
| | | color="error" |
| | | startIcon={<Delete />} |
| | | sx={{ ml: 1 }} |
| | | > |
| | | {translate('ra.action.delete')} |
| | | </Button> |
| | | <Button |
| | | variant="outlined" |
| | | color="primary" |
| | | sx={{ ml: 1 }} |
| | | startIcon={<Save />} |
| | | > |
| | | {translate('ra.action.save')} |
| | | </Button> |
| | | </Box> |
| | | </Box> |
| | | <TreeItem2 |
| | | {...props} |
| | | ref={ref} |
| | | slots={{ |
| | | label: CustomLabel, |
| | | }} |
| | | slotProps={{ |
| | | label: { secondaryLabel: item?.secondaryLabel || "" }, |
| | | }} |
| | | /> |
| | | ); |
| | | }); |
| | | |
| | | <Card> |
| | | <CardContent> |
| | | <RichTreeView |
| | | defaultExpandedItems={['grid', 'pickers']} |
| | | checkboxSelection |
| | | items={treeData} |
| | | slots={{ item: CustomTreeItem }} |
| | | onItemClick={handleNodeSelect} // 监听节点点击事件 |
| | | /> |
| | | </CardContent> |
| | | </Card> |
| | | </> |
| | | ) |
| | | } |
| | | const isLoading = false; |
| | | |
| | | React.useEffect(() => { |
| | | request |
| | | .post("/matnrGroup/tree", {}) |
| | | .then((res) => { |
| | | if (res?.data?.code === 200) { |
| | | let data = res.data.data; |
| | | console.log(data); |
| | | } else { |
| | | notify(res.data.msg); |
| | | } |
| | | }) |
| | | .catch((error) => { |
| | | notify("Error fetching tree data"); |
| | | }); |
| | | }, [searchVal]); |
| | | |
| | | const handleAdd = () => { |
| | | setCreateDialog(true); |
| | | }; |
| | | |
| | | return ( |
| | | <> |
| | | <Box |
| | | sx={{ |
| | | mt: 1, |
| | | mr: 3, |
| | | display: "flex", |
| | | alignItems: "center", |
| | | justifyContent: "space-between", |
| | | }} |
| | | > |
| | | <WhMatCreate |
| | | editRecord={editRecord} |
| | | open={createDialog} |
| | | setOpen={setCreateDialog} |
| | | /> |
| | | <Box width={300} mb={1}> |
| | | <TextField |
| | | label={translate("ra.action.search")} |
| | | value={searchVal} |
| | | onChange={(e) => handleInput(e.target.value)} |
| | | /> |
| | | </Box> |
| | | <Box> |
| | | <Button |
| | | variant="outlined" |
| | | color="primary" |
| | | startIcon={<Add />} |
| | | onClick={handleAdd} |
| | | > |
| | | {translate("ra.action.add")} |
| | | </Button> |
| | | <Button |
| | | variant="outlined" |
| | | color="error" |
| | | startIcon={<Delete />} |
| | | sx={{ ml: 1 }} |
| | | > |
| | | {translate("ra.action.delete")} |
| | | </Button> |
| | | <Button |
| | | variant="outlined" |
| | | color="primary" |
| | | sx={{ ml: 1 }} |
| | | startIcon={<Save />} |
| | | > |
| | | {translate("ra.action.save")} |
| | | </Button> |
| | | </Box> |
| | | </Box> |
| | | |
| | | <Card> |
| | | <CardContent> |
| | | <RichTreeView |
| | | defaultExpandedItems={["grid", "pickers"]} |
| | | checkboxSelection |
| | | items={treeData} |
| | | slots={{ item: CustomTreeItem }} |
| | | onItemClick={handleNodeSelect} // 监听节点点击事件 |
| | | /> |
| | | </CardContent> |
| | | </Card> |
| | | </> |
| | | ); |
| | | }; |
| | | |
| | | const WhMatList = () => { |
| | | const translate = useTranslate(); |
| | | return ( |
| | | <> |
| | | <Box sx={{ |
| | | display: 'flex', |
| | | marginBottom: 24 |
| | | }}> |
| | | <Title title={TITLE} /> |
| | | <Box> |
| | | <WhMatListAside /> |
| | | </Box> |
| | | <Box sx={{ flexGrow: 1 }}> |
| | | <WhMatListContent /> |
| | | </Box> |
| | | </Box> |
| | | </> |
| | | |
| | | ) |
| | | } |
| | | export default WhMatList; |
| | | const translate = useTranslate(); |
| | | return ( |
| | | <> |
| | | <Box |
| | | sx={{ |
| | | display: "flex", |
| | | marginBottom: 24, |
| | | }} |
| | | > |
| | | <Title title={TITLE} /> |
| | | <Box> |
| | | <WhMatListAside /> |
| | | </Box> |
| | | <Box sx={{ flexGrow: 1 }}> |
| | | <WhMatListContent /> |
| | | </Box> |
| | | </Box> |
| | | </> |
| | | ); |
| | | }; |
| | | export default WhMatList; |