Feat: User can edit his keys combination for each shortcut

This commit is contained in:
igorrCarvalho 2024-04-30 19:56:35 -03:00
commit 604e579bed
5 changed files with 213 additions and 13 deletions

View file

@ -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"];

View file

@ -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>
);
}

View file

@ -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}

View file

@ -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} );
},
}));

View file

@ -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;
};