ai-digital-live/src/components/button-batch.tsx
2024-12-28 15:02:02 +08:00

74 lines
1.9 KiB
TypeScript

import React, {useState} from "react";
import {App} from "antd";
import {ButtonType} from "antd/es/button";
import {showErrorToast, showToast} from "@/components/message.ts";
import {BizError} from "@/service/types.ts";
import {IconWarningCircle} from "@/components/icons";
import {LoadingOutlined} from "@ant-design/icons";
type Props = {
selected: any[],
type?: ButtonType;
emptyMessage: string,
confirmMessage?: React.ReactNode,
icon?: React.ReactNode,
onProcess: (ids: Id[]) => Promise<any | void>
successMessage?: string;
onSuccess?: () => void;
children?: React.ReactNode;
title?: React.ReactNode;
className?: string;
}
/**
* 统一批量操作按钮
*/
export default function ButtonBatch(
{
selected, emptyMessage, successMessage, children, icon,
title, confirmMessage, onProcess, onSuccess, className
}: Props) {
const [loading, setLoading] = useState(false)
const {modal} = App.useApp()
const onBatchProcess = async () => {
setLoading(true)
try {
await onProcess(selected)
if (successMessage) showToast(successMessage, 'success')
if (onSuccess) {
onSuccess()
}
} catch (e) {
showErrorToast(e as unknown as BizError)
} finally {
setLoading(false)
}
}
const handleBtnClick = () => {
if (loading) return;
if (selected.length == 0) {
showToast(emptyMessage, 'warning')
return;
}
if(confirmMessage){
modal.confirm({
wrapClassName: 'root-modal-confirm',
title: title || '操作提示',
centered: true,
icon: <span className="anticon anticon-exclamation-circle"><IconWarningCircle/></span>,
content: confirmMessage,
onOk: onBatchProcess
})
}else{
onBatchProcess().catch(showErrorToast);
}
}
return (
<button disabled={loading} className={className} onClick={handleBtnClick}>
<span className={'text'}>{children}</span>
{loading ? <LoadingOutlined/> : icon}
</button>
)
}