From d3cf9a502ea50d84cb87f1524e83f32f981c91ee Mon Sep 17 00:00:00 2001 From: nainglinnkhant Date: Mon, 8 Jul 2024 23:44:17 +0700 Subject: [PATCH] feat: add action key shortcuts --- package.json | 1 + pnpm-lock.yaml | 13 ++++ src/app/_components/create-task-dialog.tsx | 37 ++++++++++-- .../_components/tasks-table-floating-bar.tsx | 10 ++-- .../tasks-table-toolbar-actions.tsx | 54 +++++++++++++---- .../advanced/data-table-filter-combobox.tsx | 60 ++++++++++++++----- .../views/data-table-views-dropdown.tsx | 50 ++++++++++++---- .../data-table-columns-visibility.tsx | 51 ++++++++++++---- src/lib/utils.ts | 5 ++ 9 files changed, 219 insertions(+), 62 deletions(-) diff --git a/package.json b/package.json index e650f64..c7961e8 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "react-day-picker": "^8.10.1", "react-dom": "18.3.1", "react-hook-form": "^7.51.5", + "react-hotkeys-hook": "^4.5.0", "server-only": "^0.0.1", "sonner": "^1.4.41", "tailwind-merge": "^2.3.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 134071e..ec7588a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -95,6 +95,9 @@ dependencies: react-hook-form: specifier: ^7.51.5 version: 7.52.0(react@18.3.1) + react-hotkeys-hook: + specifier: ^4.5.0 + version: 4.5.0(react-dom@18.3.1)(react@18.3.1) server-only: specifier: ^0.0.1 version: 0.0.1 @@ -5021,6 +5024,16 @@ packages: react: 18.3.1 dev: false + /react-hotkeys-hook@4.5.0(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-Samb85GSgAWFQNvVt3PS90LPPGSf9mkH/r4au81ZP1yOIFayLC3QAvqTgGtJ8YEDMXtPmaVBs6NgipHO6h4Mug==} + peerDependencies: + react: '>=16.8.1' + react-dom: '>=16.8.1' + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} dev: true diff --git a/src/app/_components/create-task-dialog.tsx b/src/app/_components/create-task-dialog.tsx index 11b10bc..8046828 100644 --- a/src/app/_components/create-task-dialog.tsx +++ b/src/app/_components/create-task-dialog.tsx @@ -5,6 +5,7 @@ import { tasks } from "@/db/schema" import { zodResolver } from "@hookform/resolvers/zod" import { PlusIcon } from "@radix-ui/react-icons" import { useForm } from "react-hook-form" +import { useHotkeys } from "react-hotkeys-hook" import { toast } from "sonner" import { Button } from "@/components/ui/button" @@ -35,6 +36,13 @@ import { SelectValue, } from "@/components/ui/select" import { Textarea } from "@/components/ui/textarea" +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@/components/ui/tooltip" +import { Kbd } from "@/components/kbd" import { LoaderIcon } from "@/components/loader-icon" import { createTask } from "../_lib/actions" @@ -63,14 +71,31 @@ export function CreateTaskDialog() { }) } + useHotkeys("shift+n", () => { + setTimeout(() => setOpen(true), 100) + }) + return ( - - - + + + + + + + + + Add new task +
+ N +
+
+
+
+ Create task diff --git a/src/app/_components/tasks-table-floating-bar.tsx b/src/app/_components/tasks-table-floating-bar.tsx index 2f12e23..e3ece10 100644 --- a/src/app/_components/tasks-table-floating-bar.tsx +++ b/src/app/_components/tasks-table-floating-bar.tsx @@ -77,7 +77,7 @@ export function TasksTableFloatingBar({ table }: TasksTableFloatingBarProps) { /> - +

Clear selection

Esc @@ -129,7 +129,7 @@ export function TasksTableFloatingBar({ table }: TasksTableFloatingBarProps) { - +

Update status

@@ -186,7 +186,7 @@ export function TasksTableFloatingBar({ table }: TasksTableFloatingBarProps) { - +

Update priority

@@ -232,7 +232,7 @@ export function TasksTableFloatingBar({ table }: TasksTableFloatingBarProps) { )} - +

Export tasks

@@ -270,7 +270,7 @@ export function TasksTableFloatingBar({ table }: TasksTableFloatingBarProps) { )} - +

Delete tasks

diff --git a/src/app/_components/tasks-table-toolbar-actions.tsx b/src/app/_components/tasks-table-toolbar-actions.tsx index 352a617..0ed84e2 100644 --- a/src/app/_components/tasks-table-toolbar-actions.tsx +++ b/src/app/_components/tasks-table-toolbar-actions.tsx @@ -3,9 +3,17 @@ import { type Task } from "@/db/schema" import { DownloadIcon } from "@radix-ui/react-icons" import { type Table } from "@tanstack/react-table" +import { useHotkeys } from "react-hotkeys-hook" import { exportTableToCSV } from "@/lib/export" import { Button } from "@/components/ui/button" +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@/components/ui/tooltip" +import { Kbd } from "@/components/kbd" import { CreateTaskDialog } from "./create-task-dialog" import { DeleteTasksDialog } from "./delete-tasks-dialog" @@ -17,6 +25,13 @@ interface TasksTableToolbarActionsProps { export function TasksTableToolbarActions({ table, }: TasksTableToolbarActionsProps) { + useHotkeys("shift+e", () => + exportTableToCSV(table, { + filename: "tasks", + excludeColumns: ["select", "actions"], + }) + ) + return (
{table.getFilteredSelectedRowModel().rows.length > 0 ? ( @@ -28,19 +43,32 @@ export function TasksTableToolbarActions({ /> ) : null} - + + + + + + + Export csv +
+ E +
+
+
+
+ {/** * Other actions can be added here. * For example, import, view, etc. diff --git a/src/components/data-table/advanced/data-table-filter-combobox.tsx b/src/components/data-table/advanced/data-table-filter-combobox.tsx index 722a3a3..8f845f7 100644 --- a/src/components/data-table/advanced/data-table-filter-combobox.tsx +++ b/src/components/data-table/advanced/data-table-filter-combobox.tsx @@ -8,6 +8,7 @@ import { PlusIcon, TextIcon, } from "@radix-ui/react-icons" +import { useHotkeys } from "react-hotkeys-hook" import { Button } from "@/components/ui/button" import { @@ -24,6 +25,13 @@ import { PopoverTrigger, } from "@/components/ui/popover" import { Separator } from "@/components/ui/separator" +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@/components/ui/tooltip" +import { Kbd } from "@/components/kbd" interface DataTableFilterComboboxProps { selectableOptions: DataTableFilterOption[] @@ -48,24 +56,44 @@ export function DataTableFilterCombobox({ DataTableFilterOption >(selectableOptions[0] ?? ({} as DataTableFilterOption)) + const buttonRef = React.useRef(null) + + useHotkeys("shift+f", () => { + setTimeout(() => buttonRef.current?.click(), 100) + }) + return ( - - {children ?? ( - - )} - + {children ?? ( + + + + + + + + + Open filter +
+ F +
+
+
+
+ )} + { + setTimeout(() => setOpen(true), 100) + }) + return ( - - - + + + + + + + + + Open views +
+ {isMac ? "⌘" : "ctrl"}{" "} + V +
+
+
+
+ { + setTimeout(() => setOpen(true), 100) + }) + return ( - - - - + + + + + + + + + + Toggle columns +
+ C +
+
+
+
+