如何使用 React-Admin 在列表组件内创建自定义记录操作按钮?
我是 React 和 React-Admin 的新手。恕我直言,我试图实现一些简单的功能,很多人肯定已经做过了,但我找不到任何教程。
我想在
<List>
组件中的每一行的操作按钮列表(显示/编辑)中添加另一个按钮。此按钮将存档记录。
我最后一次尝试看起来像下面的代码。
import React from 'react';
import {
Datagrid,
EmailField,
List,
TextField,
ShowButton,
EditButton,
DeleteButton,
CloneButton,
} from 'react-admin';
import { makeStyles } from '@material-ui/core/styles';
import ArchiveIcon from '@material-ui/icons/Archive';
const useRowActionToolbarStyles = makeStyles({
toolbar: {
alignItems: 'center',
float: 'right',
width: '160px',
marginTop: -1,
marginBottom: -1,
},
icon_action_button: {
minWidth: '40px;'
},
});
const ArchiveButton = props => {
const transform = data => ({
...data,
archived: true
});
return <CloneButton {...props} transform={transform} />;
}
const RowActionToolbar = (props) => {
const classes = useRowActionToolbarStyles();
return (
<div className={classes.toolbar}>
<ShowButton label="" basePath={props.basePath} record={props.record} className={classes.icon_action_button}/>
<EditButton label="" basePath={props.basePath} record={props.record} className={classes.icon_action_button}/>
<ArchiveButton {...props} basePath={props.basePath} label="" icon={<ArchiveIcon/>} record={props.record} className={classes.icon_action_button} />
<DeleteButton basePath={props.basePath} label="" record={props.record} className={classes.icon_action_button}/>
</div>
);
};
export const UserList = props => {
return (
<List
{...props}
sort={{ field: 'first_name', order: 'ASC' }}
>
<Datagrid>
<TextField source="first_name"/>
<TextField source="last_name"/>
<EmailField source="email"/>
<RowActionToolbar/>
</Datagrid>
</List>
)
};
显然,此代码不起作用,因为
<CloneButton>
组件摆脱了记录的
id
。此外,除非我做错了什么(这是完全有可能的),否则它会向
create
端点发出
GET
请求。
我在
dataProvider
中使用了不同的路由(后端使用 Django 和 Django rest 框架)。我想将
PATCH
发送到详细信息端点,就像
<Edit>
组件一样。
我也尝试使用
<SaveButton>
,但也失败了。
Uncaught TypeError: Cannot read property 'save' of undefined at useSaveContext (SaveContext.js:23)
我猜
<SaveButton>
必须在
<SimpleForm>
内?
我想要
<DeleteButton>
的保存行为,即从列表中更新记录,显示记录已存档的通知(带有撤消链接),将请求发送到后端,刷新列表。
任何指导、指示都将不胜感激。
我不知道这是否是一个完整的答案,但感觉不仅仅是一条评论......
您正在尝试存档现有记录,而不是创建全新的记录,对吗? CloneButton 应该用于创建具有新 ID 的新记录(这就是您的 ID 消失的原因),因此您不想在这里使用它。 请注意,我从未使用过 CloneButton。它没有完整的文档记录,所以我可能对它的使用有误。
我认为您应该在存档按钮中使用 useRecordContext 挂钩来提取记录的所有数据,包括 id;阅读此小节: https://marmelab.com/react-admin/Architecture.html#context-pull-dont-push
我不认为转换是您在这里寻找的。您将需要使用其中一个 dataProvider 钩子,我假设 useUpdate: https://marmelab.com/react-admin/Actions.html#useupdate
//首先创建组件
const MyButton = (props: any) => {
const [sendEmailLoading, setSendEmailLoading] =
React.useState<boolean>(false);
const record = useRecordContext(props);
const sendEmail = (id: Identifier) => {
setSendEmailLoading(true)
dataProvider.sendEmail(
"notifications", { id: id })
.then(({ data }: any) => {
if (data && data.status == "success")
notify('Email send success', { type: 'success' });
setSendEmailLoading(false);
refresh();
});
};
return (
<ButtonMUI color='primary' size="small" onClick={() => {
sendEmail(record.id) }}>
{
!record.publish &&(
!sendEmailLoading ? (
translate('resources.notifications.buttons.send')
) : (
<CircularProgress size={25} thickness={2} />
)
)
}
</ButtonMUI>
)
}
//然后将其添加到数据网格列表
<Datagrid>
<NumberField source="id" />
<TextFieldRA source="subject" />
<DateField source="date" />
<BooleanField source="publish" />
{/* <EditButton /> */}
<ShowButton />
<MyButton />
</Datagrid>