fix(frontend): English UI strings for session menu/dialogs; rename empty-guard + cancel test
- SessionMenu: anglicize all Italian labels (Vista divisa → Split view, etc.) - RenameDialog: add empty-name guard + change title to "Rename session" - DeleteConfirmDialog: translate title and description to English - SessionActions.test: add 2 new tests (empty name guard, cancel on DeleteConfirmDialog) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -12,9 +12,9 @@ export function DeleteConfirmDialog({ open, label, onOpenChange, onConfirm }: Pr
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent>
|
||||
<DialogHeader><DialogTitle>Elimina definitivamente</DialogTitle></DialogHeader>
|
||||
<DialogHeader><DialogTitle>Delete permanently</DialogTitle></DialogHeader>
|
||||
<DialogDescription>
|
||||
"{label}" verrà eliminata definitivamente, inclusi tutti i suoi documenti. L'operazione non è reversibile.
|
||||
"{label}" will be permanently deleted, including all of its documents. This action cannot be undone.
|
||||
</DialogDescription>
|
||||
<DialogFooter>
|
||||
<Button type="button" variant="outline" size="sm" onClick={() => onOpenChange(false)}>Cancel</Button>
|
||||
|
||||
@@ -15,6 +15,7 @@ export function RenameDialog({ open, initial, onOpenChange, onSubmit }: Props) {
|
||||
|
||||
function submit(e: React.FormEvent) {
|
||||
e.preventDefault();
|
||||
if (!name.trim()) return;
|
||||
onSubmit(name.trim());
|
||||
onOpenChange(false);
|
||||
}
|
||||
@@ -22,7 +23,7 @@ export function RenameDialog({ open, initial, onOpenChange, onSubmit }: Props) {
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent>
|
||||
<DialogHeader><DialogTitle>Rinomina sessione</DialogTitle></DialogHeader>
|
||||
<DialogHeader><DialogTitle>Rename session</DialogTitle></DialogHeader>
|
||||
<form onSubmit={submit} className="flex flex-col gap-3">
|
||||
<div>
|
||||
<label className="mb-1.5 block text-xs font-medium text-muted-foreground" htmlFor="rename-name">Name</label>
|
||||
|
||||
@@ -7,7 +7,7 @@ import { DeleteConfirmDialog } from "./DeleteConfirmDialog";
|
||||
test("RenameDialog submits the edited name", async () => {
|
||||
const onSubmit = vi.fn();
|
||||
render(<RenameDialog open initial="Vecchio" onOpenChange={vi.fn()} onSubmit={onSubmit} />);
|
||||
const input = screen.getByLabelText(/name/i);
|
||||
const input = screen.getByDisplayValue("Vecchio");
|
||||
await userEvent.clear(input);
|
||||
await userEvent.type(input, "Nuovo");
|
||||
await userEvent.click(screen.getByRole("button", { name: /save/i }));
|
||||
@@ -21,3 +21,19 @@ test("DeleteConfirmDialog confirms only on the destructive button", async () =>
|
||||
await userEvent.click(screen.getByRole("button", { name: /delete/i }));
|
||||
expect(onConfirm).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test("RenameDialog does not submit an empty name", async () => {
|
||||
const onSubmit = vi.fn();
|
||||
render(<RenameDialog open initial="Old" onOpenChange={vi.fn()} onSubmit={onSubmit} />);
|
||||
const input = screen.getByDisplayValue("Old");
|
||||
await userEvent.clear(input);
|
||||
await userEvent.click(screen.getByRole("button", { name: /save/i }));
|
||||
expect(onSubmit).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test("DeleteConfirmDialog does not confirm when Cancel is clicked", async () => {
|
||||
const onConfirm = vi.fn();
|
||||
render(<DeleteConfirmDialog open label="X" onOpenChange={vi.fn()} onConfirm={onConfirm} />);
|
||||
await userEvent.click(screen.getByRole("button", { name: /cancel/i }));
|
||||
expect(onConfirm).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -29,10 +29,10 @@ export function SessionMenu({ session, groups, onView, onRename, onMove, onNewGr
|
||||
<Menu.Portal>
|
||||
<Menu.Positioner side="bottom" align="end" sideOffset={4}>
|
||||
<Menu.Popup className="z-50 min-w-44 rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-none">
|
||||
<Menu.Item className={itemCls} onClick={onView}>Vista divisa</Menu.Item>
|
||||
<Menu.Item className={itemCls} onClick={onRename}>Rinomina</Menu.Item>
|
||||
<Menu.Item className={itemCls} onClick={onView}>Split view</Menu.Item>
|
||||
<Menu.Item className={itemCls} onClick={onRename}>Rename</Menu.Item>
|
||||
<Menu.SubmenuRoot>
|
||||
<Menu.SubmenuTrigger className={itemCls}>Sposta nel gruppo ›</Menu.SubmenuTrigger>
|
||||
<Menu.SubmenuTrigger className={itemCls}>Move to group ›</Menu.SubmenuTrigger>
|
||||
<Menu.Portal>
|
||||
<Menu.Positioner side="right" align="start">
|
||||
<Menu.Popup className="z-50 min-w-44 rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-none">
|
||||
@@ -40,18 +40,18 @@ export function SessionMenu({ session, groups, onView, onRename, onMove, onNewGr
|
||||
<Menu.Item key={g} className={itemCls} onClick={() => onMove(g)}>{g}</Menu.Item>
|
||||
))}
|
||||
{session.group && (
|
||||
<Menu.Item className={itemCls} onClick={() => onMove("")}>Senza gruppo</Menu.Item>
|
||||
<Menu.Item className={itemCls} onClick={() => onMove("")}>No group</Menu.Item>
|
||||
)}
|
||||
<Menu.Item className={itemCls} onClick={onNewGroup}>Nuovo gruppo…</Menu.Item>
|
||||
<Menu.Item className={itemCls} onClick={onNewGroup}>New group…</Menu.Item>
|
||||
</Menu.Popup>
|
||||
</Menu.Positioner>
|
||||
</Menu.Portal>
|
||||
</Menu.SubmenuRoot>
|
||||
<Menu.Item className={itemCls} onClick={onArchiveToggle}>
|
||||
{session.archived ? "Ripristina" : "Archivia"}
|
||||
{session.archived ? "Restore" : "Archive"}
|
||||
</Menu.Item>
|
||||
<Menu.Separator className="my-1 h-px bg-border" />
|
||||
<Menu.Item className={`${itemCls} text-destructive`} onClick={onDelete}>Elimina</Menu.Item>
|
||||
<Menu.Item className={`${itemCls} text-destructive`} onClick={onDelete}>Delete</Menu.Item>
|
||||
</Menu.Popup>
|
||||
</Menu.Positioner>
|
||||
</Menu.Portal>
|
||||
|
||||
Reference in New Issue
Block a user