Files
medusa-store/packages/admin-next/dashboard/src/providers/keybind-provider/hooks.tsx
Kasper Fabricius Kristensen 75c5d5ad9e feat(dashboard,js-sdk,types): Update app layout, and add user sdk methods (#8182)
**What**
- Updates app layout (sidebar and topbar)
- Adds "System" option to theme toggle (we now default to system)
- Adds sdk methods for user endpoints (RESOLVES CC-67)
2024-07-19 11:18:48 +00:00

312 lines
7.1 KiB
TypeScript

import debounceFn from "lodash/debounce"
import { useCallback, useContext, useEffect, useState } from "react"
import { useTranslation } from "react-i18next"
import { useNavigate } from "react-router-dom"
import { useLogout } from "../../hooks/api/auth"
import { queryClient } from "../../lib/query-client"
import { KeybindContext } from "./keybind-context"
import { Shortcut } from "./types"
import { findShortcut } from "./utils"
export const useKeybind = () => {
const context = useContext(KeybindContext)
if (!context) {
throw new Error("useKeybind must be used within a KeybindProvider")
}
return context
}
export const useRegisterShortcut = () => {}
export const useShortcuts = ({
shortcuts = [],
debounce,
}: {
shortcuts?: Shortcut[]
debounce: number
}) => {
const [keys, setKeys] = useState<string[]>([])
const navigate = useNavigate()
// eslint-disable-next-line react-hooks/exhaustive-deps
const removeKeys = useCallback(
debounceFn(() => setKeys([]), debounce),
[]
)
// eslint-disable-next-line react-hooks/exhaustive-deps
const invokeShortcut = useCallback(
debounceFn((shortcut: Shortcut | null) => {
if (shortcut && shortcut.callback) {
shortcut.callback()
setKeys([])
return
}
if (shortcut && shortcut.to) {
navigate(shortcut.to)
setKeys([])
return
}
}, debounce / 2),
[]
)
useEffect(() => {
if (keys.length > 0 && shortcuts.length > 0) {
const shortcut = findShortcut(shortcuts, keys)
invokeShortcut(shortcut)
}
return () => invokeShortcut.cancel()
}, [keys, shortcuts, invokeShortcut])
useEffect(() => {
const listener = (event: KeyboardEvent) => {
const target = event.target as HTMLElement
/**
* Ignore key events from input, textarea and contenteditable elements
*/
if (
target.tagName === "INPUT" ||
target.tagName === "TEXTAREA" ||
target.contentEditable === "true"
) {
removeKeys()
return
}
setKeys((oldKeys) => [...oldKeys, event.key])
removeKeys()
}
window.addEventListener("keydown", listener)
return () => {
window.removeEventListener("keydown", listener)
}
}, [removeKeys])
}
export const useGlobalShortcuts = () => {
const { t } = useTranslation()
const navigate = useNavigate()
const { mutateAsync } = useLogout()
const handleLogout = async () => {
await mutateAsync(undefined, {
onSuccess: () => {
queryClient.clear()
navigate("/login")
},
})
}
const globalShortcuts: Shortcut[] = [
// Pages
{
keys: {
Mac: ["G", "O"],
},
label: t("app.keyboardShortcuts.navigation.goToOrders"),
type: "pageShortcut",
to: "/orders",
},
{
keys: {
Mac: ["G", "P"],
},
label: t("app.keyboardShortcuts.navigation.goToProducts"),
type: "pageShortcut",
to: "/products",
},
{
keys: {
Mac: ["G", "C"],
},
label: t("app.keyboardShortcuts.navigation.goToCollections"),
type: "pageShortcut",
to: "/collections",
},
{
keys: {
Mac: ["G", "A"],
},
label: t("app.keyboardShortcuts.navigation.goToCategories"),
type: "pageShortcut",
to: "/categories",
},
{
keys: {
Mac: ["G", "U"],
},
label: t("app.keyboardShortcuts.navigation.goToCustomers"),
type: "pageShortcut",
to: "/customers",
},
{
keys: {
Mac: ["G", "G"],
},
label: t("app.keyboardShortcuts.navigation.goToCustomerGroups"),
type: "pageShortcut",
to: "/customer-groups",
},
{
keys: {
Mac: ["G", "I"],
},
label: t("app.keyboardShortcuts.navigation.goToInventory"),
type: "pageShortcut",
to: "/inventory",
},
{
keys: {
Mac: ["G", "R"],
},
label: t("app.keyboardShortcuts.navigation.goToReservations"),
type: "pageShortcut",
to: "/reservations",
},
{
keys: {
Mac: ["G", "L"],
},
label: t("app.keyboardShortcuts.navigation.goToPriceLists"),
type: "pageShortcut",
to: "/price-lists",
},
{
keys: {
Mac: ["G", "M"],
},
label: t("app.keyboardShortcuts.navigation.goToPromotions"),
type: "pageShortcut",
to: "/promotions",
},
{
keys: {
Mac: ["G", "K"],
},
label: t("app.keyboardShortcuts.navigation.goToCampaigns"),
type: "pageShortcut",
to: "/campaigns",
},
// Settings
{
keys: {
Mac: ["G", ","],
},
label: t("app.keyboardShortcuts.settings.goToSettings"),
type: "settingShortcut",
to: "/settings",
},
{
keys: {
Mac: ["G", ",", "S"],
},
label: t("app.keyboardShortcuts.settings.goToStore"),
type: "settingShortcut",
to: "/settings/store",
},
{
keys: {
Mac: ["G", ",", "U"],
},
label: t("app.keyboardShortcuts.settings.goToUsers"),
type: "settingShortcut",
to: "/settings/users",
},
{
keys: {
Mac: ["G", ",", "R"],
},
label: t("app.keyboardShortcuts.settings.goToRegions"),
type: "settingShortcut",
to: "/settings/regions",
},
{
keys: {
Mac: ["G", ",", "T"],
},
label: t("app.keyboardShortcuts.settings.goToTaxRegions"),
type: "settingShortcut",
to: "/settings/tax-regions",
},
{
keys: {
Mac: ["G", ",", "A"],
},
label: t("app.keyboardShortcuts.settings.goToSalesChannels"),
type: "settingShortcut",
to: "/settings/sales-channels",
},
{
keys: {
Mac: ["G", ",", "P"],
},
label: t("app.keyboardShortcuts.settings.goToProductTypes"),
type: "settingShortcut",
to: "/settings/product-types",
},
{
keys: {
Mac: ["G", ",", "L"],
},
label: t("app.keyboardShortcuts.settings.goToLocations"),
type: "settingShortcut",
to: "/settings/locations",
},
{
keys: {
Mac: ["G", ",", "J"],
},
label: t("app.keyboardShortcuts.settings.goToPublishableApiKeys"),
type: "settingShortcut",
to: "/settings/publishable-api-keys",
},
{
keys: {
Mac: ["G", ",", "K"],
},
label: t("app.keyboardShortcuts.settings.goToSecretApiKeys"),
type: "settingShortcut",
to: "/settings/secret-api-keys",
},
{
keys: {
Mac: ["G", ",", "W"],
},
label: t("app.keyboardShortcuts.settings.goToWorkflows"),
type: "settingShortcut",
to: "/settings/workflows",
},
{
keys: {
Mac: ["G", ",", "M"],
},
label: t("app.keyboardShortcuts.settings.goToProfile"),
type: "settingShortcut",
to: "/settings/profile",
},
// Commands
{
keys: {
Mac: ["B", "Y", "E"],
},
label: t("actions.logout"),
type: "commandShortcut",
callback: () => handleLogout(),
},
]
return globalShortcuts
}