71aaa08230
Build and Release / Build (push) Has been cancelled
备注保存前获取完整用户详情构造请求体,TC03 清空备注场景不再丢失其他字段。 拆出 RemarkForm 组件,增加保存中禁用态和失败错误提示。
70 lines
1.9 KiB
TypeScript
70 lines
1.9 KiB
TypeScript
import { Button } from "@workspace/ui/components/button";
|
|
import { Input } from "@workspace/ui/components/input";
|
|
import { PopoverClose } from "@workspace/ui/components/popover";
|
|
import { useRef, useState } from "react";
|
|
|
|
interface RemarkFormProps {
|
|
initialRemark?: string | null;
|
|
onSave: (remark: string) => Promise<void> | void;
|
|
}
|
|
|
|
export function RemarkForm({ onSave, initialRemark }: RemarkFormProps) {
|
|
const [remark, setRemark] = useState<string>(initialRemark ?? "");
|
|
const [saving, setSaving] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
const closeRef = useRef<HTMLButtonElement>(null);
|
|
|
|
const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
setRemark(event.target.value);
|
|
};
|
|
|
|
const handleSave = async (event: React.FormEvent<HTMLFormElement>) => {
|
|
event.preventDefault();
|
|
setError(null);
|
|
setSaving(true);
|
|
|
|
try {
|
|
await onSave(remark);
|
|
closeRef.current?.click();
|
|
} catch {
|
|
setError("备注保存失败,请重试");
|
|
} finally {
|
|
setSaving(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<form onSubmit={handleSave}>
|
|
<div className="mb-2 font-semibold text-sm">备注</div>
|
|
<Input
|
|
aria-invalid={Boolean(error)}
|
|
className="w-full"
|
|
disabled={saving}
|
|
onChange={handleInputChange}
|
|
placeholder="在此输入备注..."
|
|
type="text"
|
|
value={remark}
|
|
/>
|
|
{error ? (
|
|
<p className="mt-2 text-destructive text-sm" role="alert">
|
|
{error}
|
|
</p>
|
|
) : null}
|
|
<Button
|
|
className="mt-2"
|
|
disabled={saving}
|
|
size="sm"
|
|
type="submit"
|
|
variant="default"
|
|
>
|
|
{saving ? "保存中..." : "保存"}
|
|
</Button>
|
|
<PopoverClose asChild>
|
|
<button className="sr-only" ref={closeRef} type="button">
|
|
关闭
|
|
</button>
|
|
</PopoverClose>
|
|
</form>
|
|
);
|
|
}
|