Merge remote-tracking branch 'origin/devlop-phyz' into devlop-phyz
| | |
| | | |
| | | export const ABORT_SIGNAL = false; |
| | | |
| | | export const DEFAULT_PAGE_SIZE = 20; |
| | | export const DEFAULT_PAGE_SIZE = 25; |
| | | |
| | | export const DEFAULT_START_PAGE = 1; |
| | | |
| | |
| | | taskPathTemplateNode: 'TaskPathTemplateNode', |
| | | subsystemFlowTemplate: 'SubsystemFlowTemplate', |
| | | flowStepTemplate: 'FlowStepTemplate', |
| | | taskPathTemplateMerge: 'TaskPathTemplateMerge', |
| | | }, |
| | | table: { |
| | | field: { |
| | | taskPathTemplateMerge: { |
| | | templateCode: "templateCode", |
| | | templateName: "templateName", |
| | | sourceType: "sourceType", |
| | | targetType: "targetType", |
| | | conditionExpression: "conditionExpression", |
| | | conditionDesc: "conditionDesc", |
| | | version: "version", |
| | | isCurrent: "isCurrent", |
| | | effectiveTime: "effectiveTime", |
| | | expireTime: "expireTime", |
| | | priority: "priority", |
| | | timeoutMinutes: "timeoutMinutes", |
| | | maxRetryTimes: "maxRetryTimes", |
| | | retryIntervalSeconds: "retryIntervalSeconds", |
| | | remark: "remark", |
| | | stepSize: "stepSize", |
| | | }, |
| | | flowStepTemplate: { |
| | | flowId: "flowId", |
| | | flowCode: "flowCode", |
| | |
| | | taskPathTemplateNode: '任务路径模板节点', |
| | | subsystemFlowTemplate: '子系统流程模板', |
| | | flowStepTemplate: '流程步骤模板', |
| | | taskPathTemplateMerge: '任务路径模板合并', |
| | | }, |
| | | table: { |
| | | field: { |
| | | taskPathTemplateMerge: { |
| | | templateCode: "模板编码", |
| | | templateName: "模板名称", |
| | | sourceType: "源类型", |
| | | targetType: "目标类型", |
| | | conditionExpression: "条件表达式", |
| | | conditionDesc: "条件描述", |
| | | version: "版本", |
| | | isCurrent: "是否当前", |
| | | effectiveTime: "生效时间", |
| | | expireTime: "过期时间", |
| | | priority: "优先级", |
| | | timeoutMinutes: "超时时间", |
| | | maxRetryTimes: "最大重试次数", |
| | | retryIntervalSeconds: "重试间隔", |
| | | remark: "备注", |
| | | stepSize: "步长", |
| | | }, |
| | | flowStepTemplate: { |
| | | flowId: "流程ID", |
| | | flowCode: "流程编码", |
| | |
| | | import preparation from "./orders/preparation"; |
| | | import menuPda from './menuPda'; |
| | | import taskPathTemplate from './taskPathTemplate'; |
| | | import taskPathTemplateMerge from './taskPathTemplateMerge'; |
| | | |
| | | const ResourceContent = (node) => { |
| | | switch (node.component) { |
| | |
| | | return menuPda; |
| | | case 'taskPathTemplate': |
| | | return taskPathTemplate; |
| | | case 'taskPathTemplateMerge': |
| | | return taskPathTemplateMerge; |
| | | // case "locItem": |
| | | // return locItem; |
| | | default: |
| | |
| | | import WarehouseAreaField from "./WarehouseAreaField"; |
| | | import CrossZoneAreaField from "./CrossZoneAreaField"; |
| | | import ContainerTypesField from "./ContainerTypesField"; |
| | | import ChipArrayField from '@/page/components/ChipArrayField'; |
| | | |
| | | const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({ |
| | | '& .css-1vooibu-MuiSvgIcon-root': { |
| | |
| | | render={record => record.inAble === 1 ? '是' : '否'} |
| | | /> |
| | | <WrapperField cellClassName="crossZoneArea" label="table.field.basStation.crossZoneArea"> |
| | | <CrossZoneAreaField |
| | | {/* <CrossZoneAreaField |
| | | open={areaFieldDialog} |
| | | setOpen={setAreaFieldDialog} |
| | | /> */} |
| | | |
| | | <ChipArrayField |
| | | source="areaIds" |
| | | apiEndpoint="/warehouseAreas/many/{ids}" |
| | | labelField="name" |
| | | dialogTitle={translate('table.field.basStation.crossZoneArea')} |
| | | initialDisplayCount={1} |
| | | placeholderText="{count} 个区域" |
| | | /> |
| | | </WrapperField> |
| | | <FunctionField |
| | |
| | | render={record => record.inAble === 1 ? '是' : '否'} |
| | | /> |
| | | <WrapperField cellClassName="containerType" label="table.field.basStation.containerType"> |
| | | <ContainerTypesField |
| | | open={areaFieldDialog2} |
| | | setOpen={setAreaFieldDialog2} |
| | | <ChipArrayField |
| | | source="containerTypes$" |
| | | apiEndpoint="/dictData/many/{ids}" |
| | | labelField="label" |
| | | dialogTitle={translate('table.field.basStation.containerType')} |
| | | initialDisplayCount={1} |
| | | placeholderText="{count} 个区域" |
| | | /> |
| | | </WrapperField> |
| | | <FunctionField |
| | |
| | | |
| | | const fetchAreaNames = async () => { |
| | | if (!record?.containerTypes || record.containerTypes.length === 0) return; |
| | | |
| | | |
| | | setLoading(true); |
| | | try { |
| | | try { |
| | | const res = await request.post(`/dictData/many/${record.containerTypes$.join(',')}`); |
| | | if (res?.data?.code === 200) { |
| | | setAreaNames(res.data.data || []); |
| | |
| | | }; |
| | | |
| | | React.useEffect(() => { |
| | | if (record?.containerTypes && record.containerTypes.length > 0) { |
| | | if (record?.containerTypes && record.containerTypes.length > 0) { |
| | | fetchAreaNames(); |
| | | } |
| | | }, [record]); |
| | | }, [record]); |
| | | |
| | | if (loading) { |
| | | return <CircularProgress size={20} />; |
| | |
| | | |
| | | return ( |
| | | <> |
| | | <Stack |
| | | direction="row" |
| | | gap={1} |
| | | flexWrap="wrap" |
| | | <Stack |
| | | direction="row" |
| | | gap={1} |
| | | flexWrap="wrap" |
| | | onClick={handleOpen} |
| | | sx={{ cursor: 'pointer' }} |
| | | > |
| | |
| | | )} |
| | | </Stack> |
| | | |
| | | <Dialog |
| | | open={open} |
| | | <Dialog |
| | | open={open} |
| | | onClose={handleClose} |
| | | maxWidth="md" |
| | | fullWidth |
| New file |
| | |
| | | import * as React from 'react'; |
| | | import { |
| | | Stack, |
| | | Chip, |
| | | Dialog, |
| | | DialogTitle, |
| | | DialogContent, |
| | | IconButton, |
| | | CircularProgress |
| | | } from '@mui/material'; |
| | | import { useRecordContext } from 'react-admin'; |
| | | import CloseIcon from '@mui/icons-material/Close'; |
| | | import request from '@/utils/request'; |
| | | |
| | | /** |
| | | * 通用芯片数组字段组件 |
| | | * 用于展示从 API 获取的数组数据,以芯片形式显示 |
| | | * |
| | | * @param {Object} props |
| | | * @param {string|string[]} props.source - 数据源字段名,支持多个字段名(如 ['areaIds', 'areas']) |
| | | * @param {string} props.apiEndpoint - API 端点模板,使用 {ids} 作为占位符,例如: '/warehouseAreas/many/{ids}' |
| | | * @param {string} props.labelField - 用于显示的字段名,默认为 'label' |
| | | * @param {string} props.dialogTitle - 弹窗标题 |
| | | * @param {number} props.initialDisplayCount - 初始显示的数量,默认为 1 |
| | | * @param {string} props.placeholderText - 占位符文本模板,使用 {count} 作为占位符,默认为 '{count} 项' |
| | | * @param {function} props.dataTransform - 可选的数据转换函数,用于处理特殊格式的数据源 |
| | | */ |
| | | const ChipArrayField = ({ |
| | | source, |
| | | apiEndpoint, |
| | | labelField = 'label', |
| | | dialogTitle = '详情', |
| | | initialDisplayCount = 1, |
| | | placeholderText = '{count} 项', |
| | | dataTransform = null |
| | | }) => { |
| | | const record = useRecordContext(); |
| | | const [open, setOpen] = React.useState(false); |
| | | const [items, setItems] = React.useState([]); |
| | | const [loading, setLoading] = React.useState(false); |
| | | |
| | | const handleOpen = () => { |
| | | setOpen(true); |
| | | }; |
| | | |
| | | const handleClose = () => { |
| | | setOpen(false); |
| | | }; |
| | | |
| | | // 使用 useMemo 缓存数据源值 |
| | | const sourceData = React.useMemo(() => { |
| | | if (!record) return null; |
| | | |
| | | // 支持多个字段名 |
| | | if (Array.isArray(source)) { |
| | | for (const field of source) { |
| | | if (record[field]) { |
| | | return record[field]; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | return record[source]; |
| | | }, [record, source]); |
| | | |
| | | // 使用 useCallback 缓存 fetchItems 函数 |
| | | const fetchItems = React.useCallback(async () => { |
| | | let data = sourceData; |
| | | if (!data || data.length === 0) { |
| | | setItems([]); |
| | | return; |
| | | } |
| | | |
| | | // 应用自定义数据转换函数 |
| | | if (dataTransform) { |
| | | data = dataTransform(data); |
| | | } |
| | | |
| | | setLoading(true); |
| | | try { |
| | | // 提取 ID 和排序信息 |
| | | const isObjectArray = data.length > 0 && |
| | | typeof data[0] === 'object' && |
| | | data[0] !== null && |
| | | 'id' in data[0]; |
| | | |
| | | let ids = []; |
| | | let sortMap = new Map(); // 存储 id -> sort 的映射 |
| | | |
| | | if (isObjectArray) { |
| | | // 对象数组格式,提取 ID 和排序信息 |
| | | ids = data.map(item => { |
| | | const id = item.id; |
| | | sortMap.set(id, item.sort || 0); |
| | | return id; |
| | | }); |
| | | } else { |
| | | // 纯 ID 数组格式 |
| | | ids = data.map(id => Number(id)); |
| | | } |
| | | |
| | | // 替换 API 端点中的占位符 |
| | | const url = apiEndpoint.replace('{ids}', ids.join(',')); |
| | | const res = await request.post(url); |
| | | |
| | | if (res?.data?.code === 200) { |
| | | let fetchedItems = res.data.data || []; |
| | | |
| | | // 如果有排序信息,按排序值排序 |
| | | if (sortMap.size > 0) { |
| | | fetchedItems = fetchedItems.sort((a, b) => { |
| | | const sortA = sortMap.get(a.id) || 0; |
| | | const sortB = sortMap.get(b.id) || 0; |
| | | return sortA - sortB; |
| | | }); |
| | | } |
| | | |
| | | setItems(fetchedItems); |
| | | } |
| | | } catch (error) { |
| | | console.error('获取数据失败:', error); |
| | | } finally { |
| | | setLoading(false); |
| | | } |
| | | }, [sourceData, apiEndpoint, dataTransform]); |
| | | |
| | | React.useEffect(() => { |
| | | if (sourceData && sourceData.length > 0) { |
| | | fetchItems(); |
| | | } else { |
| | | setItems([]); |
| | | } |
| | | }, [sourceData, fetchItems]); |
| | | |
| | | if (loading) { |
| | | return <CircularProgress size={20} />; |
| | | } |
| | | |
| | | return ( |
| | | <> |
| | | <Stack |
| | | direction="row" |
| | | gap={1} |
| | | flexWrap="wrap" |
| | | onClick={handleOpen} |
| | | sx={{ cursor: 'pointer' }} |
| | | > |
| | | {items.slice(0, initialDisplayCount).map((item) => ( |
| | | <Chip |
| | | size="small" |
| | | key={item.id} |
| | | label={item[labelField] || item.id} |
| | | /> |
| | | ))} |
| | | {items.length > initialDisplayCount && ( |
| | | <Chip |
| | | size="small" |
| | | label={`+${items.length - initialDisplayCount}`} |
| | | /> |
| | | )} |
| | | {items.length === 0 && sourceData && sourceData.length > 0 && ( |
| | | <Chip |
| | | size="small" |
| | | label={placeholderText.replace('{count}', sourceData.length)} |
| | | /> |
| | | )} |
| | | </Stack> |
| | | |
| | | <Dialog |
| | | open={open} |
| | | onClose={handleClose} |
| | | maxWidth="md" |
| | | fullWidth |
| | | > |
| | | <DialogTitle> |
| | | {dialogTitle} |
| | | <IconButton |
| | | aria-label="close" |
| | | onClick={handleClose} |
| | | sx={{ |
| | | position: 'absolute', |
| | | right: 8, |
| | | top: 8, |
| | | }} |
| | | > |
| | | <CloseIcon /> |
| | | </IconButton> |
| | | </DialogTitle> |
| | | <DialogContent> |
| | | {loading ? ( |
| | | <CircularProgress /> |
| | | ) : ( |
| | | <Stack direction="row" gap={1} flexWrap="wrap" sx={{ mt: 1 }}> |
| | | {items.map((item) => ( |
| | | <Chip |
| | | size="small" |
| | | key={item.id} |
| | | label={item[labelField] || item.id} |
| | | /> |
| | | ))} |
| | | </Stack> |
| | | )} |
| | | </DialogContent> |
| | | </Dialog> |
| | | </> |
| | | ); |
| | | }; |
| | | |
| | | export default ChipArrayField; |
| | |
| | | import StickyDataTable from "@/page/components/StickyDataTable"; |
| | | |
| | | const ViewTable = ({ title, resource, filter, onClick, selectedId, columns }) => { |
| | | // 只有在有 filter 时才调用 useListController,避免不必要的请求 |
| | | const shouldLoadData = !!filter; |
| | | |
| | | const listContext = useListController({ |
| | | resource: resource, |
| | | filter: filter, |
| | | filter: filter || {}, |
| | | perPage: 100, |
| | | sort: { field: 'id', order: 'ASC' }, |
| | | disableSyncWithLocation: true, |
| | | queryOptions: { |
| | | enabled: shouldLoadData, // 只有在 shouldLoadData 为 true 时才执行查询 |
| | | }, |
| | | }); |
| | | |
| | | if (!filter) { |
| | | if (!shouldLoadData) { |
| | | return ( |
| | | <Card sx={{ height: '100%', display: 'flex', flexDirection: 'column' }}> |
| | | <Box p={1} borderBottom={1} borderColor="divider"> |
| | |
| | | <ViewTable |
| | | title={translate('menu.subsystemFlowTemplate')} |
| | | resource="subsystemFlowTemplate" |
| | | filter={selectedNode ? { systemCode: selectedNode.systemCode } : null} |
| | | filter={selectedNode ? { flowCode: selectedNode.nodeCode } : null} |
| | | onClick={handleFlowClick} |
| | | selectedId={selectedFlow?.id} |
| | | columns={flowColumns} |
| | |
| | | required, |
| | | useRecordContext, |
| | | DeleteButton, |
| | | SelectArrayInput, |
| | | } from 'react-admin'; |
| | | import { useWatch, useFormContext } from "react-hook-form"; |
| | | import { Stack, Grid, Box, Typography } from '@mui/material'; |
| | |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <TextInput |
| | | label="table.field.taskPathTemplateMerge.conditionExpression" |
| | | source="conditionExpression" |
| | | parse={v => v} |
| | | validate={required()} |
| | | /> |
| | | <ReferenceArrayInput source="conditionExpression" reference="taskPathTemplate"> |
| | | <SelectArrayInput |
| | | label="table.field.taskPathTemplateMerge.conditionExpression" |
| | | optionText="templateName" |
| | | optionValue="id" |
| | | fullWidth |
| | | validate={(value) => { |
| | | if (value && value.length > 1) { |
| | | return '只能选择一个模板'; |
| | | } |
| | | return undefined; |
| | | }} |
| | | /> |
| | | </ReferenceArrayInput> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <TextInput |
| | |
| | | import { useNavigate } from 'react-router-dom'; |
| | | import { |
| | | List, |
| | | DatagridConfigurable, |
| | | SearchInput, |
| | | TopToolbar, |
| | | SelectColumnsButton, |
| | | ColumnsButton, |
| | | EditButton, |
| | | FilterButton, |
| | | CreateButton, |
| | | ExportButton, |
| | | BulkDeleteButton, |
| | | WrapperField, |
| | | useRecordContext, |
| | | useTranslate, |
| | | useNotify, |
| | | useListContext, |
| | | FunctionField, |
| | | TextField, |
| | | NumberField, |
| | | DateField, |
| | | BooleanField, |
| | | ReferenceField, |
| | | TextInput, |
| | | DateTimeInput, |
| | | DateInput, |
| | | SelectInput, |
| | | NumberInput, |
| | | ReferenceInput, |
| | | ReferenceArrayInput, |
| | | AutocompleteInput, |
| | | DeleteButton, |
| | | DataTable |
| | | } from 'react-admin'; |
| | | import { Box, Typography, Card, Stack } from '@mui/material'; |
| | | import { styled } from '@mui/material/styles'; |
| | |
| | | import MyField from "../components/MyField"; |
| | | import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting'; |
| | | import * as Common from '@/utils/common'; |
| | | import StickyDataTable from "@/page/components/StickyDataTable"; |
| | | import useTableLayout from '@/utils/useTableLayout'; |
| | | import ChipArrayField from '@/page/components/ChipArrayField'; |
| | | |
| | | const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({ |
| | | '& .css-1vooibu-MuiSvgIcon-root': { |
| | | height: '.9em' |
| | | }, |
| | | '& .RaDatagrid-row': { |
| | | cursor: 'auto' |
| | | }, |
| | | '& .column-name': { |
| | | }, |
| | | '& .opt': { |
| | | width: 200 |
| | | }, |
| | | })); |
| | | |
| | | const filters = [ |
| | | <SearchInput source="condition" alwaysOn />, |
| | |
| | | />, |
| | | ] |
| | | |
| | | const getColumns = (translate) => [ |
| | | <NumberField source="id" />, |
| | | <TextField source="templateCode" label="table.field.taskPathTemplateMerge.templateCode" />, |
| | | <TextField source="templateName" label="table.field.taskPathTemplateMerge.templateName" />, |
| | | <TextField source="sourceType" label="table.field.taskPathTemplateMerge.sourceType" />, |
| | | <TextField source="targetType" label="table.field.taskPathTemplateMerge.targetType" />, |
| | | <ChipArrayField |
| | | source="conditionExpression" |
| | | label="table.field.taskPathTemplateMerge.conditionExpression" |
| | | apiEndpoint="/taskPathTemplate/many/{ids}" |
| | | labelField="templateName" |
| | | dialogTitle={translate('table.field.taskPathTemplateMerge.conditionExpression')} |
| | | initialDisplayCount={1} |
| | | placeholderText="{count} 个模板" |
| | | />, |
| | | <TextField source="conditionDesc" label="table.field.taskPathTemplateMerge.conditionDesc" />, |
| | | <NumberField source="version" label="table.field.taskPathTemplateMerge.version" />, |
| | | <NumberField source="isCurrent" label="table.field.taskPathTemplateMerge.isCurrent" />, |
| | | <DateField source="effectiveTime" label="table.field.taskPathTemplateMerge.effectiveTime" showTime />, |
| | | <DateField source="expireTime" label="table.field.taskPathTemplateMerge.expireTime" showTime />, |
| | | <NumberField source="priority" label="table.field.taskPathTemplateMerge.priority" />, |
| | | <NumberField source="timeoutMinutes" label="table.field.taskPathTemplateMerge.timeoutMinutes" />, |
| | | <NumberField source="maxRetryTimes" label="table.field.taskPathTemplateMerge.maxRetryTimes" />, |
| | | <NumberField source="retryIntervalSeconds" label="table.field.taskPathTemplateMerge.retryIntervalSeconds" />, |
| | | <TextField source="remark" label="table.field.taskPathTemplateMerge.remark" />, |
| | | <NumberField source="stepSize" label="table.field.taskPathTemplateMerge.stepSize" />, |
| | | |
| | | <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 source="opt" cellClassName="opt" label="common.field.opt"> |
| | | <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} /> |
| | | <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} /> |
| | | </WrapperField> |
| | | ]; |
| | | |
| | | const TaskPathTemplateMergeList = () => { |
| | | const translate = useTranslate(); |
| | | |
| | |
| | | <TopToolbar> |
| | | <FilterButton /> |
| | | <MyCreateButton onClick={() => { setCreateDialog(true) }} /> |
| | | <SelectColumnsButton preferenceKey='taskPathTemplateMerge' /> |
| | | <ColumnsButton storeKey='taskPathTemplateMerge' /> |
| | | <MyExportButton /> |
| | | </TopToolbar> |
| | | )} |
| | | perPage={DEFAULT_PAGE_SIZE} |
| | | > |
| | | <StyledDatagrid |
| | | preferenceKey='taskPathTemplateMerge' |
| | | bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />} |
| | | rowClick={(id, resource, record) => false} |
| | | expand={() => <TaskPathTemplateMergePanel />} |
| | | expandSingle={true} |
| | | omit={['id', 'createTime', 'createBy', 'memo']} |
| | | > |
| | | <NumberField source="id" /> |
| | | <TextField source="templateCode" label="table.field.taskPathTemplateMerge.templateCode" /> |
| | | <TextField source="templateName" label="table.field.taskPathTemplateMerge.templateName" /> |
| | | <TextField source="sourceType" label="table.field.taskPathTemplateMerge.sourceType" /> |
| | | <TextField source="targetType" label="table.field.taskPathTemplateMerge.targetType" /> |
| | | <TextField source="conditionExpression" label="table.field.taskPathTemplateMerge.conditionExpression" /> |
| | | <TextField source="conditionDesc" label="table.field.taskPathTemplateMerge.conditionDesc" /> |
| | | <NumberField source="version" label="table.field.taskPathTemplateMerge.version" /> |
| | | <NumberField source="isCurrent" label="table.field.taskPathTemplateMerge.isCurrent" /> |
| | | <DateField source="effectiveTime" label="table.field.taskPathTemplateMerge.effectiveTime" showTime /> |
| | | <DateField source="expireTime" label="table.field.taskPathTemplateMerge.expireTime" showTime /> |
| | | <NumberField source="priority" label="table.field.taskPathTemplateMerge.priority" /> |
| | | <NumberField source="timeoutMinutes" label="table.field.taskPathTemplateMerge.timeoutMinutes" /> |
| | | <NumberField source="maxRetryTimes" label="table.field.taskPathTemplateMerge.maxRetryTimes" /> |
| | | <NumberField source="retryIntervalSeconds" label="table.field.taskPathTemplateMerge.retryIntervalSeconds" /> |
| | | <TextField source="remark" label="table.field.taskPathTemplateMerge.remark" /> |
| | | <NumberField source="stepSize" label="table.field.taskPathTemplateMerge.stepSize" /> |
| | | |
| | | <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> |
| | | <TableItems drawerVal={drawerVal} /> |
| | | </List> |
| | | <TaskPathTemplateMergeCreate |
| | | open={createDialog} |
| | |
| | | ) |
| | | } |
| | | |
| | | const TableItems = ({ drawerVal }) => { |
| | | const { isLoading } = useListContext(); |
| | | const translate = useTranslate(); |
| | | const { boxMaxWidth, boxMaxHeight } = useTableLayout(drawerVal); |
| | | const columns = getColumns(translate); |
| | | |
| | | return ( |
| | | <Box sx={{ |
| | | position: 'relative', |
| | | maxHeight: boxMaxHeight, |
| | | maxWidth: boxMaxWidth, |
| | | overflowX: 'auto', |
| | | overflowY: 'auto', |
| | | '& .MuiTableCell-root': { |
| | | whiteSpace: 'nowrap', |
| | | } |
| | | }}> |
| | | {columns.length > 0 && |
| | | <StickyDataTable |
| | | stickyRight={['opt']} |
| | | storeKey='taskPathTemplateMerge' |
| | | bulkActionButtons={false} |
| | | rowClick={false} |
| | | hiddenColumns={['id', 'createTime', 'createBy', 'memo', 'statusBool']} |
| | | > |
| | | {columns |
| | | .map((column) => ( |
| | | <DataTable.Col |
| | | key={column.key || column.props.source} |
| | | source={column.props.source} |
| | | label={column.props.label} |
| | | sx={column.props.sx} |
| | | > |
| | | {column} |
| | | </DataTable.Col> |
| | | )) |
| | | } |
| | | </StickyDataTable>} |
| | | </Box> |
| | | ) |
| | | } |
| | | |
| | | export default TaskPathTemplateMergeList; |