From d35c53fb891faf22e05a79d1282cc763cfd214c0 Mon Sep 17 00:00:00 2001 From: "Visal .In" Date: Tue, 17 Sep 2024 15:37:59 +0700 Subject: [PATCH] add commit and discard keybinding (#161) --- src/components/gui/tabs/table-data-tab.tsx | 67 +++++++++++++--------- src/components/gui/toolbar.tsx | 58 +++++++++++++++++++ src/components/gui/windows-tab.tsx | 26 ++++++--- src/lib/key-matcher.ts | 2 + 4 files changed, 118 insertions(+), 35 deletions(-) create mode 100644 src/components/gui/toolbar.tsx diff --git a/src/components/gui/tabs/table-data-tab.tsx b/src/components/gui/tabs/table-data-tab.tsx index 1569f8cc..9ab0a704 100644 --- a/src/components/gui/tabs/table-data-tab.tsx +++ b/src/components/gui/tabs/table-data-tab.tsx @@ -6,7 +6,6 @@ import { LucideArrowRight, LucideDelete, LucideFilter, - LucideLoader, LucidePlus, LucideRefreshCcw, LucideSaveAll, @@ -38,6 +37,9 @@ import ResultStats from "../result-stat"; import isEmptyResultStats from "@/components/lib/empty-stats"; import useTableResultColumnFilter from "../table-result/filter-column"; import { AlertDialogTitle } from "@radix-ui/react-alert-dialog"; +import { useCurrentTab } from "../windows-tab"; +import { KEY_BINDING } from "@/lib/key-matcher"; +import { Toolbar, ToolbarButton } from "../toolbar"; interface TableDataContentProps { tableName: string; @@ -169,6 +171,28 @@ export default function TableDataWindow({ } }, [data]); + const { isActiveTab } = useCurrentTab(); + + useEffect(() => { + if (isActiveTab) { + const handleGlobalKeyBinding = (e: KeyboardEvent) => { + if (KEY_BINDING.commit.match(e)) { + onCommit(); + e.preventDefault(); + e.stopPropagation(); + } else if (KEY_BINDING.discard.match(e)) { + onDiscard(); + e.preventDefault(); + e.stopPropagation(); + } + }; + + document.addEventListener("keydown", handleGlobalKeyBinding); + return () => + document.removeEventListener("keydown", handleGlobalKeyBinding); + } + }, [isActiveTab, onCommit, onDiscard]); + return (
{executeError && ( @@ -185,37 +209,24 @@ export default function TableDataWindow({ )}
-
- + badge={changeNumber ? changeNumber.toString() : ""} + /> - + />
@@ -337,7 +348,7 @@ export default function TableDataWindow({ }} /> -
+
diff --git a/src/components/gui/toolbar.tsx b/src/components/gui/toolbar.tsx new file mode 100644 index 00000000..0c010496 --- /dev/null +++ b/src/components/gui/toolbar.tsx @@ -0,0 +1,58 @@ +import { PropsWithChildren, ReactElement } from "react"; +import { Button } from "../ui/button"; +import { LucideLoader } from "lucide-react"; +import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"; + +export function Toolbar({ children }: PropsWithChildren) { + return
{children}
; +} + +export function ToolbarButton({ + disabled, + loading, + icon, + onClick, + badge, + text, + tooltip, + destructive, +}: { + icon?: ReactElement; + disabled?: boolean; + loading?: boolean; + badge?: string; + text: string; + onClick?: () => void; + tooltip?: ReactElement | string; + destructive?: boolean; +}) { + const buttonContent = ( + + ); + + if (tooltip) { + return ( + + {buttonContent} + {tooltip} + + ); + } + + return buttonContent; +} diff --git a/src/components/gui/windows-tab.tsx b/src/components/gui/windows-tab.tsx index 8dfe558e..d27586ae 100644 --- a/src/components/gui/windows-tab.tsx +++ b/src/components/gui/windows-tab.tsx @@ -53,10 +53,18 @@ const WindowTabsContext = createContext<{ }, }); +const CurrentWindowTab = createContext<{ isActiveTab: boolean }>({ + isActiveTab: false, +}); + export function useTabsContext() { return useContext(WindowTabsContext); } +export function useCurrentTab() { + return useContext(CurrentWindowTab); +} + export default function WindowTabs({ menu, tabs, @@ -200,15 +208,19 @@ export default function WindowTabs({
{tabs.map((tab, tabIndex) => ( -
- {tab.component} -
+
+ {tab.component} +
+ ))}
diff --git a/src/lib/key-matcher.ts b/src/lib/key-matcher.ts index bebdf8a0..c511f2e1 100644 --- a/src/lib/key-matcher.ts +++ b/src/lib/key-matcher.ts @@ -77,4 +77,6 @@ export const KEY_BINDING = { copy: new KeyMatcher({ ctrl: true, key: "c" }), paste: new KeyMatcher({ ctrl: true, key: "v" }), format: new KeyMatcher({ ctrl: true, shift: true, key: "i" }), + commit: new KeyMatcher({ ctrl: true, key: "s" }), + discard: new KeyMatcher({ ctrl: true, shift: true, key: "Delete" }), };