fix: confirm shortcut defaults reset

This commit is contained in:
Jiayuan Zhang
2026-07-12 14:51:18 +08:00
parent 80e54094a8
commit 269b5c5f1a
6 changed files with 96 additions and 5 deletions

View File

@@ -37,6 +37,12 @@
"description": "Customize product actions on this device. Click a shortcut, then press the new key combination.",
"search_placeholder": "Search actions...",
"reset_all": "Restore defaults",
"reset_confirm": {
"title": "Restore all shortcut defaults?",
"description": "This will remove every custom shortcut and restore the defaults on this device.",
"cancel": "Cancel",
"confirm": "Restore all defaults"
},
"reset": "Reset",
"disable": "Disable",
"reset_action": "Reset {{action}}",

View File

@@ -37,6 +37,12 @@
"description": "このデバイスで製品操作のショートカットをカスタマイズします。ショートカットをクリックして、新しいキーの組み合わせを押してください。",
"search_placeholder": "操作を検索...",
"reset_all": "デフォルトに戻す",
"reset_confirm": {
"title": "すべてのショートカットをデフォルトに戻しますか?",
"description": "このデバイスのカスタムショートカットをすべて削除し、デフォルト設定に戻します。",
"cancel": "キャンセル",
"confirm": "すべてデフォルトに戻す"
},
"reset": "リセット",
"disable": "無効にする",
"reset_action": "{{action}}をリセット",

View File

@@ -37,6 +37,12 @@
"description": "이 기기에서 제품 동작의 단축키를 설정합니다. 단축키를 클릭한 다음 새 키 조합을 누르세요.",
"search_placeholder": "동작 검색...",
"reset_all": "기본값 복원",
"reset_confirm": {
"title": "모든 단축키를 기본값으로 복원할까요?",
"description": "이 기기의 모든 사용자 지정 단축키를 삭제하고 기본 설정으로 복원합니다.",
"cancel": "취소",
"confirm": "모두 기본값으로 복원"
},
"reset": "재설정",
"disable": "사용 안 함",
"reset_action": "{{action}} 재설정",

View File

@@ -37,6 +37,12 @@
"description": "自定义当前设备上的产品操作。点击一个快捷键,然后按下新的组合键。",
"search_placeholder": "搜索操作...",
"reset_all": "恢复默认设置",
"reset_confirm": {
"title": "恢复所有快捷键的默认设置?",
"description": "这会清除当前设备上的所有自定义快捷键,并恢复默认设置。",
"cancel": "取消",
"confirm": "恢复全部默认设置"
},
"reset": "重置",
"disable": "停用",
"reset_action": "重置「{{action}}」",

View File

@@ -136,4 +136,35 @@ describe("KeyboardShortcutsTab", () => {
);
expect(getShortcut("createIssue")).toEqual(createShortcutChord("C"));
});
it("confirms before restoring all shortcut defaults", () => {
useShortcutStore.getState().setShortcut(
"openSearch",
createShortcutChord("J", { primary: true }),
);
renderWithI18n(<KeyboardShortcutsTab />);
fireEvent.click(screen.getByRole("button", { name: "Restore defaults" }));
expect(screen.getByRole("alertdialog")).toHaveTextContent(
"This will remove every custom shortcut and restore the defaults on this device.",
);
expect(getShortcut("openSearch")).toEqual(
createShortcutChord("J", { primary: true }),
);
fireEvent.click(screen.getByRole("button", { name: "Cancel" }));
expect(screen.queryByRole("alertdialog")).not.toBeInTheDocument();
expect(getShortcut("openSearch")).toEqual(
createShortcutChord("J", { primary: true }),
);
fireEvent.click(screen.getByRole("button", { name: "Restore defaults" }));
fireEvent.click(
screen.getByRole("button", { name: "Restore all defaults" }),
);
expect(screen.queryByRole("alertdialog")).not.toBeInTheDocument();
expect(getShortcut("openSearch")).toEqual(
createShortcutChord("K", { primary: true }),
);
});
});

View File

@@ -4,6 +4,16 @@ import { useMemo, useState } from "react";
import { Keyboard, RotateCcw, Search, X } from "lucide-react";
import { Button } from "@multica/ui/components/ui/button";
import { Input } from "@multica/ui/components/ui/input";
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from "@multica/ui/components/ui/alert-dialog";
import { cn } from "@multica/ui/lib/utils";
import {
findShortcutConflict,
@@ -42,6 +52,7 @@ export function KeyboardShortcutsTab() {
const [query, setQuery] = useState("");
const [recording, setRecording] = useState<ShortcutActionId | null>(null);
const [captureError, setCaptureError] = useState<CaptureError>(null);
const [resetConfirmOpen, setResetConfirmOpen] = useState(false);
const overrides = useShortcutStore((state) => state.overrides);
const setShortcut = useShortcutStore((state) => state.setShortcut);
const resetShortcut = useShortcutStore((state) => state.resetShortcut);
@@ -119,11 +130,7 @@ export function KeyboardShortcutsTab() {
<Button
variant="outline"
size="sm"
onClick={() => {
resetAll();
setCaptureError(null);
setRecording(null);
}}
onClick={() => setResetConfirmOpen(true)}
disabled={Object.keys(overrides).length === 0}
>
<RotateCcw className="size-3.5" />
@@ -195,6 +202,35 @@ export function KeyboardShortcutsTab() {
<FixedShortcutRow label={t(($) => $.shortcuts.fixed.close_dialog)} shortcut={createShortcutChord("Escape")} />
</SettingsCard>
</SettingsSection>
<AlertDialog open={resetConfirmOpen} onOpenChange={setResetConfirmOpen}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>
{t(($) => $.shortcuts.reset_confirm.title)}
</AlertDialogTitle>
<AlertDialogDescription>
{t(($) => $.shortcuts.reset_confirm.description)}
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>
{t(($) => $.shortcuts.reset_confirm.cancel)}
</AlertDialogCancel>
<AlertDialogAction
variant="destructive"
onClick={() => {
resetAll();
setCaptureError(null);
setRecording(null);
setResetConfirmOpen(false);
}}
>
{t(($) => $.shortcuts.reset_confirm.confirm)}
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</SettingsTab>
);
}