Skip to content

Commit

Permalink
Added hotkeyScopes to serverless functions in settings (#6710)
Browse files Browse the repository at this point in the history
Fixes #6656 
Is this the right way to implement keyboard listeners?
Please let me know, I'll make the changes accordingly.
:)


https://github.com/user-attachments/assets/af71d340-ead9-4659-81e6-a440522a194f

---------

Co-authored-by: Lucas Bordeau <[email protected]>
  • Loading branch information
ehconitin and lucasbordeau authored Aug 23, 2024
1 parent f9af25b commit 5d8162d
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 24 deletions.
20 changes: 20 additions & 0 deletions packages/twenty-front/src/hooks/useHotkeyScopeOnMount.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
import { useEffect } from 'react';

export const useHotkeyScopeOnMount = (hotkeyScope: string) => {
const {
goBackToPreviousHotkeyScope,
setHotkeyScopeAndMemorizePreviousScope,
} = usePreviousHotkeyScope();

useEffect(() => {
setHotkeyScopeAndMemorizePreviousScope(hotkeyScope);
return () => {
goBackToPreviousHotkeyScope();
};
}, [
hotkeyScope,
setHotkeyScopeAndMemorizePreviousScope,
goBackToPreviousHotkeyScope,
]);
};
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import { TableHeader } from '@/ui/layout/table/components/TableHeader';
import { Table } from '@/ui/layout/table/components/Table';
import styled from '@emotion/styled';
import { TableRow } from '@/ui/layout/table/components/TableRow';
import { TableBody } from '@/ui/layout/table/components/TableBody';
import { useGetManyServerlessFunctions } from '@/settings/serverless-functions/hooks/useGetManyServerlessFunctions';
import { SettingsServerlessFunctionsFieldItemTableRow } from '@/settings/serverless-functions/components/SettingsServerlessFunctionsFieldItemTableRow';
import { ServerlessFunction } from '~/generated-metadata/graphql';
import { SettingsServerlessFunctionsTableEmpty } from '@/settings/serverless-functions/components/SettingsServerlessFunctionsTableEmpty';
import { useGetManyServerlessFunctions } from '@/settings/serverless-functions/hooks/useGetManyServerlessFunctions';
import { SettingsServerlessFunctionHotkeyScope } from '@/settings/serverless-functions/types/SettingsServerlessFunctionHotKeyScope';
import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
import { SettingsPath } from '@/types/SettingsPath';
import { Table } from '@/ui/layout/table/components/Table';
import { TableBody } from '@/ui/layout/table/components/TableBody';
import { TableHeader } from '@/ui/layout/table/components/TableHeader';
import { TableRow } from '@/ui/layout/table/components/TableRow';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import styled from '@emotion/styled';
import { useNavigate } from 'react-router-dom';
import { Key } from 'ts-key-enum';
import { ServerlessFunction } from '~/generated-metadata/graphql';
import { useHotkeyScopeOnMount } from '~/hooks/useHotkeyScopeOnMount';

const StyledTableRow = styled(TableRow)`
grid-template-columns: 312px 132px 68px;
Expand All @@ -20,6 +25,19 @@ const StyledTableBody = styled(TableBody)`

export const SettingsServerlessFunctionsTable = () => {
const { serverlessFunctions } = useGetManyServerlessFunctions();
const navigate = useNavigate();

useHotkeyScopeOnMount(
SettingsServerlessFunctionHotkeyScope.ServerlessFunction,
);

useScopedHotkeys(
[Key.Enter],
() => {
navigate(getSettingsPagePath(SettingsPath.NewServerlessFunction));
},
SettingsServerlessFunctionHotkeyScope.ServerlessFunction,
);
return (
<>
{serverlessFunctions.length ? (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import { H2Title, IconPlayerPlay, IconGitCommit, IconRestore } from 'twenty-ui';
import { CodeEditor } from '@/ui/input/code-editor/components/CodeEditor';
import { Section } from '@/ui/layout/section/components/Section';
import { ServerlessFunctionFormValues } from '@/settings/serverless-functions/hooks/useServerlessFunctionUpdateFormState';
import { SettingsServerlessFunctionHotkeyScope } from '@/settings/serverless-functions/types/SettingsServerlessFunctionHotKeyScope';
import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
import { SettingsPath } from '@/types/SettingsPath';
import { Button } from '@/ui/input/button/components/Button';
import { CodeEditor } from '@/ui/input/code-editor/components/CodeEditor';
import { CoreEditorHeader } from '@/ui/input/code-editor/components/CodeEditorHeader';
import styled from '@emotion/styled';
import { Section } from '@/ui/layout/section/components/Section';
import { TabList } from '@/ui/layout/tab/components/TabList';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import styled from '@emotion/styled';
import { useNavigate } from 'react-router-dom';
import { Key } from 'ts-key-enum';
import { H2Title, IconGitCommit, IconPlayerPlay, IconRestore } from 'twenty-ui';
import { useHotkeyScopeOnMount } from '~/hooks/useHotkeyScopeOnMount';

const StyledTabList = styled(TabList)`
border-bottom: none;
Expand Down Expand Up @@ -76,7 +83,18 @@ export const SettingsServerlessFunctionCodeEditorTab = ({
rightNodes={[ResetButton, PublishButton, TestButton]}
/>
);
const navigate = useNavigate();
useHotkeyScopeOnMount(
SettingsServerlessFunctionHotkeyScope.ServerlessFunctionEditorTab,
);

useScopedHotkeys(
[Key.Escape],
() => {
navigate(getSettingsPagePath(SettingsPath.ServerlessFunctions));
},
SettingsServerlessFunctionHotkeyScope.ServerlessFunctionEditorTab,
);
return (
<Section>
<H2Title
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import { H2Title } from 'twenty-ui';
import { Section } from '@/ui/layout/section/components/Section';
import { SettingsServerlessFunctionNewForm } from '@/settings/serverless-functions/components/SettingsServerlessFunctionNewForm';
import { useDeleteOneServerlessFunction } from '@/settings/serverless-functions/hooks/useDeleteOneServerlessFunction';
import { ServerlessFunctionFormValues } from '@/settings/serverless-functions/hooks/useServerlessFunctionUpdateFormState';
import { SettingsServerlessFunctionHotkeyScope } from '@/settings/serverless-functions/types/SettingsServerlessFunctionHotKeyScope';
import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
import { SettingsPath } from '@/types/SettingsPath';
import { Button } from '@/ui/input/button/components/Button';
import { useState } from 'react';
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
import { SettingsServerlessFunctionNewForm } from '@/settings/serverless-functions/components/SettingsServerlessFunctionNewForm';
import { useDeleteOneServerlessFunction } from '@/settings/serverless-functions/hooks/useDeleteOneServerlessFunction';
import { Section } from '@/ui/layout/section/components/Section';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { Key } from 'ts-key-enum';
import { H2Title } from 'twenty-ui';
import { useHotkeyScopeOnMount } from '~/hooks/useHotkeyScopeOnMount';

export const SettingsServerlessFunctionSettingsTab = ({
formValues,
Expand All @@ -26,6 +32,26 @@ export const SettingsServerlessFunctionSettingsTab = ({
await deleteOneServerlessFunction({ id: serverlessFunctionId });
navigate('/settings/functions');
};

useHotkeyScopeOnMount(
SettingsServerlessFunctionHotkeyScope.ServerlessFunctionSettingsTab,
);

useScopedHotkeys(
[Key.Delete],
() => {
setIsDeleteFunctionModalOpen(true);
},
SettingsServerlessFunctionHotkeyScope.ServerlessFunctionSettingsTab,
);

useScopedHotkeys(
[Key.Escape],
() => {
navigate(getSettingsPagePath(SettingsPath.ServerlessFunctions));
},
SettingsServerlessFunctionHotkeyScope.ServerlessFunctionSettingsTab,
);
return (
<>
<SettingsServerlessFunctionNewForm
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
import { H2Title, IconPlayerPlay } from 'twenty-ui';
import { Section } from '@/ui/layout/section/components/Section';
import { H2Title, IconPlayerPlay } from 'twenty-ui';

import { LightCopyIconButton } from '@/object-record/record-field/components/LightCopyIconButton';
import { SettingsServerlessFunctionsOutputMetadataInfo } from '@/settings/serverless-functions/components/SettingsServerlessFunctionsOutputMetadataInfo';
import { settingsServerlessFunctionCodeEditorOutputParamsState } from '@/settings/serverless-functions/states/settingsServerlessFunctionCodeEditorOutputParamsState';
import { settingsServerlessFunctionInputState } from '@/settings/serverless-functions/states/settingsServerlessFunctionInputState';
import { settingsServerlessFunctionOutputState } from '@/settings/serverless-functions/states/settingsServerlessFunctionOutputState';
import { SettingsServerlessFunctionHotkeyScope } from '@/settings/serverless-functions/types/SettingsServerlessFunctionHotKeyScope';
import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
import { SettingsPath } from '@/types/SettingsPath';
import { Button } from '@/ui/input/button/components/Button';
import { CodeEditor } from '@/ui/input/code-editor/components/CodeEditor';
import styled from '@emotion/styled';
import { CoreEditorHeader } from '@/ui/input/code-editor/components/CodeEditorHeader';
import { Button } from '@/ui/input/button/components/Button';
import { LightCopyIconButton } from '@/object-record/record-field/components/LightCopyIconButton';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import styled from '@emotion/styled';
import { useNavigate } from 'react-router-dom';
import { useRecoilState, useRecoilValue } from 'recoil';
import { settingsServerlessFunctionOutputState } from '@/settings/serverless-functions/states/settingsServerlessFunctionOutputState';
import { settingsServerlessFunctionInputState } from '@/settings/serverless-functions/states/settingsServerlessFunctionInputState';
import { settingsServerlessFunctionCodeEditorOutputParamsState } from '@/settings/serverless-functions/states/settingsServerlessFunctionCodeEditorOutputParamsState';
import { SettingsServerlessFunctionsOutputMetadataInfo } from '@/settings/serverless-functions/components/SettingsServerlessFunctionsOutputMetadataInfo';
import { Key } from 'ts-key-enum';
import { useHotkeyScopeOnMount } from '~/hooks/useHotkeyScopeOnMount';

const StyledInputsContainer = styled.div`
display: flex;
Expand Down Expand Up @@ -59,6 +66,18 @@ export const SettingsServerlessFunctionTestTab = ({
rightNodes={[<LightCopyIconButton copyText={result} />]}
/>
);
const navigate = useNavigate();
useHotkeyScopeOnMount(
SettingsServerlessFunctionHotkeyScope.ServerlessFunctionTestTab,
);

useScopedHotkeys(
[Key.Escape],
() => {
navigate(getSettingsPagePath(SettingsPath.ServerlessFunctions));
},
SettingsServerlessFunctionHotkeyScope.ServerlessFunctionTestTab,
);

return (
<Section>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export enum SettingsServerlessFunctionHotkeyScope {
ServerlessFunction = 'serverless-function',
ServerlessFunctionNew = 'serverless-function-new',
ServerlessFunctionDetail = 'serverless-function-detail',
ServerlessFunctionSettingsTab = 'serverless-function-settings-tab',
ServerlessFunctionEditorTab = 'serverless-function-editor-tab',
ServerlessFunctionTestTab = 'serverless-function-test-tab',
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ import { useNavigate } from 'react-router-dom';
import { SettingsServerlessFunctionNewForm } from '@/settings/serverless-functions/components/SettingsServerlessFunctionNewForm';
import { useCreateOneServerlessFunction } from '@/settings/serverless-functions/hooks/useCreateOneServerlessFunction';
import { ServerlessFunctionNewFormValues } from '@/settings/serverless-functions/hooks/useServerlessFunctionUpdateFormState';
import { SettingsServerlessFunctionHotkeyScope } from '@/settings/serverless-functions/types/SettingsServerlessFunctionHotKeyScope';
import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
import { SettingsPath } from '@/types/SettingsPath';
import { DEFAULT_CODE } from '@/ui/input/code-editor/components/CodeEditor';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { useState } from 'react';
import { Key } from 'ts-key-enum';
import { IconFunction } from 'twenty-ui';
import { useHotkeyScopeOnMount } from '~/hooks/useHotkeyScopeOnMount';
import { isDefined } from '~/utils/isDefined';

export const SettingsServerlessFunctionsNew = () => {
Expand Down Expand Up @@ -52,6 +56,28 @@ export const SettingsServerlessFunctionsNew = () => {

const canSave = !!formValues.name && createOneServerlessFunction;

useHotkeyScopeOnMount(
SettingsServerlessFunctionHotkeyScope.ServerlessFunctionNew,
);

useScopedHotkeys(
[Key.Enter],
() => {
if (canSave !== false) {
handleSave();
}
},
SettingsServerlessFunctionHotkeyScope.ServerlessFunctionNew,
[canSave],
);
useScopedHotkeys(
[Key.Escape],
() => {
navigate(getSettingsPagePath(SettingsPath.ServerlessFunctions));
},
SettingsServerlessFunctionHotkeyScope.ServerlessFunctionNew,
);

return (
<SubMenuTopBarContainer
Icon={IconFunction}
Expand Down

0 comments on commit 5d8162d

Please sign in to comment.