From 604e579bed567a83c52f123fa54556f06fee755b Mon Sep 17 00:00:00 2001 From: igorrCarvalho Date: Tue, 30 Apr 2024 19:56:35 -0300 Subject: [PATCH] Feat: User can edit his keys combination for each shortcut --- src/frontend/src/constants/constants.ts | 41 +++++++ .../EditShortcutButton/index.tsx | 113 ++++++++++++++++++ .../pages/ShortcutsPage/index.tsx | 50 +++++++- src/frontend/src/stores/shortcuts.ts | 14 +-- src/frontend/src/types/store/index.ts | 8 +- 5 files changed, 213 insertions(+), 13 deletions(-) create mode 100644 src/frontend/src/pages/SettingsPage/pages/ShortcutsPage/EditShortcutButton/index.tsx diff --git a/src/frontend/src/constants/constants.ts b/src/frontend/src/constants/constants.ts index c8d7626ca..e862de5e9 100644 --- a/src/frontend/src/constants/constants.ts +++ b/src/frontend/src/constants/constants.ts @@ -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"]; diff --git a/src/frontend/src/pages/SettingsPage/pages/ShortcutsPage/EditShortcutButton/index.tsx b/src/frontend/src/pages/SettingsPage/pages/ShortcutsPage/EditShortcutButton/index.tsx new file mode 100644 index 000000000..738eb1829 --- /dev/null +++ b/src/frontend/src/pages/SettingsPage/pages/ShortcutsPage/EditShortcutButton/index.tsx @@ -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([]); + 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(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 ( + + + Key Combination + + {children} + +
+
+ {key} +
+
+
+ + + +
+ ); +} diff --git a/src/frontend/src/pages/SettingsPage/pages/ShortcutsPage/index.tsx b/src/frontend/src/pages/SettingsPage/pages/ShortcutsPage/index.tsx index adcfcefef..a53f785db 100644 --- a/src/frontend/src/pages/SettingsPage/pages/ShortcutsPage/index.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/ShortcutsPage/index.tsx @@ -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([]); + const shortcuts = useShortcutsStore(state => state.shortcuts) + // Column Definitions: Defines the columns to be displayed. const [colDefs, setColDefs] = useState<(ColDef | ColGroupDef)[]>([ - { 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 (
@@ -113,7 +135,27 @@ export default function ShortcutsPage() { +
+
+ + + +
+
{ + setSelectedRows(event.api.getSelectedRows().map((row) => row.name)); + }} + suppressRowClickSelection={true} domLayout="autoHeight" pagination={false} columnDefs={colDefs} @@ -128,6 +170,10 @@ export default function ShortcutsPage() { { + setSelectedRows(event.api.getSelectedRows().map((row) => row.name)); + }} + suppressRowClickSelection={true} domLayout="autoHeight" pagination={false} columnDefs={colDefs} diff --git a/src/frontend/src/stores/shortcuts.ts b/src/frontend/src/stores/shortcuts.ts index 798613708..d54753fbc 100644 --- a/src/frontend/src/stores/shortcuts.ts +++ b/src/frontend/src/stores/shortcuts.ts @@ -1,15 +1,11 @@ import { create } from "zustand"; import { shortcutsStoreType } from "../types/store"; +import { defaultShortcuts, unavailableShortcutss } from "../constants/constants"; export const useShortcutsStore = create((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} ); }, })); diff --git a/src/frontend/src/types/store/index.ts b/src/frontend/src/types/store/index.ts index b116bbc3d..cfafe4f4e 100644 --- a/src/frontend/src/types/store/index.ts +++ b/src/frontend/src/types/store/index.ts @@ -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; };