Feat: User can edit his keys combination for each shortcut
This commit is contained in:
parent
0cad2e1978
commit
604e579bed
5 changed files with 213 additions and 13 deletions
|
|
@ -754,3 +754,44 @@ export const NATIVE_CATEGORIES = [
|
|||
];
|
||||
|
||||
export const SAVE_DEBOUNCE_TIME = 300;
|
||||
|
||||
export const defaultShortcuts = [
|
||||
{
|
||||
name: "Advanced Settings",
|
||||
shortcut: "Ctrl + Shift + a"
|
||||
},
|
||||
{
|
||||
name: "Minimize",
|
||||
shortcut: "Ctrl + Shift + q"
|
||||
},
|
||||
{
|
||||
name: "Code",
|
||||
shortcut: "Ctrl + Shift + c"
|
||||
},
|
||||
{
|
||||
name: "Copy",
|
||||
shortcut: "Ctrl + c"
|
||||
},
|
||||
{
|
||||
name: "Duplicate",
|
||||
shortcut: "Ctrl + d"
|
||||
},
|
||||
{
|
||||
name: "Share",
|
||||
shortcut: "Ctrl + Shift + s"
|
||||
},
|
||||
{
|
||||
name: "Docs",
|
||||
shortcut: "Ctrl + Shift + d"
|
||||
},
|
||||
{
|
||||
name: "Save",
|
||||
shortcut: "Ctrl + s"
|
||||
},
|
||||
{
|
||||
name: "Delete",
|
||||
shortcut: "Backspace"
|
||||
},
|
||||
];
|
||||
|
||||
export const unavailableShortcutss = ["Ctrl + Shift + a", "Ctrl + Shift + q", "Ctrl + Shift + c", "Ctrl + c", "Ctrl + d", "Ctrl + Shift + s", "Ctrl + Shift + d", "Ctrl + s", "Backspace"];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,113 @@
|
|||
|
||||
|
||||
//TODO IMPLEMENT FORM LOGIC
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import useAlertStore from "../../../../../stores/alertStore";
|
||||
import { useTypesStore } from "../../../../../stores/typesStore";
|
||||
import { useGlobalVariablesStore } from "../../../../../stores/globalVariables";
|
||||
import { registerGlobalVariable } from "../../../../../controllers/API";
|
||||
import { ResponseErrorDetailAPI } from "../../../../../types/api";
|
||||
import BaseModal from "../../../../../modals/baseModal";
|
||||
import { Label } from "@radix-ui/react-select";
|
||||
import { Input } from "../../../../../components/ui/input";
|
||||
import InputComponent from "../../../../../components/inputComponent";
|
||||
import { Textarea } from "../../../../../components/ui/textarea";
|
||||
import { Button } from "../../../../../components/ui/button";
|
||||
import ForwardedIconComponent from "../../../../../components/genericIconComponent";
|
||||
import { defaultShortcuts } from "../../../../../constants/constants";
|
||||
import { useShortcutsStore } from "../../../../../stores/shortcuts";
|
||||
|
||||
export default function EditShortcutButton({ children, shortcut, defaultShortcuts, defaultCombination, open, setOpen, }: {children: JSX.Element; shortcut: string[]; defaultShortcuts: Array<{name: string; shortcut: string;}>; defaultCombination: string; open: boolean; setOpen: (bool: boolean) => void;}): JSX.Element {
|
||||
const setSuccessData = useAlertStore(state => state.setSuccessData)
|
||||
const setShortcuts = useShortcutsStore(state => state.setShortcuts);
|
||||
const unavaliableShortcuts = useShortcutsStore(state => state.unavailableShortcuts);
|
||||
const isMac = navigator.userAgent.toUpperCase().includes("MAC");
|
||||
const [fields, setFields] = useState<string[]>([]);
|
||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||
const componentFields = useTypesStore((state) => state.ComponentFields);
|
||||
const unavaliableFields =new Set(Object.keys(useGlobalVariablesStore(
|
||||
(state) => state.unavaliableFields
|
||||
)));
|
||||
|
||||
const [key, setKey] = useState<string>(isMac ? "Meta" : 'Ctrl');
|
||||
|
||||
const availableFields = Array.from(componentFields).filter(
|
||||
(field) => !unavaliableFields.has(field)
|
||||
);
|
||||
const addGlobalVariable = useGlobalVariablesStore(
|
||||
(state) => state.addGlobalVariable
|
||||
);
|
||||
|
||||
function canEditCombination(newCombination: string): boolean {
|
||||
return !unavaliableShortcuts.includes(newCombination);
|
||||
}
|
||||
|
||||
function editCombination(): void {
|
||||
if (canEditCombination(key)) {
|
||||
const newCombination = defaultShortcuts.map((s) => {
|
||||
if (s.name === shortcut[0]) {
|
||||
return {name: s.name, shortcut: key}
|
||||
}
|
||||
return {name: s.name, shortcut: s.shortcut};
|
||||
})
|
||||
const unavailable = unavaliableShortcuts.map((s) => {
|
||||
if (s === defaultCombination) return s = key;
|
||||
return s;
|
||||
})
|
||||
setShortcuts(newCombination, unavailable)
|
||||
setOpen(false)
|
||||
setSuccessData({title: `${shortcut[0]} shortcut successfully changed`})
|
||||
setKey(isMac ? "Meta" : 'Ctrl')
|
||||
return;
|
||||
}
|
||||
setErrorData({title: "Error saving key combination", list: ["This combination already exists!"]})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) setKey(isMac ? "Meta" : 'Ctrl')
|
||||
}, [open, setOpen])
|
||||
|
||||
useEffect(() => {
|
||||
function onKeyDown(e: KeyboardEvent) {
|
||||
e.preventDefault()
|
||||
console.log(e.key)
|
||||
if (key.includes(e.key)) return;
|
||||
setKey(oldKey => `${oldKey} + ${e.key}`)
|
||||
}
|
||||
|
||||
document.addEventListener("keydown", onKeyDown);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener("keydown", onKeyDown)
|
||||
}
|
||||
}, [key, setKey])
|
||||
|
||||
return (
|
||||
<BaseModal open={open} setOpen={setOpen} size="x-small">
|
||||
<BaseModal.Header
|
||||
description={
|
||||
"Set your new key combination"
|
||||
}
|
||||
>
|
||||
<span className="pr-2"> Key Combination </span>
|
||||
<ForwardedIconComponent
|
||||
name="Keyboard"
|
||||
className="h-6 w-6 pl-1 text-primary "
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</BaseModal.Header>
|
||||
<BaseModal.Trigger>{children}</BaseModal.Trigger>
|
||||
<BaseModal.Content>
|
||||
<div className="flex h-full w-full gap-4 align-center justify-center">
|
||||
<div>
|
||||
{key}
|
||||
</div>
|
||||
</div>
|
||||
</BaseModal.Content>
|
||||
<BaseModal.Footer>
|
||||
<Button onClick={editCombination}>Edit Combination</Button>
|
||||
</BaseModal.Footer>
|
||||
</BaseModal>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import { ColDef, ColGroupDef } from "ag-grid-community";
|
||||
import { useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import ForwardedIconComponent from "../../../../components/genericIconComponent";
|
||||
import TableComponent from "../../../../components/tableComponent";
|
||||
import {
|
||||
|
|
@ -9,6 +9,9 @@ import {
|
|||
CardHeader,
|
||||
CardTitle,
|
||||
} from "../../../../components/ui/card";
|
||||
import { Button } from "../../../../components/ui/button";
|
||||
import EditShortcutButton from "./EditShortcutButton";
|
||||
import { useShortcutsStore } from "../../../../stores/shortcuts";
|
||||
|
||||
export default function ShortcutsPage() {
|
||||
const advancedShortcut = "Ctrl + Shift + A";
|
||||
|
|
@ -24,9 +27,20 @@ export default function ShortcutsPage() {
|
|||
const undoShortcut = "Ctrl + Z";
|
||||
const redoShortcut = "Ctrl + Y";
|
||||
|
||||
const [selectedRows, setSelectedRows] = useState<string[]>([]);
|
||||
const shortcuts = useShortcutsStore(state => state.shortcuts)
|
||||
|
||||
// Column Definitions: Defines the columns to be displayed.
|
||||
const [colDefs, setColDefs] = useState<(ColDef<any> | ColGroupDef<any>)[]>([
|
||||
{ headerName: "Functionality", field: "name", flex: 1, editable: false }, //This column will be twice as wide as the others
|
||||
{
|
||||
headerName: "Functionality",
|
||||
field: "name",
|
||||
flex: 1,
|
||||
editable: false,
|
||||
headerCheckboxSelection: true,
|
||||
checkboxSelection: true,
|
||||
showDisabledCheckboxes: true,
|
||||
}, //This column will be twice as wide as the others
|
||||
{
|
||||
field: "shortcut",
|
||||
flex: 2,
|
||||
|
|
@ -87,6 +101,14 @@ export default function ShortcutsPage() {
|
|||
shortcut: redoShortcut,
|
||||
},
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
setNodesRowData(shortcuts)
|
||||
}, [shortcuts])
|
||||
|
||||
const combinationToEdit = shortcuts.filter((s) => s.name === selectedRows[0])
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<div className="flex h-full w-full flex-col gap-6">
|
||||
<div className="flex w-full items-center justify-between gap-4 space-y-0.5">
|
||||
|
|
@ -113,7 +135,27 @@ export default function ShortcutsPage() {
|
|||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="w-full flex justify-end align-end mb-4">
|
||||
<div className="">
|
||||
<EditShortcutButton
|
||||
defaultCombination={combinationToEdit[0]?.shortcut}
|
||||
shortcut={selectedRows}
|
||||
defaultShortcuts={shortcuts}
|
||||
open={open}
|
||||
setOpen={setOpen}
|
||||
>
|
||||
<Button data-testid="api-key-button-store" variant="primary">
|
||||
<ForwardedIconComponent name="Plus" className="mr-2 w-4" />
|
||||
New key combination
|
||||
</Button>
|
||||
</EditShortcutButton>
|
||||
</div>
|
||||
</div>
|
||||
<TableComponent
|
||||
onSelectionChanged={(event: SelectionChangedEvent) => {
|
||||
setSelectedRows(event.api.getSelectedRows().map((row) => row.name));
|
||||
}}
|
||||
suppressRowClickSelection={true}
|
||||
domLayout="autoHeight"
|
||||
pagination={false}
|
||||
columnDefs={colDefs}
|
||||
|
|
@ -128,6 +170,10 @@ export default function ShortcutsPage() {
|
|||
</CardHeader>
|
||||
<CardContent>
|
||||
<TableComponent
|
||||
onSelectionChanged={(event: SelectionChangedEvent) => {
|
||||
setSelectedRows(event.api.getSelectedRows().map((row) => row.name));
|
||||
}}
|
||||
suppressRowClickSelection={true}
|
||||
domLayout="autoHeight"
|
||||
pagination={false}
|
||||
columnDefs={colDefs}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,11 @@
|
|||
import { create } from "zustand";
|
||||
import { shortcutsStoreType } from "../types/store";
|
||||
import { defaultShortcuts, unavailableShortcutss } from "../constants/constants";
|
||||
|
||||
export const useShortcutsStore = create<shortcutsStoreType>((set, get) => ({
|
||||
openCodeModalWShortcut: false,
|
||||
handleModalWShortcut: (modal) => {
|
||||
switch (modal) {
|
||||
case "code":
|
||||
set({
|
||||
openCodeModalWShortcut: !get().openCodeModalWShortcut,
|
||||
});
|
||||
break;
|
||||
}
|
||||
unavailableShortcuts: unavailableShortcutss,
|
||||
shortcuts: defaultShortcuts,
|
||||
setShortcuts: (newShortcuts, unavailable) => {
|
||||
set({shortcuts: newShortcuts, unavailableShortcuts: unavailable} );
|
||||
},
|
||||
}));
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@ export type StoreComponentResponse = {
|
|||
};
|
||||
|
||||
export type shortcutsStoreType = {
|
||||
openCodeModalWShortcut: boolean;
|
||||
handleModalWShortcut: (str: string) => void;
|
||||
shortcuts: Array<{
|
||||
name: string;
|
||||
shortcut: string;
|
||||
}>
|
||||
unavailableShortcuts: string[];
|
||||
setShortcuts: (newShortcuts: Array<{name: string; shortcut: string;}>, unavailable: string[]) => void;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue