Jotai 13 (#18178)
## Recoil to Jotai Migration — PR 13: Workflow, Page Layout, AI, Activities, Settings, SSE & Remaining Modules ### Summary This is the 13th PR in the [14-PR migration series](packages/twenty-front/src/modules/ui/utilities/state/jotai/MIGRATION_PLAN.md) to replace Recoil with Jotai as the state management library in `twenty-front`. This PR migrates the remaining consumer code across all modules — updating ~1,076 files with ~10k insertions/deletions. ### What changed **New Jotai infrastructure (13 new files):** - `createComponentSelectorV2` and `createComponentFamilySelectorV2` — instance-scoped derived atoms, replacing Recoil's component selectors - 6 new hooks: `useRecoilComponentSelectorValueV2`, `useRecoilComponentFamilySelectorValueV2`, `useRecoilComponentSelectorCallbackStateV2`, `useRecoilComponentFamilySelectorCallbackStateV2`, `useRecoilComponentStateCallbackStateV2`, `useRecoilComponentFamilyStateCallbackStateV2` - New types: `ComponentSelectorV2`, `ComponentFamilySelectorV2`, `SelectorCallbacksV2` - Extended `buildGetHelper` to support the new selector patterns **State definition migrations:** - `createState()` → `createStateV2()` (Jotai `atom()`) - `createFamilyState()` → `createFamilyStateV2()` (Jotai `atom()` with family cache) - Recoil `selector`/`selectorFamily` → Jotai derived `atom()` via V2 utilities **Hook migrations (~2,400 removed, ~1,545 added V2 equivalents):** - `useRecoilValue` → `useRecoilValueV2` - `useRecoilState` → `useRecoilStateV2` - `useSetRecoilState` → `useSetRecoilStateV2` - `useRecoilCallback` → `useCallback` + `jotaiStore.get/set` - `useRecoilComponentValue` → `useRecoilComponentValueV2` - `useSetRecoilComponentState` → `useSetRecoilComponentStateV2` - `useRecoilComponentFamilyValue` → `useRecoilComponentFamilyValueV2` / `useFamilySelectorValueV2` - ~397 direct `import from 'recoil'` removed **Deleted files (9 files):** - `dateLocaleState.ts` — consolidated - `currentAIChatThreadTitleStateV2.ts` — renamed to replace the original - `isCommandMenuOpenedState.ts` — removed - `filesFieldUploadState.ts` — replaced by V2 - `recordStoreFamilySelector.ts`, `recordStoreFieldValueSelector.ts`, `recordStoreRecordsSelector.ts` — replaced by V2 equivalents - `settingsAllRolesSelector.ts` — replaced by `useSettingsAllRoles` hook - `settingsRoleIdsStateV2.ts` — consolidated **Modules migrated:** - Workflow (diagram, steps, variables, filters) - Page Layout (widgets, fields, graph, tabs) - AI (chat, agents, browsing context) - Activities (rich text editor, targets, timeline) - Action Menu (single/multiple record actions) - Command Menu (navigation, history, pages, workflow) - Context Store - Record Board, Record Table, Record Calendar, Record Index - Record Field, Record Filter, Record Sort, Record Group - Record Drag, Record Picker, Record Store - Views (view bar, view picker, filters, sorts) - Settings (roles, permissions, SSO, security, data model, developers, domains) - SSE (event streams, subscriptions) - Spreadsheet Import - Auth, Favorites, Front Components, Information Banner
This commit is contained in:
+29
-24
@@ -1,13 +1,14 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { act } from 'react';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { RecoilRoot, useRecoilValue } from 'recoil';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
|
||||
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
|
||||
import { commandMenuNavigationStackState } from '@/command-menu/states/commandMenuNavigationStackState';
|
||||
import { commandMenuPageInfoState } from '@/command-menu/states/commandMenuPageInfoState';
|
||||
import { commandMenuPageState } from '@/command-menu/states/commandMenuPageState';
|
||||
import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState';
|
||||
import { isCommandMenuOpenedStateV2 } from '@/command-menu/states/isCommandMenuOpenedStateV2';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
import { IconDotsVertical } from 'twenty-ui/display';
|
||||
|
||||
@@ -26,19 +27,9 @@ const renderHooks = () => {
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const commandMenu = useCommandMenu();
|
||||
const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState);
|
||||
const commandMenuNavigationStack = useRecoilValue(
|
||||
commandMenuNavigationStackState,
|
||||
);
|
||||
const commandMenuPage = useRecoilValue(commandMenuPageState);
|
||||
const commandMenuPageInfo = useRecoilValue(commandMenuPageInfoState);
|
||||
|
||||
return {
|
||||
commandMenu,
|
||||
isCommandMenuOpened,
|
||||
commandMenuNavigationStack,
|
||||
commandMenuPage,
|
||||
commandMenuPageInfo,
|
||||
};
|
||||
},
|
||||
{
|
||||
@@ -60,31 +51,31 @@ describe('useCommandMenu', () => {
|
||||
result.current.commandMenu.openCommandMenu();
|
||||
});
|
||||
|
||||
expect(result.current.isCommandMenuOpened).toBe(true);
|
||||
expect(jotaiStore.get(isCommandMenuOpenedStateV2.atom)).toBe(true);
|
||||
|
||||
act(() => {
|
||||
result.current.commandMenu.closeCommandMenu();
|
||||
});
|
||||
|
||||
expect(result.current.isCommandMenuOpened).toBe(false);
|
||||
expect(jotaiStore.get(isCommandMenuOpenedStateV2.atom)).toBe(false);
|
||||
});
|
||||
|
||||
it('should toggle the command menu', () => {
|
||||
const { result } = renderHooks();
|
||||
|
||||
expect(result.current.isCommandMenuOpened).toBe(false);
|
||||
expect(jotaiStore.get(isCommandMenuOpenedStateV2.atom)).toBe(false);
|
||||
|
||||
act(() => {
|
||||
result.current.commandMenu.toggleCommandMenu();
|
||||
});
|
||||
|
||||
expect(result.current.isCommandMenuOpened).toBe(true);
|
||||
expect(jotaiStore.get(isCommandMenuOpenedStateV2.atom)).toBe(true);
|
||||
|
||||
act(() => {
|
||||
result.current.commandMenu.toggleCommandMenu();
|
||||
});
|
||||
|
||||
expect(result.current.isCommandMenuOpened).toBe(false);
|
||||
expect(jotaiStore.get(isCommandMenuOpenedStateV2.atom)).toBe(false);
|
||||
});
|
||||
|
||||
it('should navigate command menu and reset navigation stack when resetNavigationStack is true', () => {
|
||||
@@ -99,9 +90,15 @@ describe('useCommandMenu', () => {
|
||||
});
|
||||
});
|
||||
|
||||
expect(result.current.commandMenuPage).toBe(CommandMenuPages.Root);
|
||||
expect(result.current.commandMenuPageInfo.title).toBe('First Page');
|
||||
expect(result.current.commandMenuNavigationStack).toHaveLength(1);
|
||||
expect(jotaiStore.get(commandMenuPageState.atom)).toBe(
|
||||
CommandMenuPages.Root,
|
||||
);
|
||||
expect(jotaiStore.get(commandMenuPageInfoState.atom).title).toBe(
|
||||
'First Page',
|
||||
);
|
||||
expect(jotaiStore.get(commandMenuNavigationStackState.atom)).toHaveLength(
|
||||
1,
|
||||
);
|
||||
|
||||
act(() => {
|
||||
result.current.commandMenu.navigateCommandMenu({
|
||||
@@ -112,7 +109,9 @@ describe('useCommandMenu', () => {
|
||||
});
|
||||
});
|
||||
|
||||
expect(result.current.commandMenuNavigationStack).toHaveLength(2);
|
||||
expect(jotaiStore.get(commandMenuNavigationStackState.atom)).toHaveLength(
|
||||
2,
|
||||
);
|
||||
|
||||
act(() => {
|
||||
result.current.commandMenu.navigateCommandMenu({
|
||||
@@ -123,8 +122,14 @@ describe('useCommandMenu', () => {
|
||||
});
|
||||
});
|
||||
|
||||
expect(result.current.commandMenuPage).toBe(CommandMenuPages.Root);
|
||||
expect(result.current.commandMenuPageInfo.title).toBe('Reset Page');
|
||||
expect(result.current.commandMenuNavigationStack).toHaveLength(1);
|
||||
expect(jotaiStore.get(commandMenuPageState.atom)).toBe(
|
||||
CommandMenuPages.Root,
|
||||
);
|
||||
expect(jotaiStore.get(commandMenuPageInfoState.atom).title).toBe(
|
||||
'Reset Page',
|
||||
);
|
||||
expect(jotaiStore.get(commandMenuNavigationStackState.atom)).toHaveLength(
|
||||
1,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
+32
-75
@@ -1,21 +1,23 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { act } from 'react';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { RecoilRoot, useRecoilValue, useSetRecoilState } from 'recoil';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
|
||||
import { COMMAND_MENU_COMPONENT_INSTANCE_ID } from '@/command-menu/constants/CommandMenuComponentInstanceId';
|
||||
import { COMMAND_MENU_CONTEXT_CHIP_GROUPS_DROPDOWN_ID } from '@/command-menu/constants/CommandMenuContextChipGroupsDropdownId';
|
||||
import { COMMAND_MENU_PREVIOUS_COMPONENT_INSTANCE_ID } from '@/command-menu/constants/CommandMenuPreviousComponentInstanceId';
|
||||
import { useCommandMenuCloseAnimationCompleteCleanup } from '@/command-menu/hooks/useCommandMenuCloseAnimationCompleteCleanup';
|
||||
import { commandMenuNavigationMorphItemsByPageState } from '@/command-menu/states/commandMenuNavigationMorphItemsByPageState';
|
||||
import { commandMenuNavigationStackState } from '@/command-menu/states/commandMenuNavigationStackState';
|
||||
import { commandMenuPageInfoState } from '@/command-menu/states/commandMenuPageInfoState';
|
||||
import { commandMenuPageState } from '@/command-menu/states/commandMenuPageState';
|
||||
import { commandMenuSearchState } from '@/command-menu/states/commandMenuSearchState';
|
||||
import { hasUserSelectedCommandState } from '@/command-menu/states/hasUserSelectedCommandState';
|
||||
import { isCommandMenuClosingState } from '@/command-menu/states/isCommandMenuClosingState';
|
||||
import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState';
|
||||
import { isCommandMenuOpenedStateV2 } from '@/command-menu/states/isCommandMenuOpenedStateV2';
|
||||
import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
import { IconList } from 'twenty-ui/display';
|
||||
|
||||
@@ -65,62 +67,13 @@ describe('useCommandMenuCloseAnimationCompleteCleanup', () => {
|
||||
const { commandMenuCloseAnimationCompleteCleanup } =
|
||||
useCommandMenuCloseAnimationCompleteCleanup();
|
||||
|
||||
const commandMenuPage = useRecoilValue(commandMenuPageState);
|
||||
const commandMenuPageInfo = useRecoilValue(commandMenuPageInfoState);
|
||||
const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState);
|
||||
const commandMenuSearch = useRecoilValue(commandMenuSearchState);
|
||||
const commandMenuNavigationStack = useRecoilValue(
|
||||
commandMenuNavigationStackState,
|
||||
);
|
||||
const viewableRecordId = useRecoilValueV2(viewableRecordIdState);
|
||||
|
||||
const commandMenuNavigationMorphItemsByPage = useRecoilValue(
|
||||
commandMenuNavigationMorphItemsByPageState,
|
||||
);
|
||||
const hasUserSelectedCommand = useRecoilValue(
|
||||
hasUserSelectedCommandState,
|
||||
);
|
||||
const isCommandMenuClosing = useRecoilValue(isCommandMenuClosingState);
|
||||
const viewableRecordId = useRecoilValue(viewableRecordIdState);
|
||||
|
||||
// Get setters for state modification in tests
|
||||
const setCommandMenuPage = useSetRecoilState(commandMenuPageState);
|
||||
const setCommandMenuPageInfo = useSetRecoilState(
|
||||
commandMenuPageInfoState,
|
||||
);
|
||||
const setIsCommandMenuOpened = useSetRecoilState(
|
||||
isCommandMenuOpenedState,
|
||||
);
|
||||
const setCommandMenuSearch = useSetRecoilState(commandMenuSearchState);
|
||||
const setCommandMenuNavigationStack = useSetRecoilState(
|
||||
commandMenuNavigationStackState,
|
||||
);
|
||||
|
||||
const setHasUserSelectedCommand = useSetRecoilState(
|
||||
hasUserSelectedCommandState,
|
||||
);
|
||||
const setIsCommandMenuClosing = useSetRecoilState(
|
||||
isCommandMenuClosingState,
|
||||
);
|
||||
const setViewableRecordId = useSetRecoilState(viewableRecordIdState);
|
||||
const setViewableRecordId = useSetRecoilStateV2(viewableRecordIdState);
|
||||
|
||||
return {
|
||||
commandMenuCloseAnimationCompleteCleanup,
|
||||
commandMenuPage,
|
||||
commandMenuPageInfo,
|
||||
isCommandMenuOpened,
|
||||
commandMenuSearch,
|
||||
commandMenuNavigationStack,
|
||||
commandMenuNavigationMorphItemsByPage,
|
||||
hasUserSelectedCommand,
|
||||
isCommandMenuClosing,
|
||||
viewableRecordId,
|
||||
setCommandMenuPage,
|
||||
setCommandMenuPageInfo,
|
||||
setIsCommandMenuOpened,
|
||||
setCommandMenuSearch,
|
||||
setCommandMenuNavigationStack,
|
||||
setHasUserSelectedCommand,
|
||||
setIsCommandMenuClosing,
|
||||
setViewableRecordId,
|
||||
};
|
||||
},
|
||||
@@ -135,15 +88,15 @@ describe('useCommandMenuCloseAnimationCompleteCleanup', () => {
|
||||
const { result } = renderHooks();
|
||||
|
||||
act(() => {
|
||||
result.current.setCommandMenuPage(CommandMenuPages.ViewRecord);
|
||||
result.current.setCommandMenuPageInfo({
|
||||
jotaiStore.set(commandMenuPageState.atom, CommandMenuPages.ViewRecord);
|
||||
jotaiStore.set(commandMenuPageInfoState.atom, {
|
||||
title: 'Test Record',
|
||||
Icon: IconList,
|
||||
instanceId: 'test-id',
|
||||
});
|
||||
result.current.setIsCommandMenuOpened(true);
|
||||
result.current.setCommandMenuSearch('test search');
|
||||
result.current.setCommandMenuNavigationStack([
|
||||
jotaiStore.set(isCommandMenuOpenedStateV2.atom, true);
|
||||
jotaiStore.set(commandMenuSearchState.atom, 'test search');
|
||||
jotaiStore.set(commandMenuNavigationStackState.atom, [
|
||||
{
|
||||
page: CommandMenuPages.SearchRecords,
|
||||
pageTitle: 'Search',
|
||||
@@ -151,20 +104,22 @@ describe('useCommandMenuCloseAnimationCompleteCleanup', () => {
|
||||
pageId: '1',
|
||||
},
|
||||
]);
|
||||
result.current.setHasUserSelectedCommand(true);
|
||||
result.current.setIsCommandMenuClosing(true);
|
||||
jotaiStore.set(hasUserSelectedCommandState.atom, true);
|
||||
jotaiStore.set(isCommandMenuClosingState.atom, true);
|
||||
result.current.setViewableRecordId('record-123');
|
||||
});
|
||||
|
||||
expect(result.current.commandMenuPage).toBe(CommandMenuPages.ViewRecord);
|
||||
expect(result.current.commandMenuPageInfo).toEqual({
|
||||
expect(jotaiStore.get(commandMenuPageState.atom)).toBe(
|
||||
CommandMenuPages.ViewRecord,
|
||||
);
|
||||
expect(jotaiStore.get(commandMenuPageInfoState.atom)).toEqual({
|
||||
title: 'Test Record',
|
||||
Icon: IconList,
|
||||
instanceId: 'test-id',
|
||||
});
|
||||
expect(result.current.isCommandMenuOpened).toBe(true);
|
||||
expect(result.current.commandMenuSearch).toBe('test search');
|
||||
expect(result.current.commandMenuNavigationStack).toEqual([
|
||||
expect(jotaiStore.get(isCommandMenuOpenedStateV2.atom)).toBe(true);
|
||||
expect(jotaiStore.get(commandMenuSearchState.atom)).toBe('test search');
|
||||
expect(jotaiStore.get(commandMenuNavigationStackState.atom)).toEqual([
|
||||
{
|
||||
page: CommandMenuPages.SearchRecords,
|
||||
pageTitle: 'Search',
|
||||
@@ -172,25 +127,27 @@ describe('useCommandMenuCloseAnimationCompleteCleanup', () => {
|
||||
pageId: '1',
|
||||
},
|
||||
]);
|
||||
expect(result.current.hasUserSelectedCommand).toBe(true);
|
||||
expect(result.current.isCommandMenuClosing).toBe(true);
|
||||
expect(jotaiStore.get(hasUserSelectedCommandState.atom)).toBe(true);
|
||||
expect(jotaiStore.get(isCommandMenuClosingState.atom)).toBe(true);
|
||||
expect(result.current.viewableRecordId).toBe('record-123');
|
||||
|
||||
act(() => {
|
||||
result.current.commandMenuCloseAnimationCompleteCleanup();
|
||||
});
|
||||
|
||||
expect(result.current.commandMenuPage).toBe(CommandMenuPages.Root);
|
||||
expect(result.current.commandMenuPageInfo).toEqual({
|
||||
expect(jotaiStore.get(commandMenuPageState.atom)).toBe(
|
||||
CommandMenuPages.Root,
|
||||
);
|
||||
expect(jotaiStore.get(commandMenuPageInfoState.atom)).toEqual({
|
||||
title: undefined,
|
||||
Icon: undefined,
|
||||
instanceId: '',
|
||||
});
|
||||
expect(result.current.isCommandMenuOpened).toBe(false);
|
||||
expect(result.current.commandMenuSearch).toBe('');
|
||||
expect(result.current.commandMenuNavigationStack).toEqual([]);
|
||||
expect(result.current.hasUserSelectedCommand).toBe(false);
|
||||
expect(result.current.isCommandMenuClosing).toBe(false);
|
||||
expect(jotaiStore.get(isCommandMenuOpenedStateV2.atom)).toBe(false);
|
||||
expect(jotaiStore.get(commandMenuSearchState.atom)).toBe('');
|
||||
expect(jotaiStore.get(commandMenuNavigationStackState.atom)).toEqual([]);
|
||||
expect(jotaiStore.get(hasUserSelectedCommandState.atom)).toBe(false);
|
||||
expect(jotaiStore.get(isCommandMenuClosingState.atom)).toBe(false);
|
||||
expect(result.current.viewableRecordId).toBe(null);
|
||||
});
|
||||
|
||||
|
||||
+19
-22
@@ -1,7 +1,7 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { act } from 'react';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { RecoilRoot, useRecoilValue } from 'recoil';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
|
||||
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
|
||||
import { useCommandMenuCloseAnimationCompleteCleanup } from '@/command-menu/hooks/useCommandMenuCloseAnimationCompleteCleanup';
|
||||
@@ -9,7 +9,8 @@ import { useCommandMenuHistory } from '@/command-menu/hooks/useCommandMenuHistor
|
||||
import { commandMenuNavigationStackState } from '@/command-menu/states/commandMenuNavigationStackState';
|
||||
import { commandMenuPageInfoState } from '@/command-menu/states/commandMenuPageInfoState';
|
||||
import { commandMenuPageState } from '@/command-menu/states/commandMenuPageState';
|
||||
import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState';
|
||||
import { isCommandMenuOpenedStateV2 } from '@/command-menu/states/isCommandMenuOpenedStateV2';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
import { IconList, IconSearch } from 'twenty-ui/display';
|
||||
|
||||
@@ -26,20 +27,10 @@ const renderHooks = () => {
|
||||
const commandMenuHistory = useCommandMenuHistory();
|
||||
const commandMenuCloseAnimationCompleteCleanup =
|
||||
useCommandMenuCloseAnimationCompleteCleanup();
|
||||
const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState);
|
||||
const commandMenuNavigationStack = useRecoilValue(
|
||||
commandMenuNavigationStackState,
|
||||
);
|
||||
const commandMenuPage = useRecoilValue(commandMenuPageState);
|
||||
const commandMenuPageInfo = useRecoilValue(commandMenuPageInfoState);
|
||||
|
||||
return {
|
||||
commandMenu,
|
||||
commandMenuHistory,
|
||||
isCommandMenuOpened,
|
||||
commandMenuNavigationStack,
|
||||
commandMenuPage,
|
||||
commandMenuPageInfo,
|
||||
commandMenuCloseAnimationCompleteCleanup,
|
||||
};
|
||||
},
|
||||
@@ -72,7 +63,7 @@ describe('useCommandMenuHistory', () => {
|
||||
});
|
||||
});
|
||||
|
||||
expect(result.current.commandMenuNavigationStack).toEqual([
|
||||
expect(jotaiStore.get(commandMenuNavigationStackState.atom)).toEqual([
|
||||
{
|
||||
page: CommandMenuPages.SearchRecords,
|
||||
pageTitle: 'Search',
|
||||
@@ -91,7 +82,7 @@ describe('useCommandMenuHistory', () => {
|
||||
result.current.commandMenuHistory.goBackFromCommandMenu();
|
||||
});
|
||||
|
||||
expect(result.current.commandMenuNavigationStack).toEqual([
|
||||
expect(jotaiStore.get(commandMenuNavigationStackState.atom)).toEqual([
|
||||
{
|
||||
page: CommandMenuPages.SearchRecords,
|
||||
pageTitle: 'Search',
|
||||
@@ -99,8 +90,10 @@ describe('useCommandMenuHistory', () => {
|
||||
pageId: '1',
|
||||
},
|
||||
]);
|
||||
expect(result.current.commandMenuPage).toBe(CommandMenuPages.SearchRecords);
|
||||
expect(result.current.commandMenuPageInfo).toEqual({
|
||||
expect(jotaiStore.get(commandMenuPageState.atom)).toBe(
|
||||
CommandMenuPages.SearchRecords,
|
||||
);
|
||||
expect(jotaiStore.get(commandMenuPageInfoState.atom)).toEqual({
|
||||
title: 'Search',
|
||||
Icon: IconSearch,
|
||||
instanceId: '1',
|
||||
@@ -111,14 +104,16 @@ describe('useCommandMenuHistory', () => {
|
||||
result.current.commandMenuCloseAnimationCompleteCleanup.commandMenuCloseAnimationCompleteCleanup();
|
||||
});
|
||||
|
||||
expect(result.current.commandMenuNavigationStack).toEqual([]);
|
||||
expect(result.current.commandMenuPage).toBe(CommandMenuPages.Root);
|
||||
expect(result.current.commandMenuPageInfo).toEqual({
|
||||
expect(jotaiStore.get(commandMenuNavigationStackState.atom)).toEqual([]);
|
||||
expect(jotaiStore.get(commandMenuPageState.atom)).toBe(
|
||||
CommandMenuPages.Root,
|
||||
);
|
||||
expect(jotaiStore.get(commandMenuPageInfoState.atom)).toEqual({
|
||||
title: undefined,
|
||||
instanceId: '',
|
||||
Icon: undefined,
|
||||
});
|
||||
expect(result.current.isCommandMenuOpened).toBe(false);
|
||||
expect(jotaiStore.get(isCommandMenuOpenedStateV2.atom)).toBe(false);
|
||||
});
|
||||
|
||||
it('should navigate to a page in history', () => {
|
||||
@@ -137,8 +132,10 @@ describe('useCommandMenuHistory', () => {
|
||||
result.current.commandMenuHistory.navigateCommandMenuHistory(0);
|
||||
});
|
||||
|
||||
expect(result.current.commandMenuPage).toBe(CommandMenuPages.SearchRecords);
|
||||
expect(result.current.commandMenuPageInfo).toEqual({
|
||||
expect(jotaiStore.get(commandMenuPageState.atom)).toBe(
|
||||
CommandMenuPages.SearchRecords,
|
||||
);
|
||||
expect(jotaiStore.get(commandMenuPageInfoState.atom)).toEqual({
|
||||
title: 'Search',
|
||||
Icon: IconSearch,
|
||||
instanceId: '1',
|
||||
|
||||
+1
-5
@@ -1,8 +1,7 @@
|
||||
import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { act } from 'react';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { RecoilRoot, useRecoilValue } from 'recoil';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
import { useCommandMenuOnItemClick } from '@/command-menu/hooks/useCommandMenuOnItemClick';
|
||||
|
||||
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||
@@ -21,11 +20,8 @@ const renderHooks = () => {
|
||||
() => {
|
||||
const { onItemClick } = useCommandMenuOnItemClick();
|
||||
|
||||
const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState);
|
||||
|
||||
return {
|
||||
onItemClick,
|
||||
isCommandMenuOpened,
|
||||
};
|
||||
},
|
||||
{
|
||||
|
||||
+27
-37
@@ -1,59 +1,45 @@
|
||||
import { useCommandMenuUpdateNavigationMorphItemsByPage } from '@/command-menu/hooks/useCommandMenuUpdateNavigationMorphItemsByPage';
|
||||
import { commandMenuNavigationMorphItemsByPageState } from '@/command-menu/states/commandMenuNavigationMorphItemsByPageState';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { act } from 'react';
|
||||
import { RecoilRoot, useRecoilValue } from 'recoil';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
|
||||
const pageId = 'merge-page-id';
|
||||
const objectMetadataId = 'company-metadata-id';
|
||||
|
||||
const Wrapper = ({
|
||||
children,
|
||||
initialRecordIds,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
initialRecordIds: string[];
|
||||
}) => (
|
||||
<RecoilRoot
|
||||
initializeState={({ set }) => {
|
||||
set(
|
||||
commandMenuNavigationMorphItemsByPageState,
|
||||
new Map([
|
||||
[
|
||||
pageId,
|
||||
initialRecordIds.map((recordId) => ({
|
||||
objectMetadataId,
|
||||
recordId,
|
||||
})),
|
||||
],
|
||||
]),
|
||||
);
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</RecoilRoot>
|
||||
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||
<RecoilRoot>{children}</RecoilRoot>
|
||||
);
|
||||
|
||||
const renderHooks = (initialRecordIds: string[]) =>
|
||||
renderHook(
|
||||
const renderHooks = (initialRecordIds: string[]) => {
|
||||
jotaiStore.set(
|
||||
commandMenuNavigationMorphItemsByPageState.atom,
|
||||
new Map([
|
||||
[
|
||||
pageId,
|
||||
initialRecordIds.map((recordId) => ({
|
||||
objectMetadataId,
|
||||
recordId,
|
||||
})),
|
||||
],
|
||||
]),
|
||||
);
|
||||
|
||||
return renderHook(
|
||||
() => {
|
||||
const { updateCommandMenuNavigationMorphItemsByPage } =
|
||||
useCommandMenuUpdateNavigationMorphItemsByPage();
|
||||
const commandMenuNavigationMorphItemsByPage = useRecoilValue(
|
||||
commandMenuNavigationMorphItemsByPageState,
|
||||
);
|
||||
|
||||
return {
|
||||
updateCommandMenuNavigationMorphItemsByPage,
|
||||
commandMenuNavigationMorphItemsByPage,
|
||||
};
|
||||
},
|
||||
{
|
||||
wrapper: ({ children }) => (
|
||||
<Wrapper initialRecordIds={initialRecordIds}>{children}</Wrapper>
|
||||
),
|
||||
wrapper: Wrapper,
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
describe('useCommandMenuUpdateNavigationMorphItemsByPage', () => {
|
||||
it('should replace existing items for a page instead of appending', async () => {
|
||||
@@ -68,7 +54,9 @@ describe('useCommandMenuUpdateNavigationMorphItemsByPage', () => {
|
||||
});
|
||||
|
||||
expect(
|
||||
result.current.commandMenuNavigationMorphItemsByPage.get(pageId),
|
||||
jotaiStore
|
||||
.get(commandMenuNavigationMorphItemsByPageState.atom)
|
||||
.get(pageId),
|
||||
).toEqual([
|
||||
{
|
||||
objectMetadataId,
|
||||
@@ -98,7 +86,9 @@ describe('useCommandMenuUpdateNavigationMorphItemsByPage', () => {
|
||||
});
|
||||
|
||||
expect(
|
||||
result.current.commandMenuNavigationMorphItemsByPage.get(pageId),
|
||||
jotaiStore
|
||||
.get(commandMenuNavigationMorphItemsByPageState.atom)
|
||||
.get(pageId),
|
||||
).toEqual([
|
||||
{
|
||||
objectMetadataId,
|
||||
|
||||
+6
-13
@@ -1,12 +1,12 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { act } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { COMMAND_MENU_COMPONENT_INSTANCE_ID } from '@/command-menu/constants/CommandMenuComponentInstanceId';
|
||||
import { useNavigateCommandMenu } from '@/command-menu/hooks/useNavigateCommandMenu';
|
||||
import { commandMenuNavigationStackState } from '@/command-menu/states/commandMenuNavigationStackState';
|
||||
import { commandMenuPageInfoState } from '@/command-menu/states/commandMenuPageInfoState';
|
||||
import { commandMenuPageState } from '@/command-menu/states/commandMenuPageState';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { ContextStoreViewType } from '@/context-store/types/ContextStoreViewType';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
import { Icon123, useIcons } from 'twenty-ui/display';
|
||||
@@ -40,19 +40,10 @@ const renderHooks = () => {
|
||||
() => {
|
||||
const { navigateCommandMenu } = useNavigateCommandMenu();
|
||||
|
||||
const commandMenuPage = useRecoilValue(commandMenuPageState);
|
||||
const commandMenuNavigationStack = useRecoilValue(
|
||||
commandMenuNavigationStackState,
|
||||
);
|
||||
const commandMenuPageInfo = useRecoilValue(commandMenuPageInfoState);
|
||||
|
||||
const { getIcon } = useIcons();
|
||||
|
||||
return {
|
||||
navigateCommandMenu,
|
||||
commandMenuPage,
|
||||
commandMenuNavigationStack,
|
||||
commandMenuPageInfo,
|
||||
getIcon,
|
||||
};
|
||||
},
|
||||
@@ -82,8 +73,10 @@ describe('useNavigateCommandMenu', () => {
|
||||
});
|
||||
});
|
||||
|
||||
expect(result.current.commandMenuPage).toBe(CommandMenuPages.Root);
|
||||
expect(result.current.commandMenuNavigationStack).toEqual([
|
||||
expect(jotaiStore.get(commandMenuPageState.atom)).toBe(
|
||||
CommandMenuPages.Root,
|
||||
);
|
||||
expect(jotaiStore.get(commandMenuNavigationStackState.atom)).toEqual([
|
||||
{
|
||||
page: CommandMenuPages.Root,
|
||||
pageTitle: 'Root',
|
||||
@@ -92,7 +85,7 @@ describe('useNavigateCommandMenu', () => {
|
||||
pageId: 'mocked-uuid',
|
||||
},
|
||||
]);
|
||||
expect(result.current.commandMenuPageInfo).toEqual({
|
||||
expect(jotaiStore.get(commandMenuPageInfoState.atom)).toEqual({
|
||||
title: 'Root',
|
||||
Icon: Icon123,
|
||||
instanceId: 'mocked-uuid',
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@ import { COMMAND_MENU_COMPONENT_INSTANCE_ID } from '@/command-menu/constants/Com
|
||||
import { useOpenCalendarEventInCommandMenu } from '@/command-menu/hooks/useOpenCalendarEventInCommandMenu';
|
||||
import { viewableRecordIdComponentState } from '@/command-menu/pages/record-page/states/viewableRecordIdComponentState';
|
||||
import { ContextStoreViewType } from '@/context-store/types/ContextStoreViewType';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
import { IconCalendarEvent } from 'twenty-ui/display';
|
||||
import { getJestMetadataAndApolloMocksAndActionMenuWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksAndActionMenuWrapper';
|
||||
@@ -46,7 +46,7 @@ const renderHooks = () => {
|
||||
const { openCalendarEventInCommandMenu } =
|
||||
useOpenCalendarEventInCommandMenu();
|
||||
|
||||
const viewableRecordId = useRecoilComponentValue(
|
||||
const viewableRecordId = useRecoilComponentValueV2(
|
||||
viewableRecordIdComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@ import { COMMAND_MENU_COMPONENT_INSTANCE_ID } from '@/command-menu/constants/Com
|
||||
import { useOpenEmailThreadInCommandMenu } from '@/command-menu/hooks/useOpenEmailThreadInCommandMenu';
|
||||
import { viewableRecordIdComponentState } from '@/command-menu/pages/record-page/states/viewableRecordIdComponentState';
|
||||
import { ContextStoreViewType } from '@/context-store/types/ContextStoreViewType';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
import { IconMail } from 'twenty-ui/display';
|
||||
import { getJestMetadataAndApolloMocksAndActionMenuWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksAndActionMenuWrapper';
|
||||
@@ -46,7 +46,7 @@ const renderHooks = () => {
|
||||
const { openEmailThreadInCommandMenu } =
|
||||
useOpenEmailThreadInCommandMenu();
|
||||
|
||||
const viewableRecordId = useRecoilComponentValue(
|
||||
const viewableRecordId = useRecoilComponentValueV2(
|
||||
viewableRecordIdComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
|
||||
+13
-20
@@ -1,19 +1,18 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { act } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { COMMAND_MENU_COMPONENT_INSTANCE_ID } from '@/command-menu/constants/CommandMenuComponentInstanceId';
|
||||
import { useOpenRecordInCommandMenu } from '@/command-menu/hooks/useOpenRecordInCommandMenu';
|
||||
import { viewableRecordIdComponentState } from '@/command-menu/pages/record-page/states/viewableRecordIdComponentState';
|
||||
import { viewableRecordNameSingularComponentState } from '@/command-menu/pages/record-page/states/viewableRecordNameSingularComponentState';
|
||||
import { commandMenuNavigationMorphItemsByPageState } from '@/command-menu/states/commandMenuNavigationMorphItemsByPageState';
|
||||
import { commandMenuPageState } from '@/command-menu/states/commandMenuPageState';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemIdComponentState';
|
||||
import { contextStoreCurrentViewTypeComponentState } from '@/context-store/states/contextStoreCurrentViewTypeComponentState';
|
||||
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { ContextStoreViewType } from '@/context-store/types/ContextStoreViewType';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
import { getJestMetadataAndApolloMocksAndActionMenuWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksAndActionMenuWrapper';
|
||||
@@ -53,32 +52,27 @@ const renderHooks = () => {
|
||||
() => {
|
||||
const { openRecordInCommandMenu } = useOpenRecordInCommandMenu();
|
||||
|
||||
const commandMenuPage = useRecoilValue(commandMenuPageState);
|
||||
const commandMenuNavigationMorphItemsByPage = useRecoilValue(
|
||||
commandMenuNavigationMorphItemsByPageState,
|
||||
);
|
||||
|
||||
const viewableRecordId = useRecoilComponentValue(
|
||||
const viewableRecordId = useRecoilComponentValueV2(
|
||||
viewableRecordIdComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
const viewableRecordNameSingular = useRecoilComponentValue(
|
||||
const viewableRecordNameSingular = useRecoilComponentValueV2(
|
||||
viewableRecordNameSingularComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
const currentObjectMetadataItemId = useRecoilComponentValue(
|
||||
const currentObjectMetadataItemId = useRecoilComponentValueV2(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
const targetedRecordsRule = useRecoilComponentValue(
|
||||
const targetedRecordsRule = useRecoilComponentValueV2(
|
||||
contextStoreTargetedRecordsRuleComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
const numberOfSelectedRecords = useRecoilComponentValue(
|
||||
const numberOfSelectedRecords = useRecoilComponentValueV2(
|
||||
contextStoreNumberOfSelectedRecordsComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
const currentViewType = useRecoilComponentValue(
|
||||
const currentViewType = useRecoilComponentValueV2(
|
||||
contextStoreCurrentViewTypeComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
@@ -87,8 +81,6 @@ const renderHooks = () => {
|
||||
return {
|
||||
openRecordInCommandMenu,
|
||||
viewableRecordId,
|
||||
commandMenuPage,
|
||||
commandMenuNavigationMorphItemsByPage,
|
||||
viewableRecordNameSingular,
|
||||
currentObjectMetadataItemId,
|
||||
targetedRecordsRule,
|
||||
@@ -134,10 +126,11 @@ describe('useOpenRecordInCommandMenu', () => {
|
||||
expect(result.current.numberOfSelectedRecords).toBe(1);
|
||||
expect(result.current.currentViewType).toBe(ContextStoreViewType.ShowPage);
|
||||
|
||||
expect(result.current.commandMenuNavigationMorphItemsByPage.size).toBe(1);
|
||||
expect(
|
||||
result.current.commandMenuNavigationMorphItemsByPage.get('mocked-uuid'),
|
||||
).toEqual([
|
||||
const commandMenuNavigationMorphItemsByPage = jotaiStore.get(
|
||||
commandMenuNavigationMorphItemsByPageState.atom,
|
||||
);
|
||||
expect(commandMenuNavigationMorphItemsByPage.size).toBe(1);
|
||||
expect(commandMenuNavigationMorphItemsByPage.get('mocked-uuid')).toEqual([
|
||||
{
|
||||
objectMetadataId: personMockObjectMetadataItem.id,
|
||||
recordId,
|
||||
|
||||
+43
-40
@@ -1,12 +1,12 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { act } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { COMMAND_MENU_COMPONENT_INSTANCE_ID } from '@/command-menu/constants/CommandMenuComponentInstanceId';
|
||||
import { COMMAND_MENU_PREVIOUS_COMPONENT_INSTANCE_ID } from '@/command-menu/constants/CommandMenuPreviousComponentInstanceId';
|
||||
import { useSetGlobalCommandMenuContext } from '@/command-menu/hooks/useSetGlobalCommandMenuContext';
|
||||
import { commandMenuPageInfoState } from '@/command-menu/states/commandMenuPageInfoState';
|
||||
import { hasUserSelectedCommandState } from '@/command-menu/states/hasUserSelectedCommandState';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { contextStoreAnyFieldFilterValueComponentState } from '@/context-store/states/contextStoreAnyFieldFilterValueComponentState';
|
||||
import { contextStoreCurrentViewTypeComponentState } from '@/context-store/states/contextStoreCurrentViewTypeComponentState';
|
||||
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
|
||||
@@ -14,6 +14,7 @@ import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-sto
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { ContextStoreViewType } from '@/context-store/types/ContextStoreViewType';
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { getJestMetadataAndApolloMocksAndActionMenuWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksAndActionMenuWrapper';
|
||||
import { getPeopleRecordConnectionMock } from '~/testing/mock-data/people';
|
||||
import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems';
|
||||
@@ -47,9 +48,15 @@ const wrapper = getJestMetadataAndApolloMocksAndActionMenuWrapper({
|
||||
},
|
||||
contextStoreNumberOfSelectedRecords: 2,
|
||||
contextStoreCurrentViewType: ContextStoreViewType.Table,
|
||||
onInitializeRecoilSnapshot: (snapshot) => {
|
||||
snapshot.set(recordStoreFamilyState(peopleMock[0].id), peopleMock[0]);
|
||||
snapshot.set(recordStoreFamilyState(peopleMock[1].id), peopleMock[1]);
|
||||
onInitializeRecoilSnapshot: (_snapshot) => {
|
||||
jotaiStore.set(
|
||||
recordStoreFamilyState.atomFamily(peopleMock[0].id),
|
||||
peopleMock[0],
|
||||
);
|
||||
jotaiStore.set(
|
||||
recordStoreFamilyState.atomFamily(peopleMock[1].id),
|
||||
peopleMock[1],
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -64,46 +71,34 @@ describe('useSetGlobalCommandMenuContext', () => {
|
||||
const { setGlobalCommandMenuContext } =
|
||||
useSetGlobalCommandMenuContext();
|
||||
|
||||
const targetedRecordsRule = useRecoilValue(
|
||||
contextStoreTargetedRecordsRuleComponentState.atomFamily({
|
||||
instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
}),
|
||||
const targetedRecordsRule = useRecoilComponentValueV2(
|
||||
contextStoreTargetedRecordsRuleComponentState,
|
||||
COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
);
|
||||
|
||||
const numberOfSelectedRecords = useRecoilValue(
|
||||
contextStoreNumberOfSelectedRecordsComponentState.atomFamily({
|
||||
instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
}),
|
||||
const numberOfSelectedRecords = useRecoilComponentValueV2(
|
||||
contextStoreNumberOfSelectedRecordsComponentState,
|
||||
COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
);
|
||||
|
||||
const filters = useRecoilValue(
|
||||
contextStoreFiltersComponentState.atomFamily({
|
||||
instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
}),
|
||||
const filters = useRecoilComponentValueV2(
|
||||
contextStoreFiltersComponentState,
|
||||
COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
);
|
||||
|
||||
const filterGroups = useRecoilValue(
|
||||
contextStoreFilterGroupsComponentState.atomFamily({
|
||||
instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
}),
|
||||
const filterGroups = useRecoilComponentValueV2(
|
||||
contextStoreFilterGroupsComponentState,
|
||||
COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
);
|
||||
|
||||
const anyFieldFilterValue = useRecoilValue(
|
||||
contextStoreAnyFieldFilterValueComponentState.atomFamily({
|
||||
instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
}),
|
||||
const anyFieldFilterValue = useRecoilComponentValueV2(
|
||||
contextStoreAnyFieldFilterValueComponentState,
|
||||
COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
);
|
||||
|
||||
const currentViewType = useRecoilValue(
|
||||
contextStoreCurrentViewTypeComponentState.atomFamily({
|
||||
instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
}),
|
||||
);
|
||||
|
||||
const commandMenuPageInfo = useRecoilValue(commandMenuPageInfoState);
|
||||
|
||||
const hasUserSelectedCommand = useRecoilValue(
|
||||
hasUserSelectedCommandState,
|
||||
const currentViewType = useRecoilComponentValueV2(
|
||||
contextStoreCurrentViewTypeComponentState,
|
||||
COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
);
|
||||
|
||||
return {
|
||||
@@ -113,8 +108,6 @@ describe('useSetGlobalCommandMenuContext', () => {
|
||||
filters,
|
||||
filterGroups,
|
||||
currentViewType,
|
||||
commandMenuPageInfo,
|
||||
hasUserSelectedCommand,
|
||||
anyFieldFilterValue,
|
||||
};
|
||||
},
|
||||
@@ -131,12 +124,16 @@ describe('useSetGlobalCommandMenuContext', () => {
|
||||
expect(result.current.filters).toEqual([]);
|
||||
expect(result.current.anyFieldFilterValue).toEqual('');
|
||||
expect(result.current.currentViewType).toBe(ContextStoreViewType.Table);
|
||||
expect(result.current.commandMenuPageInfo).toEqual({
|
||||
const commandMenuPageInfo = jotaiStore.get(commandMenuPageInfoState.atom);
|
||||
expect(commandMenuPageInfo).toEqual({
|
||||
title: undefined,
|
||||
Icon: undefined,
|
||||
instanceId: '',
|
||||
});
|
||||
expect(result.current.hasUserSelectedCommand).toBe(false);
|
||||
const hasUserSelectedCommand = jotaiStore.get(
|
||||
hasUserSelectedCommandState.atom,
|
||||
);
|
||||
expect(hasUserSelectedCommand).toBe(false);
|
||||
|
||||
act(() => {
|
||||
result.current.setGlobalCommandMenuContext();
|
||||
@@ -150,12 +147,18 @@ describe('useSetGlobalCommandMenuContext', () => {
|
||||
expect(result.current.filters).toEqual([]);
|
||||
expect(result.current.anyFieldFilterValue).toEqual('');
|
||||
expect(result.current.currentViewType).toBe(ContextStoreViewType.Table);
|
||||
expect(result.current.commandMenuPageInfo).toEqual({
|
||||
const commandMenuPageInfoAfter = jotaiStore.get(
|
||||
commandMenuPageInfoState.atom,
|
||||
);
|
||||
expect(commandMenuPageInfoAfter).toEqual({
|
||||
title: undefined,
|
||||
Icon: undefined,
|
||||
instanceId: '',
|
||||
});
|
||||
expect(result.current.hasUserSelectedCommand).toBe(false);
|
||||
const hasUserSelectedCommandAfter = jotaiStore.get(
|
||||
hasUserSelectedCommandState.atom,
|
||||
);
|
||||
expect(hasUserSelectedCommandAfter).toBe(false);
|
||||
});
|
||||
|
||||
it('should call copyContextStoreStates with correct parameters', () => {
|
||||
|
||||
+26
-21
@@ -1,9 +1,10 @@
|
||||
import { useUpdateCommandMenuPageInfo } from '@/command-menu/hooks/useUpdateCommandMenuPageInfo';
|
||||
import { commandMenuNavigationStackState } from '@/command-menu/states/commandMenuNavigationStackState';
|
||||
import { commandMenuPageInfoState } from '@/command-menu/states/commandMenuPageInfoState';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { act } from 'react';
|
||||
import { RecoilRoot, useRecoilValue } from 'recoil';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
import { IconArrowDown, IconDotsVertical } from 'twenty-ui/display';
|
||||
|
||||
@@ -23,30 +24,22 @@ const mockedNavigationStack = [
|
||||
];
|
||||
|
||||
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||
<RecoilRoot
|
||||
initializeState={({ set }) => {
|
||||
set(commandMenuNavigationStackState, mockedNavigationStack);
|
||||
set(commandMenuPageInfoState, mockedPageInfo);
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</RecoilRoot>
|
||||
<RecoilRoot>{children}</RecoilRoot>
|
||||
);
|
||||
|
||||
describe('useUpdateCommandMenuPageInfo', () => {
|
||||
beforeEach(() => {
|
||||
jotaiStore.set(commandMenuNavigationStackState.atom, mockedNavigationStack);
|
||||
jotaiStore.set(commandMenuPageInfoState.atom, mockedPageInfo);
|
||||
});
|
||||
|
||||
const renderHooks = () => {
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const { updateCommandMenuPageInfo } = useUpdateCommandMenuPageInfo();
|
||||
const commandMenuNavigationStack = useRecoilValue(
|
||||
commandMenuNavigationStackState,
|
||||
);
|
||||
const commandMenuPageInfo = useRecoilValue(commandMenuPageInfoState);
|
||||
|
||||
return {
|
||||
updateCommandMenuPageInfo,
|
||||
commandMenuNavigationStack,
|
||||
commandMenuPageInfo,
|
||||
};
|
||||
},
|
||||
{ wrapper: Wrapper },
|
||||
@@ -67,7 +60,10 @@ describe('useUpdateCommandMenuPageInfo', () => {
|
||||
});
|
||||
});
|
||||
|
||||
expect(result.current.commandMenuNavigationStack).toEqual([
|
||||
const commandMenuNavigationStack = jotaiStore.get(
|
||||
commandMenuNavigationStackState.atom,
|
||||
);
|
||||
expect(commandMenuNavigationStack).toEqual([
|
||||
{
|
||||
page: CommandMenuPages.Root,
|
||||
pageTitle: 'New Title',
|
||||
@@ -76,7 +72,8 @@ describe('useUpdateCommandMenuPageInfo', () => {
|
||||
},
|
||||
]);
|
||||
|
||||
expect(result.current.commandMenuPageInfo).toEqual({
|
||||
const commandMenuPageInfo = jotaiStore.get(commandMenuPageInfoState.atom);
|
||||
expect(commandMenuPageInfo).toEqual({
|
||||
title: 'New Title',
|
||||
Icon: IconArrowDown,
|
||||
instanceId: 'test-instance',
|
||||
@@ -92,7 +89,10 @@ describe('useUpdateCommandMenuPageInfo', () => {
|
||||
});
|
||||
});
|
||||
|
||||
expect(result.current.commandMenuNavigationStack).toEqual([
|
||||
const commandMenuNavigationStack = jotaiStore.get(
|
||||
commandMenuNavigationStackState.atom,
|
||||
);
|
||||
expect(commandMenuNavigationStack).toEqual([
|
||||
{
|
||||
page: CommandMenuPages.Root,
|
||||
pageTitle: 'New Title',
|
||||
@@ -101,7 +101,8 @@ describe('useUpdateCommandMenuPageInfo', () => {
|
||||
},
|
||||
]);
|
||||
|
||||
expect(result.current.commandMenuPageInfo).toEqual({
|
||||
const commandMenuPageInfo = jotaiStore.get(commandMenuPageInfoState.atom);
|
||||
expect(commandMenuPageInfo).toEqual({
|
||||
title: 'New Title',
|
||||
Icon: IconDotsVertical,
|
||||
instanceId: 'test-instance',
|
||||
@@ -117,7 +118,10 @@ describe('useUpdateCommandMenuPageInfo', () => {
|
||||
});
|
||||
});
|
||||
|
||||
expect(result.current.commandMenuNavigationStack).toEqual([
|
||||
const commandMenuNavigationStack = jotaiStore.get(
|
||||
commandMenuNavigationStackState.atom,
|
||||
);
|
||||
expect(commandMenuNavigationStack).toEqual([
|
||||
{
|
||||
page: CommandMenuPages.Root,
|
||||
pageTitle: 'Initial Title',
|
||||
@@ -126,7 +130,8 @@ describe('useUpdateCommandMenuPageInfo', () => {
|
||||
},
|
||||
]);
|
||||
|
||||
expect(result.current.commandMenuPageInfo).toEqual({
|
||||
const commandMenuPageInfo = jotaiStore.get(commandMenuPageInfoState.atom);
|
||||
expect(commandMenuPageInfo).toEqual({
|
||||
title: 'Initial Title',
|
||||
Icon: IconArrowDown,
|
||||
instanceId: 'test-instance',
|
||||
|
||||
+9
-19
@@ -1,5 +1,4 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { COMMAND_MENU_COMPONENT_INSTANCE_ID } from '@/command-menu/constants/CommandMenuComponentInstanceId';
|
||||
import { useWorkflowCommandMenu } from '@/command-menu/hooks/useWorkflowCommandMenu';
|
||||
@@ -7,14 +6,12 @@ import { viewableRecordIdComponentState } from '@/command-menu/pages/record-page
|
||||
import { viewableRecordNameSingularComponentState } from '@/command-menu/pages/record-page/states/viewableRecordNameSingularComponentState';
|
||||
import { commandMenuWorkflowIdComponentState } from '@/command-menu/pages/workflow/states/commandMenuWorkflowIdComponentState';
|
||||
import { commandMenuWorkflowVersionIdComponentState } from '@/command-menu/pages/workflow/states/commandMenuWorkflowVersionIdComponentState';
|
||||
import { commandMenuNavigationMorphItemsByPageState } from '@/command-menu/states/commandMenuNavigationMorphItemsByPageState';
|
||||
import { commandMenuPageState } from '@/command-menu/states/commandMenuPageState';
|
||||
import { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemIdComponentState';
|
||||
import { contextStoreCurrentViewTypeComponentState } from '@/context-store/states/contextStoreCurrentViewTypeComponentState';
|
||||
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { ContextStoreViewType } from '@/context-store/types/ContextStoreViewType';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { act } from 'react';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
@@ -67,40 +64,36 @@ const renderHooks = () => {
|
||||
openWorkflowEditStepTypeInCommandMenu,
|
||||
openWorkflowViewStepInCommandMenu,
|
||||
} = useWorkflowCommandMenu();
|
||||
const commandMenuPage = useRecoilValue(commandMenuPageState);
|
||||
const commandMenuNavigationMorphItemsByPage = useRecoilValue(
|
||||
commandMenuNavigationMorphItemsByPageState,
|
||||
);
|
||||
|
||||
const viewableRecordId = useRecoilComponentValue(
|
||||
const _viewableRecordId = useRecoilComponentValueV2(
|
||||
viewableRecordIdComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
const viewableRecordNameSingular = useRecoilComponentValue(
|
||||
const viewableRecordNameSingular = useRecoilComponentValueV2(
|
||||
viewableRecordNameSingularComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
const currentObjectMetadataItemId = useRecoilComponentValue(
|
||||
const currentObjectMetadataItemId = useRecoilComponentValueV2(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
const targetedRecordsRule = useRecoilComponentValue(
|
||||
const targetedRecordsRule = useRecoilComponentValueV2(
|
||||
contextStoreTargetedRecordsRuleComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
const numberOfSelectedRecords = useRecoilComponentValue(
|
||||
const numberOfSelectedRecords = useRecoilComponentValueV2(
|
||||
contextStoreNumberOfSelectedRecordsComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
const currentViewType = useRecoilComponentValue(
|
||||
const currentViewType = useRecoilComponentValueV2(
|
||||
contextStoreCurrentViewTypeComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
const workflowId = useRecoilComponentValue(
|
||||
const workflowId = useRecoilComponentValueV2(
|
||||
commandMenuWorkflowIdComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
const workflowVersionId = useRecoilComponentValue(
|
||||
const workflowVersionId = useRecoilComponentValueV2(
|
||||
commandMenuWorkflowVersionIdComponentState,
|
||||
'mocked-uuid',
|
||||
);
|
||||
@@ -114,9 +107,6 @@ const renderHooks = () => {
|
||||
openWorkflowViewStepInCommandMenu,
|
||||
workflowId,
|
||||
workflowVersionId,
|
||||
viewableRecordId,
|
||||
commandMenuPage,
|
||||
commandMenuNavigationMorphItemsByPage,
|
||||
viewableRecordNameSingular,
|
||||
currentObjectMetadataItemId,
|
||||
targetedRecordsRule,
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
import { SIDE_PANEL_FOCUS_ID } from '@/command-menu/constants/SidePanelFocusId';
|
||||
import { useNavigateCommandMenu } from '@/command-menu/hooks/useNavigateCommandMenu';
|
||||
import { commandMenuSearchState } from '@/command-menu/states/commandMenuSearchState';
|
||||
import { isCommandMenuClosingState } from '@/command-menu/states/isCommandMenuClosingState';
|
||||
import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState';
|
||||
import { isCommandMenuOpenedStateV2 } from '@/command-menu/states/isCommandMenuOpenedStateV2';
|
||||
import { addToNavPayloadRegistryStateV2 } from '@/navigation-menu-item/states/addToNavPayloadRegistryStateV2';
|
||||
import { useCloseAnyOpenDropdown } from '@/ui/layout/dropdown/hooks/useCloseAnyOpenDropdown';
|
||||
import { emitSidePanelOpenEvent } from '@/ui/layout/right-drawer/utils/emitSidePanelOpenEvent';
|
||||
import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useStore } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
import { IconDotsVertical } from 'twenty-ui/display';
|
||||
@@ -23,28 +20,19 @@ export const useCommandMenu = () => {
|
||||
const { removeFocusItemFromFocusStackById } =
|
||||
useRemoveFocusItemFromFocusStackById();
|
||||
|
||||
const store = useStore();
|
||||
const closeCommandMenu = useCallback(() => {
|
||||
const isCommandMenuOpened = jotaiStore.get(isCommandMenuOpenedStateV2.atom);
|
||||
|
||||
const closeCommandMenu = useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
() => {
|
||||
const isCommandMenuOpened = snapshot
|
||||
.getLoadable(isCommandMenuOpenedState)
|
||||
.getValue();
|
||||
|
||||
if (isCommandMenuOpened) {
|
||||
store.set(addToNavPayloadRegistryStateV2.atom, new Map());
|
||||
set(isCommandMenuOpenedState, false);
|
||||
store.set(isCommandMenuOpenedStateV2.atom, false);
|
||||
set(isCommandMenuClosingState, true);
|
||||
closeAnyOpenDropdown();
|
||||
removeFocusItemFromFocusStackById({
|
||||
focusId: SIDE_PANEL_FOCUS_ID,
|
||||
});
|
||||
}
|
||||
},
|
||||
[closeAnyOpenDropdown, removeFocusItemFromFocusStackById, store],
|
||||
);
|
||||
if (isCommandMenuOpened) {
|
||||
jotaiStore.set(addToNavPayloadRegistryStateV2.atom, new Map());
|
||||
jotaiStore.set(isCommandMenuOpenedStateV2.atom, false);
|
||||
jotaiStore.set(isCommandMenuClosingState.atom, true);
|
||||
closeAnyOpenDropdown();
|
||||
removeFocusItemFromFocusStackById({
|
||||
focusId: SIDE_PANEL_FOCUS_ID,
|
||||
});
|
||||
}
|
||||
}, [closeAnyOpenDropdown, removeFocusItemFromFocusStackById]);
|
||||
|
||||
const openCommandMenu = useCallback(() => {
|
||||
emitSidePanelOpenEvent();
|
||||
@@ -57,23 +45,17 @@ export const useCommandMenu = () => {
|
||||
});
|
||||
}, [closeAnyOpenDropdown, navigateCommandMenu]);
|
||||
|
||||
const toggleCommandMenu = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
async () => {
|
||||
const isCommandMenuOpened = snapshot
|
||||
.getLoadable(isCommandMenuOpenedState)
|
||||
.getValue();
|
||||
const toggleCommandMenu = useCallback(() => {
|
||||
const isCommandMenuOpened = jotaiStore.get(isCommandMenuOpenedStateV2.atom);
|
||||
|
||||
set(commandMenuSearchState, '');
|
||||
jotaiStore.set(commandMenuSearchState.atom, '');
|
||||
|
||||
if (isCommandMenuOpened) {
|
||||
closeCommandMenu();
|
||||
} else {
|
||||
openCommandMenu();
|
||||
}
|
||||
},
|
||||
[closeCommandMenu, openCommandMenu],
|
||||
);
|
||||
if (isCommandMenuOpened) {
|
||||
closeCommandMenu();
|
||||
} else {
|
||||
openCommandMenu();
|
||||
}
|
||||
}, [closeCommandMenu, openCommandMenu]);
|
||||
|
||||
return {
|
||||
openCommandMenu,
|
||||
|
||||
+83
-93
@@ -10,7 +10,6 @@ import { commandMenuPageState } from '@/command-menu/states/commandMenuPageState
|
||||
import { commandMenuSearchState } from '@/command-menu/states/commandMenuSearchState';
|
||||
import { hasUserSelectedCommandState } from '@/command-menu/states/hasUserSelectedCommandState';
|
||||
import { isCommandMenuClosingState } from '@/command-menu/states/isCommandMenuClosingState';
|
||||
import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState';
|
||||
import { isCommandMenuOpenedStateV2 } from '@/command-menu/states/isCommandMenuOpenedStateV2';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState';
|
||||
@@ -23,10 +22,10 @@ import { emitSidePanelCloseEvent } from '@/ui/layout/right-drawer/utils/emitSide
|
||||
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
|
||||
import { getShowPageTabListComponentId } from '@/ui/layout/show-page/utils/getShowPageTabListComponentId';
|
||||
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { WORKFLOW_LOGIC_FUNCTION_TAB_LIST_COMPONENT_ID } from '@/workflow/workflow-steps/workflow-actions/code-action/constants/WorkflowLogicFunctionTabListComponentId';
|
||||
import { WorkflowLogicFunctionTabId } from '@/workflow/workflow-steps/workflow-actions/code-action/types/WorkflowLogicFunctionTabId';
|
||||
import { useStore } from 'jotai';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { useCallback } from 'react';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
@@ -39,107 +38,98 @@ export const useCommandMenuCloseAnimationCompleteCleanup = () => {
|
||||
|
||||
const { closeDropdown } = useCloseDropdown();
|
||||
|
||||
const store = useStore();
|
||||
const commandMenuCloseAnimationCompleteCleanup = useCallback(() => {
|
||||
closeDropdown(COMMAND_MENU_CONTEXT_CHIP_GROUPS_DROPDOWN_ID);
|
||||
|
||||
const commandMenuCloseAnimationCompleteCleanup = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
() => {
|
||||
closeDropdown(COMMAND_MENU_CONTEXT_CHIP_GROUPS_DROPDOWN_ID);
|
||||
resetContextStoreStates(COMMAND_MENU_COMPONENT_INSTANCE_ID);
|
||||
resetContextStoreStates(COMMAND_MENU_PREVIOUS_COMPONENT_INSTANCE_ID);
|
||||
|
||||
resetContextStoreStates(COMMAND_MENU_COMPONENT_INSTANCE_ID);
|
||||
resetContextStoreStates(COMMAND_MENU_PREVIOUS_COMPONENT_INSTANCE_ID);
|
||||
const currentPage = jotaiStore.get(commandMenuPageState.atom);
|
||||
|
||||
const currentPage = snapshot
|
||||
.getLoadable(commandMenuPageState)
|
||||
.getValue();
|
||||
const isPageLayoutEditingPage =
|
||||
currentPage === CommandMenuPages.PageLayoutWidgetTypeSelect ||
|
||||
currentPage === CommandMenuPages.PageLayoutGraphTypeSelect ||
|
||||
currentPage === CommandMenuPages.PageLayoutIframeSettings ||
|
||||
currentPage === CommandMenuPages.PageLayoutTabSettings;
|
||||
|
||||
const isPageLayoutEditingPage =
|
||||
currentPage === CommandMenuPages.PageLayoutWidgetTypeSelect ||
|
||||
currentPage === CommandMenuPages.PageLayoutGraphTypeSelect ||
|
||||
currentPage === CommandMenuPages.PageLayoutIframeSettings ||
|
||||
currentPage === CommandMenuPages.PageLayoutTabSettings;
|
||||
if (isPageLayoutEditingPage) {
|
||||
const targetedRecordsRule = jotaiStore.get(
|
||||
contextStoreTargetedRecordsRuleComponentState.atomFamily({
|
||||
instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
}),
|
||||
);
|
||||
|
||||
if (isPageLayoutEditingPage) {
|
||||
const targetedRecordsRule = snapshot
|
||||
.getLoadable(
|
||||
contextStoreTargetedRecordsRuleComponentState.atomFamily({
|
||||
instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
}),
|
||||
)
|
||||
.getValue();
|
||||
|
||||
if (
|
||||
targetedRecordsRule.mode === 'selection' &&
|
||||
targetedRecordsRule.selectedRecordIds.length === 1
|
||||
) {
|
||||
const recordId = targetedRecordsRule.selectedRecordIds[0];
|
||||
const record = snapshot
|
||||
.getLoadable(recordStoreFamilyState(recordId))
|
||||
.getValue();
|
||||
|
||||
if (isDefined(record) && isDefined(record.pageLayoutId)) {
|
||||
set(
|
||||
pageLayoutEditingWidgetIdComponentState.atomFamily({
|
||||
instanceId: record.pageLayoutId,
|
||||
}),
|
||||
null,
|
||||
);
|
||||
set(
|
||||
pageLayoutTabSettingsOpenTabIdComponentState.atomFamily({
|
||||
instanceId: record.pageLayoutId,
|
||||
}),
|
||||
null,
|
||||
);
|
||||
set(
|
||||
pageLayoutDraggedAreaComponentState.atomFamily({
|
||||
instanceId: record.pageLayoutId,
|
||||
}),
|
||||
null,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set(viewableRecordIdState, null);
|
||||
set(commandMenuPageState, CommandMenuPages.Root);
|
||||
set(commandMenuPageInfoState, {
|
||||
title: undefined,
|
||||
Icon: undefined,
|
||||
instanceId: '',
|
||||
});
|
||||
set(isCommandMenuOpenedState, false);
|
||||
store.set(isCommandMenuOpenedStateV2.atom, false);
|
||||
set(commandMenuSearchState, '');
|
||||
set(commandMenuNavigationMorphItemsByPageState, new Map());
|
||||
set(commandMenuNavigationStackState, []);
|
||||
resetSelectedItem();
|
||||
set(hasUserSelectedCommandState, false);
|
||||
|
||||
emitSidePanelCloseEvent();
|
||||
set(isCommandMenuClosingState, false);
|
||||
store.set(
|
||||
activeTabIdComponentState.atomFamily({
|
||||
instanceId: WORKFLOW_LOGIC_FUNCTION_TAB_LIST_COMPONENT_ID,
|
||||
}),
|
||||
WorkflowLogicFunctionTabId.CODE,
|
||||
if (
|
||||
targetedRecordsRule.mode === 'selection' &&
|
||||
targetedRecordsRule.selectedRecordIds.length === 1
|
||||
) {
|
||||
const recordId = targetedRecordsRule.selectedRecordIds[0];
|
||||
const record = jotaiStore.get(
|
||||
recordStoreFamilyState.atomFamily(recordId),
|
||||
);
|
||||
|
||||
for (const [pageId, morphItems] of snapshot
|
||||
.getLoadable(commandMenuNavigationMorphItemsByPageState)
|
||||
.getValue()) {
|
||||
store.set(
|
||||
activeTabIdComponentState.atomFamily({
|
||||
instanceId: getShowPageTabListComponentId({
|
||||
pageId,
|
||||
targetObjectId: morphItems[0].recordId,
|
||||
}),
|
||||
if (isDefined(record) && isDefined(record.pageLayoutId)) {
|
||||
jotaiStore.set(
|
||||
pageLayoutEditingWidgetIdComponentState.atomFamily({
|
||||
instanceId: record.pageLayoutId,
|
||||
}),
|
||||
null,
|
||||
);
|
||||
jotaiStore.set(
|
||||
pageLayoutTabSettingsOpenTabIdComponentState.atomFamily({
|
||||
instanceId: record.pageLayoutId,
|
||||
}),
|
||||
null,
|
||||
);
|
||||
jotaiStore.set(
|
||||
pageLayoutDraggedAreaComponentState.atomFamily({
|
||||
instanceId: record.pageLayoutId,
|
||||
}),
|
||||
null,
|
||||
);
|
||||
}
|
||||
},
|
||||
[closeDropdown, resetContextStoreStates, resetSelectedItem, store],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
jotaiStore.set(viewableRecordIdState.atom, null);
|
||||
jotaiStore.set(commandMenuPageState.atom, CommandMenuPages.Root);
|
||||
jotaiStore.set(commandMenuPageInfoState.atom, {
|
||||
title: undefined,
|
||||
Icon: undefined,
|
||||
instanceId: '',
|
||||
});
|
||||
jotaiStore.set(isCommandMenuOpenedStateV2.atom, false);
|
||||
jotaiStore.set(commandMenuSearchState.atom, '');
|
||||
jotaiStore.set(commandMenuNavigationMorphItemsByPageState.atom, new Map());
|
||||
jotaiStore.set(commandMenuNavigationStackState.atom, []);
|
||||
resetSelectedItem();
|
||||
jotaiStore.set(hasUserSelectedCommandState.atom, false);
|
||||
|
||||
emitSidePanelCloseEvent();
|
||||
jotaiStore.set(isCommandMenuClosingState.atom, false);
|
||||
jotaiStore.set(
|
||||
activeTabIdComponentState.atomFamily({
|
||||
instanceId: WORKFLOW_LOGIC_FUNCTION_TAB_LIST_COMPONENT_ID,
|
||||
}),
|
||||
WorkflowLogicFunctionTabId.CODE,
|
||||
);
|
||||
|
||||
const morphItemsByPage = jotaiStore.get(
|
||||
commandMenuNavigationMorphItemsByPageState.atom,
|
||||
);
|
||||
|
||||
for (const [pageId, morphItems] of morphItemsByPage) {
|
||||
jotaiStore.set(
|
||||
activeTabIdComponentState.atomFamily({
|
||||
instanceId: getShowPageTabListComponentId({
|
||||
pageId,
|
||||
targetObjectId: morphItems[0].recordId,
|
||||
}),
|
||||
}),
|
||||
null,
|
||||
);
|
||||
}
|
||||
}, [closeDropdown, resetContextStoreStates, resetSelectedItem]);
|
||||
|
||||
return {
|
||||
commandMenuCloseAnimationCompleteCleanup,
|
||||
|
||||
@@ -5,11 +5,10 @@ import { commandMenuNavigationStackState } from '@/command-menu/states/commandMe
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { recordStoreIdentifiersFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreIdentifiersSelector';
|
||||
import { recordStoreRecordsSelector } from '@/object-record/record-store/states/selectors/recordStoreRecordsSelector';
|
||||
import { recordStoreRecordsSelectorV2 } from '@/object-record/record-store/states/selectors/recordStoreRecordsSelectorV2';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useMemo } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { allowRequestsToTwentyIconsState } from '@/client-config/states/allowRequestsToTwentyIcons';
|
||||
import { useFamilySelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilySelectorValueV2';
|
||||
@@ -24,7 +23,7 @@ const StyledIconWrapper = styled.div`
|
||||
`;
|
||||
|
||||
export const useCommandMenuContextChips = () => {
|
||||
const commandMenuNavigationStack = useRecoilValue(
|
||||
const commandMenuNavigationStack = useRecoilValueV2(
|
||||
commandMenuNavigationStackState,
|
||||
);
|
||||
|
||||
@@ -38,7 +37,7 @@ export const useCommandMenuContextChips = () => {
|
||||
|
||||
const theme = useTheme();
|
||||
|
||||
const commandMenuNavigationMorphItemsByPage = useRecoilValue(
|
||||
const commandMenuNavigationMorphItemsByPage = useRecoilValueV2(
|
||||
commandMenuNavigationMorphItemsByPageState,
|
||||
);
|
||||
|
||||
@@ -55,11 +54,9 @@ export const useCommandMenuContextChips = () => {
|
||||
allowRequestsToTwentyIcons,
|
||||
},
|
||||
);
|
||||
const records = useRecoilValue(
|
||||
recordStoreRecordsSelector({
|
||||
recordIds: allRecordIds,
|
||||
}),
|
||||
);
|
||||
const records = useFamilySelectorValueV2(recordStoreRecordsSelectorV2, {
|
||||
recordIds: allRecordIds,
|
||||
});
|
||||
|
||||
const contextChips = useMemo(() => {
|
||||
const filteredCommandMenuNavigationStack =
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
|
||||
import { commandMenuNavigationMorphItemsByPageState } from '@/command-menu/states/commandMenuNavigationMorphItemsByPageState';
|
||||
@@ -8,132 +8,123 @@ import { commandMenuPageState } from '@/command-menu/states/commandMenuPageState
|
||||
import { hasUserSelectedCommandState } from '@/command-menu/states/hasUserSelectedCommandState';
|
||||
import { getShowPageTabListComponentId } from '@/ui/layout/show-page/utils/getShowPageTabListComponentId';
|
||||
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
|
||||
import { useStore } from 'jotai';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { isNonEmptyArray } from '@sniptt/guards';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useCommandMenuHistory = () => {
|
||||
const { closeCommandMenu } = useCommandMenu();
|
||||
|
||||
const store = useStore();
|
||||
const goBackFromCommandMenu = useCallback(() => {
|
||||
const currentNavigationStack = jotaiStore.get(
|
||||
commandMenuNavigationStackState.atom,
|
||||
);
|
||||
|
||||
const goBackFromCommandMenu = useRecoilCallback(
|
||||
({ snapshot, set }) => {
|
||||
return () => {
|
||||
const currentNavigationStack = snapshot
|
||||
.getLoadable(commandMenuNavigationStackState)
|
||||
.getValue();
|
||||
const newNavigationStack = currentNavigationStack.slice(0, -1);
|
||||
const lastNavigationStackItem = newNavigationStack.at(-1);
|
||||
|
||||
const newNavigationStack = currentNavigationStack.slice(0, -1);
|
||||
const lastNavigationStackItem = newNavigationStack.at(-1);
|
||||
if (!isDefined(lastNavigationStackItem)) {
|
||||
closeCommandMenu();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isDefined(lastNavigationStackItem)) {
|
||||
closeCommandMenu();
|
||||
return;
|
||||
}
|
||||
jotaiStore.set(commandMenuPageState.atom, lastNavigationStackItem.page);
|
||||
|
||||
set(commandMenuPageState, lastNavigationStackItem.page);
|
||||
jotaiStore.set(commandMenuPageInfoState.atom, {
|
||||
title: lastNavigationStackItem.pageTitle,
|
||||
Icon: lastNavigationStackItem.pageIcon,
|
||||
instanceId: lastNavigationStackItem.pageId,
|
||||
});
|
||||
|
||||
set(commandMenuPageInfoState, {
|
||||
title: lastNavigationStackItem.pageTitle,
|
||||
Icon: lastNavigationStackItem.pageIcon,
|
||||
instanceId: lastNavigationStackItem.pageId,
|
||||
});
|
||||
jotaiStore.set(commandMenuNavigationStackState.atom, newNavigationStack);
|
||||
|
||||
set(commandMenuNavigationStackState, newNavigationStack);
|
||||
const currentMorphItems = jotaiStore.get(
|
||||
commandMenuNavigationMorphItemsByPageState.atom,
|
||||
);
|
||||
|
||||
const currentMorphItems = snapshot
|
||||
.getLoadable(commandMenuNavigationMorphItemsByPageState)
|
||||
.getValue();
|
||||
if (currentNavigationStack.length > 0) {
|
||||
const removedItem = currentNavigationStack.at(-1);
|
||||
|
||||
if (currentNavigationStack.length > 0) {
|
||||
const removedItem = currentNavigationStack.at(-1);
|
||||
|
||||
if (isDefined(removedItem)) {
|
||||
const newMorphItems = new Map(currentMorphItems);
|
||||
newMorphItems.delete(removedItem.pageId);
|
||||
set(commandMenuNavigationMorphItemsByPageState, newMorphItems);
|
||||
|
||||
const morphItems = currentMorphItems.get(removedItem.pageId);
|
||||
if (isNonEmptyArray(morphItems)) {
|
||||
store.set(
|
||||
activeTabIdComponentState.atomFamily({
|
||||
instanceId: getShowPageTabListComponentId({
|
||||
pageId: removedItem.pageId,
|
||||
targetObjectId: morphItems[0].recordId,
|
||||
}),
|
||||
}),
|
||||
null,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set(hasUserSelectedCommandState, false);
|
||||
};
|
||||
},
|
||||
[closeCommandMenu, store],
|
||||
);
|
||||
|
||||
const navigateCommandMenuHistory = useRecoilCallback(
|
||||
({ snapshot, set }) => {
|
||||
return (pageIndex: number) => {
|
||||
const currentNavigationStack = snapshot
|
||||
.getLoadable(commandMenuNavigationStackState)
|
||||
.getValue();
|
||||
|
||||
const newNavigationStack = currentNavigationStack.slice(
|
||||
0,
|
||||
pageIndex + 1,
|
||||
if (isDefined(removedItem)) {
|
||||
const newMorphItems = new Map(currentMorphItems);
|
||||
newMorphItems.delete(removedItem.pageId);
|
||||
jotaiStore.set(
|
||||
commandMenuNavigationMorphItemsByPageState.atom,
|
||||
newMorphItems,
|
||||
);
|
||||
|
||||
set(commandMenuNavigationStackState, newNavigationStack);
|
||||
|
||||
const newNavigationStackItem = newNavigationStack.at(-1);
|
||||
|
||||
if (!isDefined(newNavigationStackItem)) {
|
||||
throw new Error(
|
||||
`No command menu navigation stack item found for index ${pageIndex}`,
|
||||
const morphItems = currentMorphItems.get(removedItem.pageId);
|
||||
if (isNonEmptyArray(morphItems)) {
|
||||
jotaiStore.set(
|
||||
activeTabIdComponentState.atomFamily({
|
||||
instanceId: getShowPageTabListComponentId({
|
||||
pageId: removedItem.pageId,
|
||||
targetObjectId: morphItems[0].recordId,
|
||||
}),
|
||||
}),
|
||||
null,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set(commandMenuPageState, newNavigationStackItem.page);
|
||||
set(commandMenuPageInfoState, {
|
||||
title: newNavigationStackItem.pageTitle,
|
||||
Icon: newNavigationStackItem.pageIcon,
|
||||
instanceId: newNavigationStackItem.pageId,
|
||||
});
|
||||
const currentMorphItems = snapshot
|
||||
.getLoadable(commandMenuNavigationMorphItemsByPageState)
|
||||
.getValue();
|
||||
jotaiStore.set(hasUserSelectedCommandState.atom, false);
|
||||
}, [closeCommandMenu]);
|
||||
|
||||
for (const [pageId, morphItems] of currentMorphItems.entries()) {
|
||||
if (!newNavigationStack.some((item) => item.pageId === pageId)) {
|
||||
store.set(
|
||||
activeTabIdComponentState.atomFamily({
|
||||
instanceId: getShowPageTabListComponentId({
|
||||
pageId,
|
||||
targetObjectId: morphItems[0].recordId,
|
||||
}),
|
||||
}),
|
||||
null,
|
||||
);
|
||||
}
|
||||
}
|
||||
const navigateCommandMenuHistory = useCallback((pageIndex: number) => {
|
||||
const currentNavigationStack = jotaiStore.get(
|
||||
commandMenuNavigationStackState.atom,
|
||||
);
|
||||
|
||||
const newMorphItems = new Map(
|
||||
Array.from(currentMorphItems.entries()).filter(([pageId]) =>
|
||||
newNavigationStack.some((item) => item.pageId === pageId),
|
||||
),
|
||||
const newNavigationStack = currentNavigationStack.slice(0, pageIndex + 1);
|
||||
|
||||
jotaiStore.set(commandMenuNavigationStackState.atom, newNavigationStack);
|
||||
|
||||
const newNavigationStackItem = newNavigationStack.at(-1);
|
||||
|
||||
if (!isDefined(newNavigationStackItem)) {
|
||||
throw new Error(
|
||||
`No command menu navigation stack item found for index ${pageIndex}`,
|
||||
);
|
||||
}
|
||||
|
||||
jotaiStore.set(commandMenuPageState.atom, newNavigationStackItem.page);
|
||||
jotaiStore.set(commandMenuPageInfoState.atom, {
|
||||
title: newNavigationStackItem.pageTitle,
|
||||
Icon: newNavigationStackItem.pageIcon,
|
||||
instanceId: newNavigationStackItem.pageId,
|
||||
});
|
||||
const currentMorphItems = jotaiStore.get(
|
||||
commandMenuNavigationMorphItemsByPageState.atom,
|
||||
);
|
||||
|
||||
for (const [pageId, morphItems] of currentMorphItems.entries()) {
|
||||
if (!newNavigationStack.some((item) => item.pageId === pageId)) {
|
||||
jotaiStore.set(
|
||||
activeTabIdComponentState.atomFamily({
|
||||
instanceId: getShowPageTabListComponentId({
|
||||
pageId,
|
||||
targetObjectId: morphItems[0].recordId,
|
||||
}),
|
||||
}),
|
||||
null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
set(commandMenuNavigationMorphItemsByPageState, newMorphItems);
|
||||
const newMorphItems = new Map(
|
||||
Array.from(currentMorphItems.entries()).filter(([pageId]) =>
|
||||
newNavigationStack.some((item) => item.pageId === pageId),
|
||||
),
|
||||
);
|
||||
|
||||
set(hasUserSelectedCommandState, false);
|
||||
};
|
||||
},
|
||||
[store],
|
||||
);
|
||||
jotaiStore.set(
|
||||
commandMenuNavigationMorphItemsByPageState.atom,
|
||||
newMorphItems,
|
||||
);
|
||||
|
||||
jotaiStore.set(hasUserSelectedCommandState.atom, false);
|
||||
}, []);
|
||||
|
||||
return {
|
||||
goBackFromCommandMenu,
|
||||
|
||||
@@ -11,10 +11,10 @@ import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/s
|
||||
import { useKeyboardShortcutMenu } from '@/keyboard-shortcut-menu/hooks/useKeyboardShortcutMenu';
|
||||
import { useGlobalHotkeys } from '@/ui/utilities/hotkey/hooks/useGlobalHotkeys';
|
||||
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { Key } from 'ts-key-enum';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
import { FeatureFlagKey } from '~/generated-metadata/graphql';
|
||||
@@ -30,15 +30,15 @@ export const useCommandMenuHotKeys = () => {
|
||||
|
||||
const { setGlobalCommandMenuContext } = useSetGlobalCommandMenuContext();
|
||||
|
||||
const commandMenuSearch = useRecoilValue(commandMenuSearchState);
|
||||
const commandMenuSearch = useRecoilValueV2(commandMenuSearchState);
|
||||
|
||||
const { closeKeyboardShortcutMenu } = useKeyboardShortcutMenu();
|
||||
|
||||
const commandMenuPage = useRecoilValue(commandMenuPageState);
|
||||
const commandMenuPage = useRecoilValueV2(commandMenuPageState);
|
||||
|
||||
const isAiEnabled = useIsFeatureEnabled(FeatureFlagKey.IS_AI_ENABLED);
|
||||
|
||||
const contextStoreTargetedRecordsRuleComponent = useRecoilComponentValue(
|
||||
const contextStoreTargetedRecordsRuleComponent = useRecoilComponentValueV2(
|
||||
contextStoreTargetedRecordsRuleComponentState,
|
||||
COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
);
|
||||
|
||||
+2
-2
@@ -11,15 +11,15 @@ import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSi
|
||||
import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions';
|
||||
import { getObjectPermissionsFromMapByObjectMetadataId } from '@/settings/roles/role-permissions/objects-permissions/utils/getObjectPermissionsFromMapByObjectMetadataId';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { useMemo } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { AppPath } from 'twenty-shared/types';
|
||||
import { Avatar } from 'twenty-ui/display';
|
||||
import { useDebounce } from 'use-debounce';
|
||||
import { useSearchQuery } from '~/generated/graphql';
|
||||
|
||||
export const useCommandMenuSearchRecords = () => {
|
||||
const commandMenuSearch = useRecoilValue(commandMenuSearchState);
|
||||
const commandMenuSearch = useRecoilValueV2(commandMenuSearchState);
|
||||
const coreClient = useApolloCoreClient();
|
||||
|
||||
const [deferredCommandMenuSearch] = useDebounce(commandMenuSearch, 300);
|
||||
|
||||
+22
-19
@@ -1,5 +1,6 @@
|
||||
import { commandMenuNavigationMorphItemsByPageState } from '@/command-menu/states/commandMenuNavigationMorphItemsByPageState';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
type UpdateNavigationMorphItemsByPageParams = {
|
||||
pageId: string;
|
||||
@@ -8,26 +9,28 @@ type UpdateNavigationMorphItemsByPageParams = {
|
||||
};
|
||||
|
||||
export const useCommandMenuUpdateNavigationMorphItemsByPage = () => {
|
||||
const updateCommandMenuNavigationMorphItemsByPage = useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
async ({
|
||||
pageId,
|
||||
const updateCommandMenuNavigationMorphItemsByPage = useCallback(
|
||||
async ({
|
||||
pageId,
|
||||
objectMetadataId,
|
||||
objectRecordIds,
|
||||
}: UpdateNavigationMorphItemsByPageParams) => {
|
||||
const currentMorphItems = jotaiStore.get(
|
||||
commandMenuNavigationMorphItemsByPageState.atom,
|
||||
);
|
||||
|
||||
const newMorphItems = objectRecordIds.map((recordId) => ({
|
||||
objectMetadataId,
|
||||
objectRecordIds,
|
||||
}: UpdateNavigationMorphItemsByPageParams) => {
|
||||
const currentMorphItems = snapshot
|
||||
.getLoadable(commandMenuNavigationMorphItemsByPageState)
|
||||
.getValue();
|
||||
recordId,
|
||||
}));
|
||||
|
||||
const newMorphItems = objectRecordIds.map((recordId) => ({
|
||||
objectMetadataId,
|
||||
recordId,
|
||||
}));
|
||||
|
||||
const newMorphItemsMap = new Map(currentMorphItems);
|
||||
newMorphItemsMap.set(pageId, newMorphItems);
|
||||
set(commandMenuNavigationMorphItemsByPageState, newMorphItemsMap);
|
||||
},
|
||||
const newMorphItemsMap = new Map(currentMorphItems);
|
||||
newMorphItemsMap.set(pageId, newMorphItems);
|
||||
jotaiStore.set(
|
||||
commandMenuNavigationMorphItemsByPageState.atom,
|
||||
newMorphItemsMap,
|
||||
);
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
|
||||
+110
-128
@@ -7,153 +7,135 @@ import { contextStoreFiltersComponentState } from '@/context-store/states/contex
|
||||
import { contextStoreIsPageInEditModeComponentState } from '@/context-store/states/contextStoreIsPageInEditModeComponentState';
|
||||
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
export const useCopyContextStoreStates = () => {
|
||||
const copyContextStoreStates = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
({
|
||||
instanceIdToCopyFrom,
|
||||
instanceIdToCopyTo,
|
||||
}: {
|
||||
instanceIdToCopyFrom: string;
|
||||
instanceIdToCopyTo: string;
|
||||
}) => {
|
||||
const contextStoreCurrentObjectMetadataItemId = snapshot
|
||||
.getLoadable(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyFrom,
|
||||
}),
|
||||
)
|
||||
.getValue();
|
||||
const copyContextStoreStates = useCallback(
|
||||
({
|
||||
instanceIdToCopyFrom,
|
||||
instanceIdToCopyTo,
|
||||
}: {
|
||||
instanceIdToCopyFrom: string;
|
||||
instanceIdToCopyTo: string;
|
||||
}) => {
|
||||
const contextStoreCurrentObjectMetadataItemId = jotaiStore.get(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyFrom,
|
||||
}),
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyTo,
|
||||
}),
|
||||
contextStoreCurrentObjectMetadataItemId,
|
||||
);
|
||||
jotaiStore.set(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyTo,
|
||||
}),
|
||||
contextStoreCurrentObjectMetadataItemId,
|
||||
);
|
||||
|
||||
const contextStoreTargetedRecordsRule = snapshot
|
||||
.getLoadable(
|
||||
contextStoreTargetedRecordsRuleComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyFrom,
|
||||
}),
|
||||
)
|
||||
.getValue();
|
||||
const contextStoreTargetedRecordsRule = jotaiStore.get(
|
||||
contextStoreTargetedRecordsRuleComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyFrom,
|
||||
}),
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreTargetedRecordsRuleComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyTo,
|
||||
}),
|
||||
contextStoreTargetedRecordsRule,
|
||||
);
|
||||
jotaiStore.set(
|
||||
contextStoreTargetedRecordsRuleComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyTo,
|
||||
}),
|
||||
contextStoreTargetedRecordsRule,
|
||||
);
|
||||
|
||||
const contextStoreNumberOfSelectedRecords = snapshot
|
||||
.getLoadable(
|
||||
contextStoreNumberOfSelectedRecordsComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyFrom,
|
||||
}),
|
||||
)
|
||||
.getValue();
|
||||
const contextStoreNumberOfSelectedRecords = jotaiStore.get(
|
||||
contextStoreNumberOfSelectedRecordsComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyFrom,
|
||||
}),
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreNumberOfSelectedRecordsComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyTo,
|
||||
}),
|
||||
contextStoreNumberOfSelectedRecords,
|
||||
);
|
||||
jotaiStore.set(
|
||||
contextStoreNumberOfSelectedRecordsComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyTo,
|
||||
}),
|
||||
contextStoreNumberOfSelectedRecords,
|
||||
);
|
||||
|
||||
const contextStoreFilters = snapshot
|
||||
.getLoadable(
|
||||
contextStoreFiltersComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyFrom,
|
||||
}),
|
||||
)
|
||||
.getValue();
|
||||
const contextStoreFilters = jotaiStore.get(
|
||||
contextStoreFiltersComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyFrom,
|
||||
}),
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreFiltersComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyTo,
|
||||
}),
|
||||
contextStoreFilters,
|
||||
);
|
||||
jotaiStore.set(
|
||||
contextStoreFiltersComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyTo,
|
||||
}),
|
||||
contextStoreFilters,
|
||||
);
|
||||
|
||||
const contextStoreFilterGroups = snapshot
|
||||
.getLoadable(
|
||||
contextStoreFilterGroupsComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyFrom,
|
||||
}),
|
||||
)
|
||||
.getValue();
|
||||
const contextStoreFilterGroups = jotaiStore.get(
|
||||
contextStoreFilterGroupsComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyFrom,
|
||||
}),
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreFilterGroupsComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyTo,
|
||||
}),
|
||||
contextStoreFilterGroups,
|
||||
);
|
||||
jotaiStore.set(
|
||||
contextStoreFilterGroupsComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyTo,
|
||||
}),
|
||||
contextStoreFilterGroups,
|
||||
);
|
||||
|
||||
const contextStoreAnyFieldFilterValue = snapshot
|
||||
.getLoadable(
|
||||
contextStoreAnyFieldFilterValueComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyFrom,
|
||||
}),
|
||||
)
|
||||
.getValue();
|
||||
const contextStoreAnyFieldFilterValue = jotaiStore.get(
|
||||
contextStoreAnyFieldFilterValueComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyFrom,
|
||||
}),
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreAnyFieldFilterValueComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyTo,
|
||||
}),
|
||||
contextStoreAnyFieldFilterValue,
|
||||
);
|
||||
jotaiStore.set(
|
||||
contextStoreAnyFieldFilterValueComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyTo,
|
||||
}),
|
||||
contextStoreAnyFieldFilterValue,
|
||||
);
|
||||
|
||||
const contextStoreCurrentViewId = snapshot
|
||||
.getLoadable(
|
||||
contextStoreCurrentViewIdComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyFrom,
|
||||
}),
|
||||
)
|
||||
.getValue();
|
||||
const contextStoreCurrentViewId = jotaiStore.get(
|
||||
contextStoreCurrentViewIdComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyFrom,
|
||||
}),
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreCurrentViewIdComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyTo,
|
||||
}),
|
||||
contextStoreCurrentViewId,
|
||||
);
|
||||
jotaiStore.set(
|
||||
contextStoreCurrentViewIdComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyTo,
|
||||
}),
|
||||
contextStoreCurrentViewId,
|
||||
);
|
||||
|
||||
const contextStoreCurrentViewType = snapshot
|
||||
.getLoadable(
|
||||
contextStoreCurrentViewTypeComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyFrom,
|
||||
}),
|
||||
)
|
||||
.getValue();
|
||||
const contextStoreCurrentViewType = jotaiStore.get(
|
||||
contextStoreCurrentViewTypeComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyFrom,
|
||||
}),
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreCurrentViewTypeComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyTo,
|
||||
}),
|
||||
contextStoreCurrentViewType,
|
||||
);
|
||||
jotaiStore.set(
|
||||
contextStoreCurrentViewTypeComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyTo,
|
||||
}),
|
||||
contextStoreCurrentViewType,
|
||||
);
|
||||
|
||||
const contextStoreIsFullTabWidgetInEditMode = snapshot
|
||||
.getLoadable(
|
||||
contextStoreIsPageInEditModeComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyFrom,
|
||||
}),
|
||||
)
|
||||
.getValue();
|
||||
const contextStoreIsFullTabWidgetInEditMode = jotaiStore.get(
|
||||
contextStoreIsPageInEditModeComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyFrom,
|
||||
}),
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreIsPageInEditModeComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyTo,
|
||||
}),
|
||||
contextStoreIsFullTabWidgetInEditMode,
|
||||
);
|
||||
},
|
||||
jotaiStore.set(
|
||||
contextStoreIsPageInEditModeComponentState.atomFamily({
|
||||
instanceId: instanceIdToCopyTo,
|
||||
}),
|
||||
contextStoreIsFullTabWidgetInEditMode,
|
||||
);
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
|
||||
@@ -9,13 +9,12 @@ import { commandMenuPageState } from '@/command-menu/states/commandMenuPageState
|
||||
import { commandMenuShouldFocusTitleInputComponentState } from '@/command-menu/states/commandMenuShouldFocusTitleInputComponentState';
|
||||
import { hasUserSelectedCommandState } from '@/command-menu/states/hasUserSelectedCommandState';
|
||||
import { isCommandMenuClosingState } from '@/command-menu/states/isCommandMenuClosingState';
|
||||
import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState';
|
||||
import { isCommandMenuOpenedStateV2 } from '@/command-menu/states/isCommandMenuOpenedStateV2';
|
||||
import { MAIN_CONTEXT_STORE_INSTANCE_ID } from '@/context-store/constants/MainContextStoreInstanceId';
|
||||
import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePushFocusItemToFocusStack';
|
||||
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
|
||||
import { useStore } from 'jotai';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { useCallback } from 'react';
|
||||
import { type CommandMenuPages } from 'twenty-shared/types';
|
||||
import { type IconComponent } from 'twenty-ui/display';
|
||||
import { v4 } from 'uuid';
|
||||
@@ -36,121 +35,110 @@ export const useNavigateCommandMenu = () => {
|
||||
|
||||
const { pushFocusItemToFocusStack } = usePushFocusItemToFocusStack();
|
||||
|
||||
const store = useStore();
|
||||
const openCommandMenu = useCallback(() => {
|
||||
const isCommandMenuOpened = jotaiStore.get(isCommandMenuOpenedStateV2.atom);
|
||||
|
||||
const openCommandMenu = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
() => {
|
||||
const isCommandMenuOpened = snapshot
|
||||
.getLoadable(isCommandMenuOpenedState)
|
||||
.getValue();
|
||||
const isCommandMenuClosing = jotaiStore.get(isCommandMenuClosingState.atom);
|
||||
|
||||
const isCommandMenuClosing = snapshot
|
||||
.getLoadable(isCommandMenuClosingState)
|
||||
.getValue();
|
||||
if (isCommandMenuClosing) {
|
||||
commandMenuCloseAnimationCompleteCleanup();
|
||||
}
|
||||
|
||||
if (isCommandMenuClosing) {
|
||||
commandMenuCloseAnimationCompleteCleanup();
|
||||
}
|
||||
if (isCommandMenuOpened) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isCommandMenuOpened) {
|
||||
return;
|
||||
}
|
||||
|
||||
pushFocusItemToFocusStack({
|
||||
focusId: SIDE_PANEL_FOCUS_ID,
|
||||
component: {
|
||||
type: FocusComponentType.SIDE_PANEL,
|
||||
instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
},
|
||||
globalHotkeysConfig: {
|
||||
enableGlobalHotkeysConflictingWithKeyboard: false,
|
||||
},
|
||||
});
|
||||
|
||||
copyContextStoreStates({
|
||||
instanceIdToCopyFrom: MAIN_CONTEXT_STORE_INSTANCE_ID,
|
||||
instanceIdToCopyTo: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
});
|
||||
|
||||
set(isCommandMenuOpenedState, true);
|
||||
store.set(isCommandMenuOpenedStateV2.atom, true);
|
||||
set(hasUserSelectedCommandState, false);
|
||||
pushFocusItemToFocusStack({
|
||||
focusId: SIDE_PANEL_FOCUS_ID,
|
||||
component: {
|
||||
type: FocusComponentType.SIDE_PANEL,
|
||||
instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
},
|
||||
[
|
||||
copyContextStoreStates,
|
||||
commandMenuCloseAnimationCompleteCleanup,
|
||||
pushFocusItemToFocusStack,
|
||||
store,
|
||||
],
|
||||
);
|
||||
globalHotkeysConfig: {
|
||||
enableGlobalHotkeysConflictingWithKeyboard: false,
|
||||
},
|
||||
});
|
||||
|
||||
const navigateCommandMenu = useRecoilCallback(
|
||||
({ snapshot, set }) => {
|
||||
return ({
|
||||
page,
|
||||
pageTitle,
|
||||
pageIcon,
|
||||
pageIconColor,
|
||||
pageId,
|
||||
focusTitleInput = false,
|
||||
resetNavigationStack = false,
|
||||
}: CommandMenuNavigationStackItem & {
|
||||
resetNavigationStack?: boolean;
|
||||
focusTitleInput?: boolean;
|
||||
}) => {
|
||||
const computedPageId = pageId || v4();
|
||||
copyContextStoreStates({
|
||||
instanceIdToCopyFrom: MAIN_CONTEXT_STORE_INSTANCE_ID,
|
||||
instanceIdToCopyTo: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
});
|
||||
|
||||
openCommandMenu();
|
||||
set(commandMenuPageState, page);
|
||||
set(commandMenuPageInfoState, {
|
||||
title: pageTitle,
|
||||
Icon: pageIcon,
|
||||
instanceId: computedPageId,
|
||||
});
|
||||
jotaiStore.set(isCommandMenuOpenedStateV2.atom, true);
|
||||
jotaiStore.set(hasUserSelectedCommandState.atom, false);
|
||||
}, [
|
||||
copyContextStoreStates,
|
||||
commandMenuCloseAnimationCompleteCleanup,
|
||||
pushFocusItemToFocusStack,
|
||||
]);
|
||||
|
||||
if (focusTitleInput) {
|
||||
set(
|
||||
commandMenuShouldFocusTitleInputComponentState.atomFamily({
|
||||
instanceId: computedPageId,
|
||||
}),
|
||||
true,
|
||||
);
|
||||
}
|
||||
const navigateCommandMenu = useCallback(
|
||||
({
|
||||
page,
|
||||
pageTitle,
|
||||
pageIcon,
|
||||
pageIconColor,
|
||||
pageId,
|
||||
focusTitleInput = false,
|
||||
resetNavigationStack = false,
|
||||
}: CommandMenuNavigationStackItem & {
|
||||
resetNavigationStack?: boolean;
|
||||
focusTitleInput?: boolean;
|
||||
}) => {
|
||||
const computedPageId = pageId || v4();
|
||||
|
||||
const isCommandMenuClosing = snapshot
|
||||
.getLoadable(isCommandMenuClosingState)
|
||||
.getValue();
|
||||
openCommandMenu();
|
||||
jotaiStore.set(commandMenuPageState.atom, page);
|
||||
jotaiStore.set(commandMenuPageInfoState.atom, {
|
||||
title: pageTitle,
|
||||
Icon: pageIcon,
|
||||
instanceId: computedPageId,
|
||||
});
|
||||
|
||||
const currentNavigationStack = isCommandMenuClosing
|
||||
? []
|
||||
: snapshot.getLoadable(commandMenuNavigationStackState).getValue();
|
||||
if (focusTitleInput) {
|
||||
jotaiStore.set(
|
||||
commandMenuShouldFocusTitleInputComponentState.atomFamily({
|
||||
instanceId: computedPageId,
|
||||
}),
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
if (resetNavigationStack) {
|
||||
set(commandMenuNavigationStackState, [
|
||||
{
|
||||
page,
|
||||
pageTitle,
|
||||
pageIcon,
|
||||
pageIconColor,
|
||||
pageId: computedPageId,
|
||||
},
|
||||
]);
|
||||
const isCommandMenuClosing = jotaiStore.get(
|
||||
isCommandMenuClosingState.atom,
|
||||
);
|
||||
|
||||
set(commandMenuNavigationMorphItemsByPageState, new Map());
|
||||
} else {
|
||||
set(commandMenuNavigationStackState, [
|
||||
...currentNavigationStack,
|
||||
{
|
||||
page,
|
||||
pageTitle,
|
||||
pageIcon,
|
||||
pageIconColor,
|
||||
pageId: computedPageId,
|
||||
},
|
||||
]);
|
||||
}
|
||||
};
|
||||
const currentNavigationStack = isCommandMenuClosing
|
||||
? []
|
||||
: jotaiStore.get(commandMenuNavigationStackState.atom);
|
||||
|
||||
if (resetNavigationStack) {
|
||||
jotaiStore.set(commandMenuNavigationStackState.atom, [
|
||||
{
|
||||
page,
|
||||
pageTitle,
|
||||
pageIcon,
|
||||
pageIconColor,
|
||||
pageId: computedPageId,
|
||||
},
|
||||
]);
|
||||
|
||||
jotaiStore.set(
|
||||
commandMenuNavigationMorphItemsByPageState.atom,
|
||||
new Map(),
|
||||
);
|
||||
} else {
|
||||
jotaiStore.set(commandMenuNavigationStackState.atom, [
|
||||
...currentNavigationStack,
|
||||
{
|
||||
page,
|
||||
pageTitle,
|
||||
pageIcon,
|
||||
pageIconColor,
|
||||
pageId: computedPageId,
|
||||
},
|
||||
]);
|
||||
}
|
||||
},
|
||||
[openCommandMenu],
|
||||
);
|
||||
|
||||
+40
-41
@@ -1,7 +1,8 @@
|
||||
import { useNavigateCommandMenu } from '@/command-menu/hooks/useNavigateCommandMenu';
|
||||
import { viewableRecordIdComponentState } from '@/command-menu/pages/record-page/states/viewableRecordIdComponentState';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { useCallback } from 'react';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
import { IconCalendarEvent } from 'twenty-ui/display';
|
||||
import { v4 } from 'uuid';
|
||||
@@ -9,50 +10,48 @@ import { v4 } from 'uuid';
|
||||
export const useOpenCalendarEventInCommandMenu = () => {
|
||||
const { navigateCommandMenu } = useNavigateCommandMenu();
|
||||
|
||||
const openCalendarEventInCommandMenu = useRecoilCallback(
|
||||
({ set }) => {
|
||||
return (calendarEventId: string) => {
|
||||
const pageComponentInstanceId = v4();
|
||||
const openCalendarEventInCommandMenu = useCallback(
|
||||
(calendarEventId: string) => {
|
||||
const pageComponentInstanceId = v4();
|
||||
|
||||
set(
|
||||
viewableRecordIdComponentState.atomFamily({
|
||||
instanceId: pageComponentInstanceId,
|
||||
}),
|
||||
calendarEventId,
|
||||
);
|
||||
jotaiStore.set(
|
||||
viewableRecordIdComponentState.atomFamily({
|
||||
instanceId: pageComponentInstanceId,
|
||||
}),
|
||||
calendarEventId,
|
||||
);
|
||||
|
||||
// TODO: Uncomment this once we need to calendar event title in the navigation
|
||||
// const objectMetadataItem = snapshot
|
||||
// .getLoadable(objectMetadataItemsState)
|
||||
// .getValue()
|
||||
// .find(
|
||||
// ({ nameSingular }) =>
|
||||
// nameSingular === CoreObjectNameSingular.CalendarEvent,
|
||||
// );
|
||||
// TODO: Uncomment this once we need to calendar event title in the navigation
|
||||
// const objectMetadataItem = snapshot
|
||||
// .getLoadable(objectMetadataItemsState)
|
||||
// .getValue()
|
||||
// .find(
|
||||
// ({ nameSingular }) =>
|
||||
// nameSingular === CoreObjectNameSingular.CalendarEvent,
|
||||
// );
|
||||
|
||||
// set(
|
||||
// commandMenuNavigationMorphItemsState,
|
||||
// new Map([
|
||||
// ...snapshot
|
||||
// .getLoadable(commandMenuNavigationMorphItemsState)
|
||||
// .getValue(),
|
||||
// [
|
||||
// pageComponentInstanceId,
|
||||
// {
|
||||
// objectMetadataId: objectMetadataItem?.id,
|
||||
// recordId: calendarEventId,
|
||||
// },
|
||||
// ],
|
||||
// ]),
|
||||
// );
|
||||
// set(
|
||||
// commandMenuNavigationMorphItemsState,
|
||||
// new Map([
|
||||
// ...snapshot
|
||||
// .getLoadable(commandMenuNavigationMorphItemsState)
|
||||
// .getValue(),
|
||||
// [
|
||||
// pageComponentInstanceId,
|
||||
// {
|
||||
// objectMetadataId: objectMetadataItem?.id,
|
||||
// recordId: calendarEventId,
|
||||
// },
|
||||
// ],
|
||||
// ]),
|
||||
// );
|
||||
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.ViewCalendarEvent,
|
||||
pageTitle: t`Calendar Event`,
|
||||
pageIcon: IconCalendarEvent,
|
||||
pageId: pageComponentInstanceId,
|
||||
});
|
||||
};
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.ViewCalendarEvent,
|
||||
pageTitle: t`Calendar Event`,
|
||||
pageIcon: IconCalendarEvent,
|
||||
pageId: pageComponentInstanceId,
|
||||
});
|
||||
},
|
||||
[navigateCommandMenu],
|
||||
);
|
||||
|
||||
+40
-41
@@ -1,7 +1,8 @@
|
||||
import { useNavigateCommandMenu } from '@/command-menu/hooks/useNavigateCommandMenu';
|
||||
import { viewableRecordIdComponentState } from '@/command-menu/pages/record-page/states/viewableRecordIdComponentState';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { useCallback } from 'react';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
import { IconMail } from 'twenty-ui/display';
|
||||
import { v4 } from 'uuid';
|
||||
@@ -9,50 +10,48 @@ import { v4 } from 'uuid';
|
||||
export const useOpenEmailThreadInCommandMenu = () => {
|
||||
const { navigateCommandMenu } = useNavigateCommandMenu();
|
||||
|
||||
const openEmailThreadInCommandMenu = useRecoilCallback(
|
||||
({ set }) => {
|
||||
return (emailThreadId: string) => {
|
||||
const pageComponentInstanceId = v4();
|
||||
const openEmailThreadInCommandMenu = useCallback(
|
||||
(emailThreadId: string) => {
|
||||
const pageComponentInstanceId = v4();
|
||||
|
||||
set(
|
||||
viewableRecordIdComponentState.atomFamily({
|
||||
instanceId: pageComponentInstanceId,
|
||||
}),
|
||||
emailThreadId,
|
||||
);
|
||||
jotaiStore.set(
|
||||
viewableRecordIdComponentState.atomFamily({
|
||||
instanceId: pageComponentInstanceId,
|
||||
}),
|
||||
emailThreadId,
|
||||
);
|
||||
|
||||
// TODO: Uncomment this once we need to show the thread title in the navigation
|
||||
// const objectMetadataItem = snapshot
|
||||
// .getLoadable(objectMetadataItemsState)
|
||||
// .getValue()
|
||||
// .find(
|
||||
// ({ nameSingular }) =>
|
||||
// nameSingular === CoreObjectNameSingular.MessageThread,
|
||||
// );
|
||||
// TODO: Uncomment this once we need to show the thread title in the navigation
|
||||
// const objectMetadataItem = snapshot
|
||||
// .getLoadable(objectMetadataItemsState)
|
||||
// .getValue()
|
||||
// .find(
|
||||
// ({ nameSingular }) =>
|
||||
// nameSingular === CoreObjectNameSingular.MessageThread,
|
||||
// );
|
||||
|
||||
// set(
|
||||
// commandMenuNavigationMorphItemsState,
|
||||
// new Map([
|
||||
// ...snapshot
|
||||
// .getLoadable(commandMenuNavigationMorphItemsState)
|
||||
// .getValue(),
|
||||
// [
|
||||
// pageComponentInstanceId,
|
||||
// {
|
||||
// objectMetadataId: objectMetadataItem?.id,
|
||||
// recordId: emailThreadId,
|
||||
// },
|
||||
// ],
|
||||
// ]),
|
||||
// );
|
||||
// set(
|
||||
// commandMenuNavigationMorphItemsState,
|
||||
// new Map([
|
||||
// ...snapshot
|
||||
// .getLoadable(commandMenuNavigationMorphItemsState)
|
||||
// .getValue(),
|
||||
// [
|
||||
// pageComponentInstanceId,
|
||||
// {
|
||||
// objectMetadataId: objectMetadataItem?.id,
|
||||
// recordId: emailThreadId,
|
||||
// },
|
||||
// ],
|
||||
// ]),
|
||||
// );
|
||||
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.ViewEmailThread,
|
||||
pageTitle: t`Email Thread`,
|
||||
pageIcon: IconMail,
|
||||
pageId: pageComponentInstanceId,
|
||||
});
|
||||
};
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.ViewEmailThread,
|
||||
pageTitle: t`Email Thread`,
|
||||
pageIcon: IconMail,
|
||||
pageId: pageComponentInstanceId,
|
||||
});
|
||||
},
|
||||
[navigateCommandMenu],
|
||||
);
|
||||
|
||||
+27
-31
@@ -1,6 +1,6 @@
|
||||
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
|
||||
import { viewableFrontComponentIdComponentState } from '@/command-menu/pages/front-component/states/viewableFrontComponentIdComponentState';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
import { type IconComponent } from 'twenty-ui/display';
|
||||
import { v4 } from 'uuid';
|
||||
@@ -8,38 +8,34 @@ import { v4 } from 'uuid';
|
||||
export const useOpenFrontComponentInCommandMenu = () => {
|
||||
const { navigateCommandMenu } = useCommandMenu();
|
||||
|
||||
const openFrontComponentInCommandMenu = useRecoilCallback(
|
||||
({ set }) =>
|
||||
({
|
||||
frontComponentId,
|
||||
pageTitle,
|
||||
pageIcon,
|
||||
resetNavigationStack = false,
|
||||
}: {
|
||||
frontComponentId: string;
|
||||
pageTitle: string;
|
||||
pageIcon: IconComponent;
|
||||
resetNavigationStack?: boolean;
|
||||
}) => {
|
||||
const pageComponentInstanceId = v4();
|
||||
const openFrontComponentInCommandMenu = ({
|
||||
frontComponentId,
|
||||
pageTitle,
|
||||
pageIcon,
|
||||
resetNavigationStack = false,
|
||||
}: {
|
||||
frontComponentId: string;
|
||||
pageTitle: string;
|
||||
pageIcon: IconComponent;
|
||||
resetNavigationStack?: boolean;
|
||||
}) => {
|
||||
const pageComponentInstanceId = v4();
|
||||
|
||||
set(
|
||||
viewableFrontComponentIdComponentState.atomFamily({
|
||||
instanceId: pageComponentInstanceId,
|
||||
}),
|
||||
frontComponentId,
|
||||
);
|
||||
jotaiStore.set(
|
||||
viewableFrontComponentIdComponentState.atomFamily({
|
||||
instanceId: pageComponentInstanceId,
|
||||
}),
|
||||
frontComponentId,
|
||||
);
|
||||
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.ViewFrontComponent,
|
||||
pageTitle,
|
||||
pageIcon,
|
||||
pageId: pageComponentInstanceId,
|
||||
resetNavigationStack,
|
||||
});
|
||||
},
|
||||
[navigateCommandMenu],
|
||||
);
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.ViewFrontComponent,
|
||||
pageTitle,
|
||||
pageIcon,
|
||||
pageId: pageComponentInstanceId,
|
||||
resetNavigationStack,
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
openFrontComponentInCommandMenu,
|
||||
|
||||
+31
-35
@@ -6,8 +6,9 @@ import { useLazyFindManyRecords } from '@/object-record/hooks/useLazyFindManyRec
|
||||
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { msg, t } from '@lingui/core/macro';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { useCallback } from 'react';
|
||||
import { IconArrowMerge } from 'twenty-ui/display';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
@@ -39,43 +40,38 @@ export const useOpenMergeRecordsPageInCommandMenu = ({
|
||||
},
|
||||
});
|
||||
|
||||
const openMergeRecordsPageInCommandMenu = useRecoilCallback(
|
||||
({ set }) => {
|
||||
return async () => {
|
||||
const pageId = v4();
|
||||
const openMergeRecordsPageInCommandMenu = useCallback(async () => {
|
||||
const pageId = v4();
|
||||
|
||||
set(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState.atomFamily({
|
||||
instanceId: pageId,
|
||||
}),
|
||||
objectMetadataItem.id,
|
||||
);
|
||||
|
||||
await updateCommandMenuNavigationMorphItemsByPage({
|
||||
pageId,
|
||||
objectMetadataId: objectMetadataItem.id,
|
||||
objectRecordIds,
|
||||
});
|
||||
const { records } = await findManyRecordsLazy();
|
||||
upsertRecordsInStore({ partialRecords: records ?? [] });
|
||||
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.MergeRecords,
|
||||
pageTitle: t(msg`Merge records`),
|
||||
pageIcon: IconArrowMerge,
|
||||
pageId,
|
||||
});
|
||||
};
|
||||
},
|
||||
[
|
||||
jotaiStore.set(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState.atomFamily({
|
||||
instanceId: pageId,
|
||||
}),
|
||||
objectMetadataItem.id,
|
||||
);
|
||||
|
||||
await updateCommandMenuNavigationMorphItemsByPage({
|
||||
pageId,
|
||||
objectMetadataId: objectMetadataItem.id,
|
||||
objectRecordIds,
|
||||
findManyRecordsLazy,
|
||||
upsertRecordsInStore,
|
||||
navigateCommandMenu,
|
||||
updateCommandMenuNavigationMorphItemsByPage,
|
||||
],
|
||||
);
|
||||
});
|
||||
const { records } = await findManyRecordsLazy();
|
||||
upsertRecordsInStore({ partialRecords: records ?? [] });
|
||||
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.MergeRecords,
|
||||
pageTitle: t(msg`Merge records`),
|
||||
pageIcon: IconArrowMerge,
|
||||
pageId,
|
||||
});
|
||||
}, [
|
||||
objectMetadataItem.id,
|
||||
objectRecordIds,
|
||||
findManyRecordsLazy,
|
||||
upsertRecordsInStore,
|
||||
navigateCommandMenu,
|
||||
updateCommandMenuNavigationMorphItemsByPage,
|
||||
]);
|
||||
|
||||
return {
|
||||
openMergeRecordsPageInCommandMenu,
|
||||
|
||||
+137
-143
@@ -15,14 +15,13 @@ import { objectMetadataItemFamilySelector } from '@/object-metadata/states/objec
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { getIconColorForObjectType } from '@/object-metadata/utils/getIconColorForObjectType';
|
||||
import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState';
|
||||
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
|
||||
import { useRunWorkflowRunOpeningInCommandMenuSideEffects } from '@/workflow/hooks/useRunWorkflowRunOpeningInCommandMenuSideEffects';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { useCallback } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
import { v4 } from 'uuid';
|
||||
@@ -35,168 +34,163 @@ export const useOpenRecordInCommandMenu = () => {
|
||||
const { runWorkflowRunOpeningInCommandMenuSideEffects } =
|
||||
useRunWorkflowRunOpeningInCommandMenuSideEffects();
|
||||
|
||||
const openRecordInCommandMenu = useRecoilCallback(
|
||||
({ set, snapshot }) => {
|
||||
return ({
|
||||
recordId,
|
||||
objectNameSingular,
|
||||
isNewRecord = false,
|
||||
resetNavigationStack = false,
|
||||
}: {
|
||||
recordId: string;
|
||||
objectNameSingular: string;
|
||||
isNewRecord?: boolean;
|
||||
resetNavigationStack?: boolean;
|
||||
}) => {
|
||||
const navigationStack = getSnapshotValue(
|
||||
snapshot,
|
||||
commandMenuNavigationStackState,
|
||||
);
|
||||
const openRecordInCommandMenu = useCallback(
|
||||
({
|
||||
recordId,
|
||||
objectNameSingular,
|
||||
isNewRecord = false,
|
||||
resetNavigationStack = false,
|
||||
}: {
|
||||
recordId: string;
|
||||
objectNameSingular: string;
|
||||
isNewRecord?: boolean;
|
||||
resetNavigationStack?: boolean;
|
||||
}) => {
|
||||
const navigationStack = jotaiStore.get(
|
||||
commandMenuNavigationStackState.atom,
|
||||
);
|
||||
|
||||
const currentNavigationStackItem = navigationStack.at(-1);
|
||||
const currentNavigationStackItem = navigationStack.at(-1);
|
||||
|
||||
if (isDefined(currentNavigationStackItem)) {
|
||||
const currentRecordId = getSnapshotValue(
|
||||
snapshot,
|
||||
viewableRecordIdComponentState.atomFamily({
|
||||
instanceId: currentNavigationStackItem.pageId,
|
||||
}),
|
||||
);
|
||||
|
||||
if (currentRecordId === recordId) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const pageComponentInstanceId = v4();
|
||||
|
||||
set(
|
||||
viewableRecordNameSingularComponentState.atomFamily({
|
||||
instanceId: pageComponentInstanceId,
|
||||
}),
|
||||
objectNameSingular,
|
||||
);
|
||||
set(
|
||||
if (isDefined(currentNavigationStackItem)) {
|
||||
const currentRecordId = jotaiStore.get(
|
||||
viewableRecordIdComponentState.atomFamily({
|
||||
instanceId: pageComponentInstanceId,
|
||||
}),
|
||||
recordId,
|
||||
);
|
||||
set(viewableRecordIdState, recordId);
|
||||
|
||||
const objectMetadataItem = jotaiStore.get(
|
||||
objectMetadataItemFamilySelector.selectorFamily({
|
||||
objectName: objectNameSingular,
|
||||
objectNameType: 'singular',
|
||||
instanceId: currentNavigationStackItem.pageId,
|
||||
}),
|
||||
);
|
||||
|
||||
if (!objectMetadataItem) {
|
||||
throw new Error(
|
||||
`No object metadata item found for object name ${objectNameSingular}`,
|
||||
);
|
||||
if (currentRecordId === recordId) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
set(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState.atomFamily({
|
||||
instanceId: pageComponentInstanceId,
|
||||
}),
|
||||
objectMetadataItem.id,
|
||||
const pageComponentInstanceId = v4();
|
||||
|
||||
jotaiStore.set(
|
||||
viewableRecordNameSingularComponentState.atomFamily({
|
||||
instanceId: pageComponentInstanceId,
|
||||
}),
|
||||
objectNameSingular,
|
||||
);
|
||||
jotaiStore.set(
|
||||
viewableRecordIdComponentState.atomFamily({
|
||||
instanceId: pageComponentInstanceId,
|
||||
}),
|
||||
recordId,
|
||||
);
|
||||
jotaiStore.set(viewableRecordIdState.atom, recordId);
|
||||
|
||||
const objectMetadataItem = jotaiStore.get(
|
||||
objectMetadataItemFamilySelector.selectorFamily({
|
||||
objectName: objectNameSingular,
|
||||
objectNameType: 'singular',
|
||||
}),
|
||||
);
|
||||
|
||||
if (!objectMetadataItem) {
|
||||
throw new Error(
|
||||
`No object metadata item found for object name ${objectNameSingular}`,
|
||||
);
|
||||
}
|
||||
|
||||
set(
|
||||
contextStoreTargetedRecordsRuleComponentState.atomFamily({
|
||||
instanceId: pageComponentInstanceId,
|
||||
}),
|
||||
{
|
||||
mode: 'selection',
|
||||
selectedRecordIds: [recordId],
|
||||
},
|
||||
);
|
||||
jotaiStore.set(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState.atomFamily({
|
||||
instanceId: pageComponentInstanceId,
|
||||
}),
|
||||
objectMetadataItem.id,
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreNumberOfSelectedRecordsComponentState.atomFamily({
|
||||
instanceId: pageComponentInstanceId,
|
||||
}),
|
||||
1,
|
||||
);
|
||||
jotaiStore.set(
|
||||
contextStoreTargetedRecordsRuleComponentState.atomFamily({
|
||||
instanceId: pageComponentInstanceId,
|
||||
}),
|
||||
{
|
||||
mode: 'selection',
|
||||
selectedRecordIds: [recordId],
|
||||
},
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreCurrentViewTypeComponentState.atomFamily({
|
||||
instanceId: pageComponentInstanceId,
|
||||
}),
|
||||
ContextStoreViewType.ShowPage,
|
||||
);
|
||||
jotaiStore.set(
|
||||
contextStoreNumberOfSelectedRecordsComponentState.atomFamily({
|
||||
instanceId: pageComponentInstanceId,
|
||||
}),
|
||||
1,
|
||||
);
|
||||
|
||||
set(
|
||||
jotaiStore.set(
|
||||
contextStoreCurrentViewTypeComponentState.atomFamily({
|
||||
instanceId: pageComponentInstanceId,
|
||||
}),
|
||||
ContextStoreViewType.ShowPage,
|
||||
);
|
||||
|
||||
jotaiStore.set(
|
||||
contextStoreCurrentViewIdComponentState.atomFamily({
|
||||
instanceId: pageComponentInstanceId,
|
||||
}),
|
||||
jotaiStore.get(
|
||||
contextStoreCurrentViewIdComponentState.atomFamily({
|
||||
instanceId: pageComponentInstanceId,
|
||||
instanceId: MAIN_CONTEXT_STORE_INSTANCE_ID,
|
||||
}),
|
||||
snapshot
|
||||
.getLoadable(
|
||||
contextStoreCurrentViewIdComponentState.atomFamily({
|
||||
instanceId: MAIN_CONTEXT_STORE_INSTANCE_ID,
|
||||
}),
|
||||
)
|
||||
.getValue(),
|
||||
);
|
||||
),
|
||||
);
|
||||
|
||||
set(
|
||||
jotaiStore.set(
|
||||
contextStoreIsPageInEditModeComponentState.atomFamily({
|
||||
instanceId: pageComponentInstanceId,
|
||||
}),
|
||||
jotaiStore.get(
|
||||
contextStoreIsPageInEditModeComponentState.atomFamily({
|
||||
instanceId: pageComponentInstanceId,
|
||||
instanceId: MAIN_CONTEXT_STORE_INSTANCE_ID,
|
||||
}),
|
||||
snapshot
|
||||
.getLoadable(
|
||||
contextStoreIsPageInEditModeComponentState.atomFamily({
|
||||
instanceId: MAIN_CONTEXT_STORE_INSTANCE_ID,
|
||||
}),
|
||||
)
|
||||
.getValue(),
|
||||
);
|
||||
),
|
||||
);
|
||||
|
||||
const currentMorphItems = snapshot
|
||||
.getLoadable(commandMenuNavigationMorphItemsByPageState)
|
||||
.getValue();
|
||||
const currentMorphItems = jotaiStore.get(
|
||||
commandMenuNavigationMorphItemsByPageState.atom,
|
||||
);
|
||||
|
||||
const morphItemToAdd = {
|
||||
objectMetadataId: objectMetadataItem.id,
|
||||
recordId,
|
||||
};
|
||||
|
||||
const newMorphItemsMap = new Map(currentMorphItems);
|
||||
newMorphItemsMap.set(pageComponentInstanceId, [morphItemToAdd]);
|
||||
|
||||
set(commandMenuNavigationMorphItemsByPageState, newMorphItemsMap);
|
||||
|
||||
const Icon = objectMetadataItem?.icon
|
||||
? getIcon(objectMetadataItem.icon)
|
||||
: getIcon('IconList');
|
||||
|
||||
const IconColor = getIconColorForObjectType({
|
||||
objectType: objectMetadataItem.nameSingular,
|
||||
theme,
|
||||
});
|
||||
|
||||
const objectLabelSingular = objectMetadataItem.labelSingular;
|
||||
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.ViewRecord,
|
||||
pageTitle: isNewRecord
|
||||
? t`New ${objectLabelSingular}`
|
||||
: objectLabelSingular,
|
||||
pageIcon: Icon,
|
||||
pageIconColor: IconColor,
|
||||
pageId: pageComponentInstanceId,
|
||||
resetNavigationStack,
|
||||
});
|
||||
|
||||
if (objectNameSingular === CoreObjectNameSingular.WorkflowRun) {
|
||||
runWorkflowRunOpeningInCommandMenuSideEffects({
|
||||
objectMetadataItem,
|
||||
recordId,
|
||||
});
|
||||
}
|
||||
const morphItemToAdd = {
|
||||
objectMetadataId: objectMetadataItem.id,
|
||||
recordId,
|
||||
};
|
||||
|
||||
const newMorphItemsMap = new Map(currentMorphItems);
|
||||
newMorphItemsMap.set(pageComponentInstanceId, [morphItemToAdd]);
|
||||
|
||||
jotaiStore.set(
|
||||
commandMenuNavigationMorphItemsByPageState.atom,
|
||||
newMorphItemsMap,
|
||||
);
|
||||
|
||||
const Icon = objectMetadataItem?.icon
|
||||
? getIcon(objectMetadataItem.icon)
|
||||
: getIcon('IconList');
|
||||
|
||||
const IconColor = getIconColorForObjectType({
|
||||
objectType: objectMetadataItem.nameSingular,
|
||||
theme,
|
||||
});
|
||||
|
||||
const objectLabelSingular = objectMetadataItem.labelSingular;
|
||||
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.ViewRecord,
|
||||
pageTitle: isNewRecord
|
||||
? t`New ${objectLabelSingular}`
|
||||
: objectLabelSingular,
|
||||
pageIcon: Icon,
|
||||
pageIconColor: IconColor,
|
||||
pageId: pageComponentInstanceId,
|
||||
resetNavigationStack,
|
||||
});
|
||||
|
||||
if (objectNameSingular === CoreObjectNameSingular.WorkflowRun) {
|
||||
runWorkflowRunOpeningInCommandMenuSideEffects({
|
||||
objectMetadataItem,
|
||||
recordId,
|
||||
});
|
||||
}
|
||||
},
|
||||
[
|
||||
getIcon,
|
||||
|
||||
+8
-10
@@ -2,7 +2,7 @@ import { useNavigateCommandMenu } from '@/command-menu/hooks/useNavigateCommandM
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
|
||||
import { msg, t } from '@lingui/core/macro';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { useCallback } from 'react';
|
||||
import { IconBoxMultiple } from 'twenty-ui/display';
|
||||
|
||||
type UseOpenUpdateMultipleRecordsPageInCommandMenuProps = {
|
||||
@@ -14,15 +14,13 @@ export const useOpenUpdateMultipleRecordsPageInCommandMenu = ({
|
||||
}: UseOpenUpdateMultipleRecordsPageInCommandMenuProps) => {
|
||||
const { navigateCommandMenu } = useNavigateCommandMenu();
|
||||
|
||||
const openUpdateMultipleRecordsPageInCommandMenu = useRecoilCallback(() => {
|
||||
return async () => {
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.UpdateRecords,
|
||||
pageTitle: t(msg`Update records`),
|
||||
pageIcon: IconBoxMultiple,
|
||||
pageId: contextStoreInstanceId,
|
||||
});
|
||||
};
|
||||
const openUpdateMultipleRecordsPageInCommandMenu = useCallback(async () => {
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.UpdateRecords,
|
||||
pageTitle: t(msg`Update records`),
|
||||
pageIcon: IconBoxMultiple,
|
||||
pageId: contextStoreInstanceId,
|
||||
});
|
||||
}, [navigateCommandMenu, contextStoreInstanceId]);
|
||||
|
||||
return {
|
||||
|
||||
+48
-49
@@ -5,63 +5,62 @@ import { contextStoreFilterGroupsComponentState } from '@/context-store/states/c
|
||||
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
|
||||
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
export const useResetContextStoreStates = () => {
|
||||
const resetContextStoreStates = useRecoilCallback(({ set }) => {
|
||||
return (instanceId: string) => {
|
||||
set(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState.atomFamily({
|
||||
instanceId,
|
||||
}),
|
||||
undefined,
|
||||
);
|
||||
const resetContextStoreStates = useCallback((instanceId: string) => {
|
||||
jotaiStore.set(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState.atomFamily({
|
||||
instanceId,
|
||||
}),
|
||||
undefined,
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreTargetedRecordsRuleComponentState.atomFamily({
|
||||
instanceId,
|
||||
}),
|
||||
{
|
||||
mode: 'selection',
|
||||
selectedRecordIds: [],
|
||||
},
|
||||
);
|
||||
jotaiStore.set(
|
||||
contextStoreTargetedRecordsRuleComponentState.atomFamily({
|
||||
instanceId,
|
||||
}),
|
||||
{
|
||||
mode: 'selection',
|
||||
selectedRecordIds: [],
|
||||
},
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreNumberOfSelectedRecordsComponentState.atomFamily({
|
||||
instanceId,
|
||||
}),
|
||||
0,
|
||||
);
|
||||
jotaiStore.set(
|
||||
contextStoreNumberOfSelectedRecordsComponentState.atomFamily({
|
||||
instanceId,
|
||||
}),
|
||||
0,
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreFiltersComponentState.atomFamily({
|
||||
instanceId,
|
||||
}),
|
||||
[],
|
||||
);
|
||||
jotaiStore.set(
|
||||
contextStoreFiltersComponentState.atomFamily({
|
||||
instanceId,
|
||||
}),
|
||||
[],
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreFilterGroupsComponentState.atomFamily({
|
||||
instanceId,
|
||||
}),
|
||||
[],
|
||||
);
|
||||
jotaiStore.set(
|
||||
contextStoreFilterGroupsComponentState.atomFamily({
|
||||
instanceId,
|
||||
}),
|
||||
[],
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreAnyFieldFilterValueComponentState.atomFamily({
|
||||
instanceId,
|
||||
}),
|
||||
'',
|
||||
);
|
||||
jotaiStore.set(
|
||||
contextStoreAnyFieldFilterValueComponentState.atomFamily({
|
||||
instanceId,
|
||||
}),
|
||||
'',
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreCurrentViewIdComponentState.atomFamily({
|
||||
instanceId,
|
||||
}),
|
||||
undefined,
|
||||
);
|
||||
};
|
||||
jotaiStore.set(
|
||||
contextStoreCurrentViewIdComponentState.atomFamily({
|
||||
instanceId,
|
||||
}),
|
||||
undefined,
|
||||
);
|
||||
}, []);
|
||||
|
||||
return { resetContextStoreStates };
|
||||
|
||||
+53
-57
@@ -10,75 +10,71 @@ import { contextStoreFiltersComponentState } from '@/context-store/states/contex
|
||||
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { ContextStoreViewType } from '@/context-store/types/ContextStoreViewType';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
export const useSetGlobalCommandMenuContext = () => {
|
||||
const { copyContextStoreStates } = useCopyContextStoreStates();
|
||||
|
||||
const setGlobalCommandMenuContext = useRecoilCallback(
|
||||
({ set }) => {
|
||||
return () => {
|
||||
copyContextStoreStates({
|
||||
instanceIdToCopyFrom: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
instanceIdToCopyTo: COMMAND_MENU_PREVIOUS_COMPONENT_INSTANCE_ID,
|
||||
});
|
||||
const setGlobalCommandMenuContext = useCallback(() => {
|
||||
copyContextStoreStates({
|
||||
instanceIdToCopyFrom: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
instanceIdToCopyTo: COMMAND_MENU_PREVIOUS_COMPONENT_INSTANCE_ID,
|
||||
});
|
||||
|
||||
set(
|
||||
contextStoreTargetedRecordsRuleComponentState.atomFamily({
|
||||
instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
}),
|
||||
{
|
||||
mode: 'selection',
|
||||
selectedRecordIds: [],
|
||||
},
|
||||
);
|
||||
jotaiStore.set(
|
||||
contextStoreTargetedRecordsRuleComponentState.atomFamily({
|
||||
instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
}),
|
||||
{
|
||||
mode: 'selection',
|
||||
selectedRecordIds: [],
|
||||
},
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreNumberOfSelectedRecordsComponentState.atomFamily({
|
||||
instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
}),
|
||||
0,
|
||||
);
|
||||
jotaiStore.set(
|
||||
contextStoreNumberOfSelectedRecordsComponentState.atomFamily({
|
||||
instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
}),
|
||||
0,
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreFiltersComponentState.atomFamily({
|
||||
instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
}),
|
||||
[],
|
||||
);
|
||||
jotaiStore.set(
|
||||
contextStoreFiltersComponentState.atomFamily({
|
||||
instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
}),
|
||||
[],
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreFilterGroupsComponentState.atomFamily({
|
||||
instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
}),
|
||||
[],
|
||||
);
|
||||
jotaiStore.set(
|
||||
contextStoreFilterGroupsComponentState.atomFamily({
|
||||
instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
}),
|
||||
[],
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreAnyFieldFilterValueComponentState.atomFamily({
|
||||
instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
}),
|
||||
'',
|
||||
);
|
||||
jotaiStore.set(
|
||||
contextStoreAnyFieldFilterValueComponentState.atomFamily({
|
||||
instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
}),
|
||||
'',
|
||||
);
|
||||
|
||||
set(
|
||||
contextStoreCurrentViewTypeComponentState.atomFamily({
|
||||
instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
}),
|
||||
ContextStoreViewType.Table,
|
||||
);
|
||||
jotaiStore.set(
|
||||
contextStoreCurrentViewTypeComponentState.atomFamily({
|
||||
instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
}),
|
||||
ContextStoreViewType.Table,
|
||||
);
|
||||
|
||||
set(commandMenuPageInfoState, {
|
||||
title: undefined,
|
||||
Icon: undefined,
|
||||
instanceId: '',
|
||||
});
|
||||
jotaiStore.set(commandMenuPageInfoState.atom, {
|
||||
title: undefined,
|
||||
Icon: undefined,
|
||||
instanceId: '',
|
||||
});
|
||||
|
||||
set(hasUserSelectedCommandState, false);
|
||||
};
|
||||
},
|
||||
[copyContextStoreStates],
|
||||
);
|
||||
jotaiStore.set(hasUserSelectedCommandState.atom, false);
|
||||
}, [copyContextStoreStates]);
|
||||
|
||||
return {
|
||||
setGlobalCommandMenuContext,
|
||||
|
||||
+39
-38
@@ -1,53 +1,54 @@
|
||||
import { commandMenuNavigationStackState } from '@/command-menu/states/commandMenuNavigationStackState';
|
||||
import { commandMenuPageInfoState } from '@/command-menu/states/commandMenuPageInfoState';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { useCallback } from 'react';
|
||||
import { type IconComponent, IconDotsVertical } from 'twenty-ui/display';
|
||||
|
||||
export const useUpdateCommandMenuPageInfo = () => {
|
||||
const updateCommandMenuPageInfo = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
({
|
||||
pageTitle,
|
||||
pageIcon,
|
||||
}: {
|
||||
pageTitle?: string;
|
||||
pageIcon?: IconComponent;
|
||||
}) => {
|
||||
const commandMenuPageInfo = snapshot
|
||||
.getLoadable(commandMenuPageInfoState)
|
||||
.getValue();
|
||||
const updateCommandMenuPageInfo = useCallback(
|
||||
({
|
||||
pageTitle,
|
||||
pageIcon,
|
||||
}: {
|
||||
pageTitle?: string;
|
||||
pageIcon?: IconComponent;
|
||||
}) => {
|
||||
const commandMenuPageInfo = jotaiStore.get(commandMenuPageInfoState.atom);
|
||||
|
||||
const newCommandMenuPageInfo = {
|
||||
...commandMenuPageInfo,
|
||||
title: pageTitle ?? commandMenuPageInfo.title ?? '',
|
||||
Icon: pageIcon ?? commandMenuPageInfo.Icon ?? IconDotsVertical,
|
||||
};
|
||||
const newCommandMenuPageInfo = {
|
||||
...commandMenuPageInfo,
|
||||
title: pageTitle ?? commandMenuPageInfo.title ?? '',
|
||||
Icon: pageIcon ?? commandMenuPageInfo.Icon ?? IconDotsVertical,
|
||||
};
|
||||
|
||||
set(commandMenuPageInfoState, newCommandMenuPageInfo);
|
||||
jotaiStore.set(commandMenuPageInfoState.atom, newCommandMenuPageInfo);
|
||||
|
||||
const commandMenuNavigationStack = snapshot
|
||||
.getLoadable(commandMenuNavigationStackState)
|
||||
.getValue();
|
||||
const commandMenuNavigationStack = jotaiStore.get(
|
||||
commandMenuNavigationStackState.atom,
|
||||
);
|
||||
|
||||
const lastCommandMenuNavigationStackItem =
|
||||
commandMenuNavigationStack.at(-1);
|
||||
const lastCommandMenuNavigationStackItem =
|
||||
commandMenuNavigationStack.at(-1);
|
||||
|
||||
if (!lastCommandMenuNavigationStackItem) {
|
||||
return;
|
||||
}
|
||||
if (!lastCommandMenuNavigationStackItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
const newCommandMenuNavigationStack = [
|
||||
...commandMenuNavigationStack.slice(0, -1),
|
||||
{
|
||||
page: lastCommandMenuNavigationStackItem.page,
|
||||
pageTitle: newCommandMenuPageInfo.title,
|
||||
pageIcon: newCommandMenuPageInfo.Icon,
|
||||
pageId: lastCommandMenuNavigationStackItem.pageId,
|
||||
},
|
||||
];
|
||||
const newCommandMenuNavigationStack = [
|
||||
...commandMenuNavigationStack.slice(0, -1),
|
||||
{
|
||||
page: lastCommandMenuNavigationStackItem.page,
|
||||
pageTitle: newCommandMenuPageInfo.title,
|
||||
pageIcon: newCommandMenuPageInfo.Icon,
|
||||
pageId: lastCommandMenuNavigationStackItem.pageId,
|
||||
},
|
||||
];
|
||||
|
||||
set(commandMenuNavigationStackState, newCommandMenuNavigationStack);
|
||||
},
|
||||
jotaiStore.set(
|
||||
commandMenuNavigationStackState.atom,
|
||||
newCommandMenuNavigationStack,
|
||||
);
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
|
||||
@@ -3,11 +3,12 @@ import { commandMenuWorkflowIdComponentState } from '@/command-menu/pages/workfl
|
||||
import { commandMenuWorkflowRunIdComponentState } from '@/command-menu/pages/workflow/states/commandMenuWorkflowRunIdComponentState';
|
||||
import { commandMenuWorkflowStepIdComponentState } from '@/command-menu/pages/workflow/states/commandMenuWorkflowStepIdComponentState';
|
||||
import { commandMenuWorkflowVersionIdComponentState } from '@/command-menu/pages/workflow/states/commandMenuWorkflowVersionIdComponentState';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { type WorkflowRunStepStatus } from '@/workflow/types/Workflow';
|
||||
import { useSetInitialWorkflowRunRightDrawerTab } from '@/workflow/workflow-diagram/hooks/useSetInitialWorkflowRunRightDrawerTab';
|
||||
import { workflowSelectedNodeComponentState } from '@/workflow/workflow-diagram/states/workflowSelectedNodeComponentState';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { useCallback } from 'react';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import {
|
||||
@@ -22,233 +23,221 @@ export const useWorkflowCommandMenu = () => {
|
||||
const { setInitialWorkflowRunRightDrawerTab } =
|
||||
useSetInitialWorkflowRunRightDrawerTab();
|
||||
|
||||
const openWorkflowTriggerTypeInCommandMenu = useRecoilCallback(
|
||||
({ set }) => {
|
||||
return (workflowId: string) => {
|
||||
const pageId = v4();
|
||||
const openWorkflowTriggerTypeInCommandMenu = useCallback(
|
||||
(workflowId: string) => {
|
||||
const pageId = v4();
|
||||
|
||||
set(
|
||||
commandMenuWorkflowIdComponentState.atomFamily({
|
||||
instanceId: pageId,
|
||||
}),
|
||||
workflowId,
|
||||
);
|
||||
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.WorkflowTriggerSelectType,
|
||||
pageTitle: t`Trigger Type`,
|
||||
pageIcon: IconBolt,
|
||||
pageId,
|
||||
});
|
||||
};
|
||||
},
|
||||
[navigateCommandMenu],
|
||||
);
|
||||
|
||||
const openWorkflowCreateStepInCommandMenu = useRecoilCallback(
|
||||
({ set }) => {
|
||||
return (workflowId: string) => {
|
||||
const pageId = v4();
|
||||
|
||||
set(
|
||||
commandMenuWorkflowIdComponentState.atomFamily({
|
||||
instanceId: pageId,
|
||||
}),
|
||||
workflowId,
|
||||
);
|
||||
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.WorkflowStepCreate,
|
||||
pageTitle: t`Select Action`,
|
||||
pageIcon: IconSettingsAutomation,
|
||||
pageId,
|
||||
});
|
||||
};
|
||||
},
|
||||
[navigateCommandMenu],
|
||||
);
|
||||
|
||||
const openWorkflowEditStepInCommandMenu = useRecoilCallback(
|
||||
({ set }) => {
|
||||
return (
|
||||
workflowId: string,
|
||||
title: string,
|
||||
icon: IconComponent,
|
||||
stepId?: string,
|
||||
) => {
|
||||
const pageId = v4();
|
||||
|
||||
set(
|
||||
commandMenuWorkflowIdComponentState.atomFamily({
|
||||
instanceId: pageId,
|
||||
}),
|
||||
workflowId,
|
||||
);
|
||||
|
||||
if (isDefined(stepId)) {
|
||||
set(
|
||||
commandMenuWorkflowStepIdComponentState.atomFamily({
|
||||
instanceId: pageId,
|
||||
}),
|
||||
stepId,
|
||||
);
|
||||
|
||||
set(
|
||||
workflowSelectedNodeComponentState.atomFamily({
|
||||
instanceId: workflowId,
|
||||
}),
|
||||
stepId,
|
||||
);
|
||||
}
|
||||
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.WorkflowStepEdit,
|
||||
pageTitle: title,
|
||||
pageIcon: icon,
|
||||
pageId,
|
||||
});
|
||||
};
|
||||
},
|
||||
[navigateCommandMenu],
|
||||
);
|
||||
|
||||
const openWorkflowEditStepTypeInCommandMenu = useRecoilCallback(
|
||||
({ set }) => {
|
||||
return (workflowId: string) => {
|
||||
const pageId = v4();
|
||||
|
||||
set(
|
||||
commandMenuWorkflowIdComponentState.atomFamily({
|
||||
instanceId: pageId,
|
||||
}),
|
||||
workflowId,
|
||||
);
|
||||
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.WorkflowStepEditType,
|
||||
pageTitle: t`Select action`,
|
||||
pageIcon: IconSettingsAutomation,
|
||||
pageId,
|
||||
});
|
||||
};
|
||||
},
|
||||
[navigateCommandMenu],
|
||||
);
|
||||
|
||||
const openWorkflowViewStepInCommandMenu = useRecoilCallback(
|
||||
({ set }) => {
|
||||
return ({
|
||||
jotaiStore.set(
|
||||
commandMenuWorkflowIdComponentState.atomFamily({
|
||||
instanceId: pageId,
|
||||
}),
|
||||
workflowId,
|
||||
workflowVersionId,
|
||||
title,
|
||||
icon,
|
||||
stepId,
|
||||
}: {
|
||||
workflowId: string;
|
||||
workflowVersionId: string;
|
||||
title: string;
|
||||
icon: IconComponent;
|
||||
stepId?: string;
|
||||
}) => {
|
||||
const pageId = v4();
|
||||
);
|
||||
|
||||
set(
|
||||
commandMenuWorkflowIdComponentState.atomFamily({
|
||||
instanceId: pageId,
|
||||
}),
|
||||
workflowId,
|
||||
);
|
||||
set(
|
||||
commandMenuWorkflowVersionIdComponentState.atomFamily({
|
||||
instanceId: pageId,
|
||||
}),
|
||||
workflowVersionId,
|
||||
);
|
||||
|
||||
if (isDefined(stepId)) {
|
||||
set(
|
||||
commandMenuWorkflowStepIdComponentState.atomFamily({
|
||||
instanceId: pageId,
|
||||
}),
|
||||
stepId,
|
||||
);
|
||||
|
||||
set(
|
||||
workflowSelectedNodeComponentState.atomFamily({
|
||||
instanceId: workflowVersionId,
|
||||
}),
|
||||
stepId,
|
||||
);
|
||||
}
|
||||
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.WorkflowStepView,
|
||||
pageTitle: title,
|
||||
pageIcon: icon,
|
||||
pageId,
|
||||
});
|
||||
};
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.WorkflowTriggerSelectType,
|
||||
pageTitle: t`Trigger Type`,
|
||||
pageIcon: IconBolt,
|
||||
pageId,
|
||||
});
|
||||
},
|
||||
[navigateCommandMenu],
|
||||
);
|
||||
|
||||
const openWorkflowRunViewStepInCommandMenu = useRecoilCallback(
|
||||
({ set }) => {
|
||||
return ({
|
||||
workflowId,
|
||||
workflowRunId,
|
||||
title,
|
||||
icon,
|
||||
workflowSelectedNode,
|
||||
stepExecutionStatus,
|
||||
}: {
|
||||
workflowId: string;
|
||||
workflowRunId: string;
|
||||
title: string;
|
||||
icon: IconComponent;
|
||||
workflowSelectedNode: string;
|
||||
stepExecutionStatus: WorkflowRunStepStatus;
|
||||
}) => {
|
||||
const pageId = v4();
|
||||
const openWorkflowCreateStepInCommandMenu = useCallback(
|
||||
(workflowId: string) => {
|
||||
const pageId = v4();
|
||||
|
||||
set(
|
||||
commandMenuWorkflowIdComponentState.atomFamily({
|
||||
instanceId: pageId,
|
||||
}),
|
||||
workflowId,
|
||||
);
|
||||
set(
|
||||
commandMenuWorkflowRunIdComponentState.atomFamily({
|
||||
instanceId: pageId,
|
||||
}),
|
||||
workflowRunId,
|
||||
);
|
||||
set(
|
||||
jotaiStore.set(
|
||||
commandMenuWorkflowIdComponentState.atomFamily({
|
||||
instanceId: pageId,
|
||||
}),
|
||||
workflowId,
|
||||
);
|
||||
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.WorkflowStepCreate,
|
||||
pageTitle: t`Select Action`,
|
||||
pageIcon: IconSettingsAutomation,
|
||||
pageId,
|
||||
});
|
||||
},
|
||||
[navigateCommandMenu],
|
||||
);
|
||||
|
||||
const openWorkflowEditStepInCommandMenu = useCallback(
|
||||
(
|
||||
workflowId: string,
|
||||
title: string,
|
||||
icon: IconComponent,
|
||||
stepId?: string,
|
||||
) => {
|
||||
const pageId = v4();
|
||||
|
||||
jotaiStore.set(
|
||||
commandMenuWorkflowIdComponentState.atomFamily({
|
||||
instanceId: pageId,
|
||||
}),
|
||||
workflowId,
|
||||
);
|
||||
|
||||
if (isDefined(stepId)) {
|
||||
jotaiStore.set(
|
||||
commandMenuWorkflowStepIdComponentState.atomFamily({
|
||||
instanceId: pageId,
|
||||
}),
|
||||
workflowSelectedNode,
|
||||
stepId,
|
||||
);
|
||||
|
||||
set(
|
||||
jotaiStore.set(
|
||||
workflowSelectedNodeComponentState.atomFamily({
|
||||
instanceId: workflowRunId,
|
||||
instanceId: workflowId,
|
||||
}),
|
||||
workflowSelectedNode,
|
||||
stepId,
|
||||
);
|
||||
}
|
||||
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.WorkflowStepEdit,
|
||||
pageTitle: title,
|
||||
pageIcon: icon,
|
||||
pageId,
|
||||
});
|
||||
},
|
||||
[navigateCommandMenu],
|
||||
);
|
||||
|
||||
const openWorkflowEditStepTypeInCommandMenu = useCallback(
|
||||
(workflowId: string) => {
|
||||
const pageId = v4();
|
||||
|
||||
jotaiStore.set(
|
||||
commandMenuWorkflowIdComponentState.atomFamily({
|
||||
instanceId: pageId,
|
||||
}),
|
||||
workflowId,
|
||||
);
|
||||
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.WorkflowStepEditType,
|
||||
pageTitle: t`Select action`,
|
||||
pageIcon: IconSettingsAutomation,
|
||||
pageId,
|
||||
});
|
||||
},
|
||||
[navigateCommandMenu],
|
||||
);
|
||||
|
||||
const openWorkflowViewStepInCommandMenu = useCallback(
|
||||
({
|
||||
workflowId,
|
||||
workflowVersionId,
|
||||
title,
|
||||
icon,
|
||||
stepId,
|
||||
}: {
|
||||
workflowId: string;
|
||||
workflowVersionId: string;
|
||||
title: string;
|
||||
icon: IconComponent;
|
||||
stepId?: string;
|
||||
}) => {
|
||||
const pageId = v4();
|
||||
|
||||
jotaiStore.set(
|
||||
commandMenuWorkflowIdComponentState.atomFamily({
|
||||
instanceId: pageId,
|
||||
}),
|
||||
workflowId,
|
||||
);
|
||||
jotaiStore.set(
|
||||
commandMenuWorkflowVersionIdComponentState.atomFamily({
|
||||
instanceId: pageId,
|
||||
}),
|
||||
workflowVersionId,
|
||||
);
|
||||
|
||||
if (isDefined(stepId)) {
|
||||
jotaiStore.set(
|
||||
commandMenuWorkflowStepIdComponentState.atomFamily({
|
||||
instanceId: pageId,
|
||||
}),
|
||||
stepId,
|
||||
);
|
||||
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.WorkflowRunStepView,
|
||||
pageTitle: title,
|
||||
pageIcon: icon,
|
||||
pageId,
|
||||
});
|
||||
jotaiStore.set(
|
||||
workflowSelectedNodeComponentState.atomFamily({
|
||||
instanceId: workflowVersionId,
|
||||
}),
|
||||
stepId,
|
||||
);
|
||||
}
|
||||
|
||||
setInitialWorkflowRunRightDrawerTab({
|
||||
workflowSelectedNode,
|
||||
stepExecutionStatus,
|
||||
});
|
||||
};
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.WorkflowStepView,
|
||||
pageTitle: title,
|
||||
pageIcon: icon,
|
||||
pageId,
|
||||
});
|
||||
},
|
||||
[navigateCommandMenu],
|
||||
);
|
||||
|
||||
const openWorkflowRunViewStepInCommandMenu = useCallback(
|
||||
({
|
||||
workflowId,
|
||||
workflowRunId,
|
||||
title,
|
||||
icon,
|
||||
workflowSelectedNode,
|
||||
stepExecutionStatus,
|
||||
}: {
|
||||
workflowId: string;
|
||||
workflowRunId: string;
|
||||
title: string;
|
||||
icon: IconComponent;
|
||||
workflowSelectedNode: string;
|
||||
stepExecutionStatus: WorkflowRunStepStatus;
|
||||
}) => {
|
||||
const pageId = v4();
|
||||
|
||||
jotaiStore.set(
|
||||
commandMenuWorkflowIdComponentState.atomFamily({
|
||||
instanceId: pageId,
|
||||
}),
|
||||
workflowId,
|
||||
);
|
||||
jotaiStore.set(
|
||||
commandMenuWorkflowRunIdComponentState.atomFamily({
|
||||
instanceId: pageId,
|
||||
}),
|
||||
workflowRunId,
|
||||
);
|
||||
jotaiStore.set(
|
||||
commandMenuWorkflowStepIdComponentState.atomFamily({
|
||||
instanceId: pageId,
|
||||
}),
|
||||
workflowSelectedNode,
|
||||
);
|
||||
|
||||
jotaiStore.set(
|
||||
workflowSelectedNodeComponentState.atomFamily({
|
||||
instanceId: workflowRunId,
|
||||
}),
|
||||
workflowSelectedNode,
|
||||
);
|
||||
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.WorkflowRunStepView,
|
||||
pageTitle: title,
|
||||
pageIcon: icon,
|
||||
pageId,
|
||||
});
|
||||
|
||||
setInitialWorkflowRunRightDrawerTab({
|
||||
workflowSelectedNode,
|
||||
stepExecutionStatus,
|
||||
});
|
||||
},
|
||||
[navigateCommandMenu, setInitialWorkflowRunRightDrawerTab],
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user