|  |  |  | 
|---|
|  |  |  | useRecordContext, | 
|---|
|  |  |  | DeleteButton, | 
|---|
|  |  |  | PasswordInput, | 
|---|
|  |  |  | email, | 
|---|
|  |  |  | } from 'react-admin'; | 
|---|
|  |  |  | import { useWatch, useFormContext } from "react-hook-form"; | 
|---|
|  |  |  | import { useFormContext } from 'react-hook-form'; | 
|---|
|  |  |  | import { Stack, Grid, Box, Typography } from '@mui/material'; | 
|---|
|  |  |  | import * as Common from '@/utils/common'; | 
|---|
|  |  |  | import { EDIT_MODE } from '@/config/setting'; | 
|---|
|  |  |  | 
|---|
|  |  |  | import MemoInput from "../components/MemoInput"; | 
|---|
|  |  |  | import StatusSelectInput from "../components/StatusSelectInput"; | 
|---|
|  |  |  | import RolesSelect from "./RolesSelect"; | 
|---|
|  |  |  | import TreeSelectInput from "../components/TreeSelectInput"; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | const FormToolbar = () => { | 
|---|
|  |  |  | const { getValues } = useFormContext(); | 
|---|
|  |  |  | const { setValue, getValues } = useFormContext(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return ( | 
|---|
|  |  |  | <Toolbar sx={{ justifyContent: 'space-between' }}> | 
|---|
|  |  |  | 
|---|
|  |  |  | ) | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | const PasswordInputContainer = () => { | 
|---|
|  |  |  | const translate = useTranslate(); | 
|---|
|  |  |  | const { setValue } = useFormContext(); | 
|---|
|  |  |  | const record = useRecordContext(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | useEffect(() => { | 
|---|
|  |  |  | setTimeout(() => { | 
|---|
|  |  |  | if (record && record.password) { | 
|---|
|  |  |  | setValue('password', ''); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }, 200) | 
|---|
|  |  |  | }, [setValue, record]); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return ( | 
|---|
|  |  |  | <> | 
|---|
|  |  |  | <Typography variant="h6" gutterBottom> | 
|---|
|  |  |  | {translate('common.edit.title.changePwd')} | 
|---|
|  |  |  | </Typography> | 
|---|
|  |  |  | <Stack direction='row' gap={2}> | 
|---|
|  |  |  | <PasswordInput | 
|---|
|  |  |  | label="table.field.user.password" | 
|---|
|  |  |  | source="password" | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | <PasswordInput | 
|---|
|  |  |  | label="table.field.user.confirmPwd" | 
|---|
|  |  |  | source="confirmPassword" | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | </Stack> | 
|---|
|  |  |  | </> | 
|---|
|  |  |  | ) | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | const UserEdit = () => { | 
|---|
|  |  |  | const translate = useTranslate(); | 
|---|
|  |  |  | const record = useRecordContext(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return ( | 
|---|
|  |  |  | <SimpleForm | 
|---|
|  |  |  | shouldUnregister | 
|---|
|  |  |  | warnWhenUnsavedChanges | 
|---|
|  |  |  | toolbar={<FormToolbar />} | 
|---|
|  |  |  | mode="onTouched" | 
|---|
|  |  |  | validate={(values) => { | 
|---|
|  |  |  | const errors = {}; | 
|---|
|  |  |  | if (!values.username) { | 
|---|
|  |  |  | errors.username = 'ra.validation.required'; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (!values.nickname) { | 
|---|
|  |  |  | errors.nickname = 'ra.validation.required'; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (!values.userRoleIds) { | 
|---|
|  |  |  | errors.userRoleIds = 'ra.validation.required'; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (!values.email) { | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | const error = email()(values.email); | 
|---|
|  |  |  | if (error) { | 
|---|
|  |  |  | errors.email = error; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (values.password && values.password !== values.confirmPassword) { | 
|---|
|  |  |  | errors.confirmPassword = 'validate.pwdMisMatch'; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return errors; | 
|---|
|  |  |  | }} | 
|---|
|  |  |  | > | 
|---|
|  |  |  | <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}> | 
|---|
|  |  |  | <Grid item xs={12} md={8}> | 
|---|
|  |  |  | <Typography variant="h6" gutterBottom> | 
|---|
|  |  |  | {translate('common.edit.title.main')} | 
|---|
|  |  |  | </Typography> | 
|---|
|  |  |  | <Stack direction='row' gap={2}> | 
|---|
|  |  |  | <TextInput | 
|---|
|  |  |  | label="table.field.user.username" | 
|---|
|  |  |  | source="username" | 
|---|
|  |  |  | parse={v => v} | 
|---|
|  |  |  | autoFocus | 
|---|
|  |  |  | validate={required()} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | <TextInput | 
|---|
|  |  |  | label="table.field.user.nickname" | 
|---|
|  |  |  | source="nickname" | 
|---|
|  |  |  | parse={v => v} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | </Stack> | 
|---|
|  |  |  | <Stack direction='row' gap={2}> | 
|---|
|  |  |  | <SelectInput | 
|---|
|  |  |  | label="table.field.user.sex" | 
|---|
|  |  |  | source="sex" | 
|---|
|  |  |  | choices={[ | 
|---|
|  |  |  | { id: 0, name: '未知' }, | 
|---|
|  |  |  | { id: 1, name: '男' }, | 
|---|
|  |  |  | { id: 2, name: '女' }, | 
|---|
|  |  |  | ]} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | <TextInput | 
|---|
|  |  |  | label="table.field.user.code" | 
|---|
|  |  |  | source="code" | 
|---|
|  |  |  | parse={v => v} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | </Stack> | 
|---|
|  |  |  | <Stack direction='row' gap={2}> | 
|---|
|  |  |  | <TextInput | 
|---|
|  |  |  | label="table.field.user.phone" | 
|---|
|  |  |  | source="phone" | 
|---|
|  |  |  | parse={v => v} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | <TextInput | 
|---|
|  |  |  | label="table.field.user.email" | 
|---|
|  |  |  | source="email" | 
|---|
|  |  |  | parse={v => v} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | </Stack> | 
|---|
|  |  |  | <Stack direction='row' gap={2}> | 
|---|
|  |  |  | <TextInput | 
|---|
|  |  |  | label="table.field.user.realName" | 
|---|
|  |  |  | source="realName" | 
|---|
|  |  |  | parse={v => v} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | <TextInput | 
|---|
|  |  |  | label="table.field.user.idCard" | 
|---|
|  |  |  | source="idCard" | 
|---|
|  |  |  | parse={v => v} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | </Stack> | 
|---|
|  |  |  | <Stack direction='row' gap={2}> | 
|---|
|  |  |  | <TextInput | 
|---|
|  |  |  | label="table.field.user.birthday" | 
|---|
|  |  |  | source="birthday" | 
|---|
|  |  |  | parse={v => v} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | <TextInput | 
|---|
|  |  |  | label="table.field.user.introduction" | 
|---|
|  |  |  | multiline | 
|---|
|  |  |  | source="introduction" | 
|---|
|  |  |  | parse={v => v} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | </Stack> | 
|---|
|  |  |  | <PasswordInputContainer /> | 
|---|
|  |  |  | </Grid> | 
|---|
|  |  |  | <Grid item xs={12} md={4}> | 
|---|
|  |  |  | <Typography variant="h6" gutterBottom> | 
|---|
|  |  |  | {translate('common.edit.title.common')} | 
|---|
|  |  |  | </Typography> | 
|---|
|  |  |  | <Stack direction='row' gap={2}> | 
|---|
|  |  |  | <TreeSelectInput | 
|---|
|  |  |  | label="table.field.user.deptId" | 
|---|
|  |  |  | value={record?.deptId} | 
|---|
|  |  |  | resource={'dept'} | 
|---|
|  |  |  | source="deptId" | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | </Stack> | 
|---|
|  |  |  | <Stack direction='row' gap={2}> | 
|---|
|  |  |  | <RolesSelect | 
|---|
|  |  |  | label="table.field.user.role" | 
|---|
|  |  |  | source="userRoleIds" | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | </Stack> | 
|---|
|  |  |  | <Stack direction='row' gap={2}> | 
|---|
|  |  |  | <StatusSelectInput /> | 
|---|
|  |  |  | </Stack> | 
|---|
|  |  |  | <Box mt="2em" /> | 
|---|
|  |  |  | <MemoInput /> | 
|---|
|  |  |  | </Grid> | 
|---|
|  |  |  | </Grid> | 
|---|
|  |  |  | </SimpleForm> | 
|---|
|  |  |  | ) | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | export default function () { | 
|---|
|  |  |  | return ( | 
|---|
|  |  |  | <Edit | 
|---|
|  |  |  | redirect="list" | 
|---|
|  |  |  | mutationMode={EDIT_MODE} | 
|---|
|  |  |  | actions={<CustomerTopToolBar />} | 
|---|
|  |  |  | aside={<EditBaseAside />} | 
|---|
|  |  |  | transform={(data) => { | 
|---|
|  |  |  | return { | 
|---|
|  |  |  | ...data, | 
|---|
|  |  |  | roleIds: data['userRoleIds'] || [] | 
|---|
|  |  |  | }; | 
|---|
|  |  |  | }} | 
|---|
|  |  |  | > | 
|---|
|  |  |  | <SimpleForm | 
|---|
|  |  |  | shouldUnregister | 
|---|
|  |  |  | warnWhenUnsavedChanges | 
|---|
|  |  |  | toolbar={<FormToolbar />} | 
|---|
|  |  |  | mode="onTouched" | 
|---|
|  |  |  | defaultValues={{}} | 
|---|
|  |  |  | validate={(values) => { | 
|---|
|  |  |  | const errors = {}; | 
|---|
|  |  |  | if (!values.username) { | 
|---|
|  |  |  | errors.username = 'ra.validation.required'; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (!values.nickname) { | 
|---|
|  |  |  | errors.nickname = 'ra.validation.required'; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (!values.roleIds) { | 
|---|
|  |  |  | errors.roleIds = 'ra.validation.required'; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (!values.email) { | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | const error = email()(values.email); | 
|---|
|  |  |  | if (error) { | 
|---|
|  |  |  | errors.email = error; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (values.password && values.password !== values.confirmPassword) { | 
|---|
|  |  |  | errors.confirmPassword = 'validate.pwdMisMatch'; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return errors; | 
|---|
|  |  |  | }} | 
|---|
|  |  |  | > | 
|---|
|  |  |  | <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}> | 
|---|
|  |  |  | <Grid item xs={12} md={8}> | 
|---|
|  |  |  | <Typography variant="h6" gutterBottom> | 
|---|
|  |  |  | {translate('common.edit.title.main')} | 
|---|
|  |  |  | </Typography> | 
|---|
|  |  |  | <Stack direction='row' gap={2}> | 
|---|
|  |  |  | <TextInput | 
|---|
|  |  |  | label="table.field.user.username" | 
|---|
|  |  |  | source="username" | 
|---|
|  |  |  | parse={v => v} | 
|---|
|  |  |  | autoFocus | 
|---|
|  |  |  | validate={required()} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | {/* <Stack direction='row' gap={2}> | 
|---|
|  |  |  | <TextInput | 
|---|
|  |  |  | label="table.field.user.password" | 
|---|
|  |  |  | source="password" | 
|---|
|  |  |  | parse={v => v} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | </Stack> */} | 
|---|
|  |  |  | <TextInput | 
|---|
|  |  |  | label="table.field.user.nickname" | 
|---|
|  |  |  | source="nickname" | 
|---|
|  |  |  | parse={v => v} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | </Stack> | 
|---|
|  |  |  | {/* <Stack direction='row' gap={2}> | 
|---|
|  |  |  | <TextInput | 
|---|
|  |  |  | label="table.field.user.avatar" | 
|---|
|  |  |  | source="avatar" | 
|---|
|  |  |  | parse={v => v} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | </Stack> */} | 
|---|
|  |  |  | <Stack direction='row' gap={2}> | 
|---|
|  |  |  | <TextInput | 
|---|
|  |  |  | label="table.field.user.code" | 
|---|
|  |  |  | source="code" | 
|---|
|  |  |  | parse={v => v} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | <SelectInput | 
|---|
|  |  |  | label="table.field.user.sex" | 
|---|
|  |  |  | source="sex" | 
|---|
|  |  |  | choices={[ | 
|---|
|  |  |  | { id: 0, name: '未知' }, | 
|---|
|  |  |  | { id: 1, name: '男' }, | 
|---|
|  |  |  | { id: 2, name: '女' }, | 
|---|
|  |  |  | ]} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | </Stack> | 
|---|
|  |  |  | <Stack direction='row' gap={2}> | 
|---|
|  |  |  | <TextInput | 
|---|
|  |  |  | label="table.field.user.phone" | 
|---|
|  |  |  | source="phone" | 
|---|
|  |  |  | parse={v => v} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | <TextInput | 
|---|
|  |  |  | label="table.field.user.email" | 
|---|
|  |  |  | source="email" | 
|---|
|  |  |  | parse={v => v} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | </Stack> | 
|---|
|  |  |  | {/* <Stack direction='row' gap={2}> | 
|---|
|  |  |  | <SelectInput | 
|---|
|  |  |  | label="table.field.user.emailVerified" | 
|---|
|  |  |  | source="emailVerified" | 
|---|
|  |  |  | choices={[ | 
|---|
|  |  |  | { id: 0, name: '否' }, | 
|---|
|  |  |  | { id: 1, name: '是' }, | 
|---|
|  |  |  | ]} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | </Stack> */} | 
|---|
|  |  |  | <Stack direction='row' gap={2}> | 
|---|
|  |  |  | <TextInput | 
|---|
|  |  |  | label="table.field.user.realName" | 
|---|
|  |  |  | source="realName" | 
|---|
|  |  |  | parse={v => v} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | <TextInput | 
|---|
|  |  |  | label="table.field.user.idCard" | 
|---|
|  |  |  | source="idCard" | 
|---|
|  |  |  | parse={v => v} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | </Stack> | 
|---|
|  |  |  | <Stack direction='row' gap={2}> | 
|---|
|  |  |  | <TextInput | 
|---|
|  |  |  | label="table.field.user.birthday" | 
|---|
|  |  |  | source="birthday" | 
|---|
|  |  |  | parse={v => v} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | <TextInput | 
|---|
|  |  |  | label="table.field.user.introduction" | 
|---|
|  |  |  | source="introduction" | 
|---|
|  |  |  | parse={v => v} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | </Stack> | 
|---|
|  |  |  | <Typography variant="h6" gutterBottom> | 
|---|
|  |  |  | {translate('common.edit.title.changePwd')} | 
|---|
|  |  |  | </Typography> | 
|---|
|  |  |  | <Stack direction='row' gap={2}> | 
|---|
|  |  |  | <PasswordInput source="password" /> | 
|---|
|  |  |  | <PasswordInput source="confirmPassword" /> | 
|---|
|  |  |  | </Stack> | 
|---|
|  |  |  | </Grid> | 
|---|
|  |  |  | <Grid item xs={12} md={4}> | 
|---|
|  |  |  | <Typography variant="h6" gutterBottom> | 
|---|
|  |  |  | {translate('common.edit.title.common')} | 
|---|
|  |  |  | </Typography> | 
|---|
|  |  |  | <Stack direction='row' gap={2}> | 
|---|
|  |  |  | <ReferenceInput | 
|---|
|  |  |  | source="deptId" | 
|---|
|  |  |  | reference="dept" | 
|---|
|  |  |  | > | 
|---|
|  |  |  | <AutocompleteInput | 
|---|
|  |  |  | label="table.field.user.deptId" | 
|---|
|  |  |  | optionText="name" | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | </ReferenceInput> | 
|---|
|  |  |  | </Stack> | 
|---|
|  |  |  | <Stack direction='row' gap={2}> | 
|---|
|  |  |  | <RolesSelect | 
|---|
|  |  |  | label="table.field.user.role" | 
|---|
|  |  |  | source="roleIds" | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | </Stack> | 
|---|
|  |  |  | <Stack direction='row' gap={2}> | 
|---|
|  |  |  | <StatusSelectInput /> | 
|---|
|  |  |  | </Stack> | 
|---|
|  |  |  | <Box mt="2em" /> | 
|---|
|  |  |  | <MemoInput /> | 
|---|
|  |  |  | </Grid> | 
|---|
|  |  |  | </Grid> | 
|---|
|  |  |  | </SimpleForm> | 
|---|
|  |  |  | </Edit > | 
|---|
|  |  |  | <UserEdit /> | 
|---|
|  |  |  | </Edit> | 
|---|
|  |  |  | ) | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | export default UserEdit; | 
|---|
|  |  |  | }; | 
|---|