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:
@@ -7,9 +7,9 @@ import { useMatchingCommandMenuActions } from '@/command-menu/hooks/useMatchingC
|
||||
import { commandMenuSearchState } from '@/command-menu/states/commandMenuSearchState';
|
||||
import { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemIdComponentState';
|
||||
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export type ActionGroupConfig = {
|
||||
@@ -20,7 +20,7 @@ export type ActionGroupConfig = {
|
||||
export const CommandMenu = () => {
|
||||
const { t } = useLingui();
|
||||
|
||||
const commandMenuSearch = useRecoilValue(commandMenuSearchState);
|
||||
const commandMenuSearch = useRecoilValueV2(commandMenuSearchState);
|
||||
const { objectMetadataItems } = useObjectMetadataItems();
|
||||
|
||||
const {
|
||||
@@ -40,12 +40,12 @@ export const CommandMenu = () => {
|
||||
});
|
||||
|
||||
const previousContextStoreCurrentObjectMetadataItemId =
|
||||
useRecoilComponentValue(
|
||||
useRecoilComponentValueV2(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState,
|
||||
'command-menu-previous',
|
||||
);
|
||||
|
||||
const objectMetadataItemId = useRecoilComponentValue(
|
||||
const objectMetadataItemId = useRecoilComponentValueV2(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState,
|
||||
);
|
||||
const currentObjectMetadataItem = objectMetadataItems.find(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { currentAIChatThreadTitleStateV2 } from '@/ai/states/currentAIChatThreadTitleStateV2';
|
||||
import { currentAIChatThreadTitleState } from '@/ai/states/currentAIChatThreadTitleState';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import styled from '@emotion/styled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
@@ -12,7 +12,7 @@ const StyledPageTitle = styled.div`
|
||||
|
||||
export const CommandMenuAskAIInfo = () => {
|
||||
const currentAIChatThreadTitle = useRecoilValueV2(
|
||||
currentAIChatThreadTitleStateV2,
|
||||
currentAIChatThreadTitleState,
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -8,7 +8,7 @@ import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadat
|
||||
import { RecordComponentInstanceContextsWrapper } from '@/object-record/components/RecordComponentInstanceContextsWrapper';
|
||||
import { getRecordIndexIdFromObjectNamePluralAndViewId } from '@/object-record/utils/getRecordIndexIdFromObjectNamePluralAndViewId';
|
||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
|
||||
const StyledCommandMenuContainer = styled.div<{ isMobile: boolean }>`
|
||||
@@ -29,7 +29,7 @@ type CommandMenuContainerProps = {
|
||||
export const CommandMenuContainer = ({
|
||||
children,
|
||||
}: CommandMenuContainerProps) => {
|
||||
const objectMetadataItemId = useRecoilComponentValue(
|
||||
const objectMetadataItemId = useRecoilComponentValueV2(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState,
|
||||
COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
);
|
||||
@@ -41,7 +41,7 @@ export const CommandMenuContainer = ({
|
||||
(objectMetadataItem) => objectMetadataItem.id === objectMetadataItemId,
|
||||
);
|
||||
|
||||
const currentViewId = useRecoilComponentValue(
|
||||
const currentViewId = useRecoilComponentValueV2(
|
||||
contextStoreCurrentViewIdComponentState,
|
||||
COMMAND_MENU_COMPONENT_INSTANCE_ID,
|
||||
);
|
||||
|
||||
+2
-2
@@ -3,8 +3,8 @@ import { hasUserSelectedCommandState } from '@/command-menu/states/hasUserSelect
|
||||
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
|
||||
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { useEffect } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const CommandMenuDefaultSelectionEffect = ({
|
||||
@@ -21,7 +21,7 @@ export const CommandMenuDefaultSelectionEffect = ({
|
||||
COMMAND_MENU_LIST_SELECTABLE_LIST_ID,
|
||||
);
|
||||
|
||||
const hasUserSelectedCommand = useRecoilValue(hasUserSelectedCommandState);
|
||||
const hasUserSelectedCommand = useRecoilValueV2(hasUserSelectedCommandState);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
|
||||
import { CommandMenuPageInfoLayout } from '@/command-menu/components/CommandMenuPageInfoLayout';
|
||||
@@ -17,7 +16,7 @@ import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValu
|
||||
import { getNavigationMenuItemIconColors } from '@/navigation-menu-item/utils/getNavigationMenuItemIconColors';
|
||||
import { IconPicker } from '@/ui/input/components/IconPicker';
|
||||
import { TitleInput } from '@/ui/input/components/TitleInput';
|
||||
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
|
||||
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2';
|
||||
|
||||
const StyledClickableIconWrapper = styled.div`
|
||||
cursor: pointer;
|
||||
@@ -27,9 +26,9 @@ export const CommandMenuFolderInfo = () => {
|
||||
const theme = useTheme();
|
||||
const { t } = useLingui();
|
||||
const { getIcon } = useIcons();
|
||||
const commandMenuPageInfo = useRecoilValue(commandMenuPageInfoState);
|
||||
const commandMenuPageInfo = useRecoilValueV2(commandMenuPageInfoState);
|
||||
const [shouldFocusTitleInput, setShouldFocusTitleInput] =
|
||||
useRecoilComponentState(
|
||||
useRecoilComponentStateV2(
|
||||
commandMenuShouldFocusTitleInputComponentState,
|
||||
commandMenuPageInfo.instanceId,
|
||||
);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { IconLink } from 'twenty-ui/display';
|
||||
|
||||
import { CommandMenuPageInfoLayout } from '@/command-menu/components/CommandMenuPageInfoLayout';
|
||||
@@ -14,14 +13,14 @@ import { selectedNavigationMenuItemInEditModeStateV2 } from '@/navigation-menu-i
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { getNavigationMenuItemIconColors } from '@/navigation-menu-item/utils/getNavigationMenuItemIconColors';
|
||||
import { TitleInput } from '@/ui/input/components/TitleInput';
|
||||
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
|
||||
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2';
|
||||
|
||||
export const CommandMenuLinkInfo = () => {
|
||||
const theme = useTheme();
|
||||
const { t } = useLingui();
|
||||
const commandMenuPageInfo = useRecoilValue(commandMenuPageInfoState);
|
||||
const commandMenuPageInfo = useRecoilValueV2(commandMenuPageInfoState);
|
||||
const [shouldFocusTitleInput, setShouldFocusTitleInput] =
|
||||
useRecoilComponentState(
|
||||
useRecoilComponentStateV2(
|
||||
commandMenuShouldFocusTitleInputComponentState,
|
||||
commandMenuPageInfo.instanceId,
|
||||
);
|
||||
|
||||
@@ -8,10 +8,10 @@ import { COMMAND_MENU_SEARCH_BAR_PADDING } from '@/command-menu/constants/Comman
|
||||
import { SIDE_PANEL_FOCUS_ID } from '@/command-menu/constants/SidePanelFocusId';
|
||||
import { hasUserSelectedCommandState } from '@/command-menu/states/hasUserSelectedCommandState';
|
||||
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
|
||||
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
|
||||
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
||||
import styled from '@emotion/styled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { MOBILE_VIEWPORT } from 'twenty-ui/theme';
|
||||
|
||||
export type CommandMenuListProps = {
|
||||
@@ -63,7 +63,7 @@ export const CommandMenuList = ({
|
||||
noResults = false,
|
||||
noResultsText,
|
||||
}: CommandMenuListProps) => {
|
||||
const setHasUserSelectedCommand = useSetRecoilState(
|
||||
const setHasUserSelectedCommand = useSetRecoilStateV2(
|
||||
hasUserSelectedCommandState,
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -3,11 +3,11 @@ import { CommandMenuRecordPageLayoutInfo } from '@/command-menu/components/Comma
|
||||
import { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemIdComponentState';
|
||||
import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMetadataItemById';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const CommandMenuPageLayoutInfo = () => {
|
||||
const objectMetadataId = useRecoilComponentValue(
|
||||
const objectMetadataId = useRecoilComponentValueV2(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState,
|
||||
);
|
||||
|
||||
|
||||
+9
-9
@@ -9,12 +9,12 @@ import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDr
|
||||
import { pageLayoutEditingWidgetIdComponentState } from '@/page-layout/states/pageLayoutEditingWidgetIdComponentState';
|
||||
import { pageLayoutTabSettingsOpenTabIdComponentState } from '@/page-layout/states/pageLayoutTabSettingsOpenTabIdComponentState';
|
||||
import { TitleInput } from '@/ui/input/components/TitleInput';
|
||||
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { useState } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
@@ -27,11 +27,11 @@ export const CommandMenuPageLayoutInfoContent = ({
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const { getIcon } = useIcons();
|
||||
const commandMenuPage = useRecoilValue(commandMenuPageState);
|
||||
const commandMenuPageInfo = useRecoilValue(commandMenuPageInfoState);
|
||||
const commandMenuPage = useRecoilValueV2(commandMenuPageState);
|
||||
const commandMenuPageInfo = useRecoilValueV2(commandMenuPageInfoState);
|
||||
|
||||
const [shouldFocusTitleInput, setShouldFocusTitleInput] =
|
||||
useRecoilComponentState(
|
||||
useRecoilComponentStateV2(
|
||||
commandMenuShouldFocusTitleInputComponentState,
|
||||
commandMenuPageInfo.instanceId,
|
||||
);
|
||||
@@ -40,17 +40,17 @@ export const CommandMenuPageLayoutInfoContent = ({
|
||||
setShouldFocusTitleInput(false);
|
||||
};
|
||||
|
||||
const draftPageLayout = useRecoilComponentValue(
|
||||
const draftPageLayout = useRecoilComponentValueV2(
|
||||
pageLayoutDraftComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const pageLayoutEditingWidgetId = useRecoilComponentValue(
|
||||
const pageLayoutEditingWidgetId = useRecoilComponentValueV2(
|
||||
pageLayoutEditingWidgetIdComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const [openTabId] = useRecoilComponentState(
|
||||
const [openTabId] = useRecoilComponentStateV2(
|
||||
pageLayoutTabSettingsOpenTabIdComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
+16
-18
@@ -7,23 +7,22 @@ import { useIsRecordFieldReadOnly } from '@/object-record/read-only/hooks/useIsR
|
||||
import { FieldContext } from '@/object-record/record-field/ui/contexts/FieldContext';
|
||||
import { useRecordShowContainerActions } from '@/object-record/record-show/hooks/useRecordShowContainerActions';
|
||||
import { useRecordShowPage } from '@/object-record/record-show/hooks/useRecordShowPage';
|
||||
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
|
||||
import { recordStoreIdentifierFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreIdentifierSelector';
|
||||
import { recordStoreFamilySelectorV2 } from '@/object-record/record-store/states/selectors/recordStoreFamilySelectorV2';
|
||||
import { recordStoreIdentifierFamilySelectorV2 } from '@/object-record/record-store/states/selectors/recordStoreIdentifierFamilySelectorV2';
|
||||
import { RecordTitleCell } from '@/object-record/record-title-cell/components/RecordTitleCell';
|
||||
import { RecordTitleCellContainerType } from '@/object-record/record-title-cell/types/RecordTitleCellContainerType';
|
||||
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 { Trans } from '@lingui/react/macro';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { useFamilySelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilySelectorValueV2';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { Avatar } from 'twenty-ui/display';
|
||||
import {
|
||||
FeatureFlagKey,
|
||||
FieldMetadataType,
|
||||
} from '~/generated-metadata/graphql';
|
||||
import { dateLocaleState } from '~/localization/states/dateLocaleState';
|
||||
import { dateLocaleStateV2 } from '~/localization/states/dateLocaleStateV2';
|
||||
import { beautifyPastDateRelativeToNow } from '~/utils/date-utils';
|
||||
import { CommandMenuPageInfoLayout } from './CommandMenuPageInfoLayout';
|
||||
|
||||
@@ -32,7 +31,7 @@ export const CommandMenuRecordInfo = ({
|
||||
}: {
|
||||
commandMenuPageInstanceId: string;
|
||||
}) => {
|
||||
const viewableRecordNameSingular = useRecoilComponentValue(
|
||||
const viewableRecordNameSingular = useRecoilComponentValueV2(
|
||||
viewableRecordNameSingularComponentState,
|
||||
commandMenuPageInstanceId,
|
||||
);
|
||||
@@ -40,7 +39,7 @@ export const CommandMenuRecordInfo = ({
|
||||
allowRequestsToTwentyIconsState,
|
||||
);
|
||||
|
||||
const viewableRecordId = useRecoilComponentValue(
|
||||
const viewableRecordId = useRecoilComponentValueV2(
|
||||
viewableRecordIdComponentState,
|
||||
commandMenuPageInstanceId,
|
||||
);
|
||||
@@ -50,26 +49,25 @@ export const CommandMenuRecordInfo = ({
|
||||
viewableRecordId!,
|
||||
);
|
||||
|
||||
const recordCreatedAt = useRecoilValue<string | null>(
|
||||
recordStoreFamilySelector({
|
||||
recordId: objectRecordId,
|
||||
fieldName: 'createdAt',
|
||||
}),
|
||||
);
|
||||
const recordCreatedAt = useFamilySelectorValueV2(
|
||||
recordStoreFamilySelectorV2,
|
||||
{ recordId: objectRecordId, fieldName: 'createdAt' },
|
||||
) as string | null;
|
||||
|
||||
const isFilesFieldMigrated = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IS_FILES_FIELD_MIGRATED,
|
||||
);
|
||||
|
||||
const recordIdentifier = useRecoilValue(
|
||||
recordStoreIdentifierFamilySelector({
|
||||
const recordIdentifier = useFamilySelectorValueV2(
|
||||
recordStoreIdentifierFamilySelectorV2,
|
||||
{
|
||||
recordId: objectRecordId,
|
||||
allowRequestsToTwentyIcons,
|
||||
isFilesFieldMigrated,
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
const { localeCatalog } = useRecoilValue(dateLocaleState);
|
||||
const { localeCatalog } = useRecoilValueV2(dateLocaleStateV2);
|
||||
const beautifiedCreatedAt = isNonEmptyString(recordCreatedAt)
|
||||
? beautifyPastDateRelativeToNow(recordCreatedAt, localeCatalog)
|
||||
: '';
|
||||
|
||||
@@ -5,10 +5,10 @@ import { COMMAND_MENU_PAGES_CONFIG } from '@/command-menu/constants/CommandMenuP
|
||||
import { commandMenuPageInfoState } from '@/command-menu/states/commandMenuPageInfoState';
|
||||
import { commandMenuPageState } from '@/command-menu/states/commandMenuPageState';
|
||||
import { CommandMenuPageComponentInstanceContext } from '@/command-menu/states/contexts/CommandMenuPageComponentInstanceContext';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
const StyledCommandMenuContent = styled.div`
|
||||
@@ -17,8 +17,8 @@ const StyledCommandMenuContent = styled.div`
|
||||
`;
|
||||
|
||||
export const CommandMenuRouter = () => {
|
||||
const commandMenuPage = useRecoilValue(commandMenuPageState);
|
||||
const commandMenuPageInfo = useRecoilValue(commandMenuPageInfoState);
|
||||
const commandMenuPage = useRecoilValueV2(commandMenuPageState);
|
||||
const commandMenuPageInfo = useRecoilValueV2(commandMenuPageInfoState);
|
||||
|
||||
const commandMenuPageComponent = isDefined(commandMenuPage) ? (
|
||||
COMMAND_MENU_PAGES_CONFIG.get(commandMenuPage)
|
||||
|
||||
+5
-4
@@ -12,10 +12,11 @@ import { tableWidthResizeIsActiveState } from '@/object-record/record-table/stat
|
||||
import { ModalContainerContext } from '@/ui/layout/modal/contexts/ModalContainerContext';
|
||||
import { ResizablePanelGap } from '@/ui/layout/resizable-panel/components/ResizablePanelGap';
|
||||
import { COMMAND_MENU_CONSTRAINTS } from '@/ui/layout/resizable-panel/constants/CommandMenuConstraints';
|
||||
import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
|
||||
import styled from '@emotion/styled';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
|
||||
|
||||
const StyledSidePanelWrapper = styled.div<{
|
||||
isOpen: boolean;
|
||||
@@ -56,8 +57,8 @@ const GAP_WIDTH = 8;
|
||||
|
||||
export const CommandMenuSidePanelForDesktop = () => {
|
||||
const isCommandMenuOpened = useRecoilValueV2(isCommandMenuOpenedStateV2);
|
||||
const isCommandMenuClosing = useRecoilValue(isCommandMenuClosingState);
|
||||
const [commandMenuWidth, setCommandMenuWidth] = useRecoilState(
|
||||
const isCommandMenuClosing = useRecoilValueV2(isCommandMenuClosingState);
|
||||
const [commandMenuWidth, setCommandMenuWidth] = useRecoilStateV2(
|
||||
commandMenuWidthState,
|
||||
);
|
||||
const { closeCommandMenu } = useCommandMenu();
|
||||
@@ -71,7 +72,7 @@ export const CommandMenuSidePanelForDesktop = () => {
|
||||
const [shouldRenderContent, setShouldRenderContent] =
|
||||
useState(isCommandMenuOpened);
|
||||
|
||||
const setTableWidthResizeIsActive = useSetRecoilState(
|
||||
const setTableWidthResizeIsActive = useSetRecoilStateV2(
|
||||
tableWidthResizeIsActiveState,
|
||||
);
|
||||
|
||||
|
||||
@@ -18,8 +18,9 @@ import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { useRef } from 'react';
|
||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
import { IconX } from 'twenty-ui/display';
|
||||
import { IconButton } from 'twenty-ui/input';
|
||||
@@ -79,7 +80,7 @@ const StyledContentContainer = styled.div`
|
||||
`;
|
||||
|
||||
export const CommandMenuTopBar = () => {
|
||||
const [commandMenuSearch, setCommandMenuSearch] = useRecoilState(
|
||||
const [commandMenuSearch, setCommandMenuSearch] = useRecoilStateV2(
|
||||
commandMenuSearchState,
|
||||
);
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
@@ -94,9 +95,9 @@ export const CommandMenuTopBar = () => {
|
||||
|
||||
const { closeCommandMenu } = useCommandMenu();
|
||||
|
||||
const commandMenuPage = useRecoilValue(commandMenuPageState);
|
||||
const commandMenuPage = useRecoilValueV2(commandMenuPageState);
|
||||
|
||||
const commandMenuNavigationStack = useRecoilValue(
|
||||
const commandMenuNavigationStack = useRecoilValueV2(
|
||||
commandMenuNavigationStackState,
|
||||
);
|
||||
|
||||
|
||||
+2
-3
@@ -1,6 +1,5 @@
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { commandMenuPageState } from '@/command-menu/states/commandMenuPageState';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { useEffect } from 'react';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
|
||||
@@ -11,7 +10,7 @@ type CommandMenuTopBarInputFocusEffectProps = {
|
||||
export const CommandMenuTopBarInputFocusEffect = ({
|
||||
inputRef,
|
||||
}: CommandMenuTopBarInputFocusEffectProps) => {
|
||||
const commandMenuPage = useRecoilValue(commandMenuPageState);
|
||||
const commandMenuPage = useRecoilValueV2(commandMenuPageState);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
import { useOpenAskAIPageInCommandMenu } from '@/command-menu/hooks/useOpenAskAIPageInCommandMenu';
|
||||
import { commandMenuPageState } from '@/command-menu/states/commandMenuPageState';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import styled from '@emotion/styled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
import { IconEdit, IconSparkles } from 'twenty-ui/display';
|
||||
import { IconButton } from 'twenty-ui/input';
|
||||
@@ -19,7 +19,7 @@ const StyledIconButton = styled(IconButton)`
|
||||
export const CommandMenuTopBarRightCornerIcon = () => {
|
||||
const isMobile = useIsMobile();
|
||||
const isAiEnabled = useIsFeatureEnabled(FeatureFlagKey.IS_AI_ENABLED);
|
||||
const commandMenuPage = useRecoilValue(commandMenuPageState);
|
||||
const commandMenuPage = useRecoilValueV2(commandMenuPageState);
|
||||
const { openAskAIPage } = useOpenAskAIPageInCommandMenu();
|
||||
const { createChatThread } = useCreateNewAIChatThread();
|
||||
|
||||
|
||||
+2
-2
@@ -1,13 +1,13 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import {
|
||||
COMMAND_MENU_WIDTH_VAR,
|
||||
commandMenuWidthState,
|
||||
} from '@/command-menu/states/commandMenuWidthState';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
|
||||
export const CommandMenuWidthEffect = () => {
|
||||
const commandMenuWidth = useRecoilValue(commandMenuWidthState);
|
||||
const commandMenuWidth = useRecoilValueV2(commandMenuWidthState);
|
||||
|
||||
useEffect(() => {
|
||||
document.documentElement.style.setProperty(
|
||||
|
||||
+4
-4
@@ -5,7 +5,7 @@ import { commandMenuPageState } from '@/command-menu/states/commandMenuPageState
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
|
||||
import { TitleInput } from '@/ui/input/components/TitleInput';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useGetUpdatableWorkflowVersionOrThrow } from '@/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow';
|
||||
import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion';
|
||||
import { getAgentIdFromStep } from '@/workflow/utils/getAgentIdFromStep';
|
||||
@@ -19,8 +19,8 @@ import { getTriggerIcon } from '@/workflow/workflow-trigger/utils/getTriggerIcon
|
||||
import { getTriggerIconColor } from '@/workflow/workflow-trigger/utils/getTriggerIconColor';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { useState } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { TRIGGER_STEP_ID } from 'twenty-shared/workflow';
|
||||
@@ -35,11 +35,11 @@ export const CommandMenuWorkflowStepInfo = ({
|
||||
const theme = useTheme();
|
||||
const { getIcon } = useIcons();
|
||||
|
||||
const commandMenuPage = useRecoilValue(commandMenuPageState);
|
||||
const commandMenuPage = useRecoilValueV2(commandMenuPageState);
|
||||
|
||||
const workflowId = useCommandMenuWorkflowIdOrThrow();
|
||||
|
||||
const workflowStepId = useRecoilComponentValue(
|
||||
const workflowStepId = useRecoilComponentValueV2(
|
||||
commandMenuWorkflowStepIdComponentState,
|
||||
commandMenuPageInstanceId,
|
||||
);
|
||||
|
||||
+3
-3
@@ -7,19 +7,19 @@ import { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconArrowBackUp } from 'twenty-ui/display';
|
||||
|
||||
export const ResetContextToSelectionCommandButton = () => {
|
||||
const contextStoreTargetedRecordsRule = useRecoilComponentValue(
|
||||
const contextStoreTargetedRecordsRule = useRecoilComponentValueV2(
|
||||
contextStoreTargetedRecordsRuleComponentState,
|
||||
'command-menu-previous',
|
||||
);
|
||||
|
||||
const contextStoreCurrentObjectMetadataItemId = useRecoilComponentValue(
|
||||
const contextStoreCurrentObjectMetadataItemId = useRecoilComponentValueV2(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState,
|
||||
'command-menu-previous',
|
||||
);
|
||||
|
||||
+37
-25
@@ -3,12 +3,11 @@ import {
|
||||
type Meta,
|
||||
type StoryObj,
|
||||
} from '@storybook/react-vite';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { expect, userEvent, within } from 'storybook/test';
|
||||
|
||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWithRouterDecorator';
|
||||
import { ObjectMetadataItemsDecorator } from '~/testing/decorators/ObjectMetadataItemsDecorator';
|
||||
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
|
||||
@@ -28,13 +27,18 @@ import { CommandMenuRouter } from '@/command-menu/components/CommandMenuRouter';
|
||||
import { COMMAND_MENU_COMPONENT_INSTANCE_ID } from '@/command-menu/constants/CommandMenuComponentInstanceId';
|
||||
import { SIDE_PANEL_FOCUS_ID } from '@/command-menu/constants/SidePanelFocusId';
|
||||
import { commandMenuNavigationStackState } from '@/command-menu/states/commandMenuNavigationStackState';
|
||||
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 { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemIdComponentState';
|
||||
import { contextStoreCurrentViewTypeComponentState } from '@/context-store/states/contextStoreCurrentViewTypeComponentState';
|
||||
import { ContextStoreComponentInstanceContext } from '@/context-store/states/contexts/ContextStoreComponentInstanceContext';
|
||||
import { ContextStoreViewType } from '@/context-store/types/ContextStoreViewType';
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { RecordComponentInstanceContextsWrapper } from '@/object-record/components/RecordComponentInstanceContextsWrapper';
|
||||
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
|
||||
import { HttpResponse, graphql } from 'msw';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconDotsVertical } from 'twenty-ui/display';
|
||||
import { JestContextStoreSetter } from '~/testing/jest/JestContextStoreSetter';
|
||||
|
||||
@@ -73,26 +77,17 @@ const meta: Meta<typeof CommandMenu> = {
|
||||
component: CommandMenuRouter,
|
||||
decorators: [
|
||||
(Story) => {
|
||||
const setCurrentWorkspace = useSetRecoilStateV2(currentWorkspaceState);
|
||||
const setCurrentUserWorkspace = useSetRecoilStateV2(
|
||||
currentUserWorkspaceState,
|
||||
jotaiStore.set(currentWorkspaceState.atom, mockCurrentWorkspace);
|
||||
jotaiStore.set(
|
||||
currentWorkspaceMemberState.atom,
|
||||
mockedWorkspaceMemberData,
|
||||
);
|
||||
const setCurrentWorkspaceMember = useSetRecoilStateV2(
|
||||
currentWorkspaceMemberState,
|
||||
jotaiStore.set(
|
||||
currentUserWorkspaceState.atom,
|
||||
mockedUserData.currentUserWorkspace,
|
||||
);
|
||||
const setIsCommandMenuOpened = useSetRecoilState(
|
||||
isCommandMenuOpenedState,
|
||||
);
|
||||
const setCommandMenuNavigationStack = useSetRecoilState(
|
||||
commandMenuNavigationStackState,
|
||||
);
|
||||
|
||||
setCurrentWorkspace(mockCurrentWorkspace);
|
||||
setCurrentWorkspaceMember(mockedWorkspaceMemberData);
|
||||
setCurrentUserWorkspace(mockedUserData.currentUserWorkspace);
|
||||
|
||||
setIsCommandMenuOpened(true);
|
||||
setCommandMenuNavigationStack([
|
||||
jotaiStore.set(isCommandMenuOpenedStateV2.atom, true);
|
||||
jotaiStore.set(commandMenuNavigationStackState.atom, [
|
||||
{
|
||||
page: CommandMenuPages.Root,
|
||||
pageTitle: 'Command Menu',
|
||||
@@ -101,6 +96,25 @@ const meta: Meta<typeof CommandMenu> = {
|
||||
},
|
||||
]);
|
||||
|
||||
const objectMetadataItems = jotaiStore.get(objectMetadataItemsState.atom);
|
||||
const companyMetadataItem = objectMetadataItems.find(
|
||||
(item) => item.nameSingular === 'company',
|
||||
);
|
||||
if (isDefined(companyMetadataItem)) {
|
||||
jotaiStore.set(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState.atomFamily({
|
||||
instanceId: MAIN_CONTEXT_STORE_INSTANCE_ID,
|
||||
}),
|
||||
companyMetadataItem.id,
|
||||
);
|
||||
jotaiStore.set(
|
||||
contextStoreCurrentViewTypeComponentState.atomFamily({
|
||||
instanceId: MAIN_CONTEXT_STORE_INSTANCE_ID,
|
||||
}),
|
||||
ContextStoreViewType.Table,
|
||||
);
|
||||
}
|
||||
|
||||
return <Story />;
|
||||
},
|
||||
ContextStoreDecorator,
|
||||
@@ -139,10 +153,8 @@ export const LimitedPermissions: Story = {
|
||||
},
|
||||
decorators: [
|
||||
(Story) => {
|
||||
const setCurrentUserWorkspace = useSetRecoilStateV2(
|
||||
currentUserWorkspaceState,
|
||||
);
|
||||
setCurrentUserWorkspace(
|
||||
jotaiStore.set(
|
||||
currentUserWorkspaceState.atom,
|
||||
mockedLimitedPermissionsUserData.currentUserWorkspace,
|
||||
);
|
||||
|
||||
|
||||
+6
-2
@@ -9,6 +9,7 @@ import { CommandMenuContextRecordsChip } from '@/command-menu/components/Command
|
||||
import { PreComputedChipGeneratorsContext } from '@/object-metadata/contexts/PreComputedChipGeneratorsContext';
|
||||
import { type RecordChipData } from '@/object-record/record-field/ui/types/RecordChipData';
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { ComponentDecorator } from 'twenty-ui/testing';
|
||||
import { getJestMetadataAndApolloMocksAndActionMenuWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksAndActionMenuWrapper';
|
||||
@@ -190,9 +191,12 @@ const createContextStoreWrapper = ({
|
||||
selectedRecordIds: companies.map((company) => company.id),
|
||||
},
|
||||
contextStoreNumberOfSelectedRecords: companies.length,
|
||||
onInitializeRecoilSnapshot: (snapshot) => {
|
||||
onInitializeJotaiStore: () => {
|
||||
for (const company of companies) {
|
||||
snapshot.set(recordStoreFamilyState(company.id), company);
|
||||
jotaiStore.set(
|
||||
recordStoreFamilyState.atomFamily(company.id),
|
||||
company as ObjectRecord,
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
+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],
|
||||
);
|
||||
|
||||
+2
-2
@@ -7,12 +7,12 @@ import { useGenerateDepthRecordGqlFieldsFromObject } from '@/object-record/graph
|
||||
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
|
||||
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
|
||||
import { LayoutRenderingProvider } from '@/ui/layout/contexts/LayoutRenderingContext';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { PageLayoutType } from '~/generated-metadata/graphql';
|
||||
|
||||
export const CommandMenuCalendarEventPage = () => {
|
||||
const { upsertRecordsInStore } = useUpsertRecordsInStore();
|
||||
const viewableRecordId = useRecoilComponentValue(
|
||||
const viewableRecordId = useRecoilComponentValueV2(
|
||||
viewableRecordIdComponentState,
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { Suspense, lazy } from 'react';
|
||||
|
||||
import { viewableFrontComponentIdComponentState } from '@/command-menu/pages/front-component/states/viewableFrontComponentIdComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
const FrontComponentRenderer = lazy(() =>
|
||||
@@ -11,7 +11,7 @@ const FrontComponentRenderer = lazy(() =>
|
||||
);
|
||||
|
||||
export const CommandMenuFrontComponentPage = () => {
|
||||
const viewableFrontComponentId = useRecoilComponentValue(
|
||||
const viewableFrontComponentId = useRecoilComponentValueV2(
|
||||
viewableFrontComponentIdComponentState,
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { CommandMenuPageComponentInstanceContext } from '@/command-menu/states/contexts/CommandMenuPageComponentInstanceContext';
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
|
||||
|
||||
export const viewableFrontComponentIdComponentState = createComponentState<
|
||||
export const viewableFrontComponentIdComponentState = createComponentStateV2<
|
||||
string | null
|
||||
>({
|
||||
key: 'command-menu/viewable-front-component-id',
|
||||
|
||||
+2
-2
@@ -8,7 +8,7 @@ import { EmailThreadMessage } from '@/activities/emails/components/EmailThreadMe
|
||||
import { CommandMenuMessageThreadIntermediaryMessages } from '@/command-menu/pages/message-thread/components/CommandMenuMessageThreadIntermediaryMessages';
|
||||
import { useEmailThreadInCommandMenu } from '@/command-menu/pages/message-thread/hooks/useEmailThreadInCommandMenu';
|
||||
import { messageThreadComponentState } from '@/command-menu/pages/message-thread/states/messageThreadComponentState';
|
||||
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { ConnectedAccountProvider } from 'twenty-shared/types';
|
||||
import { assertUnreachable, isDefined } from 'twenty-shared/utils';
|
||||
@@ -47,7 +47,7 @@ const ALLOWED_REPLY_PROVIDERS = [
|
||||
];
|
||||
|
||||
export const CommandMenuMessageThreadPage = () => {
|
||||
const setMessageThread = useSetRecoilComponentState(
|
||||
const setMessageThread = useSetRecoilComponentStateV2(
|
||||
messageThreadComponentState,
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -366,8 +366,8 @@ const mocks = [
|
||||
const Wrapper = ({ children }: { children: React.ReactNode }) => {
|
||||
const MetadataWrapper = getJestMetadataAndApolloMocksWrapper({
|
||||
apolloMocks: mocks,
|
||||
onInitializeRecoilSnapshot: ({ set }) => {
|
||||
set(
|
||||
onInitializeJotaiStore: (store) => {
|
||||
store.set(
|
||||
viewableRecordIdComponentState.atomFamily({
|
||||
instanceId: 'test-instance',
|
||||
}),
|
||||
|
||||
+2
-2
@@ -13,13 +13,13 @@ import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSi
|
||||
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
|
||||
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
|
||||
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { MessageParticipantRole } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
// to improve - https://github.com/twentyhq/twenty/issues/12190
|
||||
export const useEmailThreadInCommandMenu = () => {
|
||||
const viewableRecordId = useRecoilComponentValue(
|
||||
const viewableRecordId = useRecoilComponentValueV2(
|
||||
viewableRecordIdComponentState,
|
||||
);
|
||||
const { upsertRecordsInStore } = useUpsertRecordsInStore();
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
import { type MessageThread } from '@/activities/emails/types/MessageThread';
|
||||
import { CommandMenuPageComponentInstanceContext } from '@/command-menu/states/contexts/CommandMenuPageComponentInstanceContext';
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
|
||||
|
||||
export const messageThreadComponentState =
|
||||
createComponentState<MessageThread | null>({
|
||||
createComponentStateV2<MessageThread | null>({
|
||||
key: 'messageThreadComponentState',
|
||||
defaultValue: null,
|
||||
componentInstanceContext: CommandMenuPageComponentInstanceContext,
|
||||
|
||||
+21
-38
@@ -14,11 +14,10 @@ import { currentRecordFilterGroupsComponentState } from '@/object-record/record-
|
||||
import { RecordFiltersComponentInstanceContext } from '@/object-record/record-filter/states/context/RecordFiltersComponentInstanceContext';
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { InputLabel } from '@/ui/input/components/InputLabel';
|
||||
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
|
||||
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
|
||||
import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2';
|
||||
import { useStore } from 'jotai';
|
||||
import styled from '@emotion/styled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
const StyledChartFiltersPageContainer = styled.div`
|
||||
display: flex;
|
||||
@@ -50,49 +49,33 @@ export const ChartFiltersSettings = ({
|
||||
const { updateCurrentWidgetConfig } =
|
||||
useUpdateCurrentWidgetConfig(pageLayoutId);
|
||||
|
||||
const currentRecordFiltersCallbackState = useRecoilComponentCallbackState(
|
||||
const currentRecordFiltersAtom = useRecoilComponentStateCallbackStateV2(
|
||||
currentRecordFiltersComponentState,
|
||||
instanceId,
|
||||
);
|
||||
|
||||
const currentRecordFilterGroupsCallbackState =
|
||||
useRecoilComponentCallbackState(
|
||||
currentRecordFilterGroupsComponentState,
|
||||
instanceId,
|
||||
);
|
||||
const currentRecordFilterGroupsAtom = useRecoilComponentStateCallbackStateV2(
|
||||
currentRecordFilterGroupsComponentState,
|
||||
instanceId,
|
||||
);
|
||||
|
||||
const store = useStore();
|
||||
const chartWidgetConfiguration = widget.configuration;
|
||||
|
||||
const handleFiltersUpdate = useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
() => {
|
||||
const currentRecordFilters = getSnapshotValue(
|
||||
snapshot,
|
||||
currentRecordFiltersCallbackState,
|
||||
);
|
||||
const handleFiltersUpdate = () => {
|
||||
const currentRecordFilters = store.get(currentRecordFiltersAtom);
|
||||
const currentRecordFilterGroups = store.get(currentRecordFilterGroupsAtom);
|
||||
|
||||
const currentRecordFilterGroups = getSnapshotValue(
|
||||
snapshot,
|
||||
currentRecordFilterGroupsCallbackState,
|
||||
);
|
||||
|
||||
updateCurrentWidgetConfig({
|
||||
objectMetadataId: objectMetadataItem.id,
|
||||
configToUpdate: {
|
||||
filter: {
|
||||
recordFilters: currentRecordFilters,
|
||||
recordFilterGroups: currentRecordFilterGroups,
|
||||
},
|
||||
} satisfies Partial<ChartWidgetConfiguration>,
|
||||
});
|
||||
},
|
||||
[
|
||||
currentRecordFiltersCallbackState,
|
||||
currentRecordFilterGroupsCallbackState,
|
||||
objectMetadataItem,
|
||||
updateCurrentWidgetConfig,
|
||||
],
|
||||
);
|
||||
updateCurrentWidgetConfig({
|
||||
objectMetadataId: objectMetadataItem.id,
|
||||
configToUpdate: {
|
||||
filter: {
|
||||
recordFilters: currentRecordFilters,
|
||||
recordFilterGroups: currentRecordFilterGroups,
|
||||
},
|
||||
} satisfies Partial<ChartWidgetConfiguration>,
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
+5
-5
@@ -3,8 +3,8 @@ import { type ChartFilters } from '@/command-menu/pages/page-layout/types/ChartF
|
||||
import { useSetAdvancedFilterDropdownStates } from '@/object-record/advanced-filter/hooks/useSetAdvancedFilterDropdownAllRowsStates';
|
||||
import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState';
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
|
||||
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
|
||||
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
@@ -16,13 +16,13 @@ export const ChartFiltersSettingsInitializeStateEffect = ({
|
||||
initialChartFilters,
|
||||
}: ChartFiltersSettingsInitializeStateEffectProps) => {
|
||||
const [hasInitializedChartFilters, setHasInitializedChartFilters] =
|
||||
useRecoilComponentState(hasInitializedChartFiltersComponentState);
|
||||
useRecoilComponentStateV2(hasInitializedChartFiltersComponentState);
|
||||
|
||||
const setCurrentRecordFilters = useSetRecoilComponentState(
|
||||
const setCurrentRecordFilters = useSetRecoilComponentStateV2(
|
||||
currentRecordFiltersComponentState,
|
||||
);
|
||||
|
||||
const setCurrentRecordFilterGroups = useSetRecoilComponentState(
|
||||
const setCurrentRecordFilterGroups = useSetRecoilComponentStateV2(
|
||||
currentRecordFilterGroupsComponentState,
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -14,7 +14,7 @@ import { CHART_CONFIGURATION_SETTING_IDS } from '@/command-menu/pages/page-layou
|
||||
import { shouldHideChartSetting } from '@/command-menu/pages/page-layout/utils/shouldHideChartSetting';
|
||||
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||
import { hasWidgetTooManyGroupsComponentState } from '@/page-layout/widgets/graph/states/hasWidgetTooManyGroupsComponentState';
|
||||
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
|
||||
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2';
|
||||
import styled from '@emotion/styled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { isFieldMetadataDateKind } from 'twenty-shared/utils';
|
||||
@@ -58,7 +58,7 @@ export const ChartSettings = ({ widget }: { widget: PageLayoutWidget }) => {
|
||||
CHART_CONFIGURATION_SETTING_IDS.GROUP_BY,
|
||||
);
|
||||
const [hasWidgetTooManyGroups, setHasWidgetTooManyGroups] =
|
||||
useRecoilComponentState(hasWidgetTooManyGroupsComponentState);
|
||||
useRecoilComponentStateV2(hasWidgetTooManyGroupsComponentState);
|
||||
|
||||
const handleGraphTypeChange = (graphType: GraphType) => {
|
||||
const configToUpdate = getConfigToUpdateAfterGraphTypeChange(graphType);
|
||||
|
||||
+3
-3
@@ -5,7 +5,7 @@ import { isChartWidget } from '@/command-menu/pages/page-layout/utils/isChartWid
|
||||
import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDraftComponentState';
|
||||
import { pageLayoutEditingWidgetIdComponentState } from '@/page-layout/states/pageLayoutEditingWidgetIdComponentState';
|
||||
import { WidgetComponentInstanceContext } from '@/page-layout/widgets/states/contexts/WidgetComponentInstanceContext';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import styled from '@emotion/styled';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
@@ -18,12 +18,12 @@ const StyledContainer = styled.div`
|
||||
export const CommandMenuPageLayoutChartSettings = () => {
|
||||
const { pageLayoutId } = usePageLayoutIdFromContextStoreTargetedRecord();
|
||||
|
||||
const draftPageLayout = useRecoilComponentValue(
|
||||
const draftPageLayout = useRecoilComponentValueV2(
|
||||
pageLayoutDraftComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const pageLayoutEditingWidgetId = useRecoilComponentValue(
|
||||
const pageLayoutEditingWidgetId = useRecoilComponentValueV2(
|
||||
pageLayoutEditingWidgetIdComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
+3
-3
@@ -4,19 +4,19 @@ import { isChartWidget } from '@/command-menu/pages/page-layout/utils/isChartWid
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDraftComponentState';
|
||||
import { pageLayoutEditingWidgetIdComponentState } from '@/page-layout/states/pageLayoutEditingWidgetIdComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const CommandMenuPageLayoutGraphFilter = () => {
|
||||
const { pageLayoutId } = usePageLayoutIdFromContextStoreTargetedRecord();
|
||||
|
||||
const draftPageLayout = useRecoilComponentValue(
|
||||
const draftPageLayout = useRecoilComponentValueV2(
|
||||
pageLayoutDraftComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const pageLayoutEditingWidgetId = useRecoilComponentValue(
|
||||
const pageLayoutEditingWidgetId = useRecoilComponentValueV2(
|
||||
pageLayoutEditingWidgetIdComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
+4
-4
@@ -11,8 +11,8 @@ import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDr
|
||||
import { pageLayoutTabSettingsOpenTabIdComponentState } from '@/page-layout/states/pageLayoutTabSettingsOpenTabIdComponentState';
|
||||
import { sortTabsByPosition } from '@/page-layout/utils/sortTabsByPosition';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import {
|
||||
@@ -26,12 +26,12 @@ export const CommandMenuPageLayoutTabSettings = () => {
|
||||
const { closeCommandMenu } = useCommandMenu();
|
||||
const { pageLayoutId } = usePageLayoutIdFromContextStoreTargetedRecord();
|
||||
|
||||
const draft = useRecoilComponentValue(
|
||||
const draft = useRecoilComponentValueV2(
|
||||
pageLayoutDraftComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const [openTabId, setOpenTabId] = useRecoilComponentState(
|
||||
const [openTabId, setOpenTabId] = useRecoilComponentStateV2(
|
||||
pageLayoutTabSettingsOpenTabIdComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
+4
-4
@@ -16,8 +16,8 @@ import { useRemovePageLayoutWidgetAndPreservePosition } from '@/page-layout/hook
|
||||
import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDraftComponentState';
|
||||
import { pageLayoutEditingWidgetIdComponentState } from '@/page-layout/states/pageLayoutEditingWidgetIdComponentState';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { useQuery } from '@apollo/client';
|
||||
import { t } from '@lingui/core/macro';
|
||||
@@ -79,12 +79,12 @@ export const CommandMenuPageLayoutWidgetTypeSelect = () => {
|
||||
);
|
||||
|
||||
const [pageLayoutEditingWidgetId, setPageLayoutEditingWidgetId] =
|
||||
useRecoilComponentState(
|
||||
useRecoilComponentStateV2(
|
||||
pageLayoutEditingWidgetIdComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const draftPageLayout = useRecoilComponentValue(
|
||||
const draftPageLayout = useRecoilComponentValueV2(
|
||||
pageLayoutDraftComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
+1
-2
@@ -6,7 +6,6 @@ import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { RightDrawerFooter } from '@/ui/layout/right-drawer/components/RightDrawerFooter';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useId } from 'react';
|
||||
@@ -24,7 +23,7 @@ export const WidgetSettingsFooter = ({
|
||||
const { closeDropdown } = useCloseDropdown();
|
||||
const { duplicateWidget } = useDuplicatePageLayoutWidget(pageLayoutId);
|
||||
const { deletePageLayoutWidget } = useDeletePageLayoutWidget(pageLayoutId);
|
||||
const editingWidgetId = useRecoilComponentValue(
|
||||
const editingWidgetId = useRecoilComponentValueV2(
|
||||
pageLayoutEditingWidgetIdComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
+6
-5
@@ -2,7 +2,7 @@ import { useNavigateCommandMenu } from '@/command-menu/hooks/useNavigateCommandM
|
||||
import { type PageLayoutCommandMenuPage } from '@/command-menu/pages/page-layout/types/PageLayoutCommandMenuPage';
|
||||
import { getPageLayoutIcon } from '@/command-menu/pages/page-layout/utils/getPageLayoutIcon';
|
||||
import { getPageLayoutPageTitle } from '@/command-menu/pages/page-layout/utils/getPageLayoutPageTitle';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { useCallback } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { type IconComponent } from 'twenty-ui/display';
|
||||
|
||||
@@ -17,8 +17,8 @@ type NavigatePageLayoutCommandMenuProps = {
|
||||
export const useNavigatePageLayoutCommandMenu = () => {
|
||||
const { navigateCommandMenu } = useNavigateCommandMenu();
|
||||
|
||||
const navigatePageLayoutCommandMenu = useRecoilCallback(() => {
|
||||
return ({
|
||||
const navigatePageLayoutCommandMenu = useCallback(
|
||||
({
|
||||
commandMenuPage,
|
||||
pageTitle,
|
||||
pageIcon,
|
||||
@@ -36,8 +36,9 @@ export const useNavigatePageLayoutCommandMenu = () => {
|
||||
focusTitleInput,
|
||||
resetNavigationStack,
|
||||
});
|
||||
};
|
||||
}, [navigateCommandMenu]);
|
||||
},
|
||||
[navigateCommandMenu],
|
||||
);
|
||||
|
||||
return {
|
||||
navigatePageLayoutCommandMenu,
|
||||
|
||||
+4
-4
@@ -1,10 +1,10 @@
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
|
||||
export const usePageLayoutIdFromContextStoreTargetedRecord = () => {
|
||||
const targetedRecordsRule = useRecoilComponentValue(
|
||||
const targetedRecordsRule = useRecoilComponentValueV2(
|
||||
contextStoreTargetedRecordsRuleComponentState,
|
||||
);
|
||||
|
||||
@@ -19,7 +19,7 @@ export const usePageLayoutIdFromContextStoreTargetedRecord = () => {
|
||||
|
||||
const recordId: string = targetedRecordsRule.selectedRecordIds[0];
|
||||
|
||||
const record = useRecoilValue(recordStoreFamilyState(recordId));
|
||||
const record = useFamilyRecoilValueV2(recordStoreFamilyState, recordId);
|
||||
|
||||
return { pageLayoutId: record?.pageLayoutId };
|
||||
};
|
||||
|
||||
+3
-3
@@ -2,16 +2,16 @@ import { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMetadataItemById';
|
||||
import { useRecordPageLayoutIdFromRecordStoreOrThrow } from '@/page-layout/hooks/useRecordPageLayoutIdFromRecordStoreOrThrow';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const usePageLayoutIdForRecordPageLayoutFromContextStoreTargetedRecord =
|
||||
() => {
|
||||
const targetedRecordsRule = useRecoilComponentValue(
|
||||
const targetedRecordsRule = useRecoilComponentValueV2(
|
||||
contextStoreTargetedRecordsRuleComponentState,
|
||||
);
|
||||
|
||||
const objectMetadataId = useRecoilComponentValue(
|
||||
const objectMetadataId = useRecoilComponentValueV2(
|
||||
contextStoreCurrentObjectMetadataItemIdComponentState,
|
||||
);
|
||||
|
||||
|
||||
+34
-33
@@ -5,7 +5,8 @@ import { currentRecordFilterGroupsComponentState } from '@/object-record/record-
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { hasInitializedCurrentRecordFilterGroupsComponentFamilyState } from '@/views/states/hasInitializedCurrentRecordFilterGroupsComponentFamilyState';
|
||||
import { hasInitializedCurrentRecordFiltersComponentFamilyState } from '@/views/states/hasInitializedCurrentRecordFiltersComponentFamilyState';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { useCallback } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useResetChartDraftFiltersSettings = () => {
|
||||
@@ -13,42 +14,42 @@ export const useResetChartDraftFiltersSettings = () => {
|
||||
|
||||
const { widgetInEditMode } = useWidgetInEditMode(pageLayoutId);
|
||||
|
||||
const resetChartDraftFiltersSettings = useRecoilCallback(
|
||||
({ set }) =>
|
||||
(objectMetadataItemId: string) => {
|
||||
if (!isDefined(widgetInEditMode)) {
|
||||
return;
|
||||
}
|
||||
const resetChartDraftFiltersSettings = useCallback(
|
||||
(objectMetadataItemId: string) => {
|
||||
if (!isDefined(widgetInEditMode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { instanceId } = getChartFiltersSettingsInstanceId({
|
||||
widgetId: widgetInEditMode.id,
|
||||
objectMetadataItemId: objectMetadataItemId,
|
||||
});
|
||||
const { instanceId } = getChartFiltersSettingsInstanceId({
|
||||
widgetId: widgetInEditMode.id,
|
||||
objectMetadataItemId: objectMetadataItemId,
|
||||
});
|
||||
|
||||
set(
|
||||
hasInitializedCurrentRecordFilterGroupsComponentFamilyState.atomFamily(
|
||||
{
|
||||
familyKey: {},
|
||||
instanceId,
|
||||
},
|
||||
),
|
||||
false,
|
||||
);
|
||||
jotaiStore.set(
|
||||
hasInitializedCurrentRecordFilterGroupsComponentFamilyState.atomFamily({
|
||||
familyKey: {},
|
||||
instanceId,
|
||||
}),
|
||||
false,
|
||||
);
|
||||
|
||||
set(
|
||||
hasInitializedCurrentRecordFiltersComponentFamilyState.atomFamily({
|
||||
familyKey: {},
|
||||
instanceId,
|
||||
}),
|
||||
false,
|
||||
);
|
||||
jotaiStore.set(
|
||||
hasInitializedCurrentRecordFiltersComponentFamilyState.atomFamily({
|
||||
familyKey: {},
|
||||
instanceId,
|
||||
}),
|
||||
false,
|
||||
);
|
||||
|
||||
set(currentRecordFiltersComponentState.atomFamily({ instanceId }), []);
|
||||
set(
|
||||
currentRecordFilterGroupsComponentState.atomFamily({ instanceId }),
|
||||
[],
|
||||
);
|
||||
},
|
||||
jotaiStore.set(
|
||||
currentRecordFiltersComponentState.atomFamily({ instanceId }),
|
||||
[],
|
||||
);
|
||||
jotaiStore.set(
|
||||
currentRecordFilterGroupsComponentState.atomFamily({ instanceId }),
|
||||
[],
|
||||
);
|
||||
},
|
||||
[widgetInEditMode],
|
||||
);
|
||||
|
||||
|
||||
+37
-35
@@ -1,51 +1,53 @@
|
||||
import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDraftComponentState';
|
||||
import { pageLayoutEditingWidgetIdComponentState } from '@/page-layout/states/pageLayoutEditingWidgetIdComponentState';
|
||||
import type { PageLayoutWidget } from '@/page-layout/types/PageLayoutWidget';
|
||||
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useStore } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
export const useUpdateCurrentWidgetConfig = (pageLayoutIdFromProps: string) => {
|
||||
const pageLayoutDraftCallbackState = useRecoilComponentCallbackState(
|
||||
const pageLayoutDraftAtom = useRecoilComponentStateCallbackStateV2(
|
||||
pageLayoutDraftComponentState,
|
||||
pageLayoutIdFromProps,
|
||||
);
|
||||
|
||||
const currentlyEditingWidgetId = useRecoilComponentValue(
|
||||
const currentlyEditingWidgetId = useRecoilComponentValueV2(
|
||||
pageLayoutEditingWidgetIdComponentState,
|
||||
pageLayoutIdFromProps,
|
||||
);
|
||||
|
||||
const updateCurrentWidgetConfig = useRecoilCallback(
|
||||
({ set }) =>
|
||||
({
|
||||
objectMetadataId,
|
||||
configToUpdate,
|
||||
}: {
|
||||
objectMetadataId?: string | null;
|
||||
configToUpdate?: Partial<PageLayoutWidget['configuration']>;
|
||||
}) => {
|
||||
set(pageLayoutDraftCallbackState, (prev) => ({
|
||||
...prev,
|
||||
tabs: prev.tabs.map((tab) => ({
|
||||
...tab,
|
||||
widgets: tab.widgets.map((widget) =>
|
||||
widget.id === currentlyEditingWidgetId
|
||||
? {
|
||||
...widget,
|
||||
objectMetadataId:
|
||||
objectMetadataId ?? widget.objectMetadataId,
|
||||
configuration: {
|
||||
...(widget.configuration ?? {}),
|
||||
...configToUpdate,
|
||||
} as PageLayoutWidget['configuration'],
|
||||
}
|
||||
: widget,
|
||||
),
|
||||
})),
|
||||
}));
|
||||
},
|
||||
[pageLayoutDraftCallbackState, currentlyEditingWidgetId],
|
||||
const store = useStore();
|
||||
|
||||
const updateCurrentWidgetConfig = useCallback(
|
||||
({
|
||||
objectMetadataId,
|
||||
configToUpdate,
|
||||
}: {
|
||||
objectMetadataId?: string | null;
|
||||
configToUpdate?: Partial<PageLayoutWidget['configuration']>;
|
||||
}) => {
|
||||
const prev = store.get(pageLayoutDraftAtom);
|
||||
store.set(pageLayoutDraftAtom, {
|
||||
...prev,
|
||||
tabs: prev.tabs.map((tab) => ({
|
||||
...tab,
|
||||
widgets: tab.widgets.map((widget) =>
|
||||
widget.id === currentlyEditingWidgetId
|
||||
? {
|
||||
...widget,
|
||||
objectMetadataId: objectMetadataId ?? widget.objectMetadataId,
|
||||
configuration: {
|
||||
...(widget.configuration ?? {}),
|
||||
...configToUpdate,
|
||||
} as PageLayoutWidget['configuration'],
|
||||
}
|
||||
: widget,
|
||||
),
|
||||
})),
|
||||
});
|
||||
},
|
||||
[pageLayoutDraftAtom, currentlyEditingWidgetId, store],
|
||||
);
|
||||
|
||||
return { updateCurrentWidgetConfig };
|
||||
|
||||
+105
-116
@@ -15,9 +15,9 @@ import { type PageLayoutWidget } from '@/page-layout/types/PageLayoutWidget';
|
||||
import { getTabListInstanceIdFromPageLayoutId } from '@/page-layout/utils/getTabListInstanceIdFromPageLayoutId';
|
||||
import { updateWidgetMinimumSizeForGraphType } from '@/page-layout/utils/updateWidgetMinimumSizeForGraphType';
|
||||
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
|
||||
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
|
||||
import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2';
|
||||
import { useStore } from 'jotai';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { useCallback } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { BarChartLayout } from '~/generated-metadata/graphql';
|
||||
|
||||
@@ -32,159 +32,148 @@ export const useGetConfigToUpdateAfterGraphTypeChange = ({
|
||||
|
||||
const tabListInstanceId = getTabListInstanceIdFromPageLayoutId(pageLayoutId);
|
||||
|
||||
const currentlyEditingWidgetIdState = useRecoilComponentCallbackState(
|
||||
const currentlyEditingWidgetIdState = useRecoilComponentStateCallbackStateV2(
|
||||
pageLayoutEditingWidgetIdComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const pageLayoutCurrentLayoutsState = useRecoilComponentCallbackState(
|
||||
const pageLayoutCurrentLayoutsState = useRecoilComponentStateCallbackStateV2(
|
||||
pageLayoutCurrentLayoutsComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const pageLayoutDraftState = useRecoilComponentCallbackState(
|
||||
const pageLayoutDraftState = useRecoilComponentStateCallbackStateV2(
|
||||
pageLayoutDraftComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const store = useStore();
|
||||
|
||||
const getConfigToUpdateAfterGraphTypeChange = useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
(graphType: GraphType) => {
|
||||
const currentlyEditingWidgetId = snapshot
|
||||
.getLoadable(currentlyEditingWidgetIdState)
|
||||
.getValue();
|
||||
const getConfigToUpdateAfterGraphTypeChange = useCallback(
|
||||
(graphType: GraphType) => {
|
||||
const currentlyEditingWidgetId = store.get(currentlyEditingWidgetIdState);
|
||||
|
||||
if (!isDefined(currentlyEditingWidgetId)) {
|
||||
throw new Error('No widget is currently being edited');
|
||||
}
|
||||
if (!isDefined(currentlyEditingWidgetId)) {
|
||||
throw new Error('No widget is currently being edited');
|
||||
}
|
||||
|
||||
const draftPageLayout = snapshot
|
||||
.getLoadable(pageLayoutDraftState)
|
||||
.getValue();
|
||||
const draftPageLayout = store.get(pageLayoutDraftState);
|
||||
|
||||
const widgetInDraft = draftPageLayout.tabs
|
||||
.flatMap((tab) => tab.widgets)
|
||||
.find((w) => w.id === currentlyEditingWidgetId);
|
||||
const widgetInDraft = draftPageLayout.tabs
|
||||
.flatMap((tab) => tab.widgets)
|
||||
.find((w) => w.id === currentlyEditingWidgetId);
|
||||
|
||||
if (
|
||||
!isDefined(widgetInDraft) ||
|
||||
!isDefined(widgetInDraft.configuration)
|
||||
) {
|
||||
throw new Error('Widget configuration not found in draft state');
|
||||
}
|
||||
if (
|
||||
!isDefined(widgetInDraft) ||
|
||||
!isDefined(widgetInDraft.configuration)
|
||||
) {
|
||||
throw new Error('Widget configuration not found in draft state');
|
||||
}
|
||||
|
||||
const currentConfiguration = widgetInDraft.configuration;
|
||||
const currentConfiguration = widgetInDraft.configuration;
|
||||
|
||||
if (!isWidgetConfigurationOfTypeGraph(currentConfiguration)) {
|
||||
throw new Error('Widget configuration is not a chart configuration');
|
||||
}
|
||||
if (!isWidgetConfigurationOfTypeGraph(currentConfiguration)) {
|
||||
throw new Error('Widget configuration is not a chart configuration');
|
||||
}
|
||||
|
||||
const newConfigurationType =
|
||||
getConfigurationTypeFromGraphType(graphType);
|
||||
const newConfigurationType = getConfigurationTypeFromGraphType(graphType);
|
||||
|
||||
let configToUpdate = {
|
||||
__typename:
|
||||
GRAPH_CONFIGURATION_TYPE_TO_CONFIG_TYPENAME[newConfigurationType],
|
||||
configurationType: newConfigurationType,
|
||||
} as Partial<ChartConfiguration>;
|
||||
let configToUpdate = {
|
||||
__typename:
|
||||
GRAPH_CONFIGURATION_TYPE_TO_CONFIG_TYPENAME[newConfigurationType],
|
||||
configurationType: newConfigurationType,
|
||||
} as Partial<ChartConfiguration>;
|
||||
|
||||
if (
|
||||
graphType !== GraphType.AGGREGATE &&
|
||||
graphType !== GraphType.GAUGE
|
||||
) {
|
||||
const objectMetadataItem = objectMetadataItems.find(
|
||||
(item) => item.id === widget.objectMetadataId,
|
||||
if (graphType !== GraphType.AGGREGATE && graphType !== GraphType.GAUGE) {
|
||||
const objectMetadataItem = objectMetadataItems.find(
|
||||
(item) => item.id === widget.objectMetadataId,
|
||||
);
|
||||
|
||||
const convertedAggregateOperation =
|
||||
convertAggregateOperationForDateField(
|
||||
currentConfiguration,
|
||||
objectMetadataItem,
|
||||
);
|
||||
|
||||
const convertedAggregateOperation =
|
||||
convertAggregateOperationForDateField(
|
||||
currentConfiguration,
|
||||
objectMetadataItem,
|
||||
);
|
||||
|
||||
if (isDefined(convertedAggregateOperation)) {
|
||||
configToUpdate = {
|
||||
...configToUpdate,
|
||||
aggregateOperation: convertedAggregateOperation,
|
||||
};
|
||||
}
|
||||
if (isDefined(convertedAggregateOperation)) {
|
||||
configToUpdate = {
|
||||
...configToUpdate,
|
||||
aggregateOperation: convertedAggregateOperation,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const isPieChart = graphType === GraphType.PIE;
|
||||
const isVerticalBarChart = graphType === GraphType.VERTICAL_BAR;
|
||||
const isHorizontalBarChart = graphType === GraphType.HORIZONTAL_BAR;
|
||||
const isLineChart = graphType === GraphType.LINE;
|
||||
const isBarOrLineChart =
|
||||
isVerticalBarChart || isHorizontalBarChart || isLineChart;
|
||||
const isPieChart = graphType === GraphType.PIE;
|
||||
const isVerticalBarChart = graphType === GraphType.VERTICAL_BAR;
|
||||
const isHorizontalBarChart = graphType === GraphType.HORIZONTAL_BAR;
|
||||
const isLineChart = graphType === GraphType.LINE;
|
||||
const isBarOrLineChart =
|
||||
isVerticalBarChart || isHorizontalBarChart || isLineChart;
|
||||
|
||||
const wasBarOrLineChart =
|
||||
isWidgetConfigurationOfType(
|
||||
currentConfiguration,
|
||||
'BarChartConfiguration',
|
||||
) ||
|
||||
isWidgetConfigurationOfType(
|
||||
currentConfiguration,
|
||||
'LineChartConfiguration',
|
||||
);
|
||||
|
||||
const wasPieChart = isWidgetConfigurationOfType(
|
||||
const wasBarOrLineChart =
|
||||
isWidgetConfigurationOfType(
|
||||
currentConfiguration,
|
||||
'PieChartConfiguration',
|
||||
'BarChartConfiguration',
|
||||
) ||
|
||||
isWidgetConfigurationOfType(
|
||||
currentConfiguration,
|
||||
'LineChartConfiguration',
|
||||
);
|
||||
|
||||
if (isPieChart && wasBarOrLineChart) {
|
||||
configToUpdate = {
|
||||
...configToUpdate,
|
||||
...convertBarOrLineChartConfigToPieChart(currentConfiguration),
|
||||
};
|
||||
}
|
||||
const wasPieChart = isWidgetConfigurationOfType(
|
||||
currentConfiguration,
|
||||
'PieChartConfiguration',
|
||||
);
|
||||
|
||||
if (isBarOrLineChart && wasPieChart) {
|
||||
configToUpdate = {
|
||||
...configToUpdate,
|
||||
...convertPieChartConfigToBarOrLineChart(currentConfiguration),
|
||||
};
|
||||
}
|
||||
if (isPieChart && wasBarOrLineChart) {
|
||||
configToUpdate = {
|
||||
...configToUpdate,
|
||||
...convertBarOrLineChartConfigToPieChart(currentConfiguration),
|
||||
};
|
||||
}
|
||||
|
||||
if (isHorizontalBarChart) {
|
||||
configToUpdate = {
|
||||
...configToUpdate,
|
||||
layout: BarChartLayout.HORIZONTAL,
|
||||
};
|
||||
}
|
||||
if (isBarOrLineChart && wasPieChart) {
|
||||
configToUpdate = {
|
||||
...configToUpdate,
|
||||
...convertPieChartConfigToBarOrLineChart(currentConfiguration),
|
||||
};
|
||||
}
|
||||
|
||||
if (isVerticalBarChart) {
|
||||
configToUpdate = {
|
||||
...configToUpdate,
|
||||
layout: BarChartLayout.VERTICAL,
|
||||
};
|
||||
}
|
||||
if (isHorizontalBarChart) {
|
||||
configToUpdate = {
|
||||
...configToUpdate,
|
||||
layout: BarChartLayout.HORIZONTAL,
|
||||
};
|
||||
}
|
||||
|
||||
const activeTabId = store.get(
|
||||
activeTabIdComponentState.atomFamily({
|
||||
instanceId: tabListInstanceId,
|
||||
}),
|
||||
);
|
||||
if (isVerticalBarChart) {
|
||||
configToUpdate = {
|
||||
...configToUpdate,
|
||||
layout: BarChartLayout.VERTICAL,
|
||||
};
|
||||
}
|
||||
|
||||
if (isDefined(activeTabId) && isDefined(currentlyEditingWidgetId)) {
|
||||
const currentLayouts = snapshot
|
||||
.getLoadable(pageLayoutCurrentLayoutsState)
|
||||
.getValue();
|
||||
const activeTabId = store.get(
|
||||
activeTabIdComponentState.atomFamily({
|
||||
instanceId: tabListInstanceId,
|
||||
}),
|
||||
);
|
||||
|
||||
const updatedLayouts = updateWidgetMinimumSizeForGraphType({
|
||||
configurationType: newConfigurationType,
|
||||
widgetId: currentlyEditingWidgetId,
|
||||
tabId: activeTabId,
|
||||
currentLayouts,
|
||||
});
|
||||
if (isDefined(activeTabId) && isDefined(currentlyEditingWidgetId)) {
|
||||
const currentLayouts = store.get(pageLayoutCurrentLayoutsState);
|
||||
|
||||
set(pageLayoutCurrentLayoutsState, updatedLayouts);
|
||||
}
|
||||
const updatedLayouts = updateWidgetMinimumSizeForGraphType({
|
||||
configurationType: newConfigurationType,
|
||||
widgetId: currentlyEditingWidgetId,
|
||||
tabId: activeTabId,
|
||||
currentLayouts,
|
||||
});
|
||||
|
||||
return configToUpdate;
|
||||
},
|
||||
store.set(pageLayoutCurrentLayoutsState, updatedLayouts);
|
||||
}
|
||||
|
||||
return configToUpdate;
|
||||
},
|
||||
[
|
||||
currentlyEditingWidgetIdState,
|
||||
objectMetadataItems,
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDraftComponentState';
|
||||
import { pageLayoutEditingWidgetIdComponentState } from '@/page-layout/states/pageLayoutEditingWidgetIdComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
|
||||
export const useWidgetInEditMode = (pageLayoutId: string) => {
|
||||
const draftPageLayout = useRecoilComponentValue(
|
||||
const draftPageLayout = useRecoilComponentValueV2(
|
||||
pageLayoutDraftComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const pageLayoutEditingWidgetId = useRecoilComponentValue(
|
||||
const pageLayoutEditingWidgetId = useRecoilComponentValueV2(
|
||||
pageLayoutEditingWidgetIdComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
import { RecordFiltersComponentInstanceContext } from '@/object-record/record-filter/states/context/RecordFiltersComponentInstanceContext';
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
|
||||
|
||||
export const hasInitializedChartFiltersComponentState =
|
||||
createComponentState<boolean>({
|
||||
createComponentStateV2<boolean>({
|
||||
key: 'hasInitializedCurrentRecordFiltersComponentFamilyState',
|
||||
defaultValue: false,
|
||||
componentInstanceContext: RecordFiltersComponentInstanceContext,
|
||||
|
||||
+8
-10
@@ -8,11 +8,11 @@ import { INFORMATION_BANNER_HEIGHT } from '@/information-banner/constants/Inform
|
||||
import { RecordComponentInstanceContextsWrapper } from '@/object-record/components/RecordComponentInstanceContextsWrapper';
|
||||
import { PageLayoutRecordPageRenderer } from '@/object-record/record-show/components/PageLayoutRecordPageRenderer';
|
||||
import { useRecordShowPage } from '@/object-record/record-show/hooks/useRecordShowPage';
|
||||
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
|
||||
import { recordStoreFamilySelectorV2 } from '@/object-record/record-store/states/selectors/recordStoreFamilySelectorV2';
|
||||
import { useComponentInstanceStateContext } from '@/ui/utilities/state/component-state/hooks/useComponentInstanceStateContext';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useFamilySelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilySelectorValueV2';
|
||||
|
||||
const StyledRightDrawerRecord = styled.div<{
|
||||
hasDeletedRecordBanner: boolean;
|
||||
@@ -26,11 +26,11 @@ const StyledRightDrawerRecord = styled.div<{
|
||||
`;
|
||||
|
||||
export const CommandMenuRecordPage = () => {
|
||||
const viewableRecordNameSingular = useRecoilComponentValue(
|
||||
const viewableRecordNameSingular = useRecoilComponentValueV2(
|
||||
viewableRecordNameSingularComponentState,
|
||||
);
|
||||
|
||||
const viewableRecordId = useRecoilComponentValue(
|
||||
const viewableRecordId = useRecoilComponentValueV2(
|
||||
viewableRecordIdComponentState,
|
||||
);
|
||||
|
||||
@@ -47,11 +47,9 @@ export const CommandMenuRecordPage = () => {
|
||||
viewableRecordId,
|
||||
);
|
||||
|
||||
const recordDeletedAt = useRecoilValue(
|
||||
recordStoreFamilySelector({
|
||||
recordId: objectRecordId,
|
||||
fieldName: 'deletedAt',
|
||||
}),
|
||||
const recordDeletedAt = useFamilySelectorValueV2(
|
||||
recordStoreFamilySelectorV2,
|
||||
{ recordId: objectRecordId, fieldName: 'deletedAt' },
|
||||
);
|
||||
|
||||
const commandMenuPageInstanceId = useComponentInstanceStateContext(
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { CommandMenuPageComponentInstanceContext } from '@/command-menu/states/contexts/CommandMenuPageComponentInstanceContext';
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
|
||||
|
||||
export const viewableRecordIdComponentState = createComponentState<
|
||||
export const viewableRecordIdComponentState = createComponentStateV2<
|
||||
string | null
|
||||
>({
|
||||
key: 'command-menu/viewable-record-id',
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { CommandMenuPageComponentInstanceContext } from '@/command-menu/states/contexts/CommandMenuPageComponentInstanceContext';
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
|
||||
|
||||
export const viewableRecordNameSingularComponentState = createComponentState<
|
||||
export const viewableRecordNameSingularComponentState = createComponentStateV2<
|
||||
string | null
|
||||
>({
|
||||
key: 'command-menu/viewable-record-name-singular',
|
||||
|
||||
+2
-2
@@ -11,8 +11,8 @@ import { RECORD_ACTIONS } from '@/workflow/workflow-steps/workflow-actions/const
|
||||
import { getActionIconColorOrThrow } from '@/workflow/workflow-steps/workflow-actions/utils/getActionIconColorOrThrow';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { IconFunction } from 'twenty-ui/display';
|
||||
import { MenuItem } from 'twenty-ui/navigation';
|
||||
import { FeatureFlagKey } from '~/generated-metadata/graphql';
|
||||
@@ -35,7 +35,7 @@ export const CommandMenuWorkflowSelectAction = ({
|
||||
|
||||
const { t } = useLingui();
|
||||
|
||||
const logicFunctions = useRecoilValue(logicFunctionsState);
|
||||
const logicFunctions = useRecoilValueV2(logicFunctionsState);
|
||||
|
||||
const toolFunctions = logicFunctions.filter((fn) => fn.isTool === true);
|
||||
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
import { commandMenuWorkflowIdComponentState } from '@/command-menu/pages/workflow/states/commandMenuWorkflowIdComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useCommandMenuWorkflowIdOrThrow = () => {
|
||||
const workflowId = useRecoilComponentValue(
|
||||
const workflowId = useRecoilComponentValueV2(
|
||||
commandMenuWorkflowIdComponentState,
|
||||
);
|
||||
if (!isDefined(workflowId)) {
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { CommandMenuPageComponentInstanceContext } from '@/command-menu/states/contexts/CommandMenuPageComponentInstanceContext';
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
|
||||
|
||||
export const commandMenuWorkflowIdComponentState = createComponentState<
|
||||
export const commandMenuWorkflowIdComponentState = createComponentStateV2<
|
||||
string | undefined
|
||||
>({
|
||||
key: 'command-menu/workflow-id',
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { CommandMenuPageComponentInstanceContext } from '@/command-menu/states/contexts/CommandMenuPageComponentInstanceContext';
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
|
||||
|
||||
export const commandMenuWorkflowRunIdComponentState = createComponentState<
|
||||
export const commandMenuWorkflowRunIdComponentState = createComponentStateV2<
|
||||
string | undefined
|
||||
>({
|
||||
key: 'command-menu/workflow-run-id',
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { CommandMenuPageComponentInstanceContext } from '@/command-menu/states/contexts/CommandMenuPageComponentInstanceContext';
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
|
||||
|
||||
export const commandMenuWorkflowStepIdComponentState = createComponentState<
|
||||
export const commandMenuWorkflowStepIdComponentState = createComponentStateV2<
|
||||
string | undefined
|
||||
>({
|
||||
key: 'command-menu/workflow-step-id',
|
||||
|
||||
+7
-8
@@ -1,10 +1,9 @@
|
||||
import { CommandMenuPageComponentInstanceContext } from '@/command-menu/states/contexts/CommandMenuPageComponentInstanceContext';
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
|
||||
|
||||
export const commandMenuWorkflowVersionIdComponentState = createComponentState<
|
||||
string | undefined
|
||||
>({
|
||||
key: 'command-menu/workflow-version-id',
|
||||
defaultValue: undefined,
|
||||
componentInstanceContext: CommandMenuPageComponentInstanceContext,
|
||||
});
|
||||
export const commandMenuWorkflowVersionIdComponentState =
|
||||
createComponentStateV2<string | undefined>({
|
||||
key: 'command-menu/workflow-version-id',
|
||||
defaultValue: undefined,
|
||||
componentInstanceContext: CommandMenuPageComponentInstanceContext,
|
||||
});
|
||||
|
||||
+6
-6
@@ -4,8 +4,8 @@ import {
|
||||
type WorkflowActionSelection,
|
||||
} from '@/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction';
|
||||
import { commandMenuNavigationStackState } from '@/command-menu/states/commandMenuNavigationStackState';
|
||||
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion';
|
||||
import { workflowVisualizerWorkflowIdComponentState } from '@/workflow/states/workflowVisualizerWorkflowIdComponentState';
|
||||
import {
|
||||
@@ -18,13 +18,13 @@ import { useUpdateStep } from '@/workflow/workflow-steps/hooks/useUpdateStep';
|
||||
import { workflowInsertStepIdsComponentState } from '@/workflow/workflow-steps/states/workflowInsertStepIdsComponentState';
|
||||
import { prepareIfElseStepWithNewBranch } from '@/workflow/workflow-steps/workflow-actions/if-else-action/utils/prepareIfElseStepWithNewBranch';
|
||||
import { getActionIcon } from '@/workflow/workflow-steps/workflow-actions/utils/getActionIcon';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
|
||||
export const CommandMenuWorkflowCreateStepContent = () => {
|
||||
const { getIcon } = useIcons();
|
||||
const workflowVisualizerWorkflowId = useRecoilComponentValue(
|
||||
const workflowVisualizerWorkflowId = useRecoilComponentValueV2(
|
||||
workflowVisualizerWorkflowIdComponentState,
|
||||
);
|
||||
|
||||
@@ -36,12 +36,12 @@ export const CommandMenuWorkflowCreateStepContent = () => {
|
||||
|
||||
const { openWorkflowEditStepInCommandMenu } = useWorkflowCommandMenu();
|
||||
const { closeRightClickMenu } = useCloseRightClickMenu();
|
||||
const setCommandMenuNavigationStack = useSetRecoilState(
|
||||
const setCommandMenuNavigationStack = useSetRecoilStateV2(
|
||||
commandMenuNavigationStackState,
|
||||
);
|
||||
|
||||
const [workflowInsertStepIds, setWorkflowInsertStepIds] =
|
||||
useRecoilComponentState(workflowInsertStepIdsComponentState);
|
||||
useRecoilComponentStateV2(workflowInsertStepIdsComponentState);
|
||||
|
||||
const handleIfElseParentStep = async ({
|
||||
parentStep,
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useFlowOrThrow } from '@/workflow/hooks/useFlowOrThrow';
|
||||
import { workflowSelectedNodeComponentState } from '@/workflow/workflow-diagram/states/workflowSelectedNodeComponentState';
|
||||
import { WorkflowStepDetail } from '@/workflow/workflow-steps/components/WorkflowStepDetail';
|
||||
@@ -15,7 +15,7 @@ const StyledContainer = styled.div`
|
||||
|
||||
export const CommandMenuWorkflowEditStepContent = () => {
|
||||
const flow = useFlowOrThrow();
|
||||
const workflowSelectedNode = useRecoilComponentValue(
|
||||
const workflowSelectedNode = useRecoilComponentValueV2(
|
||||
workflowSelectedNodeComponentState,
|
||||
);
|
||||
|
||||
|
||||
+5
-5
@@ -4,7 +4,7 @@ import {
|
||||
type WorkflowActionSelection,
|
||||
} from '@/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction';
|
||||
import { commandMenuNavigationStackState } from '@/command-menu/states/commandMenuNavigationStackState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useFlowOrThrow } from '@/workflow/hooks/useFlowOrThrow';
|
||||
import { workflowVisualizerWorkflowIdComponentState } from '@/workflow/states/workflowVisualizerWorkflowIdComponentState';
|
||||
import {
|
||||
@@ -15,16 +15,16 @@ import { useCloseRightClickMenu } from '@/workflow/workflow-diagram/hooks/useClo
|
||||
import { workflowSelectedNodeComponentState } from '@/workflow/workflow-diagram/states/workflowSelectedNodeComponentState';
|
||||
import { useUpdateStep } from '@/workflow/workflow-steps/hooks/useUpdateStep';
|
||||
import { getActionIcon } from '@/workflow/workflow-steps/workflow-actions/utils/getActionIcon';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
|
||||
export const CommandMenuWorkflowEditStepTypeContent = () => {
|
||||
const { getIcon } = useIcons();
|
||||
const workflowSelectedNode = useRecoilComponentValue(
|
||||
const workflowSelectedNode = useRecoilComponentValueV2(
|
||||
workflowSelectedNodeComponentState,
|
||||
);
|
||||
const workflowVisualizerWorkflowId = useRecoilComponentValue(
|
||||
const workflowVisualizerWorkflowId = useRecoilComponentValueV2(
|
||||
workflowVisualizerWorkflowIdComponentState,
|
||||
);
|
||||
const flow = useFlowOrThrow();
|
||||
@@ -33,7 +33,7 @@ export const CommandMenuWorkflowEditStepTypeContent = () => {
|
||||
|
||||
const { openWorkflowEditStepInCommandMenu } = useWorkflowCommandMenu();
|
||||
const { closeRightClickMenu } = useCloseRightClickMenu();
|
||||
const setCommandMenuNavigationStack = useSetRecoilState(
|
||||
const setCommandMenuNavigationStack = useSetRecoilStateV2(
|
||||
commandMenuNavigationStackState,
|
||||
);
|
||||
|
||||
|
||||
+1
-2
@@ -7,7 +7,6 @@ import { TabList } from '@/ui/layout/tab-list/components/TabList';
|
||||
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
|
||||
import { type SingleTabProps } from '@/ui/layout/tab-list/types/SingleTabProps';
|
||||
import { useComponentInstanceStateContext } from '@/ui/utilities/state/component-state/hooks/useComponentInstanceStateContext';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useFlowOrThrow } from '@/workflow/hooks/useFlowOrThrow';
|
||||
import { useWorkflowRun } from '@/workflow/hooks/useWorkflowRun';
|
||||
@@ -44,7 +43,7 @@ type TabId = WorkflowRunTabIdType;
|
||||
|
||||
export const CommandMenuWorkflowRunViewStepContent = () => {
|
||||
const flow = useFlowOrThrow();
|
||||
const workflowSelectedNode = useRecoilComponentValue(
|
||||
const workflowSelectedNode = useRecoilComponentValueV2(
|
||||
workflowSelectedNodeComponentState,
|
||||
);
|
||||
const workflowRunId = useWorkflowRunIdOrThrow();
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
import { commandMenuWorkflowRunIdComponentState } from '@/command-menu/pages/workflow/states/commandMenuWorkflowRunIdComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useCommandMenuWorkflowRunIdOrThrow = () => {
|
||||
const workflowRunId = useRecoilComponentValue(
|
||||
const workflowRunId = useRecoilComponentValueV2(
|
||||
commandMenuWorkflowRunIdComponentState,
|
||||
);
|
||||
if (!isDefined(workflowRunId)) {
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
import { CommandMenuWorkflowRunStepContentComponentInstanceContext } from '@/command-menu/pages/workflow/step/view-run/states/contexts/CommandMenuWorkflowRunStepContentComponentInstanceContext';
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
|
||||
|
||||
export const workflowRunIteratorSubStepIterationIndexComponentState =
|
||||
createComponentState<number>({
|
||||
createComponentStateV2<number>({
|
||||
key: 'workflowRunIteratorSubStepIterationIndexComponentState',
|
||||
defaultValue: 0,
|
||||
componentInstanceContext:
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useFlowOrThrow } from '@/workflow/hooks/useFlowOrThrow';
|
||||
import { workflowSelectedNodeComponentState } from '@/workflow/workflow-diagram/states/workflowSelectedNodeComponentState';
|
||||
import { WorkflowStepDetail } from '@/workflow/workflow-steps/components/WorkflowStepDetail';
|
||||
@@ -13,7 +13,7 @@ const StyledContainer = styled.div`
|
||||
|
||||
export const CommandMenuWorkflowViewStepContent = () => {
|
||||
const flow = useFlowOrThrow();
|
||||
const workflowSelectedNode = useRecoilComponentValue(
|
||||
const workflowSelectedNode = useRecoilComponentValueV2(
|
||||
workflowSelectedNodeComponentState,
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
import { commandMenuWorkflowVersionIdComponentState } from '@/command-menu/pages/workflow/states/commandMenuWorkflowVersionIdComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useCommandMenuWorkflowVersionIdOrThrow = () => {
|
||||
const workflowVersionId = useRecoilComponentValue(
|
||||
const workflowVersionId = useRecoilComponentValueV2(
|
||||
commandMenuWorkflowVersionIdComponentState,
|
||||
);
|
||||
if (!isDefined(workflowVersionId)) {
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { useWorkflowCommandMenu } from '@/command-menu/hooks/useWorkflowCommandMenu';
|
||||
import { useCommandMenuWorkflowIdOrThrow } from '@/command-menu/pages/workflow/hooks/useCommandMenuWorkflowIdOrThrow';
|
||||
import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems';
|
||||
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
|
||||
import { useFlowOrThrow } from '@/workflow/hooks/useFlowOrThrow';
|
||||
import {
|
||||
type WorkflowTrigger,
|
||||
@@ -29,7 +29,7 @@ export const CommandMenuWorkflowSelectTriggerTypeContent = () => {
|
||||
const { activeNonSystemObjectMetadataItems } =
|
||||
useFilteredObjectMetadataItems();
|
||||
|
||||
const setWorkflowSelectedNode = useSetRecoilComponentState(
|
||||
const setWorkflowSelectedNode = useSetRecoilComponentStateV2(
|
||||
workflowSelectedNodeComponentState,
|
||||
);
|
||||
const { openWorkflowEditStepInCommandMenu } = useWorkflowCommandMenu();
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { type MorphItem } from '@/object-record/multiple-objects/types/MorphItem';
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
|
||||
|
||||
export const commandMenuNavigationMorphItemsByPageState = createState<
|
||||
export const commandMenuNavigationMorphItemsByPageState = createStateV2<
|
||||
Map<string, MorphItem[]>
|
||||
>({
|
||||
key: 'command-menu/commandMenuNavigationMorphItemsByPageState',
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
|
||||
import { type CommandMenuPages } from 'twenty-shared/types';
|
||||
import { type IconComponent } from 'twenty-ui/display';
|
||||
|
||||
@@ -10,7 +10,7 @@ export type CommandMenuNavigationStackItem = {
|
||||
pageId: string;
|
||||
};
|
||||
|
||||
export const commandMenuNavigationStackState = createState<
|
||||
export const commandMenuNavigationStackState = createStateV2<
|
||||
CommandMenuNavigationStackItem[]
|
||||
>({
|
||||
key: 'command-menu/commandMenuNavigationStackState',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { type IconComponent } from 'twenty-ui/display';
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
|
||||
|
||||
export const commandMenuPageInfoState = createState<{
|
||||
export const commandMenuPageInfoState = createStateV2<{
|
||||
title?: string;
|
||||
Icon?: IconComponent;
|
||||
instanceId: string;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
|
||||
export const commandMenuPageState = createState<CommandMenuPages>({
|
||||
export const commandMenuPageState = createStateV2<CommandMenuPages>({
|
||||
key: 'command-menu/commandMenuPageState',
|
||||
defaultValue: CommandMenuPages.Root,
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
export const commandMenuSearchState = createState<string>({
|
||||
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
|
||||
export const commandMenuSearchState = createStateV2<string>({
|
||||
key: 'command-menu/commandMenuSearchState',
|
||||
defaultValue: '',
|
||||
});
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
|
||||
|
||||
import { CommandMenuPageComponentInstanceContext } from './contexts/CommandMenuPageComponentInstanceContext';
|
||||
|
||||
export const commandMenuShouldFocusTitleInputComponentState =
|
||||
createComponentState<boolean>({
|
||||
createComponentStateV2<boolean>({
|
||||
key: 'commandMenuShouldFocusTitleInputComponentState',
|
||||
defaultValue: false,
|
||||
componentInstanceContext: CommandMenuPageComponentInstanceContext,
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import { atom } from 'recoil';
|
||||
|
||||
import { COMMAND_MENU_CONSTRAINTS } from '@/ui/layout/resizable-panel/constants/CommandMenuConstraints';
|
||||
import { localStorageEffect } from '~/utils/recoil/localStorageEffect';
|
||||
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
|
||||
|
||||
export const COMMAND_MENU_WIDTH_VAR = '--command-menu-width';
|
||||
|
||||
export const commandMenuWidthState = atom<number>({
|
||||
export const commandMenuWidthState = createStateV2<number>({
|
||||
key: 'commandMenuWidth',
|
||||
default: COMMAND_MENU_CONSTRAINTS.default,
|
||||
effects: [localStorageEffect()],
|
||||
defaultValue: COMMAND_MENU_CONSTRAINTS.default,
|
||||
useLocalStorage: true,
|
||||
});
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
export const hasUserSelectedCommandState = createState({
|
||||
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
|
||||
export const hasUserSelectedCommandState = createStateV2({
|
||||
key: 'hasUserSelectedCommandState',
|
||||
defaultValue: false,
|
||||
});
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user