Refactor hotkyes in its own lib folder (#660)
* Refactor hotkyes in its own lib folder * Lint * Fix PR comments * rename hotkeysScope into hotkeyScope
This commit is contained in:
@ -1,15 +1,15 @@
|
|||||||
import { AnalyticsHook } from './sync-hooks/AnalyticsHook';
|
import { AnalyticsHook } from './sync-hooks/AnalyticsHook';
|
||||||
import { GotoHotkeysHooks } from './sync-hooks/GotoHotkeysHooks';
|
import { GotoHotkeysHooks } from './sync-hooks/GotoHotkeysHooks';
|
||||||
import { HotkeysScopeAutoSyncHook } from './sync-hooks/HotkeysScopeAutoSyncHook';
|
import { HotkeyScopeAutoSyncHook } from './sync-hooks/HotkeyScopeAutoSyncHook';
|
||||||
import { HotkeysScopeBrowserRouterSync } from './sync-hooks/HotkeysScopeBrowserRouterSync';
|
import { HotkeyScopeBrowserRouterSync } from './sync-hooks/HotkeyScopeBrowserRouterSync';
|
||||||
|
|
||||||
export function AppInternalHooks() {
|
export function AppInternalHooks() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<AnalyticsHook />
|
<AnalyticsHook />
|
||||||
<GotoHotkeysHooks />
|
<GotoHotkeysHooks />
|
||||||
<HotkeysScopeAutoSyncHook />
|
<HotkeyScopeAutoSyncHook />
|
||||||
<HotkeysScopeBrowserRouterSync />
|
<HotkeyScopeBrowserRouterSync />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { HotkeysProvider } from 'react-hotkeys-hook';
|
|||||||
import { BrowserRouter } from 'react-router-dom';
|
import { BrowserRouter } from 'react-router-dom';
|
||||||
import { RecoilRoot } from 'recoil';
|
import { RecoilRoot } from 'recoil';
|
||||||
|
|
||||||
import { INITIAL_HOTKEYS_SCOPES } from '@/hotkeys/constants';
|
import { INITIAL_HOTKEYS_SCOPES } from '@/lib/hotkeys/constants';
|
||||||
import { ThemeType } from '@/ui/themes/themes';
|
import { ThemeType } from '@/ui/themes/themes';
|
||||||
|
|
||||||
import '@emotion/react';
|
import '@emotion/react';
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { usePreviousHotkeysScope } from '@/hotkeys/hooks/internal/usePreviousHotkeysScope';
|
import { usePreviousHotkeyScope } from '@/lib/hotkeys/hooks/usePreviousHotkeyScope';
|
||||||
import { useScopedHotkeys } from '@/hotkeys/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/lib/hotkeys/hooks/useScopedHotkeys';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
import { AppHotkeyScope } from '@/lib/hotkeys/types/AppHotkeyScope';
|
||||||
|
|
||||||
import { isCommandMenuOpenedState } from '../states/isCommandMenuOpened';
|
import { isCommandMenuOpenedState } from '../states/isCommandMenuOpened';
|
||||||
|
|
||||||
@ -23,22 +23,22 @@ export function CommandMenu() {
|
|||||||
() => {
|
() => {
|
||||||
handleOpenChange(!open);
|
handleOpenChange(!open);
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.CommandMenu,
|
AppHotkeyScope.CommandMenu,
|
||||||
[setOpen, open, handleOpenChange],
|
[setOpen, open, handleOpenChange],
|
||||||
);
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
setHotkeysScopeAndMemorizePreviousScope,
|
setHotkeyScopeAndMemorizePreviousScope,
|
||||||
goBackToPreviousHotkeysScope,
|
goBackToPreviousHotkeyScope,
|
||||||
} = usePreviousHotkeysScope();
|
} = usePreviousHotkeyScope();
|
||||||
|
|
||||||
function handleOpenChange(newOpenState: boolean) {
|
function handleOpenChange(newOpenState: boolean) {
|
||||||
if (newOpenState) {
|
if (newOpenState) {
|
||||||
setOpen(true);
|
setOpen(true);
|
||||||
setHotkeysScopeAndMemorizePreviousScope(InternalHotkeysScope.CommandMenu);
|
setHotkeyScopeAndMemorizePreviousScope(AppHotkeyScope.CommandMenu);
|
||||||
} else {
|
} else {
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
goBackToPreviousHotkeysScope();
|
goBackToPreviousHotkeyScope();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,13 +11,13 @@ import {
|
|||||||
import { useHandleCheckableCommentThreadTargetChange } from '@/comments/hooks/useHandleCheckableCommentThreadTargetChange';
|
import { useHandleCheckableCommentThreadTargetChange } from '@/comments/hooks/useHandleCheckableCommentThreadTargetChange';
|
||||||
import { CommentableEntityForSelect } from '@/comments/types/CommentableEntityForSelect';
|
import { CommentableEntityForSelect } from '@/comments/types/CommentableEntityForSelect';
|
||||||
import { CompanyChip } from '@/companies/components/CompanyChip';
|
import { CompanyChip } from '@/companies/components/CompanyChip';
|
||||||
import { usePreviousHotkeysScope } from '@/hotkeys/hooks/internal/usePreviousHotkeysScope';
|
import { usePreviousHotkeyScope } from '@/lib/hotkeys/hooks/usePreviousHotkeyScope';
|
||||||
import { useScopedHotkeys } from '@/hotkeys/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/lib/hotkeys/hooks/useScopedHotkeys';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
import { PersonChip } from '@/people/components/PersonChip';
|
import { PersonChip } from '@/people/components/PersonChip';
|
||||||
import { RecoilScope } from '@/recoil-scope/components/RecoilScope';
|
import { RecoilScope } from '@/recoil-scope/components/RecoilScope';
|
||||||
import { MultipleEntitySelect } from '@/relation-picker/components/MultipleEntitySelect';
|
import { MultipleEntitySelect } from '@/relation-picker/components/MultipleEntitySelect';
|
||||||
import { useFilteredSearchEntityQuery } from '@/relation-picker/hooks/useFilteredSearchEntityQuery';
|
import { useFilteredSearchEntityQuery } from '@/relation-picker/hooks/useFilteredSearchEntityQuery';
|
||||||
|
import { RelationPickerHotkeyScope } from '@/relation-picker/types/RelationPickerHotkeyScope';
|
||||||
import { useListenClickOutsideArrayOfRef } from '@/ui/hooks/useListenClickOutsideArrayOfRef';
|
import { useListenClickOutsideArrayOfRef } from '@/ui/hooks/useListenClickOutsideArrayOfRef';
|
||||||
import { flatMapAndSortEntityForSelectArrayOfArrayByName } from '@/ui/utils/flatMapAndSortEntityForSelectArrayByName';
|
import { flatMapAndSortEntityForSelectArrayOfArrayByName } from '@/ui/utils/flatMapAndSortEntityForSelectArrayByName';
|
||||||
import { getLogoUrlFromDomainName } from '@/utils/utils';
|
import { getLogoUrlFromDomainName } from '@/utils/utils';
|
||||||
@ -122,17 +122,17 @@ export function CommentThreadRelationPicker({ commentThread }: OwnProps) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
setHotkeysScopeAndMemorizePreviousScope,
|
setHotkeyScopeAndMemorizePreviousScope,
|
||||||
goBackToPreviousHotkeysScope,
|
goBackToPreviousHotkeyScope,
|
||||||
} = usePreviousHotkeysScope();
|
} = usePreviousHotkeyScope();
|
||||||
|
|
||||||
function handleRelationContainerClick() {
|
function handleRelationContainerClick() {
|
||||||
if (isMenuOpen) {
|
if (isMenuOpen) {
|
||||||
exitEditMode();
|
exitEditMode();
|
||||||
} else {
|
} else {
|
||||||
setIsMenuOpen(true);
|
setIsMenuOpen(true);
|
||||||
setHotkeysScopeAndMemorizePreviousScope(
|
setHotkeyScopeAndMemorizePreviousScope(
|
||||||
InternalHotkeysScope.RelationPicker,
|
RelationPickerHotkeyScope.RelationPicker,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -147,7 +147,7 @@ export function CommentThreadRelationPicker({ commentThread }: OwnProps) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function exitEditMode() {
|
function exitEditMode() {
|
||||||
goBackToPreviousHotkeysScope();
|
goBackToPreviousHotkeyScope();
|
||||||
setIsMenuOpen(false);
|
setIsMenuOpen(false);
|
||||||
setSearchFilter('');
|
setSearchFilter('');
|
||||||
}
|
}
|
||||||
@ -157,7 +157,7 @@ export function CommentThreadRelationPicker({ commentThread }: OwnProps) {
|
|||||||
() => {
|
() => {
|
||||||
exitEditMode();
|
exitEditMode();
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.RelationPicker,
|
RelationPickerHotkeyScope.RelationPicker,
|
||||||
[exitEditMode],
|
[exitEditMode],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { useSetHotkeysScope } from '@/hotkeys/hooks/useSetHotkeysScope';
|
import { useSetHotkeyScope } from '@/lib/hotkeys/hooks/useSetHotkeyScope';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
import { RightDrawerHotkeyScope } from '@/ui/layout/right-drawer/types/RightDrawerHotkeyScope';
|
||||||
import { RightDrawerPages } from '@/ui/layout/right-drawer/types/RightDrawerPages';
|
import { RightDrawerPages } from '@/ui/layout/right-drawer/types/RightDrawerPages';
|
||||||
|
|
||||||
import { useOpenRightDrawer } from '../../ui/layout/right-drawer/hooks/useOpenRightDrawer';
|
import { useOpenRightDrawer } from '../../ui/layout/right-drawer/hooks/useOpenRightDrawer';
|
||||||
@ -12,10 +12,10 @@ export function useOpenCommentThreadRightDrawer() {
|
|||||||
const [, setViewableCommentThreadId] = useRecoilState(
|
const [, setViewableCommentThreadId] = useRecoilState(
|
||||||
viewableCommentThreadIdState,
|
viewableCommentThreadIdState,
|
||||||
);
|
);
|
||||||
const setHotkeysScope = useSetHotkeysScope();
|
const setHotkeyScope = useSetHotkeyScope();
|
||||||
|
|
||||||
return function openCommentThreadRightDrawer(commentThreadId: string) {
|
return function openCommentThreadRightDrawer(commentThreadId: string) {
|
||||||
setHotkeysScope(InternalHotkeysScope.RightDrawer, { goto: false });
|
setHotkeyScope(RightDrawerHotkeyScope.RightDrawer, { goto: false });
|
||||||
setViewableCommentThreadId(commentThreadId);
|
setViewableCommentThreadId(commentThreadId);
|
||||||
openRightDrawer(RightDrawerPages.EditCommentThread);
|
openRightDrawer(RightDrawerPages.EditCommentThread);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -4,9 +4,9 @@ import { v4 } from 'uuid';
|
|||||||
|
|
||||||
import { currentUserState } from '@/auth/states/currentUserState';
|
import { currentUserState } from '@/auth/states/currentUserState';
|
||||||
import { GET_COMPANIES } from '@/companies/services';
|
import { GET_COMPANIES } from '@/companies/services';
|
||||||
import { useSetHotkeysScope } from '@/hotkeys/hooks/useSetHotkeysScope';
|
import { useSetHotkeyScope } from '@/lib/hotkeys/hooks/useSetHotkeyScope';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
import { GET_PEOPLE } from '@/people/services';
|
import { GET_PEOPLE } from '@/people/services';
|
||||||
|
import { RightDrawerHotkeyScope } from '@/ui/layout/right-drawer/types/RightDrawerHotkeyScope';
|
||||||
import { RightDrawerPages } from '@/ui/layout/right-drawer/types/RightDrawerPages';
|
import { RightDrawerPages } from '@/ui/layout/right-drawer/types/RightDrawerPages';
|
||||||
import { selectedRowIdsSelector } from '@/ui/tables/states/selectedRowIdsSelector';
|
import { selectedRowIdsSelector } from '@/ui/tables/states/selectedRowIdsSelector';
|
||||||
import {
|
import {
|
||||||
@ -30,7 +30,7 @@ export function useOpenCreateCommentThreadDrawerForSelectedRowIds() {
|
|||||||
const [, setViewableCommentThreadId] = useRecoilState(
|
const [, setViewableCommentThreadId] = useRecoilState(
|
||||||
viewableCommentThreadIdState,
|
viewableCommentThreadIdState,
|
||||||
);
|
);
|
||||||
const setHotkeysScope = useSetHotkeysScope();
|
const setHotkeyScope = useSetHotkeyScope();
|
||||||
|
|
||||||
const [, setCommentableEntityArray] = useRecoilState(
|
const [, setCommentableEntityArray] = useRecoilState(
|
||||||
commentableEntityArrayState,
|
commentableEntityArrayState,
|
||||||
@ -67,7 +67,7 @@ export function useOpenCreateCommentThreadDrawerForSelectedRowIds() {
|
|||||||
getOperationName(GET_COMMENT_THREADS_BY_TARGETS) ?? '',
|
getOperationName(GET_COMMENT_THREADS_BY_TARGETS) ?? '',
|
||||||
],
|
],
|
||||||
onCompleted(data) {
|
onCompleted(data) {
|
||||||
setHotkeysScope(InternalHotkeysScope.RightDrawer, { goto: false });
|
setHotkeyScope(RightDrawerHotkeyScope.RightDrawer, { goto: false });
|
||||||
setViewableCommentThreadId(data.createOneCommentThread.id);
|
setViewableCommentThreadId(data.createOneCommentThread.id);
|
||||||
setCommentableEntityArray(commentableEntityArray);
|
setCommentableEntityArray(commentableEntityArray);
|
||||||
openRightDrawer(RightDrawerPages.CreateCommentThread);
|
openRightDrawer(RightDrawerPages.CreateCommentThread);
|
||||||
|
|||||||
@ -4,9 +4,9 @@ import { v4 } from 'uuid';
|
|||||||
|
|
||||||
import { currentUserState } from '@/auth/states/currentUserState';
|
import { currentUserState } from '@/auth/states/currentUserState';
|
||||||
import { GET_COMPANIES } from '@/companies/services';
|
import { GET_COMPANIES } from '@/companies/services';
|
||||||
import { useSetHotkeysScope } from '@/hotkeys/hooks/useSetHotkeysScope';
|
import { useSetHotkeyScope } from '@/lib/hotkeys/hooks/useSetHotkeyScope';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
import { GET_PEOPLE } from '@/people/services';
|
import { GET_PEOPLE } from '@/people/services';
|
||||||
|
import { RightDrawerHotkeyScope } from '@/ui/layout/right-drawer/types/RightDrawerHotkeyScope';
|
||||||
import { RightDrawerPages } from '@/ui/layout/right-drawer/types/RightDrawerPages';
|
import { RightDrawerPages } from '@/ui/layout/right-drawer/types/RightDrawerPages';
|
||||||
import { useCreateCommentThreadMutation } from '~/generated/graphql';
|
import { useCreateCommentThreadMutation } from '~/generated/graphql';
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ export function useOpenCreateCommentThreadDrawer() {
|
|||||||
const openRightDrawer = useOpenRightDrawer();
|
const openRightDrawer = useOpenRightDrawer();
|
||||||
const [createCommentThreadMutation] = useCreateCommentThreadMutation();
|
const [createCommentThreadMutation] = useCreateCommentThreadMutation();
|
||||||
const currentUser = useRecoilValue(currentUserState);
|
const currentUser = useRecoilValue(currentUserState);
|
||||||
const setHotkeysScope = useSetHotkeysScope();
|
const setHotkeyScope = useSetHotkeyScope();
|
||||||
|
|
||||||
const [, setCommentableEntityArray] = useRecoilState(
|
const [, setCommentableEntityArray] = useRecoilState(
|
||||||
commentableEntityArrayState,
|
commentableEntityArrayState,
|
||||||
@ -54,7 +54,7 @@ export function useOpenCreateCommentThreadDrawer() {
|
|||||||
getOperationName(GET_COMMENT_THREADS_BY_TARGETS) ?? '',
|
getOperationName(GET_COMMENT_THREADS_BY_TARGETS) ?? '',
|
||||||
],
|
],
|
||||||
onCompleted(data) {
|
onCompleted(data) {
|
||||||
setHotkeysScope(InternalHotkeysScope.RightDrawer, { goto: false });
|
setHotkeyScope(RightDrawerHotkeyScope.RightDrawer, { goto: false });
|
||||||
setViewableCommentThreadId(data.createOneCommentThread.id);
|
setViewableCommentThreadId(data.createOneCommentThread.id);
|
||||||
setCommentableEntityArray([entity]);
|
setCommentableEntityArray([entity]);
|
||||||
openRightDrawer(RightDrawerPages.CreateCommentThread);
|
openRightDrawer(RightDrawerPages.CreateCommentThread);
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { useSetHotkeysScope } from '@/hotkeys/hooks/useSetHotkeysScope';
|
import { useSetHotkeyScope } from '@/lib/hotkeys/hooks/useSetHotkeyScope';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
import { RightDrawerHotkeyScope } from '@/ui/layout/right-drawer/types/RightDrawerHotkeyScope';
|
||||||
import { RightDrawerPages } from '@/ui/layout/right-drawer/types/RightDrawerPages';
|
import { RightDrawerPages } from '@/ui/layout/right-drawer/types/RightDrawerPages';
|
||||||
|
|
||||||
import { useOpenRightDrawer } from '../../ui/layout/right-drawer/hooks/useOpenRightDrawer';
|
import { useOpenRightDrawer } from '../../ui/layout/right-drawer/hooks/useOpenRightDrawer';
|
||||||
@ -14,12 +14,12 @@ export function useOpenTimelineRightDrawer() {
|
|||||||
const [, setCommentableEntityArray] = useRecoilState(
|
const [, setCommentableEntityArray] = useRecoilState(
|
||||||
commentableEntityArrayState,
|
commentableEntityArrayState,
|
||||||
);
|
);
|
||||||
const setHotkeysScope = useSetHotkeysScope();
|
const setHotkeyScope = useSetHotkeyScope();
|
||||||
|
|
||||||
return function openTimelineRightDrawer(
|
return function openTimelineRightDrawer(
|
||||||
commentableEntityArray: CommentableEntity[],
|
commentableEntityArray: CommentableEntity[],
|
||||||
) {
|
) {
|
||||||
setHotkeysScope(InternalHotkeysScope.RightDrawer, { goto: false });
|
setHotkeyScope(RightDrawerHotkeyScope.RightDrawer, { goto: false });
|
||||||
setCommentableEntityArray(commentableEntityArray);
|
setCommentableEntityArray(commentableEntityArray);
|
||||||
openRightDrawer(RightDrawerPages.Timeline);
|
openRightDrawer(RightDrawerPages.Timeline);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
import { PersonChip } from '@/people/components/PersonChip';
|
import { PersonChip } from '@/people/components/PersonChip';
|
||||||
|
import { RelationPickerHotkeyScope } from '@/relation-picker/types/RelationPickerHotkeyScope';
|
||||||
import { EditableCell } from '@/ui/components/editable-cell/EditableCell';
|
import { EditableCell } from '@/ui/components/editable-cell/EditableCell';
|
||||||
import { Company, User } from '~/generated/graphql';
|
import { Company, User } from '~/generated/graphql';
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ export type OwnProps = {
|
|||||||
export function CompanyAccountOwnerCell({ company }: OwnProps) {
|
export function CompanyAccountOwnerCell({ company }: OwnProps) {
|
||||||
return (
|
return (
|
||||||
<EditableCell
|
<EditableCell
|
||||||
editHotkeysScope={{ scope: InternalHotkeysScope.RelationPicker }}
|
editHotkeyScope={{ scope: RelationPickerHotkeyScope.RelationPicker }}
|
||||||
editModeContent={<CompanyAccountOwnerPicker company={company} />}
|
editModeContent={<CompanyAccountOwnerPicker company={company} />}
|
||||||
nonEditModeContent={
|
nonEditModeContent={
|
||||||
company.accountOwner?.displayName ? (
|
company.accountOwner?.displayName ? (
|
||||||
|
|||||||
@ -1,23 +0,0 @@
|
|||||||
import { CustomHotkeysScopes } from '../types/internal/CustomHotkeysScope';
|
|
||||||
import { HotkeysScope } from '../types/internal/HotkeysScope';
|
|
||||||
import { InternalHotkeysScope } from '../types/internal/InternalHotkeysScope';
|
|
||||||
|
|
||||||
export const INITIAL_HOTKEYS_SCOPES: string[] = [InternalHotkeysScope.App];
|
|
||||||
|
|
||||||
export const ALWAYS_ON_HOTKEYS_SCOPES: string[] = [
|
|
||||||
InternalHotkeysScope.CommandMenu,
|
|
||||||
InternalHotkeysScope.App,
|
|
||||||
];
|
|
||||||
|
|
||||||
export const DEFAULT_HOTKEYS_SCOPE_CUSTOM_SCOPES: CustomHotkeysScopes = {
|
|
||||||
commandMenu: true,
|
|
||||||
goto: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const INITIAL_HOTKEYS_SCOPE: HotkeysScope = {
|
|
||||||
scope: InternalHotkeysScope.App,
|
|
||||||
customScopes: {
|
|
||||||
commandMenu: true,
|
|
||||||
goto: true,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
import { useEffect } from 'react';
|
|
||||||
import { useRecoilValue } from 'recoil';
|
|
||||||
|
|
||||||
import { currentHotkeysScopeState } from '@/hotkeys/states/internal/currentHotkeysScopeState';
|
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
|
|
||||||
import { useHotkeysScopes } from './useHotkeysScopes';
|
|
||||||
|
|
||||||
export function useHotkeysScopeAutoSync() {
|
|
||||||
const { setHotkeysScopes } = useHotkeysScopes();
|
|
||||||
|
|
||||||
const currentHotkeysScope = useRecoilValue(currentHotkeysScopeState);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const scopesToSet: string[] = [];
|
|
||||||
|
|
||||||
if (currentHotkeysScope.customScopes?.commandMenu) {
|
|
||||||
scopesToSet.push(InternalHotkeysScope.CommandMenu);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentHotkeysScope?.customScopes?.goto) {
|
|
||||||
scopesToSet.push(InternalHotkeysScope.Goto);
|
|
||||||
}
|
|
||||||
|
|
||||||
scopesToSet.push(currentHotkeysScope.scope);
|
|
||||||
|
|
||||||
setHotkeysScopes(scopesToSet);
|
|
||||||
}, [setHotkeysScopes, currentHotkeysScope]);
|
|
||||||
}
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
import { useState } from 'react';
|
|
||||||
import { useRecoilValue } from 'recoil';
|
|
||||||
|
|
||||||
import { currentHotkeysScopeState } from '@/hotkeys/states/internal/currentHotkeysScopeState';
|
|
||||||
import { CustomHotkeysScopes } from '@/hotkeys/types/internal/CustomHotkeysScope';
|
|
||||||
import { HotkeysScope } from '@/hotkeys/types/internal/HotkeysScope';
|
|
||||||
|
|
||||||
import { useSetHotkeysScope } from '../useSetHotkeysScope';
|
|
||||||
|
|
||||||
export function usePreviousHotkeysScope() {
|
|
||||||
const [previousHotkeysScope, setPreviousHotkeysScope] =
|
|
||||||
useState<HotkeysScope | null>();
|
|
||||||
|
|
||||||
const setHotkeysScope = useSetHotkeysScope();
|
|
||||||
|
|
||||||
const currentHotkeysScope = useRecoilValue(currentHotkeysScopeState);
|
|
||||||
|
|
||||||
function goBackToPreviousHotkeysScope() {
|
|
||||||
if (previousHotkeysScope) {
|
|
||||||
setHotkeysScope(
|
|
||||||
previousHotkeysScope.scope,
|
|
||||||
previousHotkeysScope.customScopes,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setHotkeysScopeAndMemorizePreviousScope(
|
|
||||||
scope: string,
|
|
||||||
customScopes?: CustomHotkeysScopes,
|
|
||||||
) {
|
|
||||||
setPreviousHotkeysScope(currentHotkeysScope);
|
|
||||||
setHotkeysScope(scope, customScopes);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
setHotkeysScopeAndMemorizePreviousScope,
|
|
||||||
goBackToPreviousHotkeysScope,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
import { atom } from 'recoil';
|
|
||||||
|
|
||||||
import { INITIAL_HOTKEYS_SCOPE } from '@/hotkeys/constants';
|
|
||||||
import { HotkeysScope } from '@/hotkeys/types/internal/HotkeysScope';
|
|
||||||
|
|
||||||
export const currentHotkeysScopeState = atom<HotkeysScope>({
|
|
||||||
key: 'currentHotkeysScopeState',
|
|
||||||
default: INITIAL_HOTKEYS_SCOPE,
|
|
||||||
});
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
import { CustomHotkeysScopes } from './CustomHotkeysScope';
|
|
||||||
|
|
||||||
export type HotkeysScope = {
|
|
||||||
scope: string;
|
|
||||||
customScopes?: CustomHotkeysScopes;
|
|
||||||
};
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
export enum InternalHotkeysScope {
|
|
||||||
App = 'app',
|
|
||||||
Goto = 'goto',
|
|
||||||
CommandMenu = 'command-menu',
|
|
||||||
Table = 'table',
|
|
||||||
TableSoftFocus = 'table-soft-focus',
|
|
||||||
CellEditMode = 'cell-edit-mode',
|
|
||||||
CellDateEditMode = 'cell-date-edit-mode',
|
|
||||||
BoardCardFieldEditMode = 'board-card-field-edit-mode',
|
|
||||||
RightDrawer = 'right-drawer',
|
|
||||||
TableHeaderDropdownButton = 'table-header-dropdown-button',
|
|
||||||
RelationPicker = 'relation-picker',
|
|
||||||
CellDoubleTextInput = 'cell-double-text-input',
|
|
||||||
TextInput = 'text-input',
|
|
||||||
Settings = 'settings',
|
|
||||||
CreateWokspace = 'create-workspace',
|
|
||||||
PasswordLogin = 'password-login',
|
|
||||||
AuthIndex = 'auth-index',
|
|
||||||
CreateProfile = 'create-profile',
|
|
||||||
ShowPage = 'show-page',
|
|
||||||
}
|
|
||||||
@ -2,12 +2,13 @@ import { ReactNode, useRef } from 'react';
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { Key } from 'ts-key-enum';
|
import { Key } from 'ts-key-enum';
|
||||||
|
|
||||||
import { useScopedHotkeys } from '@/hotkeys/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/lib/hotkeys/hooks/useScopedHotkeys';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
import { useOutsideAlerter } from '@/ui/hooks/useOutsideAlerter';
|
import { useOutsideAlerter } from '@/ui/hooks/useOutsideAlerter';
|
||||||
import { IconChevronDown } from '@/ui/icons/index';
|
import { IconChevronDown } from '@/ui/icons/index';
|
||||||
import { overlayBackground, textInputStyle } from '@/ui/themes/effects';
|
import { overlayBackground, textInputStyle } from '@/ui/themes/effects';
|
||||||
|
|
||||||
|
import { FiltersHotkeyScope } from '../types/FiltersHotkeyScope';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
label: string;
|
label: string;
|
||||||
isActive: boolean;
|
isActive: boolean;
|
||||||
@ -15,7 +16,7 @@ type OwnProps = {
|
|||||||
isUnfolded?: boolean;
|
isUnfolded?: boolean;
|
||||||
onIsUnfoldedChange?: (newIsUnfolded: boolean) => void;
|
onIsUnfoldedChange?: (newIsUnfolded: boolean) => void;
|
||||||
resetState?: () => void;
|
resetState?: () => void;
|
||||||
hotkeysScope: InternalHotkeysScope;
|
HotkeyScope: FiltersHotkeyScope;
|
||||||
};
|
};
|
||||||
|
|
||||||
const StyledDropdownButtonContainer = styled.div`
|
const StyledDropdownButtonContainer = styled.div`
|
||||||
@ -160,14 +161,14 @@ function DropdownButton({
|
|||||||
children,
|
children,
|
||||||
isUnfolded = false,
|
isUnfolded = false,
|
||||||
onIsUnfoldedChange,
|
onIsUnfoldedChange,
|
||||||
hotkeysScope,
|
HotkeyScope,
|
||||||
}: OwnProps) {
|
}: OwnProps) {
|
||||||
useScopedHotkeys(
|
useScopedHotkeys(
|
||||||
[Key.Enter, Key.Escape],
|
[Key.Enter, Key.Escape],
|
||||||
() => {
|
() => {
|
||||||
onIsUnfoldedChange?.(false);
|
onIsUnfoldedChange?.(false);
|
||||||
},
|
},
|
||||||
hotkeysScope,
|
HotkeyScope,
|
||||||
[onIsUnfoldedChange],
|
[onIsUnfoldedChange],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -1,15 +1,17 @@
|
|||||||
import { Context, useCallback, useState } from 'react';
|
import { Context, useCallback, useState } from 'react';
|
||||||
import { Key } from 'ts-key-enum';
|
import { Key } from 'ts-key-enum';
|
||||||
|
|
||||||
import { useScopedHotkeys } from '@/hotkeys/hooks/useScopedHotkeys';
|
|
||||||
import { useSetHotkeysScope } from '@/hotkeys/hooks/useSetHotkeysScope';
|
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
import { filterDefinitionUsedInDropdownScopedState } from '@/lib/filters-and-sorts/states/filterDefinitionUsedInDropdownScopedState';
|
import { filterDefinitionUsedInDropdownScopedState } from '@/lib/filters-and-sorts/states/filterDefinitionUsedInDropdownScopedState';
|
||||||
import { filterDropdownSearchInputScopedState } from '@/lib/filters-and-sorts/states/filterDropdownSearchInputScopedState';
|
import { filterDropdownSearchInputScopedState } from '@/lib/filters-and-sorts/states/filterDropdownSearchInputScopedState';
|
||||||
import { filtersScopedState } from '@/lib/filters-and-sorts/states/filtersScopedState';
|
import { filtersScopedState } from '@/lib/filters-and-sorts/states/filtersScopedState';
|
||||||
import { isFilterDropdownOperandSelectUnfoldedScopedState } from '@/lib/filters-and-sorts/states/isFilterDropdownOperandSelectUnfoldedScopedState';
|
import { isFilterDropdownOperandSelectUnfoldedScopedState } from '@/lib/filters-and-sorts/states/isFilterDropdownOperandSelectUnfoldedScopedState';
|
||||||
import { selectedOperandInDropdownScopedState } from '@/lib/filters-and-sorts/states/selectedOperandInDropdownScopedState';
|
import { selectedOperandInDropdownScopedState } from '@/lib/filters-and-sorts/states/selectedOperandInDropdownScopedState';
|
||||||
|
import { useScopedHotkeys } from '@/lib/hotkeys/hooks/useScopedHotkeys';
|
||||||
|
import { useSetHotkeyScope } from '@/lib/hotkeys/hooks/useSetHotkeyScope';
|
||||||
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
||||||
|
import { RelationPickerHotkeyScope } from '@/relation-picker/types/RelationPickerHotkeyScope';
|
||||||
|
|
||||||
|
import { FiltersHotkeyScope } from '../types/FiltersHotkeyScope';
|
||||||
|
|
||||||
import DropdownButton from './DropdownButton';
|
import DropdownButton from './DropdownButton';
|
||||||
import { FilterDropdownDateSearchInput } from './FilterDropdownDateSearchInput';
|
import { FilterDropdownDateSearchInput } from './FilterDropdownDateSearchInput';
|
||||||
@ -23,10 +25,10 @@ import { FilterDropdownTextSearchInput } from './FilterDropdownTextSearchInput';
|
|||||||
|
|
||||||
export function FilterDropdownButton({
|
export function FilterDropdownButton({
|
||||||
context,
|
context,
|
||||||
hotkeysScope,
|
HotkeyScope,
|
||||||
}: {
|
}: {
|
||||||
context: Context<string | null>;
|
context: Context<string | null>;
|
||||||
hotkeysScope: InternalHotkeysScope;
|
HotkeyScope: FiltersHotkeyScope;
|
||||||
}) {
|
}) {
|
||||||
const [isUnfolded, setIsUnfolded] = useState(false);
|
const [isUnfolded, setIsUnfolded] = useState(false);
|
||||||
|
|
||||||
@ -65,15 +67,15 @@ export function FilterDropdownButton({
|
|||||||
|
|
||||||
const isFilterSelected = (filters?.length ?? 0) > 0;
|
const isFilterSelected = (filters?.length ?? 0) > 0;
|
||||||
|
|
||||||
const setHotkeysScope = useSetHotkeysScope();
|
const setHotkeyScope = useSetHotkeyScope();
|
||||||
|
|
||||||
function handleIsUnfoldedChange(newIsUnfolded: boolean) {
|
function handleIsUnfoldedChange(newIsUnfolded: boolean) {
|
||||||
if (newIsUnfolded) {
|
if (newIsUnfolded) {
|
||||||
setHotkeysScope(hotkeysScope);
|
setHotkeyScope(HotkeyScope);
|
||||||
setIsUnfolded(true);
|
setIsUnfolded(true);
|
||||||
} else {
|
} else {
|
||||||
if (filterDefinitionUsedInDropdown?.type === 'entity') {
|
if (filterDefinitionUsedInDropdown?.type === 'entity') {
|
||||||
setHotkeysScope(hotkeysScope);
|
setHotkeyScope(HotkeyScope);
|
||||||
}
|
}
|
||||||
setIsUnfolded(false);
|
setIsUnfolded(false);
|
||||||
resetState();
|
resetState();
|
||||||
@ -85,7 +87,7 @@ export function FilterDropdownButton({
|
|||||||
() => {
|
() => {
|
||||||
handleIsUnfoldedChange(false);
|
handleIsUnfoldedChange(false);
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.RelationPicker,
|
RelationPickerHotkeyScope.RelationPicker,
|
||||||
[handleIsUnfoldedChange],
|
[handleIsUnfoldedChange],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -95,7 +97,7 @@ export function FilterDropdownButton({
|
|||||||
isActive={isFilterSelected}
|
isActive={isFilterSelected}
|
||||||
isUnfolded={isUnfolded}
|
isUnfolded={isUnfolded}
|
||||||
onIsUnfoldedChange={handleIsUnfoldedChange}
|
onIsUnfoldedChange={handleIsUnfoldedChange}
|
||||||
hotkeysScope={hotkeysScope}
|
HotkeyScope={HotkeyScope}
|
||||||
>
|
>
|
||||||
{!filterDefinitionUsedInDropdown ? (
|
{!filterDefinitionUsedInDropdown ? (
|
||||||
<FilterDropdownFilterSelect context={context} />
|
<FilterDropdownFilterSelect context={context} />
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
import { Context } from 'react';
|
import { Context } from 'react';
|
||||||
|
|
||||||
import { useSetHotkeysScope } from '@/hotkeys/hooks/useSetHotkeysScope';
|
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
import { availableFiltersScopedState } from '@/lib/filters-and-sorts/states/availableFiltersScopedState';
|
import { availableFiltersScopedState } from '@/lib/filters-and-sorts/states/availableFiltersScopedState';
|
||||||
import { filterDefinitionUsedInDropdownScopedState } from '@/lib/filters-and-sorts/states/filterDefinitionUsedInDropdownScopedState';
|
import { filterDefinitionUsedInDropdownScopedState } from '@/lib/filters-and-sorts/states/filterDefinitionUsedInDropdownScopedState';
|
||||||
import { filterDropdownSearchInputScopedState } from '@/lib/filters-and-sorts/states/filterDropdownSearchInputScopedState';
|
import { filterDropdownSearchInputScopedState } from '@/lib/filters-and-sorts/states/filterDropdownSearchInputScopedState';
|
||||||
import { selectedOperandInDropdownScopedState } from '@/lib/filters-and-sorts/states/selectedOperandInDropdownScopedState';
|
import { selectedOperandInDropdownScopedState } from '@/lib/filters-and-sorts/states/selectedOperandInDropdownScopedState';
|
||||||
import { getOperandsForFilterType } from '@/lib/filters-and-sorts/utils/getOperandsForFilterType';
|
import { getOperandsForFilterType } from '@/lib/filters-and-sorts/utils/getOperandsForFilterType';
|
||||||
|
import { useSetHotkeyScope } from '@/lib/hotkeys/hooks/useSetHotkeyScope';
|
||||||
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
||||||
import { useRecoilScopedValue } from '@/recoil-scope/hooks/useRecoilScopedValue';
|
import { useRecoilScopedValue } from '@/recoil-scope/hooks/useRecoilScopedValue';
|
||||||
|
import { RelationPickerHotkeyScope } from '@/relation-picker/types/RelationPickerHotkeyScope';
|
||||||
import { DropdownMenuItemContainer } from '@/ui/components/menu/DropdownMenuItemContainer';
|
import { DropdownMenuItemContainer } from '@/ui/components/menu/DropdownMenuItemContainer';
|
||||||
import { DropdownMenuSelectableItem } from '@/ui/components/menu/DropdownMenuSelectableItem';
|
import { DropdownMenuSelectableItem } from '@/ui/components/menu/DropdownMenuSelectableItem';
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ export function FilterDropdownFilterSelect({
|
|||||||
context,
|
context,
|
||||||
);
|
);
|
||||||
|
|
||||||
const setHotkeysScope = useSetHotkeysScope();
|
const setHotkeyScope = useSetHotkeyScope();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownMenuItemContainer style={{ maxHeight: '300px' }}>
|
<DropdownMenuItemContainer style={{ maxHeight: '300px' }}>
|
||||||
@ -50,7 +50,7 @@ export function FilterDropdownFilterSelect({
|
|||||||
setFilterDefinitionUsedInDropdown(availableFilter);
|
setFilterDefinitionUsedInDropdown(availableFilter);
|
||||||
|
|
||||||
if (availableFilter.type === 'entity') {
|
if (availableFilter.type === 'entity') {
|
||||||
setHotkeysScope(InternalHotkeysScope.RelationPicker);
|
setHotkeyScope(RelationPickerHotkeyScope.RelationPicker);
|
||||||
}
|
}
|
||||||
|
|
||||||
setSelectedOperandInDropdown(
|
setSelectedOperandInDropdown(
|
||||||
|
|||||||
@ -1,18 +1,19 @@
|
|||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
|
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
import {
|
import {
|
||||||
SelectedSortType,
|
SelectedSortType,
|
||||||
SortType,
|
SortType,
|
||||||
} from '@/lib/filters-and-sorts/interfaces/sorts/interface';
|
} from '@/lib/filters-and-sorts/interfaces/sorts/interface';
|
||||||
|
|
||||||
|
import { FiltersHotkeyScope } from '../types/FiltersHotkeyScope';
|
||||||
|
|
||||||
import DropdownButton from './DropdownButton';
|
import DropdownButton from './DropdownButton';
|
||||||
|
|
||||||
type OwnProps<SortField> = {
|
type OwnProps<SortField> = {
|
||||||
isSortSelected: boolean;
|
isSortSelected: boolean;
|
||||||
onSortSelect: (sort: SelectedSortType<SortField>) => void;
|
onSortSelect: (sort: SelectedSortType<SortField>) => void;
|
||||||
availableSorts: SortType<SortField>[];
|
availableSorts: SortType<SortField>[];
|
||||||
hotkeysScope: InternalHotkeysScope;
|
HotkeyScope: FiltersHotkeyScope;
|
||||||
};
|
};
|
||||||
|
|
||||||
const options: Array<SelectedSortType<any>['order']> = ['asc', 'desc'];
|
const options: Array<SelectedSortType<any>['order']> = ['asc', 'desc'];
|
||||||
@ -21,7 +22,7 @@ export function SortDropdownButton<SortField>({
|
|||||||
isSortSelected,
|
isSortSelected,
|
||||||
availableSorts,
|
availableSorts,
|
||||||
onSortSelect,
|
onSortSelect,
|
||||||
hotkeysScope,
|
HotkeyScope,
|
||||||
}: OwnProps<SortField>) {
|
}: OwnProps<SortField>) {
|
||||||
const [isUnfolded, setIsUnfolded] = useState(false);
|
const [isUnfolded, setIsUnfolded] = useState(false);
|
||||||
|
|
||||||
@ -57,7 +58,7 @@ export function SortDropdownButton<SortField>({
|
|||||||
isActive={isSortSelected}
|
isActive={isSortSelected}
|
||||||
isUnfolded={isUnfolded}
|
isUnfolded={isUnfolded}
|
||||||
onIsUnfoldedChange={handleIsUnfoldedChange}
|
onIsUnfoldedChange={handleIsUnfoldedChange}
|
||||||
hotkeysScope={hotkeysScope}
|
HotkeyScope={HotkeyScope}
|
||||||
>
|
>
|
||||||
{isOptionUnfolded
|
{isOptionUnfolded
|
||||||
? options.map((option, index) => (
|
? options.map((option, index) => (
|
||||||
|
|||||||
@ -0,0 +1,3 @@
|
|||||||
|
export enum FiltersHotkeyScope {
|
||||||
|
FilterDropdownButton = 'filter-dropdown-button',
|
||||||
|
}
|
||||||
23
front/src/modules/lib/hotkeys/constants/index.ts
Normal file
23
front/src/modules/lib/hotkeys/constants/index.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { AppHotkeyScope } from '../types/AppHotkeyScope';
|
||||||
|
import { CustomHotkeyScopes } from '../types/CustomHotkeyScope';
|
||||||
|
import { HotkeyScope } from '../types/HotkeyScope';
|
||||||
|
|
||||||
|
export const INITIAL_HOTKEYS_SCOPES: string[] = [AppHotkeyScope.App];
|
||||||
|
|
||||||
|
export const ALWAYS_ON_HOTKEYS_SCOPES: string[] = [
|
||||||
|
AppHotkeyScope.CommandMenu,
|
||||||
|
AppHotkeyScope.App,
|
||||||
|
];
|
||||||
|
|
||||||
|
export const DEFAULT_HOTKEYS_SCOPE_CUSTOM_SCOPES: CustomHotkeyScopes = {
|
||||||
|
commandMenu: true,
|
||||||
|
goto: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const INITIAL_HOTKEYS_SCOPE: HotkeyScope = {
|
||||||
|
scope: AppHotkeyScope.App,
|
||||||
|
customScopes: {
|
||||||
|
commandMenu: true,
|
||||||
|
goto: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
|
import { currentHotkeyScopeState } from '@/lib/hotkeys/states/internal/currentHotkeyScopeState';
|
||||||
|
|
||||||
|
import { AppHotkeyScope } from '../../types/AppHotkeyScope';
|
||||||
|
|
||||||
|
import { useHotkeyScopes } from './useHotkeyScopes';
|
||||||
|
|
||||||
|
export function useHotkeyScopeAutoSync() {
|
||||||
|
const { setHotkeyScopes } = useHotkeyScopes();
|
||||||
|
|
||||||
|
const currentHotkeyScope = useRecoilValue(currentHotkeyScopeState);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const scopesToSet: string[] = [];
|
||||||
|
|
||||||
|
if (currentHotkeyScope.customScopes?.commandMenu) {
|
||||||
|
scopesToSet.push(AppHotkeyScope.CommandMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentHotkeyScope?.customScopes?.goto) {
|
||||||
|
scopesToSet.push(AppHotkeyScope.Goto);
|
||||||
|
}
|
||||||
|
|
||||||
|
scopesToSet.push(currentHotkeyScope.scope);
|
||||||
|
|
||||||
|
setHotkeyScopes(scopesToSet);
|
||||||
|
}, [setHotkeyScopes, currentHotkeyScope]);
|
||||||
|
}
|
||||||
@ -1,12 +1,12 @@
|
|||||||
import { useHotkeysContext } from 'react-hotkeys-hook';
|
import { useHotkeysContext } from 'react-hotkeys-hook';
|
||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
import { internalHotkeysEnabledScopesState } from '@/hotkeys/states/internal/internalHotkeysEnabledScopesState';
|
import { internalHotkeysEnabledScopesState } from '../../states/internal/internalHotkeysEnabledScopesState';
|
||||||
|
|
||||||
export function useHotkeysScopes() {
|
export function useHotkeyScopes() {
|
||||||
const { disableScope, enableScope } = useHotkeysContext();
|
const { disableScope, enableScope } = useHotkeysContext();
|
||||||
|
|
||||||
const disableAllHotkeysScopes = useRecoilCallback(
|
const disableAllHotkeyScopes = useRecoilCallback(
|
||||||
({ set, snapshot }) => {
|
({ set, snapshot }) => {
|
||||||
return async () => {
|
return async () => {
|
||||||
const enabledScopes = await snapshot.getPromise(
|
const enabledScopes = await snapshot.getPromise(
|
||||||
@ -23,7 +23,7 @@ export function useHotkeysScopes() {
|
|||||||
[disableScope],
|
[disableScope],
|
||||||
);
|
);
|
||||||
|
|
||||||
const enableHotkeysScope = useRecoilCallback(
|
const enableHotkeyScope = useRecoilCallback(
|
||||||
({ set, snapshot }) => {
|
({ set, snapshot }) => {
|
||||||
return async (scopeToEnable: string) => {
|
return async (scopeToEnable: string) => {
|
||||||
const enabledScopes = await snapshot.getPromise(
|
const enabledScopes = await snapshot.getPromise(
|
||||||
@ -42,7 +42,7 @@ export function useHotkeysScopes() {
|
|||||||
[enableScope],
|
[enableScope],
|
||||||
);
|
);
|
||||||
|
|
||||||
const disableHotkeysScope = useRecoilCallback(
|
const disableHotkeyScope = useRecoilCallback(
|
||||||
({ set, snapshot }) => {
|
({ set, snapshot }) => {
|
||||||
return async (scopeToDisable: string) => {
|
return async (scopeToDisable: string) => {
|
||||||
const enabledScopes = await snapshot.getPromise(
|
const enabledScopes = await snapshot.getPromise(
|
||||||
@ -65,7 +65,7 @@ export function useHotkeysScopes() {
|
|||||||
[disableScope],
|
[disableScope],
|
||||||
);
|
);
|
||||||
|
|
||||||
const setHotkeysScopes = useRecoilCallback(
|
const setHotkeyScopes = useRecoilCallback(
|
||||||
({ set, snapshot }) => {
|
({ set, snapshot }) => {
|
||||||
return async (scopesToSet: string[]) => {
|
return async (scopesToSet: string[]) => {
|
||||||
const enabledScopes = await snapshot.getPromise(
|
const enabledScopes = await snapshot.getPromise(
|
||||||
@ -95,9 +95,9 @@ export function useHotkeysScopes() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
disableAllHotkeysScopes,
|
disableAllHotkeyScopes,
|
||||||
enableHotkeysScope,
|
enableHotkeyScope,
|
||||||
disableHotkeysScope,
|
disableHotkeyScope,
|
||||||
setHotkeysScopes,
|
setHotkeyScopes,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import { Keys } from 'react-hotkeys-hook/dist/types';
|
import { Keys } from 'react-hotkeys-hook/dist/types';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
import { InternalHotkeysScope } from '../types/internal/InternalHotkeysScope';
|
import { AppHotkeyScope } from '../types/AppHotkeyScope';
|
||||||
|
|
||||||
import { useSequenceHotkeys } from './useSequenceScopedHotkeys';
|
import { useSequenceHotkeys } from './useSequenceScopedHotkeys';
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ export function useGoToHotkeys(key: Keys, location: string) {
|
|||||||
() => {
|
() => {
|
||||||
navigate(location);
|
navigate(location);
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.Goto,
|
AppHotkeyScope.Goto,
|
||||||
{
|
{
|
||||||
enableOnContentEditable: true,
|
enableOnContentEditable: true,
|
||||||
enableOnFormTags: true,
|
enableOnFormTags: true,
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
import { useState } from 'react';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
|
import { currentHotkeyScopeState } from '../states/internal/currentHotkeyScopeState';
|
||||||
|
import { CustomHotkeyScopes } from '../types/CustomHotkeyScope';
|
||||||
|
import { HotkeyScope } from '../types/HotkeyScope';
|
||||||
|
|
||||||
|
import { useSetHotkeyScope } from './useSetHotkeyScope';
|
||||||
|
|
||||||
|
export function usePreviousHotkeyScope() {
|
||||||
|
const [previousHotkeyScope, setPreviousHotkeyScope] =
|
||||||
|
useState<HotkeyScope | null>();
|
||||||
|
|
||||||
|
const setHotkeyScope = useSetHotkeyScope();
|
||||||
|
|
||||||
|
const currentHotkeyScope = useRecoilValue(currentHotkeyScopeState);
|
||||||
|
|
||||||
|
function goBackToPreviousHotkeyScope() {
|
||||||
|
if (previousHotkeyScope) {
|
||||||
|
setHotkeyScope(
|
||||||
|
previousHotkeyScope.scope,
|
||||||
|
previousHotkeyScope.customScopes,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setHotkeyScopeAndMemorizePreviousScope(
|
||||||
|
scope: string,
|
||||||
|
customScopes?: CustomHotkeyScopes,
|
||||||
|
) {
|
||||||
|
setPreviousHotkeyScope(currentHotkeyScope);
|
||||||
|
setHotkeyScope(scope, customScopes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
setHotkeyScopeAndMemorizePreviousScope,
|
||||||
|
goBackToPreviousHotkeyScope,
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -3,12 +3,12 @@ import { useRecoilCallback } from 'recoil';
|
|||||||
import { isDefined } from '@/utils/type-guards/isDefined';
|
import { isDefined } from '@/utils/type-guards/isDefined';
|
||||||
|
|
||||||
import { DEFAULT_HOTKEYS_SCOPE_CUSTOM_SCOPES } from '../constants';
|
import { DEFAULT_HOTKEYS_SCOPE_CUSTOM_SCOPES } from '../constants';
|
||||||
import { currentHotkeysScopeState } from '../states/internal/currentHotkeysScopeState';
|
import { currentHotkeyScopeState } from '../states/internal/currentHotkeyScopeState';
|
||||||
import { CustomHotkeysScopes } from '../types/internal/CustomHotkeysScope';
|
import { CustomHotkeyScopes } from '../types/CustomHotkeyScope';
|
||||||
|
|
||||||
function isCustomScopesEqual(
|
function isCustomScopesEqual(
|
||||||
customScopesA: CustomHotkeysScopes | undefined,
|
customScopesA: CustomHotkeyScopes | undefined,
|
||||||
customScopesB: CustomHotkeysScopes | undefined,
|
customScopesB: CustomHotkeyScopes | undefined,
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
customScopesA?.commandMenu === customScopesB?.commandMenu &&
|
customScopesA?.commandMenu === customScopesB?.commandMenu &&
|
||||||
@ -16,19 +16,19 @@ function isCustomScopesEqual(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useSetHotkeysScope() {
|
export function useSetHotkeyScope() {
|
||||||
return useRecoilCallback(
|
return useRecoilCallback(
|
||||||
({ snapshot, set }) =>
|
({ snapshot, set }) =>
|
||||||
async (hotkeysScopeToSet: string, customScopes?: CustomHotkeysScopes) => {
|
async (HotkeyScopeToSet: string, customScopes?: CustomHotkeyScopes) => {
|
||||||
const currentHotkeysScope = await snapshot.getPromise(
|
const currentHotkeyScope = await snapshot.getPromise(
|
||||||
currentHotkeysScopeState,
|
currentHotkeyScopeState,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (currentHotkeysScope.scope === hotkeysScopeToSet) {
|
if (currentHotkeyScope.scope === HotkeyScopeToSet) {
|
||||||
if (!isDefined(customScopes)) {
|
if (!isDefined(customScopes)) {
|
||||||
if (
|
if (
|
||||||
isCustomScopesEqual(
|
isCustomScopesEqual(
|
||||||
currentHotkeysScope?.customScopes,
|
currentHotkeyScope?.customScopes,
|
||||||
DEFAULT_HOTKEYS_SCOPE_CUSTOM_SCOPES,
|
DEFAULT_HOTKEYS_SCOPE_CUSTOM_SCOPES,
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
@ -37,7 +37,7 @@ export function useSetHotkeysScope() {
|
|||||||
} else {
|
} else {
|
||||||
if (
|
if (
|
||||||
isCustomScopesEqual(
|
isCustomScopesEqual(
|
||||||
currentHotkeysScope?.customScopes,
|
currentHotkeyScope?.customScopes,
|
||||||
customScopes,
|
customScopes,
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
@ -46,8 +46,8 @@ export function useSetHotkeysScope() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set(currentHotkeysScopeState, {
|
set(currentHotkeyScopeState, {
|
||||||
scope: hotkeysScopeToSet,
|
scope: HotkeyScopeToSet,
|
||||||
customScopes: {
|
customScopes: {
|
||||||
commandMenu: customScopes?.commandMenu ?? true,
|
commandMenu: customScopes?.commandMenu ?? true,
|
||||||
goto: customScopes?.goto ?? false,
|
goto: customScopes?.goto ?? false,
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
import { atom } from 'recoil';
|
||||||
|
|
||||||
|
import { INITIAL_HOTKEYS_SCOPE } from '../../constants';
|
||||||
|
import { HotkeyScope } from '../../types/HotkeyScope';
|
||||||
|
|
||||||
|
export const currentHotkeyScopeState = atom<HotkeyScope>({
|
||||||
|
key: 'currentHotkeyScopeState',
|
||||||
|
default: INITIAL_HOTKEYS_SCOPE,
|
||||||
|
});
|
||||||
5
front/src/modules/lib/hotkeys/types/AppHotkeyScope.ts
Normal file
5
front/src/modules/lib/hotkeys/types/AppHotkeyScope.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export enum AppHotkeyScope {
|
||||||
|
App = 'app',
|
||||||
|
Goto = 'goto',
|
||||||
|
CommandMenu = 'command-menu',
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
export type CustomHotkeysScopes = {
|
export type CustomHotkeyScopes = {
|
||||||
goto?: boolean;
|
goto?: boolean;
|
||||||
commandMenu?: boolean;
|
commandMenu?: boolean;
|
||||||
};
|
};
|
||||||
6
front/src/modules/lib/hotkeys/types/HotkeyScope.ts
Normal file
6
front/src/modules/lib/hotkeys/types/HotkeyScope.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { CustomHotkeyScopes } from './CustomHotkeyScope';
|
||||||
|
|
||||||
|
export type HotkeyScope = {
|
||||||
|
scope: string;
|
||||||
|
customScopes?: CustomHotkeyScopes;
|
||||||
|
};
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import { CompanyChip } from '@/companies/components/CompanyChip';
|
import { CompanyChip } from '@/companies/components/CompanyChip';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
||||||
|
import { RelationPickerHotkeyScope } from '@/relation-picker/types/RelationPickerHotkeyScope';
|
||||||
import { EditableCell } from '@/ui/components/editable-cell/EditableCell';
|
import { EditableCell } from '@/ui/components/editable-cell/EditableCell';
|
||||||
import { isCreateModeScopedState } from '@/ui/components/editable-cell/states/isCreateModeScopedState';
|
import { isCreateModeScopedState } from '@/ui/components/editable-cell/states/isCreateModeScopedState';
|
||||||
import { getLogoUrlFromDomainName } from '@/utils/utils';
|
import { getLogoUrlFromDomainName } from '@/utils/utils';
|
||||||
@ -24,7 +24,7 @@ export function PeopleCompanyCell({ people }: OwnProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<EditableCell
|
<EditableCell
|
||||||
editHotkeysScope={{ scope: InternalHotkeysScope.RelationPicker }}
|
editHotkeyScope={{ scope: RelationPickerHotkeyScope.RelationPicker }}
|
||||||
editModeContent={
|
editModeContent={
|
||||||
isCreating ? (
|
isCreating ? (
|
||||||
<PeopleCompanyCreateCell people={people} />
|
<PeopleCompanyCreateCell people={people} />
|
||||||
|
|||||||
@ -1,14 +1,15 @@
|
|||||||
import { Key } from 'ts-key-enum';
|
import { Key } from 'ts-key-enum';
|
||||||
|
|
||||||
import { useScopedHotkeys } from '@/hotkeys/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/lib/hotkeys/hooks/useScopedHotkeys';
|
||||||
import { useSetHotkeysScope } from '@/hotkeys/hooks/useSetHotkeysScope';
|
import { useSetHotkeyScope } from '@/lib/hotkeys/hooks/useSetHotkeyScope';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
||||||
import { SingleEntitySelect } from '@/relation-picker/components/SingleEntitySelect';
|
import { SingleEntitySelect } from '@/relation-picker/components/SingleEntitySelect';
|
||||||
import { useFilteredSearchEntityQuery } from '@/relation-picker/hooks/useFilteredSearchEntityQuery';
|
import { useFilteredSearchEntityQuery } from '@/relation-picker/hooks/useFilteredSearchEntityQuery';
|
||||||
import { relationPickerSearchFilterScopedState } from '@/relation-picker/states/relationPickerSearchFilterScopedState';
|
import { relationPickerSearchFilterScopedState } from '@/relation-picker/states/relationPickerSearchFilterScopedState';
|
||||||
|
import { RelationPickerHotkeyScope } from '@/relation-picker/types/RelationPickerHotkeyScope';
|
||||||
import { useEditableCell } from '@/ui/components/editable-cell/hooks/useEditableCell';
|
import { useEditableCell } from '@/ui/components/editable-cell/hooks/useEditableCell';
|
||||||
import { isCreateModeScopedState } from '@/ui/components/editable-cell/states/isCreateModeScopedState';
|
import { isCreateModeScopedState } from '@/ui/components/editable-cell/states/isCreateModeScopedState';
|
||||||
|
import { TableHotkeyScope } from '@/ui/tables/types/TableHotkeyScope';
|
||||||
import { getLogoUrlFromDomainName } from '@/utils/utils';
|
import { getLogoUrlFromDomainName } from '@/utils/utils';
|
||||||
import {
|
import {
|
||||||
CommentableType,
|
CommentableType,
|
||||||
@ -32,7 +33,7 @@ export function PeopleCompanyPicker({ people }: OwnProps) {
|
|||||||
|
|
||||||
const { closeEditableCell } = useEditableCell();
|
const { closeEditableCell } = useEditableCell();
|
||||||
|
|
||||||
const addToScopeStack = useSetHotkeysScope();
|
const addToScopeStack = useSetHotkeyScope();
|
||||||
|
|
||||||
const companies = useFilteredSearchEntityQuery({
|
const companies = useFilteredSearchEntityQuery({
|
||||||
queryHook: useSearchCompanyQuery,
|
queryHook: useSearchCompanyQuery,
|
||||||
@ -62,13 +63,13 @@ export function PeopleCompanyPicker({ people }: OwnProps) {
|
|||||||
|
|
||||||
function handleCreate() {
|
function handleCreate() {
|
||||||
setIsCreating(true);
|
setIsCreating(true);
|
||||||
addToScopeStack(InternalHotkeysScope.CellDoubleTextInput);
|
addToScopeStack(TableHotkeyScope.CellDoubleTextInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
useScopedHotkeys(
|
useScopedHotkeys(
|
||||||
Key.Escape,
|
Key.Escape,
|
||||||
() => closeEditableCell(),
|
() => closeEditableCell(),
|
||||||
InternalHotkeysScope.RelationPicker,
|
RelationPickerHotkeyScope.RelationPicker,
|
||||||
[closeEditableCell],
|
[closeEditableCell],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -3,9 +3,9 @@ import { getOperationName } from '@apollo/client/utilities';
|
|||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
import { usePreviousHotkeysScope } from '@/hotkeys/hooks/internal/usePreviousHotkeysScope';
|
import { usePreviousHotkeyScope } from '@/lib/hotkeys/hooks/usePreviousHotkeyScope';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
import { RecoilScope } from '@/recoil-scope/components/RecoilScope';
|
import { RecoilScope } from '@/recoil-scope/components/RecoilScope';
|
||||||
|
import { RelationPickerHotkeyScope } from '@/relation-picker/types/RelationPickerHotkeyScope';
|
||||||
import { Column } from '@/ui/board/components/Board';
|
import { Column } from '@/ui/board/components/Board';
|
||||||
import { NewButton as UINewButton } from '@/ui/board/components/NewButton';
|
import { NewButton as UINewButton } from '@/ui/board/components/NewButton';
|
||||||
import {
|
import {
|
||||||
@ -32,9 +32,9 @@ export function NewButton({ pipelineId, columnId }: OwnProps) {
|
|||||||
const [boardItems, setBoardItems] = useRecoilState(boardItemsState);
|
const [boardItems, setBoardItems] = useRecoilState(boardItemsState);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
goBackToPreviousHotkeysScope,
|
goBackToPreviousHotkeyScope,
|
||||||
setHotkeysScopeAndMemorizePreviousScope,
|
setHotkeyScopeAndMemorizePreviousScope,
|
||||||
} = usePreviousHotkeysScope();
|
} = usePreviousHotkeyScope();
|
||||||
|
|
||||||
const [createOnePipelineProgress] = useCreateOnePipelineProgressMutation({
|
const [createOnePipelineProgress] = useCreateOnePipelineProgressMutation({
|
||||||
refetchQueries: [getOperationName(GET_PIPELINES) ?? ''],
|
refetchQueries: [getOperationName(GET_PIPELINES) ?? ''],
|
||||||
@ -45,7 +45,7 @@ export function NewButton({ pipelineId, columnId }: OwnProps) {
|
|||||||
if (!company) return;
|
if (!company) return;
|
||||||
|
|
||||||
setIsCreatingCard(false);
|
setIsCreatingCard(false);
|
||||||
goBackToPreviousHotkeysScope();
|
goBackToPreviousHotkeyScope();
|
||||||
|
|
||||||
const newUuid = uuidv4();
|
const newUuid = uuidv4();
|
||||||
const newBoard = JSON.parse(JSON.stringify(board));
|
const newBoard = JSON.parse(JSON.stringify(board));
|
||||||
@ -82,19 +82,19 @@ export function NewButton({ pipelineId, columnId }: OwnProps) {
|
|||||||
setBoard,
|
setBoard,
|
||||||
boardItems,
|
boardItems,
|
||||||
setBoardItems,
|
setBoardItems,
|
||||||
goBackToPreviousHotkeysScope,
|
goBackToPreviousHotkeyScope,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleNewClick = useCallback(() => {
|
const handleNewClick = useCallback(() => {
|
||||||
setIsCreatingCard(true);
|
setIsCreatingCard(true);
|
||||||
setHotkeysScopeAndMemorizePreviousScope(
|
setHotkeyScopeAndMemorizePreviousScope(
|
||||||
InternalHotkeysScope.RelationPicker,
|
RelationPickerHotkeyScope.RelationPicker,
|
||||||
);
|
);
|
||||||
}, [setIsCreatingCard, setHotkeysScopeAndMemorizePreviousScope]);
|
}, [setIsCreatingCard, setHotkeyScopeAndMemorizePreviousScope]);
|
||||||
|
|
||||||
function handleCancel() {
|
function handleCancel() {
|
||||||
goBackToPreviousHotkeysScope();
|
goBackToPreviousHotkeyScope();
|
||||||
setIsCreatingCard(false);
|
setIsCreatingCard(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
import { useRef } from 'react';
|
import { useRef } from 'react';
|
||||||
import { Key } from 'ts-key-enum';
|
import { Key } from 'ts-key-enum';
|
||||||
|
|
||||||
import { useScopedHotkeys } from '@/hotkeys/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/lib/hotkeys/hooks/useScopedHotkeys';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
import { EntityForSelect } from '@/relation-picker/types/EntityForSelect';
|
import { EntityForSelect } from '@/relation-picker/types/EntityForSelect';
|
||||||
import { DropdownMenuItem } from '@/ui/components/menu/DropdownMenuItem';
|
import { DropdownMenuItem } from '@/ui/components/menu/DropdownMenuItem';
|
||||||
import { DropdownMenuItemContainer } from '@/ui/components/menu/DropdownMenuItemContainer';
|
import { DropdownMenuItemContainer } from '@/ui/components/menu/DropdownMenuItemContainer';
|
||||||
@ -11,6 +10,7 @@ import { Avatar } from '@/users/components/Avatar';
|
|||||||
import { isDefined } from '@/utils/type-guards/isDefined';
|
import { isDefined } from '@/utils/type-guards/isDefined';
|
||||||
|
|
||||||
import { useEntitySelectScroll } from '../hooks/useEntitySelectScroll';
|
import { useEntitySelectScroll } from '../hooks/useEntitySelectScroll';
|
||||||
|
import { RelationPickerHotkeyScope } from '../types/RelationPickerHotkeyScope';
|
||||||
|
|
||||||
import { CompanyPickerSkeleton } from './skeletons/CompanyPickerSkeleton';
|
import { CompanyPickerSkeleton } from './skeletons/CompanyPickerSkeleton';
|
||||||
import { DropdownMenuItemContainerSkeleton } from './skeletons/DropdownMenuItemContainerSkeleton';
|
import { DropdownMenuItemContainerSkeleton } from './skeletons/DropdownMenuItemContainerSkeleton';
|
||||||
@ -50,7 +50,7 @@ export function SingleEntitySelectBase<
|
|||||||
onEntitySelected(entitiesInDropdown[hoveredIndex]);
|
onEntitySelected(entitiesInDropdown[hoveredIndex]);
|
||||||
resetScroll();
|
resetScroll();
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.RelationPicker,
|
RelationPickerHotkeyScope.RelationPicker,
|
||||||
[entitiesInDropdown, hoveredIndex, onEntitySelected],
|
[entitiesInDropdown, hoveredIndex, onEntitySelected],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ export function SingleEntitySelectBase<
|
|||||||
() => {
|
() => {
|
||||||
onCancel?.();
|
onCancel?.();
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.RelationPicker,
|
RelationPickerHotkeyScope.RelationPicker,
|
||||||
[onCancel],
|
[onCancel],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
import scrollIntoView from 'scroll-into-view';
|
import scrollIntoView from 'scroll-into-view';
|
||||||
import { Key } from 'ts-key-enum';
|
import { Key } from 'ts-key-enum';
|
||||||
|
|
||||||
import { useScopedHotkeys } from '@/hotkeys/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/lib/hotkeys/hooks/useScopedHotkeys';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
||||||
|
|
||||||
import { relationPickerHoverIndexScopedState } from '../states/relationPickerHoverIndexScopedState';
|
import { relationPickerHoverIndexScopedState } from '../states/relationPickerHoverIndexScopedState';
|
||||||
import { EntityForSelect } from '../types/EntityForSelect';
|
import { EntityForSelect } from '../types/EntityForSelect';
|
||||||
|
import { RelationPickerHotkeyScope } from '../types/RelationPickerHotkeyScope';
|
||||||
|
|
||||||
export function useEntitySelectScroll<
|
export function useEntitySelectScroll<
|
||||||
CustomEntityForSelect extends EntityForSelect,
|
CustomEntityForSelect extends EntityForSelect,
|
||||||
@ -60,7 +60,7 @@ export function useEntitySelectScroll<
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.RelationPicker,
|
RelationPickerHotkeyScope.RelationPicker,
|
||||||
[setHoveredIndex, entities],
|
[setHoveredIndex, entities],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -87,7 +87,7 @@ export function useEntitySelectScroll<
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.RelationPicker,
|
RelationPickerHotkeyScope.RelationPicker,
|
||||||
[setHoveredIndex, entities],
|
[setHoveredIndex, entities],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,3 @@
|
|||||||
|
export enum RelationPickerHotkeyScope {
|
||||||
|
RelationPicker = 'relation-picker',
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import { ReactElement } from 'react';
|
import { ReactElement } from 'react';
|
||||||
|
|
||||||
import { HotkeysScope } from '@/hotkeys/types/internal/HotkeysScope';
|
import { HotkeyScope } from '@/lib/hotkeys/types/HotkeyScope';
|
||||||
import { RecoilScope } from '@/recoil-scope/components/RecoilScope';
|
import { RecoilScope } from '@/recoil-scope/components/RecoilScope';
|
||||||
|
|
||||||
import { BoardCardFieldContext } from '../states/BoardCardFieldContext';
|
import { BoardCardFieldContext } from '../states/BoardCardFieldContext';
|
||||||
@ -12,7 +12,7 @@ type OwnProps = {
|
|||||||
nonEditModeContent: ReactElement;
|
nonEditModeContent: ReactElement;
|
||||||
editModeHorizontalAlign?: 'left' | 'right';
|
editModeHorizontalAlign?: 'left' | 'right';
|
||||||
editModeVerticalPosition?: 'over' | 'below';
|
editModeVerticalPosition?: 'over' | 'below';
|
||||||
editHotkeysScope?: HotkeysScope;
|
editHotkeyScope?: HotkeyScope;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function BoardCardEditableField(props: OwnProps) {
|
export function BoardCardEditableField(props: OwnProps) {
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
import { ReactElement, useRef } from 'react';
|
import { ReactElement, useRef } from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { useScopedHotkeys } from '@/hotkeys/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/lib/hotkeys/hooks/useScopedHotkeys';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
import { useListenClickOutsideArrayOfRef } from '@/ui/hooks/useListenClickOutsideArrayOfRef';
|
import { useListenClickOutsideArrayOfRef } from '@/ui/hooks/useListenClickOutsideArrayOfRef';
|
||||||
import { overlayBackground } from '@/ui/themes/effects';
|
import { overlayBackground } from '@/ui/themes/effects';
|
||||||
|
|
||||||
|
import { BoardCardFieldHotkeyScope } from '../types/BoardCardFieldHotkeyScope';
|
||||||
|
|
||||||
export const BoardCardFieldEditModeContainer = styled.div<
|
export const BoardCardFieldEditModeContainer = styled.div<
|
||||||
Omit<OwnProps, 'onExit'>
|
Omit<OwnProps, 'onExit'>
|
||||||
>`
|
>`
|
||||||
@ -51,7 +52,7 @@ export function BoardCardEditableFieldEditMode({
|
|||||||
() => {
|
() => {
|
||||||
onExit();
|
onExit();
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.BoardCardFieldEditMode,
|
BoardCardFieldHotkeyScope.BoardCardFieldEditMode,
|
||||||
[onExit],
|
[onExit],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -60,7 +61,7 @@ export function BoardCardEditableFieldEditMode({
|
|||||||
() => {
|
() => {
|
||||||
onExit();
|
onExit();
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.BoardCardFieldEditMode,
|
BoardCardFieldHotkeyScope.BoardCardFieldEditMode,
|
||||||
[onExit],
|
[onExit],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import { ReactElement } from 'react';
|
import { ReactElement } from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { usePreviousHotkeysScope } from '@/hotkeys/hooks/internal/usePreviousHotkeysScope';
|
import { usePreviousHotkeyScope } from '@/lib/hotkeys/hooks/usePreviousHotkeyScope';
|
||||||
import { HotkeysScope } from '@/hotkeys/types/internal/HotkeysScope';
|
import { HotkeyScope } from '@/lib/hotkeys/types/HotkeyScope';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
|
|
||||||
import { useBoardCardField } from '../hooks/useBoardCardField';
|
import { useBoardCardField } from '../hooks/useBoardCardField';
|
||||||
|
import { BoardCardFieldHotkeyScope } from '../types/BoardCardFieldHotkeyScope';
|
||||||
|
|
||||||
import { BoardCardEditableFieldDisplayMode } from './BoardCardEditableFieldDisplayMode';
|
import { BoardCardEditableFieldDisplayMode } from './BoardCardEditableFieldDisplayMode';
|
||||||
import { BoardCardEditableFieldEditMode } from './BoardCardEditableFieldEditMode';
|
import { BoardCardEditableFieldEditMode } from './BoardCardEditableFieldEditMode';
|
||||||
@ -26,7 +26,7 @@ type OwnProps = {
|
|||||||
nonEditModeContent: ReactElement;
|
nonEditModeContent: ReactElement;
|
||||||
editModeHorizontalAlign?: 'left' | 'right';
|
editModeHorizontalAlign?: 'left' | 'right';
|
||||||
editModeVerticalPosition?: 'over' | 'below';
|
editModeVerticalPosition?: 'over' | 'below';
|
||||||
editHotkeysScope?: HotkeysScope;
|
editHotkeyScope?: HotkeyScope;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function BoardCardEditableFieldInternal({
|
export function BoardCardEditableFieldInternal({
|
||||||
@ -34,7 +34,7 @@ export function BoardCardEditableFieldInternal({
|
|||||||
editModeVerticalPosition = 'over',
|
editModeVerticalPosition = 'over',
|
||||||
editModeContent,
|
editModeContent,
|
||||||
nonEditModeContent,
|
nonEditModeContent,
|
||||||
editHotkeysScope,
|
editHotkeyScope,
|
||||||
}: OwnProps) {
|
}: OwnProps) {
|
||||||
const { openBoardCardField, isBoardCardFieldInEditMode } =
|
const { openBoardCardField, isBoardCardFieldInEditMode } =
|
||||||
useBoardCardField();
|
useBoardCardField();
|
||||||
@ -42,22 +42,23 @@ export function BoardCardEditableFieldInternal({
|
|||||||
const { closeBoardCardField } = useBoardCardField();
|
const { closeBoardCardField } = useBoardCardField();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
goBackToPreviousHotkeysScope,
|
goBackToPreviousHotkeyScope,
|
||||||
setHotkeysScopeAndMemorizePreviousScope,
|
setHotkeyScopeAndMemorizePreviousScope,
|
||||||
} = usePreviousHotkeysScope();
|
} = usePreviousHotkeyScope();
|
||||||
|
|
||||||
function handleOnClick() {
|
function handleOnClick() {
|
||||||
if (!isBoardCardFieldInEditMode) {
|
if (!isBoardCardFieldInEditMode) {
|
||||||
openBoardCardField();
|
openBoardCardField();
|
||||||
setHotkeysScopeAndMemorizePreviousScope(
|
setHotkeyScopeAndMemorizePreviousScope(
|
||||||
editHotkeysScope?.scope ?? InternalHotkeysScope.BoardCardFieldEditMode,
|
editHotkeyScope?.scope ??
|
||||||
editHotkeysScope?.customScopes ?? {},
|
BoardCardFieldHotkeyScope.BoardCardFieldEditMode,
|
||||||
|
editHotkeyScope?.customScopes ?? {},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleEditModeExit() {
|
function handleEditModeExit() {
|
||||||
goBackToPreviousHotkeysScope();
|
goBackToPreviousHotkeyScope();
|
||||||
closeBoardCardField();
|
closeBoardCardField();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,3 @@
|
|||||||
|
export enum BoardCardFieldHotkeyScope {
|
||||||
|
BoardCardFieldEditMode = 'board-card-field-edit-mode',
|
||||||
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import { ReactElement } from 'react';
|
import { ReactElement } from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { HotkeysScope } from '@/hotkeys/types/internal/HotkeysScope';
|
import { HotkeyScope } from '@/lib/hotkeys/types/HotkeyScope';
|
||||||
|
|
||||||
import { useCurrentCellEditMode } from './hooks/useCurrentCellEditMode';
|
import { useCurrentCellEditMode } from './hooks/useCurrentCellEditMode';
|
||||||
import { useIsSoftFocusOnCurrentCell } from './hooks/useIsSoftFocusOnCurrentCell';
|
import { useIsSoftFocusOnCurrentCell } from './hooks/useIsSoftFocusOnCurrentCell';
|
||||||
@ -25,7 +25,7 @@ type OwnProps = {
|
|||||||
nonEditModeContent: ReactElement;
|
nonEditModeContent: ReactElement;
|
||||||
editModeHorizontalAlign?: 'left' | 'right';
|
editModeHorizontalAlign?: 'left' | 'right';
|
||||||
editModeVerticalPosition?: 'over' | 'below';
|
editModeVerticalPosition?: 'over' | 'below';
|
||||||
editHotkeysScope?: HotkeysScope;
|
editHotkeyScope?: HotkeyScope;
|
||||||
onSubmit?: () => void;
|
onSubmit?: () => void;
|
||||||
onCancel?: () => void;
|
onCancel?: () => void;
|
||||||
};
|
};
|
||||||
@ -35,7 +35,7 @@ export function EditableCell({
|
|||||||
editModeVerticalPosition = 'over',
|
editModeVerticalPosition = 'over',
|
||||||
editModeContent,
|
editModeContent,
|
||||||
nonEditModeContent,
|
nonEditModeContent,
|
||||||
editHotkeysScope,
|
editHotkeyScope,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
onCancel,
|
onCancel,
|
||||||
}: OwnProps) {
|
}: OwnProps) {
|
||||||
@ -55,7 +55,7 @@ export function EditableCell({
|
|||||||
{editModeContent}
|
{editModeContent}
|
||||||
</EditableCellEditMode>
|
</EditableCellEditMode>
|
||||||
) : hasSoftFocus ? (
|
) : hasSoftFocus ? (
|
||||||
<EditableCellSoftFocusMode editHotkeysScope={editHotkeysScope}>
|
<EditableCellSoftFocusMode editHotkeyScope={editHotkeyScope}>
|
||||||
{nonEditModeContent}
|
{nonEditModeContent}
|
||||||
</EditableCellSoftFocusMode>
|
</EditableCellSoftFocusMode>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { useScopedHotkeys } from '@/hotkeys/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/lib/hotkeys/hooks/useScopedHotkeys';
|
||||||
import { HotkeysScope } from '@/hotkeys/types/internal/HotkeysScope';
|
import { HotkeyScope } from '@/lib/hotkeys/types/HotkeyScope';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
import { TableHotkeyScope } from '@/ui/tables/types/TableHotkeyScope';
|
||||||
import { isNonTextWritingKey } from '@/utils/hotkeys/isNonTextWritingKey';
|
import { isNonTextWritingKey } from '@/utils/hotkeys/isNonTextWritingKey';
|
||||||
|
|
||||||
import { useEditableCell } from './hooks/useEditableCell';
|
import { useEditableCell } from './hooks/useEditableCell';
|
||||||
@ -13,14 +13,14 @@ import {
|
|||||||
|
|
||||||
export function EditableCellSoftFocusMode({
|
export function EditableCellSoftFocusMode({
|
||||||
children,
|
children,
|
||||||
editHotkeysScope,
|
editHotkeyScope,
|
||||||
}: React.PropsWithChildren<{ editHotkeysScope?: HotkeysScope }>) {
|
}: React.PropsWithChildren<{ editHotkeyScope?: HotkeyScope }>) {
|
||||||
const { openEditableCell } = useEditableCell();
|
const { openEditableCell } = useEditableCell();
|
||||||
|
|
||||||
function openEditMode() {
|
function openEditMode() {
|
||||||
openEditableCell(
|
openEditableCell(
|
||||||
editHotkeysScope ?? {
|
editHotkeyScope ?? {
|
||||||
scope: InternalHotkeysScope.CellEditMode,
|
scope: TableHotkeyScope.CellEditMode,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -30,7 +30,7 @@ export function EditableCellSoftFocusMode({
|
|||||||
() => {
|
() => {
|
||||||
openEditMode();
|
openEditMode();
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.TableSoftFocus,
|
TableHotkeyScope.TableSoftFocus,
|
||||||
[openEditMode],
|
[openEditMode],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ export function EditableCellSoftFocusMode({
|
|||||||
|
|
||||||
openEditMode();
|
openEditMode();
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.TableSoftFocus,
|
TableHotkeyScope.TableSoftFocus,
|
||||||
[openEditMode],
|
[openEditMode],
|
||||||
{
|
{
|
||||||
preventDefault: false,
|
preventDefault: false,
|
||||||
|
|||||||
@ -1,28 +1,28 @@
|
|||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
import { useSetHotkeysScope } from '@/hotkeys/hooks/useSetHotkeysScope';
|
import { useSetHotkeyScope } from '@/lib/hotkeys/hooks/useSetHotkeyScope';
|
||||||
import { HotkeysScope } from '@/hotkeys/types/internal/HotkeysScope';
|
import { HotkeyScope } from '@/lib/hotkeys/types/HotkeyScope';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
import { useCloseCurrentCellInEditMode } from '@/ui/tables/hooks/useClearCellInEditMode';
|
import { useCloseCurrentCellInEditMode } from '@/ui/tables/hooks/useClearCellInEditMode';
|
||||||
import { isSomeInputInEditModeState } from '@/ui/tables/states/isSomeInputInEditModeState';
|
import { isSomeInputInEditModeState } from '@/ui/tables/states/isSomeInputInEditModeState';
|
||||||
|
import { TableHotkeyScope } from '@/ui/tables/types/TableHotkeyScope';
|
||||||
|
|
||||||
import { useCurrentCellEditMode } from './useCurrentCellEditMode';
|
import { useCurrentCellEditMode } from './useCurrentCellEditMode';
|
||||||
|
|
||||||
export function useEditableCell() {
|
export function useEditableCell() {
|
||||||
const { setCurrentCellInEditMode } = useCurrentCellEditMode();
|
const { setCurrentCellInEditMode } = useCurrentCellEditMode();
|
||||||
|
|
||||||
const setHotkeysScope = useSetHotkeysScope();
|
const setHotkeyScope = useSetHotkeyScope();
|
||||||
|
|
||||||
const closeCurrentCellInEditMode = useCloseCurrentCellInEditMode();
|
const closeCurrentCellInEditMode = useCloseCurrentCellInEditMode();
|
||||||
|
|
||||||
function closeEditableCell() {
|
function closeEditableCell() {
|
||||||
closeCurrentCellInEditMode();
|
closeCurrentCellInEditMode();
|
||||||
setHotkeysScope(InternalHotkeysScope.TableSoftFocus);
|
setHotkeyScope(TableHotkeyScope.TableSoftFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
const openEditableCell = useRecoilCallback(
|
const openEditableCell = useRecoilCallback(
|
||||||
({ snapshot, set }) =>
|
({ snapshot, set }) =>
|
||||||
(hotkeysScope: HotkeysScope) => {
|
(HotkeyScope: HotkeyScope) => {
|
||||||
const isSomeInputInEditMode = snapshot
|
const isSomeInputInEditMode = snapshot
|
||||||
.getLoadable(isSomeInputInEditModeState)
|
.getLoadable(isSomeInputInEditModeState)
|
||||||
.valueOrThrow();
|
.valueOrThrow();
|
||||||
@ -32,10 +32,10 @@ export function useEditableCell() {
|
|||||||
|
|
||||||
setCurrentCellInEditMode();
|
setCurrentCellInEditMode();
|
||||||
|
|
||||||
setHotkeysScope(hotkeysScope.scope);
|
setHotkeyScope(HotkeyScope.scope);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[setCurrentCellInEditMode, setHotkeysScope],
|
[setCurrentCellInEditMode, setHotkeyScope],
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { useScopedHotkeys } from '@/hotkeys/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/lib/hotkeys/hooks/useScopedHotkeys';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
import { useListenClickOutsideArrayOfRef } from '@/ui/hooks/useListenClickOutsideArrayOfRef';
|
import { useListenClickOutsideArrayOfRef } from '@/ui/hooks/useListenClickOutsideArrayOfRef';
|
||||||
import { useMoveSoftFocus } from '@/ui/tables/hooks/useMoveSoftFocus';
|
import { useMoveSoftFocus } from '@/ui/tables/hooks/useMoveSoftFocus';
|
||||||
|
import { TableHotkeyScope } from '@/ui/tables/types/TableHotkeyScope';
|
||||||
|
|
||||||
import { useCurrentCellEditMode } from './useCurrentCellEditMode';
|
import { useCurrentCellEditMode } from './useCurrentCellEditMode';
|
||||||
import { useEditableCell } from './useEditableCell';
|
import { useEditableCell } from './useEditableCell';
|
||||||
@ -28,7 +28,7 @@ export function useRegisterCloseCellHandlers(
|
|||||||
closeEditableCell();
|
closeEditableCell();
|
||||||
moveDown();
|
moveDown();
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.CellEditMode,
|
TableHotkeyScope.CellEditMode,
|
||||||
[closeEditableCell, onSubmit, moveDown],
|
[closeEditableCell, onSubmit, moveDown],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ export function useRegisterCloseCellHandlers(
|
|||||||
closeEditableCell();
|
closeEditableCell();
|
||||||
onCancel?.();
|
onCancel?.();
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.CellEditMode,
|
TableHotkeyScope.CellEditMode,
|
||||||
[closeEditableCell, onCancel],
|
[closeEditableCell, onCancel],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ export function useRegisterCloseCellHandlers(
|
|||||||
closeEditableCell();
|
closeEditableCell();
|
||||||
moveRight();
|
moveRight();
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.CellEditMode,
|
TableHotkeyScope.CellEditMode,
|
||||||
[closeEditableCell, onSubmit, moveRight],
|
[closeEditableCell, onSubmit, moveRight],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ export function useRegisterCloseCellHandlers(
|
|||||||
closeEditableCell();
|
closeEditableCell();
|
||||||
moveLeft();
|
moveLeft();
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.CellEditMode,
|
TableHotkeyScope.CellEditMode,
|
||||||
[closeEditableCell, onSubmit, moveRight],
|
[closeEditableCell, onSubmit, moveRight],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
import { useSetHotkeysScope } from '@/hotkeys/hooks/useSetHotkeysScope';
|
import { useSetHotkeyScope } from '@/lib/hotkeys/hooks/useSetHotkeyScope';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
||||||
import { useSetSoftFocusPosition } from '@/ui/tables/hooks/useSetSoftFocusPosition';
|
import { useSetSoftFocusPosition } from '@/ui/tables/hooks/useSetSoftFocusPosition';
|
||||||
import { CellContext } from '@/ui/tables/states/CellContext';
|
import { CellContext } from '@/ui/tables/states/CellContext';
|
||||||
@ -11,6 +10,7 @@ import { currentRowNumberScopedState } from '@/ui/tables/states/currentRowNumber
|
|||||||
import { isSoftFocusActiveState } from '@/ui/tables/states/isSoftFocusActiveState';
|
import { isSoftFocusActiveState } from '@/ui/tables/states/isSoftFocusActiveState';
|
||||||
import { RowContext } from '@/ui/tables/states/RowContext';
|
import { RowContext } from '@/ui/tables/states/RowContext';
|
||||||
import { CellPosition } from '@/ui/tables/types/CellPosition';
|
import { CellPosition } from '@/ui/tables/types/CellPosition';
|
||||||
|
import { TableHotkeyScope } from '@/ui/tables/types/TableHotkeyScope';
|
||||||
|
|
||||||
export function useSetSoftFocusOnCurrentCell() {
|
export function useSetSoftFocusOnCurrentCell() {
|
||||||
const setSoftFocusPosition = useSetSoftFocusPosition();
|
const setSoftFocusPosition = useSetSoftFocusPosition();
|
||||||
@ -33,7 +33,7 @@ export function useSetSoftFocusOnCurrentCell() {
|
|||||||
[currentColumnNumber, currentRowNumber],
|
[currentColumnNumber, currentRowNumber],
|
||||||
);
|
);
|
||||||
|
|
||||||
const setHotkeysScope = useSetHotkeysScope();
|
const setHotkeyScope = useSetHotkeyScope();
|
||||||
|
|
||||||
return useRecoilCallback(
|
return useRecoilCallback(
|
||||||
({ set }) =>
|
({ set }) =>
|
||||||
@ -42,8 +42,8 @@ export function useSetSoftFocusOnCurrentCell() {
|
|||||||
|
|
||||||
set(isSoftFocusActiveState, true);
|
set(isSoftFocusActiveState, true);
|
||||||
|
|
||||||
setHotkeysScope(InternalHotkeysScope.TableSoftFocus);
|
setHotkeyScope(TableHotkeyScope.TableSoftFocus);
|
||||||
},
|
},
|
||||||
[setHotkeysScope, currentTablePosition, setSoftFocusPosition],
|
[setHotkeyScope, currentTablePosition, setSoftFocusPosition],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
import { InplaceInputDateDisplayMode } from '@/ui/inplace-inputs/components/InplaceInputDateDisplayMode';
|
import { InplaceInputDateDisplayMode } from '@/ui/inplace-inputs/components/InplaceInputDateDisplayMode';
|
||||||
|
import { TableHotkeyScope } from '@/ui/tables/types/TableHotkeyScope';
|
||||||
|
|
||||||
import { EditableCell } from '../EditableCell';
|
import { EditableCell } from '../EditableCell';
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ export function EditableCellDate({
|
|||||||
<EditableCellDateEditMode onChange={onChange} value={value} />
|
<EditableCellDateEditMode onChange={onChange} value={value} />
|
||||||
}
|
}
|
||||||
nonEditModeContent={<InplaceInputDateDisplayMode value={value} />}
|
nonEditModeContent={<InplaceInputDateDisplayMode value={value} />}
|
||||||
editHotkeysScope={{ scope: InternalHotkeysScope.CellDateEditMode }}
|
editHotkeyScope={{ scope: TableHotkeyScope.CellDateEditMode }}
|
||||||
></EditableCell>
|
></EditableCell>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import { Key } from 'ts-key-enum';
|
import { Key } from 'ts-key-enum';
|
||||||
|
|
||||||
import { useScopedHotkeys } from '@/hotkeys/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/lib/hotkeys/hooks/useScopedHotkeys';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
import { InplaceInputDateEditMode } from '@/ui/inplace-inputs/components/InplaceInputDateEditMode';
|
import { InplaceInputDateEditMode } from '@/ui/inplace-inputs/components/InplaceInputDateEditMode';
|
||||||
|
import { TableHotkeyScope } from '@/ui/tables/types/TableHotkeyScope';
|
||||||
|
|
||||||
import { useEditableCell } from '../hooks/useEditableCell';
|
import { useEditableCell } from '../hooks/useEditableCell';
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ export function EditableCellDateEditMode({
|
|||||||
() => {
|
() => {
|
||||||
closeEditableCell();
|
closeEditableCell();
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.CellDateEditMode,
|
TableHotkeyScope.CellDateEditMode,
|
||||||
[closeEditableCell],
|
[closeEditableCell],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { ReactElement, useEffect, useState } from 'react';
|
import { ReactElement, useEffect, useState } from 'react';
|
||||||
|
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
import { TableHotkeyScope } from '@/ui/tables/types/TableHotkeyScope';
|
||||||
|
|
||||||
import { CellSkeleton } from '../CellSkeleton';
|
import { CellSkeleton } from '../CellSkeleton';
|
||||||
import { EditableCell } from '../EditableCell';
|
import { EditableCell } from '../EditableCell';
|
||||||
@ -46,7 +46,7 @@ export function EditableCellDoubleText({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<EditableCell
|
<EditableCell
|
||||||
editHotkeysScope={{ scope: InternalHotkeysScope.CellDoubleTextInput }}
|
editHotkeyScope={{ scope: TableHotkeyScope.CellDoubleTextInput }}
|
||||||
editModeContent={
|
editModeContent={
|
||||||
<EditableCellDoubleTextEditMode
|
<EditableCellDoubleTextEditMode
|
||||||
firstValue={firstInternalValue}
|
firstValue={firstInternalValue}
|
||||||
|
|||||||
@ -2,10 +2,10 @@ import { ChangeEvent, useRef, useState } from 'react';
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { Key } from 'ts-key-enum';
|
import { Key } from 'ts-key-enum';
|
||||||
|
|
||||||
import { useScopedHotkeys } from '@/hotkeys/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/lib/hotkeys/hooks/useScopedHotkeys';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
import { InplaceInputTextEditMode } from '@/ui/inplace-inputs/components/InplaceInputTextEditMode';
|
import { InplaceInputTextEditMode } from '@/ui/inplace-inputs/components/InplaceInputTextEditMode';
|
||||||
import { useMoveSoftFocus } from '@/ui/tables/hooks/useMoveSoftFocus';
|
import { useMoveSoftFocus } from '@/ui/tables/hooks/useMoveSoftFocus';
|
||||||
|
import { TableHotkeyScope } from '@/ui/tables/types/TableHotkeyScope';
|
||||||
|
|
||||||
import { useEditableCell } from '../hooks/useEditableCell';
|
import { useEditableCell } from '../hooks/useEditableCell';
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ export function EditableCellDoubleTextEditMode({
|
|||||||
moveDown();
|
moveDown();
|
||||||
onSubmit?.();
|
onSubmit?.();
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.CellDoubleTextInput,
|
TableHotkeyScope.CellDoubleTextInput,
|
||||||
[closeCell],
|
[closeCell],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ export function EditableCellDoubleTextEditMode({
|
|||||||
onCancel?.();
|
onCancel?.();
|
||||||
closeCell();
|
closeCell();
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.CellDoubleTextInput,
|
TableHotkeyScope.CellDoubleTextInput,
|
||||||
[closeCell],
|
[closeCell],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ export function EditableCellDoubleTextEditMode({
|
|||||||
moveRight();
|
moveRight();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.CellDoubleTextInput,
|
TableHotkeyScope.CellDoubleTextInput,
|
||||||
[closeCell, moveRight, focusPosition],
|
[closeCell, moveRight, focusPosition],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -101,7 +101,7 @@ export function EditableCellDoubleTextEditMode({
|
|||||||
moveLeft();
|
moveLeft();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.CellDoubleTextInput,
|
TableHotkeyScope.CellDoubleTextInput,
|
||||||
[closeCell, moveRight, focusPosition],
|
[closeCell, moveRight, focusPosition],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -10,11 +10,12 @@ import styled from '@emotion/styled';
|
|||||||
import { IconAlertCircle } from '@tabler/icons-react';
|
import { IconAlertCircle } from '@tabler/icons-react';
|
||||||
import { Key } from 'ts-key-enum';
|
import { Key } from 'ts-key-enum';
|
||||||
|
|
||||||
import { usePreviousHotkeysScope } from '@/hotkeys/hooks/internal/usePreviousHotkeysScope';
|
import { usePreviousHotkeyScope } from '@/lib/hotkeys/hooks/usePreviousHotkeyScope';
|
||||||
import { useScopedHotkeys } from '@/hotkeys/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/lib/hotkeys/hooks/useScopedHotkeys';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
import { IconEye, IconEyeOff } from '@/ui/icons/index';
|
import { IconEye, IconEyeOff } from '@/ui/icons/index';
|
||||||
|
|
||||||
|
import { InputHotkeyScope } from './types/InputHotkeyScope';
|
||||||
|
|
||||||
type OwnProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'onChange'> & {
|
type OwnProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'onChange'> & {
|
||||||
label?: string;
|
label?: string;
|
||||||
onChange?: (text: string) => void;
|
onChange?: (text: string) => void;
|
||||||
@ -110,18 +111,18 @@ export function TextInput({
|
|||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
goBackToPreviousHotkeysScope,
|
goBackToPreviousHotkeyScope,
|
||||||
setHotkeysScopeAndMemorizePreviousScope,
|
setHotkeyScopeAndMemorizePreviousScope,
|
||||||
} = usePreviousHotkeysScope();
|
} = usePreviousHotkeyScope();
|
||||||
|
|
||||||
const handleFocus: FocusEventHandler<HTMLInputElement> = (e) => {
|
const handleFocus: FocusEventHandler<HTMLInputElement> = (e) => {
|
||||||
onFocus?.(e);
|
onFocus?.(e);
|
||||||
setHotkeysScopeAndMemorizePreviousScope(InternalHotkeysScope.TextInput);
|
setHotkeyScopeAndMemorizePreviousScope(InputHotkeyScope.TextInput);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBlur: FocusEventHandler<HTMLInputElement> = (e) => {
|
const handleBlur: FocusEventHandler<HTMLInputElement> = (e) => {
|
||||||
onBlur?.(e);
|
onBlur?.(e);
|
||||||
goBackToPreviousHotkeysScope();
|
goBackToPreviousHotkeyScope();
|
||||||
};
|
};
|
||||||
|
|
||||||
useScopedHotkeys(
|
useScopedHotkeys(
|
||||||
@ -129,7 +130,7 @@ export function TextInput({
|
|||||||
() => {
|
() => {
|
||||||
inputRef.current?.blur();
|
inputRef.current?.blur();
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.TextInput,
|
InputHotkeyScope.TextInput,
|
||||||
);
|
);
|
||||||
|
|
||||||
const [passwordVisible, setPasswordVisible] = useState(false);
|
const [passwordVisible, setPasswordVisible] = useState(false);
|
||||||
|
|||||||
@ -0,0 +1,3 @@
|
|||||||
|
export enum InputHotkeyScope {
|
||||||
|
TextInput = 'text-input',
|
||||||
|
}
|
||||||
@ -1,7 +1,6 @@
|
|||||||
import { ReactNode, useCallback, useState } from 'react';
|
import { ReactNode, useCallback, useState } from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
import { FilterDropdownButton } from '@/lib/filters-and-sorts/components/FilterDropdownButton';
|
import { FilterDropdownButton } from '@/lib/filters-and-sorts/components/FilterDropdownButton';
|
||||||
import SortAndFilterBar from '@/lib/filters-and-sorts/components/SortAndFilterBar';
|
import SortAndFilterBar from '@/lib/filters-and-sorts/components/SortAndFilterBar';
|
||||||
import { SortDropdownButton } from '@/lib/filters-and-sorts/components/SortDropdownButton';
|
import { SortDropdownButton } from '@/lib/filters-and-sorts/components/SortDropdownButton';
|
||||||
@ -9,6 +8,7 @@ import {
|
|||||||
SelectedSortType,
|
SelectedSortType,
|
||||||
SortType,
|
SortType,
|
||||||
} from '@/lib/filters-and-sorts/interfaces/sorts/interface';
|
} from '@/lib/filters-and-sorts/interfaces/sorts/interface';
|
||||||
|
import { FiltersHotkeyScope } from '@/lib/filters-and-sorts/types/FiltersHotkeyScope';
|
||||||
import { TableContext } from '@/ui/tables/states/TableContext';
|
import { TableContext } from '@/ui/tables/states/TableContext';
|
||||||
|
|
||||||
type OwnProps<SortField> = {
|
type OwnProps<SortField> = {
|
||||||
@ -93,13 +93,13 @@ export function TableHeader<SortField>({
|
|||||||
<StyledFilters>
|
<StyledFilters>
|
||||||
<FilterDropdownButton
|
<FilterDropdownButton
|
||||||
context={TableContext}
|
context={TableContext}
|
||||||
hotkeysScope={InternalHotkeysScope.TableHeaderDropdownButton}
|
HotkeyScope={FiltersHotkeyScope.FilterDropdownButton}
|
||||||
/>
|
/>
|
||||||
<SortDropdownButton<SortField>
|
<SortDropdownButton<SortField>
|
||||||
isSortSelected={sorts.length > 0}
|
isSortSelected={sorts.length > 0}
|
||||||
availableSorts={availableSorts || []}
|
availableSorts={availableSorts || []}
|
||||||
onSortSelect={sortSelect}
|
onSortSelect={sortSelect}
|
||||||
hotkeysScope={InternalHotkeysScope.TableHeaderDropdownButton}
|
HotkeyScope={FiltersHotkeyScope.FilterDropdownButton}
|
||||||
/>
|
/>
|
||||||
</StyledFilters>
|
</StyledFilters>
|
||||||
</StyledTableHeader>
|
</StyledTableHeader>
|
||||||
|
|||||||
@ -0,0 +1,3 @@
|
|||||||
|
export enum RightDrawerHotkeyScope {
|
||||||
|
RightDrawer = 'right-drawer',
|
||||||
|
}
|
||||||
@ -1,17 +1,14 @@
|
|||||||
import { useScopedHotkeys } from '@/hotkeys/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/lib/hotkeys/hooks/useScopedHotkeys';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
import { TableHotkeyScope } from '@/ui/tables/types/TableHotkeyScope';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
onAddButtonClick?: () => void;
|
onAddButtonClick?: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function TopBarHotkeys({ onAddButtonClick }: OwnProps) {
|
export function TopBarHotkeys({ onAddButtonClick }: OwnProps) {
|
||||||
useScopedHotkeys(
|
useScopedHotkeys('c', () => onAddButtonClick?.(), TableHotkeyScope.Table, [
|
||||||
'c',
|
onAddButtonClick,
|
||||||
() => onAddButtonClick?.(),
|
]);
|
||||||
InternalHotkeysScope.Table,
|
|
||||||
[onAddButtonClick],
|
|
||||||
);
|
|
||||||
|
|
||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
import { useSetHotkeysScope } from '@/hotkeys/hooks/useSetHotkeysScope';
|
import { useSetHotkeyScope } from '@/lib/hotkeys/hooks/useSetHotkeyScope';
|
||||||
import { currentHotkeysScopeState } from '@/hotkeys/states/internal/currentHotkeysScopeState';
|
import { currentHotkeyScopeState } from '@/lib/hotkeys/states/internal/currentHotkeyScopeState';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
|
|
||||||
import { isSoftFocusActiveState } from '../states/isSoftFocusActiveState';
|
import { isSoftFocusActiveState } from '../states/isSoftFocusActiveState';
|
||||||
import { isSomeInputInEditModeState } from '../states/isSomeInputInEditModeState';
|
import { isSomeInputInEditModeState } from '../states/isSomeInputInEditModeState';
|
||||||
|
import { TableHotkeyScope } from '../types/TableHotkeyScope';
|
||||||
|
|
||||||
import { useCloseCurrentCellInEditMode } from './useClearCellInEditMode';
|
import { useCloseCurrentCellInEditMode } from './useClearCellInEditMode';
|
||||||
import { useDisableSoftFocus } from './useDisableSoftFocus';
|
import { useDisableSoftFocus } from './useDisableSoftFocus';
|
||||||
@ -14,7 +14,7 @@ export function useLeaveTableFocus() {
|
|||||||
const disableSoftFocus = useDisableSoftFocus();
|
const disableSoftFocus = useDisableSoftFocus();
|
||||||
const closeCurrentCellInEditMode = useCloseCurrentCellInEditMode();
|
const closeCurrentCellInEditMode = useCloseCurrentCellInEditMode();
|
||||||
|
|
||||||
const setHotkeysScope = useSetHotkeysScope();
|
const setHotkeyScope = useSetHotkeyScope();
|
||||||
|
|
||||||
return useRecoilCallback(
|
return useRecoilCallback(
|
||||||
({ snapshot }) =>
|
({ snapshot }) =>
|
||||||
@ -27,8 +27,8 @@ export function useLeaveTableFocus() {
|
|||||||
.getLoadable(isSomeInputInEditModeState)
|
.getLoadable(isSomeInputInEditModeState)
|
||||||
.valueOrThrow();
|
.valueOrThrow();
|
||||||
|
|
||||||
const currentHotkeysScope = snapshot
|
const currentHotkeyScope = snapshot
|
||||||
.getLoadable(currentHotkeysScopeState)
|
.getLoadable(currentHotkeyScopeState)
|
||||||
.valueOrThrow();
|
.valueOrThrow();
|
||||||
|
|
||||||
if (isSomeInputInEditMode) {
|
if (isSomeInputInEditMode) {
|
||||||
@ -39,15 +39,15 @@ export function useLeaveTableFocus() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentHotkeysScope?.scope === InternalHotkeysScope.Table) {
|
if (currentHotkeyScope?.scope === TableHotkeyScope.Table) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
closeCurrentCellInEditMode();
|
closeCurrentCellInEditMode();
|
||||||
disableSoftFocus();
|
disableSoftFocus();
|
||||||
|
|
||||||
setHotkeysScope(InternalHotkeysScope.Table, { goto: true });
|
setHotkeyScope(TableHotkeyScope.Table, { goto: true });
|
||||||
},
|
},
|
||||||
[setHotkeysScope, closeCurrentCellInEditMode, disableSoftFocus],
|
[setHotkeyScope, closeCurrentCellInEditMode, disableSoftFocus],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
import { Key } from 'ts-key-enum';
|
import { Key } from 'ts-key-enum';
|
||||||
|
|
||||||
import { useScopedHotkeys } from '@/hotkeys/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/lib/hotkeys/hooks/useScopedHotkeys';
|
||||||
import { useSetHotkeysScope } from '@/hotkeys/hooks/useSetHotkeysScope';
|
import { useSetHotkeyScope } from '@/lib/hotkeys/hooks/useSetHotkeyScope';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
|
|
||||||
import { isSomeInputInEditModeState } from '../states/isSomeInputInEditModeState';
|
import { isSomeInputInEditModeState } from '../states/isSomeInputInEditModeState';
|
||||||
|
import { TableHotkeyScope } from '../types/TableHotkeyScope';
|
||||||
|
|
||||||
import { useDisableSoftFocus } from './useDisableSoftFocus';
|
import { useDisableSoftFocus } from './useDisableSoftFocus';
|
||||||
import { useMoveSoftFocus } from './useMoveSoftFocus';
|
import { useMoveSoftFocus } from './useMoveSoftFocus';
|
||||||
@ -14,7 +14,7 @@ export function useMapKeyboardToSoftFocus() {
|
|||||||
const { moveDown, moveLeft, moveRight, moveUp } = useMoveSoftFocus();
|
const { moveDown, moveLeft, moveRight, moveUp } = useMoveSoftFocus();
|
||||||
|
|
||||||
const disableSoftFocus = useDisableSoftFocus();
|
const disableSoftFocus = useDisableSoftFocus();
|
||||||
const setHotkeysScope = useSetHotkeysScope();
|
const setHotkeyScope = useSetHotkeyScope();
|
||||||
|
|
||||||
const [isSomeInputInEditMode] = useRecoilState(isSomeInputInEditModeState);
|
const [isSomeInputInEditMode] = useRecoilState(isSomeInputInEditModeState);
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ export function useMapKeyboardToSoftFocus() {
|
|||||||
moveUp();
|
moveUp();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.TableSoftFocus,
|
TableHotkeyScope.TableSoftFocus,
|
||||||
[moveUp, isSomeInputInEditMode],
|
[moveUp, isSomeInputInEditMode],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ export function useMapKeyboardToSoftFocus() {
|
|||||||
moveDown();
|
moveDown();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.TableSoftFocus,
|
TableHotkeyScope.TableSoftFocus,
|
||||||
[moveDown, isSomeInputInEditMode],
|
[moveDown, isSomeInputInEditMode],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ export function useMapKeyboardToSoftFocus() {
|
|||||||
moveLeft();
|
moveLeft();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.TableSoftFocus,
|
TableHotkeyScope.TableSoftFocus,
|
||||||
[moveLeft, isSomeInputInEditMode],
|
[moveLeft, isSomeInputInEditMode],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -58,17 +58,17 @@ export function useMapKeyboardToSoftFocus() {
|
|||||||
moveRight();
|
moveRight();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.TableSoftFocus,
|
TableHotkeyScope.TableSoftFocus,
|
||||||
[moveRight, isSomeInputInEditMode],
|
[moveRight, isSomeInputInEditMode],
|
||||||
);
|
);
|
||||||
|
|
||||||
useScopedHotkeys(
|
useScopedHotkeys(
|
||||||
[Key.Escape],
|
[Key.Escape],
|
||||||
() => {
|
() => {
|
||||||
setHotkeysScope(InternalHotkeysScope.Table, { goto: true });
|
setHotkeyScope(TableHotkeyScope.Table, { goto: true });
|
||||||
disableSoftFocus();
|
disableSoftFocus();
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.TableSoftFocus,
|
TableHotkeyScope.TableSoftFocus,
|
||||||
[disableSoftFocus],
|
[disableSoftFocus],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
7
front/src/modules/ui/tables/types/TableHotkeyScope.ts
Normal file
7
front/src/modules/ui/tables/types/TableHotkeyScope.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export enum TableHotkeyScope {
|
||||||
|
CellDoubleTextInput = 'cell-double-text-input',
|
||||||
|
CellEditMode = 'cell-edit-mode',
|
||||||
|
CellDateEditMode = 'cell-date-edit-mode',
|
||||||
|
TableSoftFocus = 'table-soft-focus',
|
||||||
|
Table = 'table',
|
||||||
|
}
|
||||||
@ -13,8 +13,7 @@ import { Title } from '@/auth/components/ui/Title';
|
|||||||
import { useOnboardingStatus } from '@/auth/hooks/useOnboardingStatus';
|
import { useOnboardingStatus } from '@/auth/hooks/useOnboardingStatus';
|
||||||
import { currentUserState } from '@/auth/states/currentUserState';
|
import { currentUserState } from '@/auth/states/currentUserState';
|
||||||
import { OnboardingStatus } from '@/auth/utils/getOnboardingStatus';
|
import { OnboardingStatus } from '@/auth/utils/getOnboardingStatus';
|
||||||
import { useScopedHotkeys } from '@/hotkeys/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/lib/hotkeys/hooks/useScopedHotkeys';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
import { ProfilePictureUploader } from '@/settings/profile/components/ProfilePictureUploader';
|
import { ProfilePictureUploader } from '@/settings/profile/components/ProfilePictureUploader';
|
||||||
import { useSnackBar } from '@/snack-bar/hooks/useSnackBar';
|
import { useSnackBar } from '@/snack-bar/hooks/useSnackBar';
|
||||||
import { MainButton } from '@/ui/components/buttons/MainButton';
|
import { MainButton } from '@/ui/components/buttons/MainButton';
|
||||||
@ -22,6 +21,7 @@ import { TextInput } from '@/ui/components/inputs/TextInput';
|
|||||||
import { SubSectionTitle } from '@/ui/components/section-titles/SubSectionTitle';
|
import { SubSectionTitle } from '@/ui/components/section-titles/SubSectionTitle';
|
||||||
import { GET_CURRENT_USER } from '@/users/queries';
|
import { GET_CURRENT_USER } from '@/users/queries';
|
||||||
import { useUpdateUserMutation } from '~/generated/graphql';
|
import { useUpdateUserMutation } from '~/generated/graphql';
|
||||||
|
import { PageHotkeyScope } from '~/sync-hooks/types/PageHotkeyScope';
|
||||||
|
|
||||||
const StyledContentContainer = styled.div`
|
const StyledContentContainer = styled.div`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -129,7 +129,7 @@ export function CreateProfile() {
|
|||||||
() => {
|
() => {
|
||||||
onSubmit(getValues());
|
onSubmit(getValues());
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.CreateProfile,
|
PageHotkeyScope.CreateProfile,
|
||||||
[onSubmit],
|
[onSubmit],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -10,8 +10,7 @@ import { SubTitle } from '@/auth/components/ui/SubTitle';
|
|||||||
import { Title } from '@/auth/components/ui/Title';
|
import { Title } from '@/auth/components/ui/Title';
|
||||||
import { useOnboardingStatus } from '@/auth/hooks/useOnboardingStatus';
|
import { useOnboardingStatus } from '@/auth/hooks/useOnboardingStatus';
|
||||||
import { OnboardingStatus } from '@/auth/utils/getOnboardingStatus';
|
import { OnboardingStatus } from '@/auth/utils/getOnboardingStatus';
|
||||||
import { useScopedHotkeys } from '@/hotkeys/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/lib/hotkeys/hooks/useScopedHotkeys';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
import { WorkspaceLogoUploader } from '@/settings/workspace/components/WorkspaceLogoUploader';
|
import { WorkspaceLogoUploader } from '@/settings/workspace/components/WorkspaceLogoUploader';
|
||||||
import { useSnackBar } from '@/snack-bar/hooks/useSnackBar';
|
import { useSnackBar } from '@/snack-bar/hooks/useSnackBar';
|
||||||
import { MainButton } from '@/ui/components/buttons/MainButton';
|
import { MainButton } from '@/ui/components/buttons/MainButton';
|
||||||
@ -19,6 +18,7 @@ import { TextInput } from '@/ui/components/inputs/TextInput';
|
|||||||
import { SubSectionTitle } from '@/ui/components/section-titles/SubSectionTitle';
|
import { SubSectionTitle } from '@/ui/components/section-titles/SubSectionTitle';
|
||||||
import { GET_CURRENT_USER } from '@/users/queries';
|
import { GET_CURRENT_USER } from '@/users/queries';
|
||||||
import { useUpdateWorkspaceMutation } from '~/generated/graphql';
|
import { useUpdateWorkspaceMutation } from '~/generated/graphql';
|
||||||
|
import { PageHotkeyScope } from '~/sync-hooks/types/PageHotkeyScope';
|
||||||
|
|
||||||
const StyledContentContainer = styled.div`
|
const StyledContentContainer = styled.div`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -101,7 +101,7 @@ export function CreateWorkspace() {
|
|||||||
() => {
|
() => {
|
||||||
onSubmit(getValues());
|
onSubmit(getValues());
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.CreateWokspace,
|
PageHotkeyScope.CreateWokspace,
|
||||||
[onSubmit],
|
[onSubmit],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -12,12 +12,12 @@ import { Title } from '@/auth/components/ui/Title';
|
|||||||
import { authFlowUserEmailState } from '@/auth/states/authFlowUserEmailState';
|
import { authFlowUserEmailState } from '@/auth/states/authFlowUserEmailState';
|
||||||
import { authProvidersState } from '@/client-config/states/authProvidersState';
|
import { authProvidersState } from '@/client-config/states/authProvidersState';
|
||||||
import { isDemoModeState } from '@/client-config/states/isDemoModeState';
|
import { isDemoModeState } from '@/client-config/states/isDemoModeState';
|
||||||
import { useScopedHotkeys } from '@/hotkeys/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/lib/hotkeys/hooks/useScopedHotkeys';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
import { MainButton } from '@/ui/components/buttons/MainButton';
|
import { MainButton } from '@/ui/components/buttons/MainButton';
|
||||||
import { TextInput } from '@/ui/components/inputs/TextInput';
|
import { TextInput } from '@/ui/components/inputs/TextInput';
|
||||||
import { AnimatedEaseIn } from '@/ui/components/motion/AnimatedEaseIn';
|
import { AnimatedEaseIn } from '@/ui/components/motion/AnimatedEaseIn';
|
||||||
import { IconBrandGoogle } from '@/ui/icons';
|
import { IconBrandGoogle } from '@/ui/icons';
|
||||||
|
import { PageHotkeyScope } from '~/sync-hooks/types/PageHotkeyScope';
|
||||||
|
|
||||||
const StyledContentContainer = styled.div`
|
const StyledContentContainer = styled.div`
|
||||||
width: 200px;
|
width: 200px;
|
||||||
@ -60,7 +60,7 @@ export function Index() {
|
|||||||
() => {
|
() => {
|
||||||
onPasswordLoginClick();
|
onPasswordLoginClick();
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.AuthIndex,
|
PageHotkeyScope.AuthIndex,
|
||||||
[onPasswordLoginClick],
|
[onPasswordLoginClick],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -13,13 +13,13 @@ import { useAuth } from '@/auth/hooks/useAuth';
|
|||||||
import { authFlowUserEmailState } from '@/auth/states/authFlowUserEmailState';
|
import { authFlowUserEmailState } from '@/auth/states/authFlowUserEmailState';
|
||||||
import { PASSWORD_REGEX } from '@/auth/utils/passwordRegex';
|
import { PASSWORD_REGEX } from '@/auth/utils/passwordRegex';
|
||||||
import { isDemoModeState } from '@/client-config/states/isDemoModeState';
|
import { isDemoModeState } from '@/client-config/states/isDemoModeState';
|
||||||
import { useScopedHotkeys } from '@/hotkeys/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/lib/hotkeys/hooks/useScopedHotkeys';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
|
||||||
import { useSnackBar } from '@/snack-bar/hooks/useSnackBar';
|
import { useSnackBar } from '@/snack-bar/hooks/useSnackBar';
|
||||||
import { MainButton } from '@/ui/components/buttons/MainButton';
|
import { MainButton } from '@/ui/components/buttons/MainButton';
|
||||||
import { TextInput } from '@/ui/components/inputs/TextInput';
|
import { TextInput } from '@/ui/components/inputs/TextInput';
|
||||||
import { SubSectionTitle } from '@/ui/components/section-titles/SubSectionTitle';
|
import { SubSectionTitle } from '@/ui/components/section-titles/SubSectionTitle';
|
||||||
import { useCheckUserExistsQuery } from '~/generated/graphql';
|
import { useCheckUserExistsQuery } from '~/generated/graphql';
|
||||||
|
import { PageHotkeyScope } from '~/sync-hooks/types/PageHotkeyScope';
|
||||||
|
|
||||||
const StyledContentContainer = styled.div`
|
const StyledContentContainer = styled.div`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -132,7 +132,7 @@ export function PasswordLogin() {
|
|||||||
() => {
|
() => {
|
||||||
onSubmit(getValues());
|
onSubmit(getValues());
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.PasswordLogin,
|
PageHotkeyScope.PasswordLogin,
|
||||||
[onSubmit],
|
[onSubmit],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useGoToHotkeys } from '@/hotkeys/hooks/useGoToHotkeys';
|
import { useGoToHotkeys } from '@/lib/hotkeys/hooks/useGoToHotkeys';
|
||||||
|
|
||||||
export function GotoHotkeysHooks() {
|
export function GotoHotkeysHooks() {
|
||||||
useGoToHotkeys('p', '/people');
|
useGoToHotkeys('p', '/people');
|
||||||
|
|||||||
7
front/src/sync-hooks/HotkeyScopeAutoSyncHook.tsx
Normal file
7
front/src/sync-hooks/HotkeyScopeAutoSyncHook.tsx
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { useHotkeyScopeAutoSync } from '@/lib/hotkeys/hooks/internal/useHotkeyScopeAutoSync';
|
||||||
|
|
||||||
|
export function HotkeyScopeAutoSyncHook() {
|
||||||
|
useHotkeyScopeAutoSync();
|
||||||
|
|
||||||
|
return <></>;
|
||||||
|
}
|
||||||
@ -1,71 +1,71 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
import { useSetHotkeysScope } from '@/hotkeys/hooks/useSetHotkeysScope';
|
import { useSetHotkeyScope } from '@/lib/hotkeys/hooks/useSetHotkeyScope';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
import { TableHotkeyScope } from '@/ui/tables/types/TableHotkeyScope';
|
||||||
import { PageHotkeysScope } from '@/hotkeys/types/internal/PageHotkeysScope';
|
|
||||||
|
|
||||||
import { useIsMatchingLocation } from './hooks/useIsMatchingLocation';
|
import { useIsMatchingLocation } from './hooks/useIsMatchingLocation';
|
||||||
import { AppBasePath } from './types/AppBasePath';
|
import { AppBasePath } from './types/AppBasePath';
|
||||||
import { AppPath } from './types/AppPath';
|
import { AppPath } from './types/AppPath';
|
||||||
import { AuthPath } from './types/AuthPath';
|
import { AuthPath } from './types/AuthPath';
|
||||||
|
import { PageHotkeyScope } from './types/PageHotkeyScope';
|
||||||
import { SettingsPath } from './types/SettingsPath';
|
import { SettingsPath } from './types/SettingsPath';
|
||||||
|
|
||||||
export function HotkeysScopeBrowserRouterSync() {
|
export function HotkeyScopeBrowserRouterSync() {
|
||||||
const isMatchingLocation = useIsMatchingLocation();
|
const isMatchingLocation = useIsMatchingLocation();
|
||||||
|
|
||||||
const setHotkeysScope = useSetHotkeysScope();
|
const setHotkeyScope = useSetHotkeyScope();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case isMatchingLocation(AppBasePath.Root, AppPath.CompaniesPage): {
|
case isMatchingLocation(AppBasePath.Root, AppPath.CompaniesPage): {
|
||||||
setHotkeysScope(InternalHotkeysScope.Table, { goto: true });
|
setHotkeyScope(TableHotkeyScope.Table, { goto: true });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case isMatchingLocation(AppBasePath.Root, AppPath.PeoplePage): {
|
case isMatchingLocation(AppBasePath.Root, AppPath.PeoplePage): {
|
||||||
setHotkeysScope(InternalHotkeysScope.Table, { goto: true });
|
setHotkeyScope(TableHotkeyScope.Table, { goto: true });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case isMatchingLocation(AppBasePath.Root, AppPath.CompanyShowPage): {
|
case isMatchingLocation(AppBasePath.Root, AppPath.CompanyShowPage): {
|
||||||
setHotkeysScope(PageHotkeysScope.CompanyShowPage, { goto: true });
|
setHotkeyScope(PageHotkeyScope.CompanyShowPage, { goto: true });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case isMatchingLocation(AppBasePath.Root, AppPath.PersonShowPage): {
|
case isMatchingLocation(AppBasePath.Root, AppPath.PersonShowPage): {
|
||||||
setHotkeysScope(PageHotkeysScope.PersonShowPage, { goto: true });
|
setHotkeyScope(PageHotkeyScope.PersonShowPage, { goto: true });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case isMatchingLocation(AppBasePath.Root, AppPath.OpportunitiesPage): {
|
case isMatchingLocation(AppBasePath.Root, AppPath.OpportunitiesPage): {
|
||||||
setHotkeysScope(PageHotkeysScope.OpportunitiesPage, { goto: true });
|
setHotkeyScope(PageHotkeyScope.OpportunitiesPage, { goto: true });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case isMatchingLocation(AppBasePath.Auth, AuthPath.Index): {
|
case isMatchingLocation(AppBasePath.Auth, AuthPath.Index): {
|
||||||
setHotkeysScope(InternalHotkeysScope.AuthIndex);
|
setHotkeyScope(PageHotkeyScope.AuthIndex);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case isMatchingLocation(AppBasePath.Auth, AuthPath.CreateProfile): {
|
case isMatchingLocation(AppBasePath.Auth, AuthPath.CreateProfile): {
|
||||||
setHotkeysScope(InternalHotkeysScope.CreateProfile);
|
setHotkeyScope(PageHotkeyScope.CreateProfile);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case isMatchingLocation(AppBasePath.Auth, AuthPath.CreateWorkspace): {
|
case isMatchingLocation(AppBasePath.Auth, AuthPath.CreateWorkspace): {
|
||||||
setHotkeysScope(InternalHotkeysScope.CreateWokspace);
|
setHotkeyScope(PageHotkeyScope.CreateWokspace);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case isMatchingLocation(AppBasePath.Auth, AuthPath.PasswordLogin): {
|
case isMatchingLocation(AppBasePath.Auth, AuthPath.PasswordLogin): {
|
||||||
setHotkeysScope(InternalHotkeysScope.PasswordLogin);
|
setHotkeyScope(PageHotkeyScope.PasswordLogin);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case isMatchingLocation(AppBasePath.Settings, SettingsPath.ProfilePage): {
|
case isMatchingLocation(AppBasePath.Settings, SettingsPath.ProfilePage): {
|
||||||
setHotkeysScope(PageHotkeysScope.ProfilePage, { goto: true });
|
setHotkeyScope(PageHotkeyScope.ProfilePage, { goto: true });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case isMatchingLocation(
|
case isMatchingLocation(
|
||||||
AppBasePath.Settings,
|
AppBasePath.Settings,
|
||||||
SettingsPath.WorkspaceMembersPage,
|
SettingsPath.WorkspaceMembersPage,
|
||||||
): {
|
): {
|
||||||
setHotkeysScope(PageHotkeysScope.WorkspaceMemberPage, { goto: true });
|
setHotkeyScope(PageHotkeyScope.WorkspaceMemberPage, { goto: true });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [isMatchingLocation, setHotkeysScope]);
|
}, [isMatchingLocation, setHotkeyScope]);
|
||||||
|
|
||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
@ -1,7 +0,0 @@
|
|||||||
import { useHotkeysScopeAutoSync } from '@/hotkeys/hooks/internal/useHotkeysScopeAutoSync';
|
|
||||||
|
|
||||||
export function HotkeysScopeAutoSyncHook() {
|
|
||||||
useHotkeysScopeAutoSync();
|
|
||||||
|
|
||||||
return <></>;
|
|
||||||
}
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
export enum PageHotkeysScope {
|
export enum PageHotkeyScope {
|
||||||
Settings = 'settings',
|
Settings = 'settings',
|
||||||
CreateWokspace = 'create-workspace',
|
CreateWokspace = 'create-workspace',
|
||||||
PasswordLogin = 'password-login',
|
PasswordLogin = 'password-login',
|
||||||
@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import { HotkeysProvider } from 'react-hotkeys-hook';
|
import { HotkeysProvider } from 'react-hotkeys-hook';
|
||||||
import { MemoryRouter } from 'react-router-dom';
|
import { MemoryRouter } from 'react-router-dom';
|
||||||
|
|
||||||
import { INITIAL_HOTKEYS_SCOPES } from '@/hotkeys/constants';
|
import { INITIAL_HOTKEYS_SCOPES } from '@/lib/hotkeys/constants';
|
||||||
import { RecoilScope } from '@/recoil-scope/components/RecoilScope';
|
import { RecoilScope } from '@/recoil-scope/components/RecoilScope';
|
||||||
import { HooksEntityTable } from '@/ui/components/table/HooksEntityTable';
|
import { HooksEntityTable } from '@/ui/components/table/HooksEntityTable';
|
||||||
import { DefaultLayout } from '@/ui/layout/DefaultLayout';
|
import { DefaultLayout } from '@/ui/layout/DefaultLayout';
|
||||||
|
|||||||
Reference in New Issue
Block a user