diff --git a/packages/twenty-front/src/localization/states/dateLocaleStateV2.ts b/packages/twenty-front/src/localization/states/dateLocaleState.ts similarity index 80% rename from packages/twenty-front/src/localization/states/dateLocaleStateV2.ts rename to packages/twenty-front/src/localization/states/dateLocaleState.ts index 778c14e4b3..09ad6457e4 100644 --- a/packages/twenty-front/src/localization/states/dateLocaleStateV2.ts +++ b/packages/twenty-front/src/localization/states/dateLocaleState.ts @@ -9,8 +9,8 @@ type DateLocaleState = { localeCatalog: Locale; }; -export const dateLocaleStateV2 = createStateV2({ - key: 'dateLocaleStateV2', +export const dateLocaleState = createStateV2({ + key: 'dateLocaleState', defaultValue: { locale: undefined, localeCatalog: enUS, diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/run-workflow-actions/hooks/useRunWorkflowRecordActions.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/run-workflow-actions/hooks/useRunWorkflowRecordActions.tsx index 78d333a52c..8974a381bb 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/run-workflow-actions/hooks/useRunWorkflowRecordActions.tsx +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/run-workflow-actions/hooks/useRunWorkflowRecordActions.tsx @@ -7,7 +7,6 @@ import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/s import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useRecordIndexIdFromCurrentContextStore } from '@/object-record/record-index/hooks/useRecordIndexIdFromCurrentContextStore'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2'; import { useActiveWorkflowVersionsWithManualTrigger } from '@/workflow/hooks/useActiveWorkflowVersionsWithManualTrigger'; @@ -20,6 +19,7 @@ import { useCallback } from 'react'; import { QUERY_MAX_RECORDS } from 'twenty-shared/constants'; import { capitalize, isDefined } from 'twenty-shared/utils'; import { useIcons } from 'twenty-ui/display'; +import { useStore } from 'jotai'; export const useRunWorkflowRecordActions = ({ objectMetadataItem, @@ -28,6 +28,7 @@ export const useRunWorkflowRecordActions = ({ objectMetadataItem: ObjectMetadataItem; skip?: boolean; }) => { + const store = useStore(); const { getIcon } = useIcons(); const { enqueueWarningSnackBar } = useSnackBar(); const { recordIndexId } = useRecordIndexIdFromCurrentContextStore(); @@ -88,7 +89,7 @@ export const useRunWorkflowRecordActions = ({ const objectNamePlural = objectMetadataItem.namePlural; const selectedRecords = limitedSelectedRecordIds .map((recordId) => - jotaiStore.get(recordStoreFamilyState.atomFamily(recordId)), + store.get(recordStoreFamilyState.atomFamily(recordId)), ) .filter(isDefined); @@ -101,7 +102,7 @@ export const useRunWorkflowRecordActions = ({ }); } else { for (const selectedRecordId of limitedSelectedRecordIds) { - const selectedRecord = jotaiStore.get( + const selectedRecord = store.get( recordStoreFamilyState.atomFamily(selectedRecordId), ); @@ -117,7 +118,7 @@ export const useRunWorkflowRecordActions = ({ } } }, - [runWorkflowVersion, objectMetadataItem, enqueueWarningSnackBar], + [runWorkflowVersion, objectMetadataItem, enqueueWarningSnackBar, store], ); return activeWorkflowVersions diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useSelectedRecordIdOrThrow.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useSelectedRecordIdOrThrow.tsx index 605409f1e1..a5bc5a5ebd 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useSelectedRecordIdOrThrow.tsx +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useSelectedRecordIdOrThrow.tsx @@ -1,13 +1,9 @@ import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState'; -import { useRecordIndexIdFromCurrentContextStore } from '@/object-record/record-index/hooks/useRecordIndexIdFromCurrentContextStore'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2'; export const useSelectedRecordIdOrThrow = () => { - const { recordIndexId } = useRecordIndexIdFromCurrentContextStore(); - const contextStoreTargetedRecordsRule = useRecoilComponentValueV2( contextStoreTargetedRecordsRuleComponentState, - recordIndexId, ); if ( diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useSelectedRecordIds.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useSelectedRecordIds.tsx index 683358c4a5..2395e90219 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useSelectedRecordIds.tsx +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/hooks/useSelectedRecordIds.tsx @@ -1,13 +1,9 @@ import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState'; -import { useRecordIndexIdFromCurrentContextStore } from '@/object-record/record-index/hooks/useRecordIndexIdFromCurrentContextStore'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2'; export const useSelectedRecordIds = () => { - const { recordIndexId } = useRecordIndexIdFromCurrentContextStore(); - const contextStoreTargetedRecordsRule = useRecoilComponentValueV2( contextStoreTargetedRecordsRuleComponentState, - recordIndexId, ); if ( diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/components/TidyUpWorkflowSingleRecordAction.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/components/TidyUpWorkflowSingleRecordAction.tsx index 20ec531a59..9bbc355527 100644 --- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/components/TidyUpWorkflowSingleRecordAction.tsx +++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/workflow-actions/components/TidyUpWorkflowSingleRecordAction.tsx @@ -4,10 +4,11 @@ import { useGetUpdatableWorkflowVersionOrThrow } from '@/workflow/hooks/useGetUp import { getWorkflowVisualizerComponentInstanceId } from '@/workflow/utils/getWorkflowVisualizerComponentInstanceId'; import { workflowDiagramComponentState } from '@/workflow/workflow-diagram/states/workflowDiagramComponentState'; import { useTidyUpWorkflowVersion } from '@/workflow/workflow-version/hooks/useTidyUpWorkflowVersion'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { isDefined } from 'twenty-shared/utils'; +import { useStore } from 'jotai'; export const TidyUpWorkflowSingleRecordAction = () => { + const store = useStore(); const recordId = useSelectedRecordIdOrThrow(); const { tidyUpWorkflowVersion } = useTidyUpWorkflowVersion(); const instanceId = getWorkflowVisualizerComponentInstanceId({ @@ -20,7 +21,7 @@ export const TidyUpWorkflowSingleRecordAction = () => { const workflowDiagramAtom = workflowDiagramComponentState.atomFamily({ instanceId, }); - const workflowDiagram = jotaiStore.get(workflowDiagramAtom); + const workflowDiagram = store.get(workflowDiagramAtom); if (!isDefined(workflowDiagram)) { return; diff --git a/packages/twenty-front/src/modules/action-menu/hooks/useShouldActionBeRegisteredParams.ts b/packages/twenty-front/src/modules/action-menu/hooks/useShouldActionBeRegisteredParams.ts index 5b98c56e3d..07a28ae548 100644 --- a/packages/twenty-front/src/modules/action-menu/hooks/useShouldActionBeRegisteredParams.ts +++ b/packages/twenty-front/src/modules/action-menu/hooks/useShouldActionBeRegisteredParams.ts @@ -21,17 +21,18 @@ import { useRecoilComponentSelectorValueV2 } from '@/ui/utilities/state/jotai/ho import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2'; import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2'; import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; import { useCallback, useContext, useMemo } from 'react'; import { isDefined } from 'twenty-shared/utils'; import { FeatureFlagKey } from '~/generated-metadata/graphql'; +import { useStore } from 'jotai'; export const useShouldActionBeRegisteredParams = ({ objectMetadataItem, }: { objectMetadataItem?: ObjectMetadataItem; }): ShouldBeRegisteredFunctionParams => { + const store = useStore(); const { sortedFavorites: favorites } = useFavorites(); const { navigationMenuItems } = usePrefetchedNavigationMenuItemsData(); const isNavigationMenuItemEditingEnabled = useIsFeatureEnabled( @@ -119,24 +120,24 @@ export const useShouldActionBeRegisteredParams = ({ const getObjectReadPermission = useCallback( (objectMetadataNameSingular: string) => { - return jotaiStore.get( + return store.get( objectPermissionsFamilySelector.selectorFamily({ objectNameSingular: objectMetadataNameSingular, }), ).canRead; }, - [], + [store], ); const getObjectWritePermission = useCallback( (objectMetadataNameSingular: string) => { - return jotaiStore.get( + return store.get( objectPermissionsFamilySelector.selectorFamily({ objectNameSingular: objectMetadataNameSingular, }), ).canUpdate; }, - [], + [store], ); const forceRegisteredActionsByKey = useRecoilValueV2( diff --git a/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventsCard.tsx b/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventsCard.tsx index 622ce272c4..b6b91017de 100644 --- a/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventsCard.tsx +++ b/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventsCard.tsx @@ -26,7 +26,7 @@ import { Section, } from 'twenty-ui/layout'; import { type TimelineCalendarEventsWithTotal } from '~/generated/graphql'; -import { dateLocaleStateV2 } from '~/localization/states/dateLocaleStateV2'; +import { dateLocaleState } from '~/localization/states/dateLocaleState'; const StyledContainer = styled.div` box-sizing: border-box; @@ -49,7 +49,7 @@ const StyledTitleContainer = styled.div` export const CalendarEventsCard = () => { const { t } = useLingui(); const targetRecord = useTargetRecord(); - const { localeCatalog } = useRecoilValueV2(dateLocaleStateV2); + const { localeCatalog } = useRecoilValueV2(dateLocaleState); const [query, queryName] = targetRecord.targetObjectNameSingular === CoreObjectNameSingular.Person diff --git a/packages/twenty-front/src/modules/activities/emails/components/EmailThreadHeader.tsx b/packages/twenty-front/src/modules/activities/emails/components/EmailThreadHeader.tsx index ce026d9445..6fa88d5c3f 100644 --- a/packages/twenty-front/src/modules/activities/emails/components/EmailThreadHeader.tsx +++ b/packages/twenty-front/src/modules/activities/emails/components/EmailThreadHeader.tsx @@ -2,7 +2,7 @@ import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValu import styled from '@emotion/styled'; import { t } from '@lingui/core/macro'; -import { dateLocaleStateV2 } from '~/localization/states/dateLocaleStateV2'; +import { dateLocaleState } from '~/localization/states/dateLocaleState'; import { beautifyPastDateRelativeToNow } from '~/utils/date-utils'; type EmailThreadHeaderProps = { @@ -43,7 +43,7 @@ export const EmailThreadHeader = ({ subject, lastMessageSentAt, }: EmailThreadHeaderProps) => { - const { localeCatalog } = useRecoilValueV2(dateLocaleStateV2); + const { localeCatalog } = useRecoilValueV2(dateLocaleState); const lastMessageSentAtFormatted = beautifyPastDateRelativeToNow( lastMessageSentAt, localeCatalog, diff --git a/packages/twenty-front/src/modules/activities/emails/components/EmailThreadMessageSender.tsx b/packages/twenty-front/src/modules/activities/emails/components/EmailThreadMessageSender.tsx index 02bb62e67e..c0147a8ebe 100644 --- a/packages/twenty-front/src/modules/activities/emails/components/EmailThreadMessageSender.tsx +++ b/packages/twenty-front/src/modules/activities/emails/components/EmailThreadMessageSender.tsx @@ -4,7 +4,7 @@ import { ParticipantChip } from '@/activities/components/ParticipantChip'; import { type EmailThreadMessageParticipant } from '@/activities/emails/types/EmailThreadMessageParticipant'; import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { AppTooltip, TooltipPosition } from 'twenty-ui/display'; -import { dateLocaleStateV2 } from '~/localization/states/dateLocaleStateV2'; +import { dateLocaleState } from '~/localization/states/dateLocaleState'; import { beautifyPastDateRelativeToNow, formatToHumanReadableDate, @@ -31,7 +31,7 @@ export const EmailThreadMessageSender = ({ sender, sentAt, }: EmailThreadMessageSenderProps) => { - const { localeCatalog } = useRecoilValueV2(dateLocaleStateV2); + const { localeCatalog } = useRecoilValueV2(dateLocaleState); const tooltipId = `date-tooltip-${sentAt.replace(/[^a-zA-Z0-9]/g, '-')}`; return ( diff --git a/packages/twenty-front/src/modules/activities/inline-cell/hooks/useOpenActivityTargetCellEditMode.ts b/packages/twenty-front/src/modules/activities/inline-cell/hooks/useOpenActivityTargetCellEditMode.ts index 2334762e28..a99ec42bea 100644 --- a/packages/twenty-front/src/modules/activities/inline-cell/hooks/useOpenActivityTargetCellEditMode.ts +++ b/packages/twenty-front/src/modules/activities/inline-cell/hooks/useOpenActivityTargetCellEditMode.ts @@ -1,6 +1,5 @@ import { type ActivityTargetWithTargetRecord } from '@/activities/types/ActivityTargetObject'; import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { useMultipleRecordPickerOpen } from '@/object-record/record-picker/multiple-record-picker/hooks/useMultipleRecordPickerOpen'; import { useMultipleRecordPickerPerformSearch } from '@/object-record/record-picker/multiple-record-picker/hooks/useMultipleRecordPickerPerformSearch'; @@ -10,6 +9,7 @@ import { multipleRecordPickerSearchableObjectMetadataItemsComponentState } from import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePushFocusItemToFocusStack'; import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType'; import { useCallback } from 'react'; +import { useStore } from 'jotai'; type OpenActivityTargetCellEditModeProps = { recordPickerInstanceId: string; @@ -18,6 +18,7 @@ type OpenActivityTargetCellEditModeProps = { // TODO: deprecate this once we are supporting one to many through relations export const useOpenActivityTargetCellEditMode = () => { + const store = useStore(); const { performSearch: multipleRecordPickerPerformSearch } = useMultipleRecordPickerPerformSearch(); const { openMultipleRecordPicker } = useMultipleRecordPickerOpen(); @@ -29,7 +30,7 @@ export const useOpenActivityTargetCellEditMode = () => { recordPickerInstanceId, activityTargetObjectRecords, }: OpenActivityTargetCellEditModeProps) => { - const objectMetadataItems = jotaiStore + const objectMetadataItems = store .get(objectMetadataItemsState.atom) .filter( (objectMetadataItem) => @@ -41,7 +42,7 @@ export const useOpenActivityTargetCellEditMode = () => { CoreObjectNameSingular.WorkspaceMember, ); - jotaiStore.set( + store.set( multipleRecordPickerPickableMorphItemsComponentState.atomFamily({ instanceId: recordPickerInstanceId, }), @@ -54,7 +55,7 @@ export const useOpenActivityTargetCellEditMode = () => { })), ); - jotaiStore.set( + store.set( multipleRecordPickerSearchableObjectMetadataItemsComponentState.atomFamily( { instanceId: recordPickerInstanceId, @@ -63,7 +64,7 @@ export const useOpenActivityTargetCellEditMode = () => { objectMetadataItems, ); - jotaiStore.set( + store.set( multipleRecordPickerSearchFilterComponentState.atomFamily({ instanceId: recordPickerInstanceId, }), @@ -102,6 +103,7 @@ export const useOpenActivityTargetCellEditMode = () => { multipleRecordPickerPerformSearch, openMultipleRecordPicker, pushFocusItemToFocusStack, + store, ], ); diff --git a/packages/twenty-front/src/modules/activities/timeline-activities/components/EventRow.tsx b/packages/twenty-front/src/modules/activities/timeline-activities/components/EventRow.tsx index f0dca9899e..0f1306ccec 100644 --- a/packages/twenty-front/src/modules/activities/timeline-activities/components/EventRow.tsx +++ b/packages/twenty-front/src/modules/activities/timeline-activities/components/EventRow.tsx @@ -14,7 +14,7 @@ import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataI import { getObjectRecordIdentifier } from '@/object-metadata/utils/getObjectRecordIdentifier'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2'; -import { dateLocaleStateV2 } from '~/localization/states/dateLocaleStateV2'; +import { dateLocaleState } from '~/localization/states/dateLocaleState'; import { beautifyPastDateRelativeToNow } from '~/utils/date-utils'; import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull'; import { allowRequestsToTwentyIconsState } from '@/client-config/states/allowRequestsToTwentyIcons'; @@ -99,7 +99,7 @@ export const EventRow = ({ allowRequestsToTwentyIconsState, ); - const { localeCatalog } = useRecoilValueV2(dateLocaleStateV2); + const { localeCatalog } = useRecoilValueV2(dateLocaleState); const { recordId } = useContext(TimelineActivityContext); diff --git a/packages/twenty-front/src/modules/ai/components/AIChatMessage.tsx b/packages/twenty-front/src/modules/ai/components/AIChatMessage.tsx index fb19f44013..14685ac5aa 100644 --- a/packages/twenty-front/src/modules/ai/components/AIChatMessage.tsx +++ b/packages/twenty-front/src/modules/ai/components/AIChatMessage.tsx @@ -9,7 +9,7 @@ import { LightCopyIconButton } from '@/object-record/record-field/ui/components/ import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { type ExtendedUIMessage } from 'twenty-shared/ai'; import { isDefined } from 'twenty-shared/utils'; -import { dateLocaleStateV2 } from '~/localization/states/dateLocaleStateV2'; +import { dateLocaleState } from '~/localization/states/dateLocaleState'; import { beautifyPastDateRelativeToNow } from '~/utils/date-utils'; const StyledMessageBubble = styled.div<{ isUser?: boolean }>` @@ -141,7 +141,7 @@ export const AIChatMessage = ({ isLastMessageStreaming: boolean; error?: Error | null; }) => { - const { localeCatalog } = useRecoilValueV2(dateLocaleStateV2); + const { localeCatalog } = useRecoilValueV2(dateLocaleState); const isUser = message.role === AgentMessageRole.USER; const showError = diff --git a/packages/twenty-front/src/modules/app/components/App.tsx b/packages/twenty-front/src/modules/app/components/App.tsx index f43239740a..1a138d54a8 100644 --- a/packages/twenty-front/src/modules/app/components/App.tsx +++ b/packages/twenty-front/src/modules/app/components/App.tsx @@ -6,9 +6,9 @@ import { AppRootErrorFallback } from '@/error-handler/components/AppRootErrorFal import { ExceptionHandlerProvider } from '@/error-handler/components/ExceptionHandlerProvider'; import { SnackBarComponentInstanceContext } from '@/ui/feedback/snack-bar-manager/contexts/SnackBarComponentInstanceContext'; import { ClickOutsideListenerContext } from '@/ui/utilities/pointer-event/contexts/ClickOutsideListenerContext'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { i18n } from '@lingui/core'; import { I18nProvider } from '@lingui/react'; +import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { Provider as JotaiProvider } from 'jotai'; import { HelmetProvider } from 'react-helmet-async'; import { RecoilRoot } from 'recoil'; diff --git a/packages/twenty-front/src/modules/app/effect-components/PageChangeEffect.tsx b/packages/twenty-front/src/modules/app/effect-components/PageChangeEffect.tsx index 459ef643b4..1582a1cc50 100644 --- a/packages/twenty-front/src/modules/app/effect-components/PageChangeEffect.tsx +++ b/packages/twenty-front/src/modules/app/effect-components/PageChangeEffect.tsx @@ -35,7 +35,6 @@ import { PageFocusId } from '@/types/PageFocusId'; import { useResetFocusStackToFocusItem } from '@/ui/utilities/focus/hooks/useResetFocusStackToFocusItem'; import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { AppBasePath, AppPath, CommandMenuPages } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; import { AnalyticsType } from '~/generated-metadata/graphql'; @@ -43,10 +42,12 @@ import { usePageChangeEffectNavigateLocation } from '~/hooks/usePageChangeEffect import { useInitializeQueryParamState } from '~/modules/app/hooks/useInitializeQueryParamState'; import { isMatchingLocation } from '~/utils/isMatchingLocation'; import { getPageTitleFromPath } from '~/utils/title-utils'; +import { useStore } from 'jotai'; // TODO: break down into smaller functions and / or hooks // - moved usePageChangeEffectNavigateLocation into dedicated hook export const PageChangeEffect = () => { + const store = useStore(); const navigate = useNavigate(); const [previousLocation, setPreviousLocation] = useState(''); @@ -99,12 +100,12 @@ export const PageChangeEffect = () => { const { closeCommandMenu } = useCommandMenu(); const closeCommandMenuUnlessOnEditPage = useCallback(() => { - const currentPage = jotaiStore.get(commandMenuPageState.atom); + const currentPage = store.get(commandMenuPageState.atom); if (currentPage === CommandMenuPages.NavigationMenuItemEdit) { return; } closeCommandMenu(); - }, [closeCommandMenu]); + }, [closeCommandMenu, store]); const { resetFocusStackToFocusItem } = useResetFocusStackToFocusItem(); diff --git a/packages/twenty-front/src/modules/app/hooks/useExecuteTasksOnAnyLocationChange.ts b/packages/twenty-front/src/modules/app/hooks/useExecuteTasksOnAnyLocationChange.ts index a7c5b36bbe..547edf21a7 100644 --- a/packages/twenty-front/src/modules/app/hooks/useExecuteTasksOnAnyLocationChange.ts +++ b/packages/twenty-front/src/modules/app/hooks/useExecuteTasksOnAnyLocationChange.ts @@ -1,7 +1,6 @@ import { MAIN_CONTEXT_STORE_INSTANCE_ID } from '@/context-store/constants/MainContextStoreInstanceId'; import { contextStoreIsPageInEditModeComponentState } from '@/context-store/states/contextStoreIsPageInEditModeComponentState'; import { currentPageLayoutIdState } from '@/page-layout/states/currentPageLayoutIdState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { hasInitializedFieldsWidgetGroupsDraftComponentState } from '@/page-layout/states/hasInitializedFieldsWidgetGroupsDraftComponentState'; import { isPageLayoutInEditModeComponentState } from '@/page-layout/states/isPageLayoutInEditModeComponentState'; import { pageLayoutCurrentLayoutsComponentState } from '@/page-layout/states/pageLayoutCurrentLayoutsComponentState'; @@ -12,22 +11,24 @@ import { convertPageLayoutToTabLayouts } from '@/page-layout/utils/convertPageLa import { useCloseAnyOpenDropdown } from '@/ui/layout/dropdown/hooks/useCloseAnyOpenDropdown'; import { useCallback } from 'react'; import { isDefined } from 'twenty-shared/utils'; +import { useStore } from 'jotai'; export const useExecuteTasksOnAnyLocationChange = () => { + const store = useStore(); const { closeAnyOpenDropdown } = useCloseAnyOpenDropdown(); const resetPageLayoutEditMode = useCallback(() => { - const pageLayoutId = jotaiStore.get(currentPageLayoutIdState.atom); + const pageLayoutId = store.get(currentPageLayoutIdState.atom); if (isDefined(pageLayoutId)) { - const pageLayoutPersisted = jotaiStore.get( + const pageLayoutPersisted = store.get( pageLayoutPersistedComponentState.atomFamily({ instanceId: pageLayoutId, }), ); if (isDefined(pageLayoutPersisted)) { - jotaiStore.set( + store.set( pageLayoutDraftComponentState.atomFamily({ instanceId: pageLayoutId, }), @@ -41,7 +42,7 @@ export const useExecuteTasksOnAnyLocationChange = () => { ); const tabLayouts = convertPageLayoutToTabLayouts(pageLayoutPersisted); - jotaiStore.set( + store.set( pageLayoutCurrentLayoutsComponentState.atomFamily({ instanceId: pageLayoutId, }), @@ -49,37 +50,37 @@ export const useExecuteTasksOnAnyLocationChange = () => { ); } - jotaiStore.set( + store.set( isPageLayoutInEditModeComponentState.atomFamily({ instanceId: pageLayoutId, }), false, ); - jotaiStore.set( + store.set( pageLayoutIsInitializedComponentState.atomFamily({ instanceId: pageLayoutId, }), false, ); - jotaiStore.set( + store.set( hasInitializedFieldsWidgetGroupsDraftComponentState.atomFamily({ instanceId: pageLayoutId, }), {}, ); - jotaiStore.set(currentPageLayoutIdState.atom, null); + store.set(currentPageLayoutIdState.atom, null); } - jotaiStore.set( + store.set( contextStoreIsPageInEditModeComponentState.atomFamily({ instanceId: MAIN_CONTEXT_STORE_INSTANCE_ID, }), false, ); - }, []); + }, [store]); /** * Be careful to put idempotent tasks here. diff --git a/packages/twenty-front/src/modules/app/hooks/useInitializeQueryParamState.ts b/packages/twenty-front/src/modules/app/hooks/useInitializeQueryParamState.ts index 7f84ba7a5f..afba3cfc92 100644 --- a/packages/twenty-front/src/modules/app/hooks/useInitializeQueryParamState.ts +++ b/packages/twenty-front/src/modules/app/hooks/useInitializeQueryParamState.ts @@ -3,16 +3,17 @@ import { useCallback } from 'react'; import { billingCheckoutSessionState } from '@/auth/states/billingCheckoutSessionState'; import { type BillingCheckoutSession } from '@/auth/types/billingCheckoutSession.type'; import { BILLING_CHECKOUT_SESSION_DEFAULT_VALUE } from '@/billing/constants/BillingCheckoutSessionDefaultValue'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import deepEqual from 'deep-equal'; +import { useStore } from 'jotai'; // Initialize state that are hydrated from query parameters // We used to use recoil-sync to do this, but it was causing issues with Firefox export const useInitializeQueryParamState = () => { + const store = useStore(); const initializeQueryParamState = useCallback(() => { const handlers = { billingCheckoutSession: (value: string) => { - const billingCheckoutSession = jotaiStore.get( + const billingCheckoutSession = store.get( billingCheckoutSessionState.atom, ); @@ -27,7 +28,7 @@ export const useInitializeQueryParamState = () => { 'requirePaymentMethod' in parsedValue && !deepEqual(billingCheckoutSession, parsedValue) ) { - jotaiStore.set( + store.set( billingCheckoutSessionState.atom, parsedValue as BillingCheckoutSession, ); @@ -38,7 +39,7 @@ export const useInitializeQueryParamState = () => { 'Failed to parse billingCheckoutSession from URL', error, ); - jotaiStore.set( + store.set( billingCheckoutSessionState.atom, BILLING_CHECKOUT_SESSION_DEFAULT_VALUE, ); @@ -54,7 +55,7 @@ export const useInitializeQueryParamState = () => { handler(value); } } - }, []); + }, [store]); return { initializeQueryParamState }; }; diff --git a/packages/twenty-front/src/modules/auth/components/VerifyLoginTokenEffect.tsx b/packages/twenty-front/src/modules/auth/components/VerifyLoginTokenEffect.tsx index cb2cb48db7..006ef62255 100644 --- a/packages/twenty-front/src/modules/auth/components/VerifyLoginTokenEffect.tsx +++ b/packages/twenty-front/src/modules/auth/components/VerifyLoginTokenEffect.tsx @@ -22,7 +22,9 @@ export const VerifyLoginTokenEffect = () => { ); useEffect(() => { - if (!clientConfigLoaded) return; + if (!clientConfigLoaded) { + return; + } if (isDefined(loginToken)) { verifyLoginToken(loginToken); diff --git a/packages/twenty-front/src/modules/auth/hooks/useAuth.ts b/packages/twenty-front/src/modules/auth/hooks/useAuth.ts index d7760142bb..bdb5d51932 100644 --- a/packages/twenty-front/src/modules/auth/hooks/useAuth.ts +++ b/packages/twenty-front/src/modules/auth/hooks/useAuth.ts @@ -21,7 +21,6 @@ import { import { tokenPairState } from '@/auth/states/tokenPairState'; 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 { isAppEffectRedirectEnabledState } from '@/app/states/isAppEffectRedirectEnabledState'; import { availableWorkspacesState } from '@/auth/states/availableWorkspacesState'; @@ -63,8 +62,10 @@ import { SOURCE_LOCALE } from 'twenty-shared/translations'; import { isDefined } from 'twenty-shared/utils'; import { cookieStorage } from '~/utils/cookie-storage'; import { getWorkspaceUrl } from '~/utils/getWorkspaceUrl'; +import { useStore } from 'jotai'; export const useAuth = () => { + const store = useStore(); const setTokenPair = useSetRecoilStateV2(tokenPairState); const setLoginToken = useSetRecoilStateV2(loginTokenState); const setIsAppEffectRedirectEnabled = useSetRecoilStateV2( @@ -119,23 +120,19 @@ export const useAuth = () => { const navigate = useNavigate(); const clearSession = useCallback(async () => { - const sseClient = jotaiStore.get(sseClientState.atom); + const sseClient = store.get(sseClientState.atom); sseClient?.dispose(); const emptySnapshot = snapshot_UNSTABLE(); - const authProvidersValue = jotaiStore.get(workspaceAuthProvidersState.atom); - const domainConfigurationValue = jotaiStore.get( - domainConfigurationState.atom, - ); - const workspacePublicDataValue = jotaiStore.get( - workspacePublicDataState.atom, - ); - const lastAuthenticatedMethod = jotaiStore.get( + const authProvidersValue = store.get(workspaceAuthProvidersState.atom); + const domainConfigurationValue = store.get(domainConfigurationState.atom); + const workspacePublicDataValue = store.get(workspacePublicDataState.atom); + const lastAuthenticatedMethod = store.get( lastAuthenticatedMethodState.atom, ); - const isCaptchaScriptLoadedValue = jotaiStore.get( + const isCaptchaScriptLoadedValue = store.get( isCaptchaScriptLoadedState.atom, ); @@ -148,27 +145,27 @@ export const useAuth = () => { goToRecoilSnapshot(initialSnapshot); - jotaiStore.set(workspaceAuthProvidersState.atom, authProvidersValue); - jotaiStore.set(workspacePublicDataState.atom, workspacePublicDataValue); - jotaiStore.set(domainConfigurationState.atom, domainConfigurationValue); - jotaiStore.set(isCaptchaScriptLoadedState.atom, isCaptchaScriptLoadedValue); - jotaiStore.set(lastAuthenticatedMethodState.atom, lastAuthenticatedMethod); + store.set(workspaceAuthProvidersState.atom, authProvidersValue); + store.set(workspacePublicDataState.atom, workspacePublicDataValue); + store.set(domainConfigurationState.atom, domainConfigurationValue); + store.set(isCaptchaScriptLoadedState.atom, isCaptchaScriptLoadedValue); + store.set(lastAuthenticatedMethodState.atom, lastAuthenticatedMethod); // Reset user-data Jotai states that were migrated from Recoil // (Recoil snapshot reset no longer handles these since they are Jotai V2) - jotaiStore.set(tokenPairState.atom, null); - jotaiStore.set(currentUserState.atom, null); - jotaiStore.set(currentWorkspaceState.atom, null); - jotaiStore.set(currentUserWorkspaceState.atom, null); - jotaiStore.set(currentWorkspaceMemberState.atom, null); - jotaiStore.set(currentWorkspaceMembersState.atom, []); - jotaiStore.set(availableWorkspacesState.atom, { + store.set(tokenPairState.atom, null); + store.set(currentUserState.atom, null); + store.set(currentWorkspaceState.atom, null); + store.set(currentUserWorkspaceState.atom, null); + store.set(currentWorkspaceMemberState.atom, null); + store.set(currentWorkspaceMembersState.atom, []); + store.set(availableWorkspacesState.atom, { availableWorkspacesForSignIn: [], availableWorkspacesForSignUp: [], }); - jotaiStore.set(loginTokenState.atom, null); - jotaiStore.set(signInUpStepState.atom, SignInUpStep.Init); - jotaiStore.set(coreViewsState.atom, []); + store.set(loginTokenState.atom, null); + store.set(signInUpStepState.atom, SignInUpStep.Init); + store.set(coreViewsState.atom, []); await client.clearStore(); setLastAuthenticateWorkspaceDomain(null); @@ -180,6 +177,7 @@ export const useAuth = () => { setLastAuthenticateWorkspaceDomain, resetToMockedMetadata, navigate, + store, ]); const handleSetAuthTokens = useCallback( diff --git a/packages/twenty-front/src/modules/captcha/hooks/useReadCaptchaToken.ts b/packages/twenty-front/src/modules/captcha/hooks/useReadCaptchaToken.ts index 64488e359f..95094a6f1f 100644 --- a/packages/twenty-front/src/modules/captcha/hooks/useReadCaptchaToken.ts +++ b/packages/twenty-front/src/modules/captcha/hooks/useReadCaptchaToken.ts @@ -1,16 +1,17 @@ import { captchaTokenState } from '@/captcha/states/captchaTokenState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useCallback } from 'react'; import { isDefined } from 'twenty-shared/utils'; +import { useStore } from 'jotai'; export const useReadCaptchaToken = () => { + const store = useStore(); const readCaptchaToken = useCallback(() => { - const existingCaptchaToken = jotaiStore.get(captchaTokenState.atom); + const existingCaptchaToken = store.get(captchaTokenState.atom); if (isDefined(existingCaptchaToken)) { return existingCaptchaToken; } - }, []); + }, [store]); return { readCaptchaToken }; }; diff --git a/packages/twenty-front/src/modules/captcha/hooks/useRequestFreshCaptchaToken.ts b/packages/twenty-front/src/modules/captcha/hooks/useRequestFreshCaptchaToken.ts index 51eed388b9..1b0802f1b4 100644 --- a/packages/twenty-front/src/modules/captcha/hooks/useRequestFreshCaptchaToken.ts +++ b/packages/twenty-front/src/modules/captcha/hooks/useRequestFreshCaptchaToken.ts @@ -3,12 +3,13 @@ import { isRequestingCaptchaTokenState } from '@/captcha/states/isRequestingCapt import { isCaptchaRequiredForPath } from '@/captcha/utils/isCaptchaRequiredForPath'; import { captchaState } from '@/client-config/states/captchaState'; import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useCallback } from 'react'; import { assertIsDefinedOrThrow, isDefined } from 'twenty-shared/utils'; import { CaptchaDriverType } from '~/generated-metadata/graphql'; +import { useStore } from 'jotai'; export const useRequestFreshCaptchaToken = () => { + const store = useStore(); const setCaptchaToken = useSetRecoilStateV2(captchaTokenState); const setIsRequestingCaptchaToken = useSetRecoilStateV2( isRequestingCaptchaTokenState, @@ -19,7 +20,7 @@ export const useRequestFreshCaptchaToken = () => { return; } - const captcha = jotaiStore.get(captchaState.atom); + const captcha = store.get(captchaState.atom); if (!isDefined(captcha)) { return; @@ -52,7 +53,7 @@ export const useRequestFreshCaptchaToken = () => { }, }); } - }, [setCaptchaToken, setIsRequestingCaptchaToken]); + }, [setCaptchaToken, setIsRequestingCaptchaToken, store]); return { requestFreshCaptchaToken }; }; diff --git a/packages/twenty-front/src/modules/client-config/hooks/useClientConfig.ts b/packages/twenty-front/src/modules/client-config/hooks/useClientConfig.ts index df79dc97f6..839d10f19e 100644 --- a/packages/twenty-front/src/modules/client-config/hooks/useClientConfig.ts +++ b/packages/twenty-front/src/modules/client-config/hooks/useClientConfig.ts @@ -33,7 +33,7 @@ import { getClientConfig } from '@/client-config/utils/getClientConfig'; import { allowRequestsToTwentyIconsState } from '@/client-config/states/allowRequestsToTwentyIcons'; import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; +import { useStore } from 'jotai'; type UseClientConfigResult = { data: { clientConfig: ClientConfig } | undefined; @@ -44,6 +44,7 @@ type UseClientConfigResult = { }; export const useClientConfig = (): UseClientConfigResult => { + const store = useStore(); const setIsAnalyticsEnabled = useSetRecoilStateV2(isAnalyticsEnabledState); const setDomainConfiguration = useSetRecoilStateV2(domainConfigurationState); const setAuthProviders = useSetRecoilStateV2(authProvidersState); @@ -191,7 +192,7 @@ export const useClientConfig = (): UseClientConfigResult => { setGoogleMessagingEnabled(clientConfig?.isGoogleMessagingEnabled); setGoogleCalendarEnabled(clientConfig?.isGoogleCalendarEnabled); setIsAttachmentPreviewEnabled(clientConfig?.isAttachmentPreviewEnabled); - jotaiStore.set( + store.set( isAttachmentPreviewEnabledStateV2.atom, clientConfig?.isAttachmentPreviewEnabled, ); @@ -252,6 +253,7 @@ export const useClientConfig = (): UseClientConfigResult => { setSentryConfig, setSupportChat, setAllowRequestsToTwentyIcons, + store, ]); return { diff --git a/packages/twenty-front/src/modules/command-menu/components/CommandMenuRecordInfo.tsx b/packages/twenty-front/src/modules/command-menu/components/CommandMenuRecordInfo.tsx index 0523302ff1..310d8f6f3f 100644 --- a/packages/twenty-front/src/modules/command-menu/components/CommandMenuRecordInfo.tsx +++ b/packages/twenty-front/src/modules/command-menu/components/CommandMenuRecordInfo.tsx @@ -22,7 +22,7 @@ import { FeatureFlagKey, FieldMetadataType, } from '~/generated-metadata/graphql'; -import { dateLocaleStateV2 } from '~/localization/states/dateLocaleStateV2'; +import { dateLocaleState } from '~/localization/states/dateLocaleState'; import { beautifyPastDateRelativeToNow } from '~/utils/date-utils'; import { CommandMenuPageInfoLayout } from './CommandMenuPageInfoLayout'; @@ -67,7 +67,7 @@ export const CommandMenuRecordInfo = ({ }, ); - const { localeCatalog } = useRecoilValueV2(dateLocaleStateV2); + const { localeCatalog } = useRecoilValueV2(dateLocaleState); const beautifiedCreatedAt = isNonEmptyString(recordCreatedAt) ? beautifyPastDateRelativeToNow(recordCreatedAt, localeCatalog) : ''; diff --git a/packages/twenty-front/src/modules/command-menu/hooks/__tests__/useCommandMenu.test.tsx b/packages/twenty-front/src/modules/command-menu/hooks/__tests__/useCommandMenu.test.tsx index 95bfefcc99..4deb3a4ce6 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/__tests__/useCommandMenu.test.tsx +++ b/packages/twenty-front/src/modules/command-menu/hooks/__tests__/useCommandMenu.test.tsx @@ -1,4 +1,5 @@ import { renderHook } from '@testing-library/react'; +import { Provider as JotaiProvider } from 'jotai'; import { act } from 'react'; import { MemoryRouter } from 'react-router-dom'; import { RecoilRoot } from 'recoil'; @@ -13,14 +14,16 @@ import { CommandMenuPages } from 'twenty-shared/types'; import { IconDotsVertical } from 'twenty-ui/display'; const Wrapper = ({ children }: { children: React.ReactNode }) => ( - - - {children} - - + + + + {children} + + + ); const renderHooks = () => { diff --git a/packages/twenty-front/src/modules/command-menu/hooks/__tests__/useCommandMenuCloseAnimationCompleteCleanup.test.tsx b/packages/twenty-front/src/modules/command-menu/hooks/__tests__/useCommandMenuCloseAnimationCompleteCleanup.test.tsx index 7cc86a6256..0bc53ffe62 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/__tests__/useCommandMenuCloseAnimationCompleteCleanup.test.tsx +++ b/packages/twenty-front/src/modules/command-menu/hooks/__tests__/useCommandMenuCloseAnimationCompleteCleanup.test.tsx @@ -1,4 +1,5 @@ import { renderHook } from '@testing-library/react'; +import { Provider as JotaiProvider } from 'jotai'; import { act } from 'react'; import { MemoryRouter } from 'react-router-dom'; import { RecoilRoot } from 'recoil'; @@ -51,9 +52,11 @@ jest.mock('@/ui/layout/right-drawer/utils/emitSidePanelCloseEvent', () => ({ })); const Wrapper = ({ children }: { children: React.ReactNode }) => ( - - {children} - + + + {children} + + ); describe('useCommandMenuCloseAnimationCompleteCleanup', () => { diff --git a/packages/twenty-front/src/modules/command-menu/hooks/__tests__/useCommandMenuHistory.test.tsx b/packages/twenty-front/src/modules/command-menu/hooks/__tests__/useCommandMenuHistory.test.tsx index 2b63f7a3e2..36fe500dad 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/__tests__/useCommandMenuHistory.test.tsx +++ b/packages/twenty-front/src/modules/command-menu/hooks/__tests__/useCommandMenuHistory.test.tsx @@ -1,4 +1,5 @@ import { renderHook } from '@testing-library/react'; +import { Provider as JotaiProvider } from 'jotai'; import { act } from 'react'; import { MemoryRouter } from 'react-router-dom'; import { RecoilRoot } from 'recoil'; @@ -15,9 +16,11 @@ import { CommandMenuPages } from 'twenty-shared/types'; import { IconList, IconSearch } from 'twenty-ui/display'; const Wrapper = ({ children }: { children: React.ReactNode }) => ( - - {children} - + + + {children} + + ); const renderHooks = () => { diff --git a/packages/twenty-front/src/modules/command-menu/hooks/__tests__/useCommandMenuUpdateNavigationMorphItemsByPage.test.tsx b/packages/twenty-front/src/modules/command-menu/hooks/__tests__/useCommandMenuUpdateNavigationMorphItemsByPage.test.tsx index 10b2bf1514..65693b943f 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/__tests__/useCommandMenuUpdateNavigationMorphItemsByPage.test.tsx +++ b/packages/twenty-front/src/modules/command-menu/hooks/__tests__/useCommandMenuUpdateNavigationMorphItemsByPage.test.tsx @@ -2,6 +2,7 @@ import { useCommandMenuUpdateNavigationMorphItemsByPage } from '@/command-menu/h import { commandMenuNavigationMorphItemsByPageState } from '@/command-menu/states/commandMenuNavigationMorphItemsByPageState'; import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { renderHook } from '@testing-library/react'; +import { Provider as JotaiProvider } from 'jotai'; import { act } from 'react'; import { RecoilRoot } from 'recoil'; @@ -9,7 +10,9 @@ const pageId = 'merge-page-id'; const objectMetadataId = 'company-metadata-id'; const Wrapper = ({ children }: { children: React.ReactNode }) => ( - {children} + + {children} + ); const renderHooks = (initialRecordIds: string[]) => { diff --git a/packages/twenty-front/src/modules/command-menu/hooks/__tests__/useUpdateCommandMenuPageInfo.test.tsx b/packages/twenty-front/src/modules/command-menu/hooks/__tests__/useUpdateCommandMenuPageInfo.test.tsx index 84686295ea..8fd3653bf4 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/__tests__/useUpdateCommandMenuPageInfo.test.tsx +++ b/packages/twenty-front/src/modules/command-menu/hooks/__tests__/useUpdateCommandMenuPageInfo.test.tsx @@ -3,6 +3,7 @@ import { commandMenuNavigationStackState } from '@/command-menu/states/commandMe import { commandMenuPageInfoState } from '@/command-menu/states/commandMenuPageInfoState'; import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { renderHook } from '@testing-library/react'; +import { Provider as JotaiProvider } from 'jotai'; import { act } from 'react'; import { RecoilRoot } from 'recoil'; import { CommandMenuPages } from 'twenty-shared/types'; @@ -24,7 +25,9 @@ const mockedNavigationStack = [ ]; const Wrapper = ({ children }: { children: React.ReactNode }) => ( - {children} + + {children} + ); describe('useUpdateCommandMenuPageInfo', () => { diff --git a/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenu.ts b/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenu.ts index 0740bcfbaa..d7b7314f62 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenu.ts +++ b/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenu.ts @@ -7,13 +7,14 @@ import { addToNavPayloadRegistryStateV2 } from '@/navigation-menu-item/states/ad 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 { useCallback } from 'react'; import { CommandMenuPages } from 'twenty-shared/types'; import { IconDotsVertical } from 'twenty-ui/display'; +import { useStore } from 'jotai'; export const useCommandMenu = () => { + const store = useStore(); const { navigateCommandMenu } = useNavigateCommandMenu(); const { closeAnyOpenDropdown } = useCloseAnyOpenDropdown(); @@ -21,18 +22,18 @@ export const useCommandMenu = () => { useRemoveFocusItemFromFocusStackById(); const closeCommandMenu = useCallback(() => { - const isCommandMenuOpened = jotaiStore.get(isCommandMenuOpenedStateV2.atom); + const isCommandMenuOpened = store.get(isCommandMenuOpenedStateV2.atom); if (isCommandMenuOpened) { - jotaiStore.set(addToNavPayloadRegistryStateV2.atom, new Map()); - jotaiStore.set(isCommandMenuOpenedStateV2.atom, false); - jotaiStore.set(isCommandMenuClosingState.atom, true); + store.set(addToNavPayloadRegistryStateV2.atom, new Map()); + store.set(isCommandMenuOpenedStateV2.atom, false); + store.set(isCommandMenuClosingState.atom, true); closeAnyOpenDropdown(); removeFocusItemFromFocusStackById({ focusId: SIDE_PANEL_FOCUS_ID, }); } - }, [closeAnyOpenDropdown, removeFocusItemFromFocusStackById]); + }, [closeAnyOpenDropdown, removeFocusItemFromFocusStackById, store]); const openCommandMenu = useCallback(() => { emitSidePanelOpenEvent(); @@ -46,16 +47,16 @@ export const useCommandMenu = () => { }, [closeAnyOpenDropdown, navigateCommandMenu]); const toggleCommandMenu = useCallback(() => { - const isCommandMenuOpened = jotaiStore.get(isCommandMenuOpenedStateV2.atom); + const isCommandMenuOpened = store.get(isCommandMenuOpenedStateV2.atom); - jotaiStore.set(commandMenuSearchState.atom, ''); + store.set(commandMenuSearchState.atom, ''); if (isCommandMenuOpened) { closeCommandMenu(); } else { openCommandMenu(); } - }, [closeCommandMenu, openCommandMenu]); + }, [closeCommandMenu, openCommandMenu, store]); return { openCommandMenu, diff --git a/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenuCloseAnimationCompleteCleanup.ts b/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenuCloseAnimationCompleteCleanup.ts index 7d0c2bdc18..3a8921a70d 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenuCloseAnimationCompleteCleanup.ts +++ b/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenuCloseAnimationCompleteCleanup.ts @@ -22,14 +22,15 @@ 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 { useCallback } from 'react'; import { CommandMenuPages } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; +import { useStore } from 'jotai'; export const useCommandMenuCloseAnimationCompleteCleanup = () => { + const store = useStore(); const { resetSelectedItem } = useSelectableList( COMMAND_MENU_LIST_SELECTABLE_LIST_ID, ); @@ -44,7 +45,7 @@ export const useCommandMenuCloseAnimationCompleteCleanup = () => { resetContextStoreStates(COMMAND_MENU_COMPONENT_INSTANCE_ID); resetContextStoreStates(COMMAND_MENU_PREVIOUS_COMPONENT_INSTANCE_ID); - const currentPage = jotaiStore.get(commandMenuPageState.atom); + const currentPage = store.get(commandMenuPageState.atom); const isPageLayoutEditingPage = currentPage === CommandMenuPages.PageLayoutWidgetTypeSelect || @@ -53,7 +54,7 @@ export const useCommandMenuCloseAnimationCompleteCleanup = () => { currentPage === CommandMenuPages.PageLayoutTabSettings; if (isPageLayoutEditingPage) { - const targetedRecordsRule = jotaiStore.get( + const targetedRecordsRule = store.get( contextStoreTargetedRecordsRuleComponentState.atomFamily({ instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID, }), @@ -64,24 +65,22 @@ export const useCommandMenuCloseAnimationCompleteCleanup = () => { targetedRecordsRule.selectedRecordIds.length === 1 ) { const recordId = targetedRecordsRule.selectedRecordIds[0]; - const record = jotaiStore.get( - recordStoreFamilyState.atomFamily(recordId), - ); + const record = store.get(recordStoreFamilyState.atomFamily(recordId)); if (isDefined(record) && isDefined(record.pageLayoutId)) { - jotaiStore.set( + store.set( pageLayoutEditingWidgetIdComponentState.atomFamily({ instanceId: record.pageLayoutId, }), null, ); - jotaiStore.set( + store.set( pageLayoutTabSettingsOpenTabIdComponentState.atomFamily({ instanceId: record.pageLayoutId, }), null, ); - jotaiStore.set( + store.set( pageLayoutDraggedAreaComponentState.atomFamily({ instanceId: record.pageLayoutId, }), @@ -91,35 +90,35 @@ export const useCommandMenuCloseAnimationCompleteCleanup = () => { } } - jotaiStore.set(viewableRecordIdState.atom, null); - jotaiStore.set(commandMenuPageState.atom, CommandMenuPages.Root); - jotaiStore.set(commandMenuPageInfoState.atom, { + store.set(viewableRecordIdState.atom, null); + store.set(commandMenuPageState.atom, CommandMenuPages.Root); + store.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, []); + store.set(isCommandMenuOpenedStateV2.atom, false); + store.set(commandMenuSearchState.atom, ''); + store.set(commandMenuNavigationMorphItemsByPageState.atom, new Map()); + store.set(commandMenuNavigationStackState.atom, []); resetSelectedItem(); - jotaiStore.set(hasUserSelectedCommandState.atom, false); + store.set(hasUserSelectedCommandState.atom, false); emitSidePanelCloseEvent(); - jotaiStore.set(isCommandMenuClosingState.atom, false); - jotaiStore.set( + store.set(isCommandMenuClosingState.atom, false); + store.set( activeTabIdComponentState.atomFamily({ instanceId: WORKFLOW_LOGIC_FUNCTION_TAB_LIST_COMPONENT_ID, }), WorkflowLogicFunctionTabId.CODE, ); - const morphItemsByPage = jotaiStore.get( + const morphItemsByPage = store.get( commandMenuNavigationMorphItemsByPageState.atom, ); for (const [pageId, morphItems] of morphItemsByPage) { - jotaiStore.set( + store.set( activeTabIdComponentState.atomFamily({ instanceId: getShowPageTabListComponentId({ pageId, @@ -129,7 +128,7 @@ export const useCommandMenuCloseAnimationCompleteCleanup = () => { null, ); } - }, [closeDropdown, resetContextStoreStates, resetSelectedItem]); + }, [closeDropdown, resetContextStoreStates, resetSelectedItem, store]); return { commandMenuCloseAnimationCompleteCleanup, diff --git a/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenuHistory.ts b/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenuHistory.ts index 40d16028c6..1a19471e2f 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenuHistory.ts +++ b/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenuHistory.ts @@ -8,15 +8,16 @@ 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 { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { isNonEmptyArray } from '@sniptt/guards'; import { isDefined } from 'twenty-shared/utils'; +import { useStore } from 'jotai'; export const useCommandMenuHistory = () => { + const store = useStore(); const { closeCommandMenu } = useCommandMenu(); const goBackFromCommandMenu = useCallback(() => { - const currentNavigationStack = jotaiStore.get( + const currentNavigationStack = store.get( commandMenuNavigationStackState.atom, ); @@ -28,17 +29,17 @@ export const useCommandMenuHistory = () => { return; } - jotaiStore.set(commandMenuPageState.atom, lastNavigationStackItem.page); + store.set(commandMenuPageState.atom, lastNavigationStackItem.page); - jotaiStore.set(commandMenuPageInfoState.atom, { + store.set(commandMenuPageInfoState.atom, { title: lastNavigationStackItem.pageTitle, Icon: lastNavigationStackItem.pageIcon, instanceId: lastNavigationStackItem.pageId, }); - jotaiStore.set(commandMenuNavigationStackState.atom, newNavigationStack); + store.set(commandMenuNavigationStackState.atom, newNavigationStack); - const currentMorphItems = jotaiStore.get( + const currentMorphItems = store.get( commandMenuNavigationMorphItemsByPageState.atom, ); @@ -48,14 +49,14 @@ export const useCommandMenuHistory = () => { if (isDefined(removedItem)) { const newMorphItems = new Map(currentMorphItems); newMorphItems.delete(removedItem.pageId); - jotaiStore.set( + store.set( commandMenuNavigationMorphItemsByPageState.atom, newMorphItems, ); const morphItems = currentMorphItems.get(removedItem.pageId); if (isNonEmptyArray(morphItems)) { - jotaiStore.set( + store.set( activeTabIdComponentState.atomFamily({ instanceId: getShowPageTabListComponentId({ pageId: removedItem.pageId, @@ -68,63 +69,63 @@ export const useCommandMenuHistory = () => { } } - jotaiStore.set(hasUserSelectedCommandState.atom, false); - }, [closeCommandMenu]); + store.set(hasUserSelectedCommandState.atom, false); + }, [closeCommandMenu, store]); - const navigateCommandMenuHistory = useCallback((pageIndex: number) => { - const currentNavigationStack = jotaiStore.get( - commandMenuNavigationStackState.atom, - ); - - 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}`, + const navigateCommandMenuHistory = useCallback( + (pageIndex: number) => { + const currentNavigationStack = store.get( + commandMenuNavigationStackState.atom, ); - } - 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, - ); + const newNavigationStack = currentNavigationStack.slice(0, pageIndex + 1); - 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, + store.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}`, ); } - } - const newMorphItems = new Map( - Array.from(currentMorphItems.entries()).filter(([pageId]) => - newNavigationStack.some((item) => item.pageId === pageId), - ), - ); + store.set(commandMenuPageState.atom, newNavigationStackItem.page); + store.set(commandMenuPageInfoState.atom, { + title: newNavigationStackItem.pageTitle, + Icon: newNavigationStackItem.pageIcon, + instanceId: newNavigationStackItem.pageId, + }); + const currentMorphItems = store.get( + commandMenuNavigationMorphItemsByPageState.atom, + ); - jotaiStore.set( - commandMenuNavigationMorphItemsByPageState.atom, - newMorphItems, - ); + 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, + ); + } + } - jotaiStore.set(hasUserSelectedCommandState.atom, false); - }, []); + const newMorphItems = new Map( + Array.from(currentMorphItems.entries()).filter(([pageId]) => + newNavigationStack.some((item) => item.pageId === pageId), + ), + ); + + store.set(commandMenuNavigationMorphItemsByPageState.atom, newMorphItems); + + store.set(hasUserSelectedCommandState.atom, false); + }, + [store], + ); return { goBackFromCommandMenu, diff --git a/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenuUpdateNavigationMorphItemsByPage.tsx b/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenuUpdateNavigationMorphItemsByPage.tsx index c9b7838dc4..0b3043c6eb 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenuUpdateNavigationMorphItemsByPage.tsx +++ b/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenuUpdateNavigationMorphItemsByPage.tsx @@ -1,6 +1,6 @@ import { commandMenuNavigationMorphItemsByPageState } from '@/command-menu/states/commandMenuNavigationMorphItemsByPageState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useCallback } from 'react'; +import { useStore } from 'jotai'; type UpdateNavigationMorphItemsByPageParams = { pageId: string; @@ -9,13 +9,14 @@ type UpdateNavigationMorphItemsByPageParams = { }; export const useCommandMenuUpdateNavigationMorphItemsByPage = () => { + const store = useStore(); const updateCommandMenuNavigationMorphItemsByPage = useCallback( async ({ pageId, objectMetadataId, objectRecordIds, }: UpdateNavigationMorphItemsByPageParams) => { - const currentMorphItems = jotaiStore.get( + const currentMorphItems = store.get( commandMenuNavigationMorphItemsByPageState.atom, ); @@ -26,12 +27,12 @@ export const useCommandMenuUpdateNavigationMorphItemsByPage = () => { const newMorphItemsMap = new Map(currentMorphItems); newMorphItemsMap.set(pageId, newMorphItems); - jotaiStore.set( + store.set( commandMenuNavigationMorphItemsByPageState.atom, newMorphItemsMap, ); }, - [], + [store], ); return { diff --git a/packages/twenty-front/src/modules/command-menu/hooks/useCopyContextStoreAndActionMenuStates.ts b/packages/twenty-front/src/modules/command-menu/hooks/useCopyContextStoreAndActionMenuStates.ts index a877251dca..f98c465a53 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/useCopyContextStoreAndActionMenuStates.ts +++ b/packages/twenty-front/src/modules/command-menu/hooks/useCopyContextStoreAndActionMenuStates.ts @@ -7,10 +7,11 @@ 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 { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useCallback } from 'react'; +import { useStore } from 'jotai'; export const useCopyContextStoreStates = () => { + const store = useStore(); const copyContextStoreStates = useCallback( ({ instanceIdToCopyFrom, @@ -19,124 +20,124 @@ export const useCopyContextStoreStates = () => { instanceIdToCopyFrom: string; instanceIdToCopyTo: string; }) => { - const contextStoreCurrentObjectMetadataItemId = jotaiStore.get( + const contextStoreCurrentObjectMetadataItemId = store.get( contextStoreCurrentObjectMetadataItemIdComponentState.atomFamily({ instanceId: instanceIdToCopyFrom, }), ); - jotaiStore.set( + store.set( contextStoreCurrentObjectMetadataItemIdComponentState.atomFamily({ instanceId: instanceIdToCopyTo, }), contextStoreCurrentObjectMetadataItemId, ); - const contextStoreTargetedRecordsRule = jotaiStore.get( + const contextStoreTargetedRecordsRule = store.get( contextStoreTargetedRecordsRuleComponentState.atomFamily({ instanceId: instanceIdToCopyFrom, }), ); - jotaiStore.set( + store.set( contextStoreTargetedRecordsRuleComponentState.atomFamily({ instanceId: instanceIdToCopyTo, }), contextStoreTargetedRecordsRule, ); - const contextStoreNumberOfSelectedRecords = jotaiStore.get( + const contextStoreNumberOfSelectedRecords = store.get( contextStoreNumberOfSelectedRecordsComponentState.atomFamily({ instanceId: instanceIdToCopyFrom, }), ); - jotaiStore.set( + store.set( contextStoreNumberOfSelectedRecordsComponentState.atomFamily({ instanceId: instanceIdToCopyTo, }), contextStoreNumberOfSelectedRecords, ); - const contextStoreFilters = jotaiStore.get( + const contextStoreFilters = store.get( contextStoreFiltersComponentState.atomFamily({ instanceId: instanceIdToCopyFrom, }), ); - jotaiStore.set( + store.set( contextStoreFiltersComponentState.atomFamily({ instanceId: instanceIdToCopyTo, }), contextStoreFilters, ); - const contextStoreFilterGroups = jotaiStore.get( + const contextStoreFilterGroups = store.get( contextStoreFilterGroupsComponentState.atomFamily({ instanceId: instanceIdToCopyFrom, }), ); - jotaiStore.set( + store.set( contextStoreFilterGroupsComponentState.atomFamily({ instanceId: instanceIdToCopyTo, }), contextStoreFilterGroups, ); - const contextStoreAnyFieldFilterValue = jotaiStore.get( + const contextStoreAnyFieldFilterValue = store.get( contextStoreAnyFieldFilterValueComponentState.atomFamily({ instanceId: instanceIdToCopyFrom, }), ); - jotaiStore.set( + store.set( contextStoreAnyFieldFilterValueComponentState.atomFamily({ instanceId: instanceIdToCopyTo, }), contextStoreAnyFieldFilterValue, ); - const contextStoreCurrentViewId = jotaiStore.get( + const contextStoreCurrentViewId = store.get( contextStoreCurrentViewIdComponentState.atomFamily({ instanceId: instanceIdToCopyFrom, }), ); - jotaiStore.set( + store.set( contextStoreCurrentViewIdComponentState.atomFamily({ instanceId: instanceIdToCopyTo, }), contextStoreCurrentViewId, ); - const contextStoreCurrentViewType = jotaiStore.get( + const contextStoreCurrentViewType = store.get( contextStoreCurrentViewTypeComponentState.atomFamily({ instanceId: instanceIdToCopyFrom, }), ); - jotaiStore.set( + store.set( contextStoreCurrentViewTypeComponentState.atomFamily({ instanceId: instanceIdToCopyTo, }), contextStoreCurrentViewType, ); - const contextStoreIsFullTabWidgetInEditMode = jotaiStore.get( + const contextStoreIsFullTabWidgetInEditMode = store.get( contextStoreIsPageInEditModeComponentState.atomFamily({ instanceId: instanceIdToCopyFrom, }), ); - jotaiStore.set( + store.set( contextStoreIsPageInEditModeComponentState.atomFamily({ instanceId: instanceIdToCopyTo, }), contextStoreIsFullTabWidgetInEditMode, ); }, - [], + [store], ); return { copyContextStoreStates }; diff --git a/packages/twenty-front/src/modules/command-menu/hooks/useNavigateCommandMenu.ts b/packages/twenty-front/src/modules/command-menu/hooks/useNavigateCommandMenu.ts index 1b45daf45f..06470b5ff7 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/useNavigateCommandMenu.ts +++ b/packages/twenty-front/src/modules/command-menu/hooks/useNavigateCommandMenu.ts @@ -13,11 +13,11 @@ import { isCommandMenuOpenedStateV2 } from '@/command-menu/states/isCommandMenuO 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 { 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'; +import { useStore } from 'jotai'; export type CommandMenuNavigationStackItem = { page: CommandMenuPages; @@ -28,6 +28,7 @@ export type CommandMenuNavigationStackItem = { }; export const useNavigateCommandMenu = () => { + const store = useStore(); const { copyContextStoreStates } = useCopyContextStoreStates(); const { commandMenuCloseAnimationCompleteCleanup } = @@ -36,9 +37,9 @@ export const useNavigateCommandMenu = () => { const { pushFocusItemToFocusStack } = usePushFocusItemToFocusStack(); const openCommandMenu = useCallback(() => { - const isCommandMenuOpened = jotaiStore.get(isCommandMenuOpenedStateV2.atom); + const isCommandMenuOpened = store.get(isCommandMenuOpenedStateV2.atom); - const isCommandMenuClosing = jotaiStore.get(isCommandMenuClosingState.atom); + const isCommandMenuClosing = store.get(isCommandMenuClosingState.atom); if (isCommandMenuClosing) { commandMenuCloseAnimationCompleteCleanup(); @@ -64,12 +65,13 @@ export const useNavigateCommandMenu = () => { instanceIdToCopyTo: COMMAND_MENU_COMPONENT_INSTANCE_ID, }); - jotaiStore.set(isCommandMenuOpenedStateV2.atom, true); - jotaiStore.set(hasUserSelectedCommandState.atom, false); + store.set(isCommandMenuOpenedStateV2.atom, true); + store.set(hasUserSelectedCommandState.atom, false); }, [ copyContextStoreStates, commandMenuCloseAnimationCompleteCleanup, pushFocusItemToFocusStack, + store, ]); const navigateCommandMenu = useCallback( @@ -88,15 +90,15 @@ export const useNavigateCommandMenu = () => { const computedPageId = pageId || v4(); openCommandMenu(); - jotaiStore.set(commandMenuPageState.atom, page); - jotaiStore.set(commandMenuPageInfoState.atom, { + store.set(commandMenuPageState.atom, page); + store.set(commandMenuPageInfoState.atom, { title: pageTitle, Icon: pageIcon, instanceId: computedPageId, }); if (focusTitleInput) { - jotaiStore.set( + store.set( commandMenuShouldFocusTitleInputComponentState.atomFamily({ instanceId: computedPageId, }), @@ -104,16 +106,14 @@ export const useNavigateCommandMenu = () => { ); } - const isCommandMenuClosing = jotaiStore.get( - isCommandMenuClosingState.atom, - ); + const isCommandMenuClosing = store.get(isCommandMenuClosingState.atom); const currentNavigationStack = isCommandMenuClosing ? [] - : jotaiStore.get(commandMenuNavigationStackState.atom); + : store.get(commandMenuNavigationStackState.atom); if (resetNavigationStack) { - jotaiStore.set(commandMenuNavigationStackState.atom, [ + store.set(commandMenuNavigationStackState.atom, [ { page, pageTitle, @@ -123,12 +123,9 @@ export const useNavigateCommandMenu = () => { }, ]); - jotaiStore.set( - commandMenuNavigationMorphItemsByPageState.atom, - new Map(), - ); + store.set(commandMenuNavigationMorphItemsByPageState.atom, new Map()); } else { - jotaiStore.set(commandMenuNavigationStackState.atom, [ + store.set(commandMenuNavigationStackState.atom, [ ...currentNavigationStack, { page, @@ -140,7 +137,7 @@ export const useNavigateCommandMenu = () => { ]); } }, - [openCommandMenu], + [openCommandMenu, store], ); return { diff --git a/packages/twenty-front/src/modules/command-menu/hooks/useOpenCalendarEventInCommandMenu.ts b/packages/twenty-front/src/modules/command-menu/hooks/useOpenCalendarEventInCommandMenu.ts index 5bfbbbcd97..e29d49c316 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/useOpenCalendarEventInCommandMenu.ts +++ b/packages/twenty-front/src/modules/command-menu/hooks/useOpenCalendarEventInCommandMenu.ts @@ -1,20 +1,21 @@ 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 { useCallback } from 'react'; import { CommandMenuPages } from 'twenty-shared/types'; import { IconCalendarEvent } from 'twenty-ui/display'; import { v4 } from 'uuid'; +import { useStore } from 'jotai'; export const useOpenCalendarEventInCommandMenu = () => { + const store = useStore(); const { navigateCommandMenu } = useNavigateCommandMenu(); const openCalendarEventInCommandMenu = useCallback( (calendarEventId: string) => { const pageComponentInstanceId = v4(); - jotaiStore.set( + store.set( viewableRecordIdComponentState.atomFamily({ instanceId: pageComponentInstanceId, }), @@ -53,7 +54,7 @@ export const useOpenCalendarEventInCommandMenu = () => { pageId: pageComponentInstanceId, }); }, - [navigateCommandMenu], + [navigateCommandMenu, store], ); return { diff --git a/packages/twenty-front/src/modules/command-menu/hooks/useOpenEmailThreadInCommandMenu.ts b/packages/twenty-front/src/modules/command-menu/hooks/useOpenEmailThreadInCommandMenu.ts index b76ec54757..b2d233d008 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/useOpenEmailThreadInCommandMenu.ts +++ b/packages/twenty-front/src/modules/command-menu/hooks/useOpenEmailThreadInCommandMenu.ts @@ -1,20 +1,21 @@ 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 { useCallback } from 'react'; import { CommandMenuPages } from 'twenty-shared/types'; import { IconMail } from 'twenty-ui/display'; import { v4 } from 'uuid'; +import { useStore } from 'jotai'; export const useOpenEmailThreadInCommandMenu = () => { + const store = useStore(); const { navigateCommandMenu } = useNavigateCommandMenu(); const openEmailThreadInCommandMenu = useCallback( (emailThreadId: string) => { const pageComponentInstanceId = v4(); - jotaiStore.set( + store.set( viewableRecordIdComponentState.atomFamily({ instanceId: pageComponentInstanceId, }), @@ -53,7 +54,7 @@ export const useOpenEmailThreadInCommandMenu = () => { pageId: pageComponentInstanceId, }); }, - [navigateCommandMenu], + [navigateCommandMenu, store], ); return { diff --git a/packages/twenty-front/src/modules/command-menu/hooks/useOpenFrontComponentInCommandMenu.ts b/packages/twenty-front/src/modules/command-menu/hooks/useOpenFrontComponentInCommandMenu.ts index 5fe20b612d..3288dfd78b 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/useOpenFrontComponentInCommandMenu.ts +++ b/packages/twenty-front/src/modules/command-menu/hooks/useOpenFrontComponentInCommandMenu.ts @@ -1,11 +1,12 @@ import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu'; import { viewableFrontComponentIdComponentState } from '@/command-menu/pages/front-component/states/viewableFrontComponentIdComponentState'; -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'; +import { useStore } from 'jotai'; export const useOpenFrontComponentInCommandMenu = () => { + const store = useStore(); const { navigateCommandMenu } = useCommandMenu(); const openFrontComponentInCommandMenu = ({ @@ -21,7 +22,7 @@ export const useOpenFrontComponentInCommandMenu = () => { }) => { const pageComponentInstanceId = v4(); - jotaiStore.set( + store.set( viewableFrontComponentIdComponentState.atomFamily({ instanceId: pageComponentInstanceId, }), diff --git a/packages/twenty-front/src/modules/command-menu/hooks/useOpenMergeRecordsPageInCommandMenu.tsx b/packages/twenty-front/src/modules/command-menu/hooks/useOpenMergeRecordsPageInCommandMenu.tsx index 63070f41df..c54b35995a 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/useOpenMergeRecordsPageInCommandMenu.tsx +++ b/packages/twenty-front/src/modules/command-menu/hooks/useOpenMergeRecordsPageInCommandMenu.tsx @@ -6,11 +6,11 @@ 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 { useCallback } from 'react'; import { IconArrowMerge } from 'twenty-ui/display'; import { v4 } from 'uuid'; +import { useStore } from 'jotai'; type UseOpenMergeRecordsPageInCommandMenuProps = { objectNameSingular: string; @@ -21,6 +21,7 @@ export const useOpenMergeRecordsPageInCommandMenu = ({ objectNameSingular, objectRecordIds, }: UseOpenMergeRecordsPageInCommandMenuProps) => { + const store = useStore(); const { objectMetadataItem } = useObjectMetadataItem({ objectNameSingular, }); @@ -43,7 +44,7 @@ export const useOpenMergeRecordsPageInCommandMenu = ({ const openMergeRecordsPageInCommandMenu = useCallback(async () => { const pageId = v4(); - jotaiStore.set( + store.set( contextStoreCurrentObjectMetadataItemIdComponentState.atomFamily({ instanceId: pageId, }), @@ -71,6 +72,7 @@ export const useOpenMergeRecordsPageInCommandMenu = ({ upsertRecordsInStore, navigateCommandMenu, updateCommandMenuNavigationMorphItemsByPage, + store, ]); return { diff --git a/packages/twenty-front/src/modules/command-menu/hooks/useOpenRecordInCommandMenu.ts b/packages/twenty-front/src/modules/command-menu/hooks/useOpenRecordInCommandMenu.ts index bcd32e808a..9f835e35ad 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/useOpenRecordInCommandMenu.ts +++ b/packages/twenty-front/src/modules/command-menu/hooks/useOpenRecordInCommandMenu.ts @@ -15,7 +15,6 @@ 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 { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { CommandMenuPages } from 'twenty-shared/types'; import { useRunWorkflowRunOpeningInCommandMenuSideEffects } from '@/workflow/hooks/useRunWorkflowRunOpeningInCommandMenuSideEffects'; @@ -25,8 +24,10 @@ import { useCallback } from 'react'; import { isDefined } from 'twenty-shared/utils'; import { useIcons } from 'twenty-ui/display'; import { v4 } from 'uuid'; +import { useStore } from 'jotai'; export const useOpenRecordInCommandMenu = () => { + const store = useStore(); const theme = useTheme(); const { getIcon } = useIcons(); @@ -46,14 +47,12 @@ export const useOpenRecordInCommandMenu = () => { isNewRecord?: boolean; resetNavigationStack?: boolean; }) => { - const navigationStack = jotaiStore.get( - commandMenuNavigationStackState.atom, - ); + const navigationStack = store.get(commandMenuNavigationStackState.atom); const currentNavigationStackItem = navigationStack.at(-1); if (isDefined(currentNavigationStackItem)) { - const currentRecordId = jotaiStore.get( + const currentRecordId = store.get( viewableRecordIdComponentState.atomFamily({ instanceId: currentNavigationStackItem.pageId, }), @@ -66,21 +65,21 @@ export const useOpenRecordInCommandMenu = () => { const pageComponentInstanceId = v4(); - jotaiStore.set( + store.set( viewableRecordNameSingularComponentState.atomFamily({ instanceId: pageComponentInstanceId, }), objectNameSingular, ); - jotaiStore.set( + store.set( viewableRecordIdComponentState.atomFamily({ instanceId: pageComponentInstanceId, }), recordId, ); - jotaiStore.set(viewableRecordIdState.atom, recordId); + store.set(viewableRecordIdState.atom, recordId); - const objectMetadataItem = jotaiStore.get( + const objectMetadataItem = store.get( objectMetadataItemFamilySelector.selectorFamily({ objectName: objectNameSingular, objectNameType: 'singular', @@ -93,14 +92,14 @@ export const useOpenRecordInCommandMenu = () => { ); } - jotaiStore.set( + store.set( contextStoreCurrentObjectMetadataItemIdComponentState.atomFamily({ instanceId: pageComponentInstanceId, }), objectMetadataItem.id, ); - jotaiStore.set( + store.set( contextStoreTargetedRecordsRuleComponentState.atomFamily({ instanceId: pageComponentInstanceId, }), @@ -110,43 +109,43 @@ export const useOpenRecordInCommandMenu = () => { }, ); - jotaiStore.set( + store.set( contextStoreNumberOfSelectedRecordsComponentState.atomFamily({ instanceId: pageComponentInstanceId, }), 1, ); - jotaiStore.set( + store.set( contextStoreCurrentViewTypeComponentState.atomFamily({ instanceId: pageComponentInstanceId, }), ContextStoreViewType.ShowPage, ); - jotaiStore.set( + store.set( contextStoreCurrentViewIdComponentState.atomFamily({ instanceId: pageComponentInstanceId, }), - jotaiStore.get( + store.get( contextStoreCurrentViewIdComponentState.atomFamily({ instanceId: MAIN_CONTEXT_STORE_INSTANCE_ID, }), ), ); - jotaiStore.set( + store.set( contextStoreIsPageInEditModeComponentState.atomFamily({ instanceId: pageComponentInstanceId, }), - jotaiStore.get( + store.get( contextStoreIsPageInEditModeComponentState.atomFamily({ instanceId: MAIN_CONTEXT_STORE_INSTANCE_ID, }), ), ); - const currentMorphItems = jotaiStore.get( + const currentMorphItems = store.get( commandMenuNavigationMorphItemsByPageState.atom, ); @@ -158,7 +157,7 @@ export const useOpenRecordInCommandMenu = () => { const newMorphItemsMap = new Map(currentMorphItems); newMorphItemsMap.set(pageComponentInstanceId, [morphItemToAdd]); - jotaiStore.set( + store.set( commandMenuNavigationMorphItemsByPageState.atom, newMorphItemsMap, ); @@ -197,6 +196,7 @@ export const useOpenRecordInCommandMenu = () => { navigateCommandMenu, runWorkflowRunOpeningInCommandMenuSideEffects, theme, + store, ], ); diff --git a/packages/twenty-front/src/modules/command-menu/hooks/useResetContextStoreStates.ts b/packages/twenty-front/src/modules/command-menu/hooks/useResetContextStoreStates.ts index c2556772fb..87bc3c6650 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/useResetContextStoreStates.ts +++ b/packages/twenty-front/src/modules/command-menu/hooks/useResetContextStoreStates.ts @@ -5,63 +5,67 @@ 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 { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useCallback } from 'react'; +import { useStore } from 'jotai'; export const useResetContextStoreStates = () => { - const resetContextStoreStates = useCallback((instanceId: string) => { - jotaiStore.set( - contextStoreCurrentObjectMetadataItemIdComponentState.atomFamily({ - instanceId, - }), - undefined, - ); + const store = useStore(); + const resetContextStoreStates = useCallback( + (instanceId: string) => { + store.set( + contextStoreCurrentObjectMetadataItemIdComponentState.atomFamily({ + instanceId, + }), + undefined, + ); - jotaiStore.set( - contextStoreTargetedRecordsRuleComponentState.atomFamily({ - instanceId, - }), - { - mode: 'selection', - selectedRecordIds: [], - }, - ); + store.set( + contextStoreTargetedRecordsRuleComponentState.atomFamily({ + instanceId, + }), + { + mode: 'selection', + selectedRecordIds: [], + }, + ); - jotaiStore.set( - contextStoreNumberOfSelectedRecordsComponentState.atomFamily({ - instanceId, - }), - 0, - ); + store.set( + contextStoreNumberOfSelectedRecordsComponentState.atomFamily({ + instanceId, + }), + 0, + ); - jotaiStore.set( - contextStoreFiltersComponentState.atomFamily({ - instanceId, - }), - [], - ); + store.set( + contextStoreFiltersComponentState.atomFamily({ + instanceId, + }), + [], + ); - jotaiStore.set( - contextStoreFilterGroupsComponentState.atomFamily({ - instanceId, - }), - [], - ); + store.set( + contextStoreFilterGroupsComponentState.atomFamily({ + instanceId, + }), + [], + ); - jotaiStore.set( - contextStoreAnyFieldFilterValueComponentState.atomFamily({ - instanceId, - }), - '', - ); + store.set( + contextStoreAnyFieldFilterValueComponentState.atomFamily({ + instanceId, + }), + '', + ); - jotaiStore.set( - contextStoreCurrentViewIdComponentState.atomFamily({ - instanceId, - }), - undefined, - ); - }, []); + store.set( + contextStoreCurrentViewIdComponentState.atomFamily({ + instanceId, + }), + undefined, + ); + }, + [store], + ); return { resetContextStoreStates }; }; diff --git a/packages/twenty-front/src/modules/command-menu/hooks/useSetGlobalCommandMenuContext.ts b/packages/twenty-front/src/modules/command-menu/hooks/useSetGlobalCommandMenuContext.ts index cd37a19a80..f643228831 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/useSetGlobalCommandMenuContext.ts +++ b/packages/twenty-front/src/modules/command-menu/hooks/useSetGlobalCommandMenuContext.ts @@ -10,10 +10,11 @@ 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 { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useCallback } from 'react'; +import { useStore } from 'jotai'; export const useSetGlobalCommandMenuContext = () => { + const store = useStore(); const { copyContextStoreStates } = useCopyContextStoreStates(); const setGlobalCommandMenuContext = useCallback(() => { @@ -22,7 +23,7 @@ export const useSetGlobalCommandMenuContext = () => { instanceIdToCopyTo: COMMAND_MENU_PREVIOUS_COMPONENT_INSTANCE_ID, }); - jotaiStore.set( + store.set( contextStoreTargetedRecordsRuleComponentState.atomFamily({ instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID, }), @@ -32,49 +33,49 @@ export const useSetGlobalCommandMenuContext = () => { }, ); - jotaiStore.set( + store.set( contextStoreNumberOfSelectedRecordsComponentState.atomFamily({ instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID, }), 0, ); - jotaiStore.set( + store.set( contextStoreFiltersComponentState.atomFamily({ instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID, }), [], ); - jotaiStore.set( + store.set( contextStoreFilterGroupsComponentState.atomFamily({ instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID, }), [], ); - jotaiStore.set( + store.set( contextStoreAnyFieldFilterValueComponentState.atomFamily({ instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID, }), '', ); - jotaiStore.set( + store.set( contextStoreCurrentViewTypeComponentState.atomFamily({ instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID, }), ContextStoreViewType.Table, ); - jotaiStore.set(commandMenuPageInfoState.atom, { + store.set(commandMenuPageInfoState.atom, { title: undefined, Icon: undefined, instanceId: '', }); - jotaiStore.set(hasUserSelectedCommandState.atom, false); - }, [copyContextStoreStates]); + store.set(hasUserSelectedCommandState.atom, false); + }, [copyContextStoreStates, store]); return { setGlobalCommandMenuContext, diff --git a/packages/twenty-front/src/modules/command-menu/hooks/useUpdateCommandMenuPageInfo.ts b/packages/twenty-front/src/modules/command-menu/hooks/useUpdateCommandMenuPageInfo.ts index 8d0775460b..2243ee3b65 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/useUpdateCommandMenuPageInfo.ts +++ b/packages/twenty-front/src/modules/command-menu/hooks/useUpdateCommandMenuPageInfo.ts @@ -1,10 +1,11 @@ import { commandMenuNavigationStackState } from '@/command-menu/states/commandMenuNavigationStackState'; import { commandMenuPageInfoState } from '@/command-menu/states/commandMenuPageInfoState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useCallback } from 'react'; import { type IconComponent, IconDotsVertical } from 'twenty-ui/display'; +import { useStore } from 'jotai'; export const useUpdateCommandMenuPageInfo = () => { + const store = useStore(); const updateCommandMenuPageInfo = useCallback( ({ pageTitle, @@ -13,7 +14,7 @@ export const useUpdateCommandMenuPageInfo = () => { pageTitle?: string; pageIcon?: IconComponent; }) => { - const commandMenuPageInfo = jotaiStore.get(commandMenuPageInfoState.atom); + const commandMenuPageInfo = store.get(commandMenuPageInfoState.atom); const newCommandMenuPageInfo = { ...commandMenuPageInfo, @@ -21,9 +22,9 @@ export const useUpdateCommandMenuPageInfo = () => { Icon: pageIcon ?? commandMenuPageInfo.Icon ?? IconDotsVertical, }; - jotaiStore.set(commandMenuPageInfoState.atom, newCommandMenuPageInfo); + store.set(commandMenuPageInfoState.atom, newCommandMenuPageInfo); - const commandMenuNavigationStack = jotaiStore.get( + const commandMenuNavigationStack = store.get( commandMenuNavigationStackState.atom, ); @@ -44,12 +45,12 @@ export const useUpdateCommandMenuPageInfo = () => { }, ]; - jotaiStore.set( + store.set( commandMenuNavigationStackState.atom, newCommandMenuNavigationStack, ); }, - [], + [store], ); return { diff --git a/packages/twenty-front/src/modules/command-menu/hooks/useWorkflowCommandMenu.ts b/packages/twenty-front/src/modules/command-menu/hooks/useWorkflowCommandMenu.ts index ef58a0587f..ec47351016 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/useWorkflowCommandMenu.ts +++ b/packages/twenty-front/src/modules/command-menu/hooks/useWorkflowCommandMenu.ts @@ -3,7 +3,6 @@ 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'; @@ -17,8 +16,10 @@ import { IconSettingsAutomation, } from 'twenty-ui/display'; import { v4 } from 'uuid'; +import { useStore } from 'jotai'; export const useWorkflowCommandMenu = () => { + const store = useStore(); const { navigateCommandMenu } = useNavigateCommandMenu(); const { setInitialWorkflowRunRightDrawerTab } = useSetInitialWorkflowRunRightDrawerTab(); @@ -27,7 +28,7 @@ export const useWorkflowCommandMenu = () => { (workflowId: string) => { const pageId = v4(); - jotaiStore.set( + store.set( commandMenuWorkflowIdComponentState.atomFamily({ instanceId: pageId, }), @@ -41,14 +42,14 @@ export const useWorkflowCommandMenu = () => { pageId, }); }, - [navigateCommandMenu], + [navigateCommandMenu, store], ); const openWorkflowCreateStepInCommandMenu = useCallback( (workflowId: string) => { const pageId = v4(); - jotaiStore.set( + store.set( commandMenuWorkflowIdComponentState.atomFamily({ instanceId: pageId, }), @@ -62,7 +63,7 @@ export const useWorkflowCommandMenu = () => { pageId, }); }, - [navigateCommandMenu], + [navigateCommandMenu, store], ); const openWorkflowEditStepInCommandMenu = useCallback( @@ -74,7 +75,7 @@ export const useWorkflowCommandMenu = () => { ) => { const pageId = v4(); - jotaiStore.set( + store.set( commandMenuWorkflowIdComponentState.atomFamily({ instanceId: pageId, }), @@ -82,14 +83,14 @@ export const useWorkflowCommandMenu = () => { ); if (isDefined(stepId)) { - jotaiStore.set( + store.set( commandMenuWorkflowStepIdComponentState.atomFamily({ instanceId: pageId, }), stepId, ); - jotaiStore.set( + store.set( workflowSelectedNodeComponentState.atomFamily({ instanceId: workflowId, }), @@ -104,14 +105,14 @@ export const useWorkflowCommandMenu = () => { pageId, }); }, - [navigateCommandMenu], + [navigateCommandMenu, store], ); const openWorkflowEditStepTypeInCommandMenu = useCallback( (workflowId: string) => { const pageId = v4(); - jotaiStore.set( + store.set( commandMenuWorkflowIdComponentState.atomFamily({ instanceId: pageId, }), @@ -125,7 +126,7 @@ export const useWorkflowCommandMenu = () => { pageId, }); }, - [navigateCommandMenu], + [navigateCommandMenu, store], ); const openWorkflowViewStepInCommandMenu = useCallback( @@ -144,13 +145,13 @@ export const useWorkflowCommandMenu = () => { }) => { const pageId = v4(); - jotaiStore.set( + store.set( commandMenuWorkflowIdComponentState.atomFamily({ instanceId: pageId, }), workflowId, ); - jotaiStore.set( + store.set( commandMenuWorkflowVersionIdComponentState.atomFamily({ instanceId: pageId, }), @@ -158,14 +159,14 @@ export const useWorkflowCommandMenu = () => { ); if (isDefined(stepId)) { - jotaiStore.set( + store.set( commandMenuWorkflowStepIdComponentState.atomFamily({ instanceId: pageId, }), stepId, ); - jotaiStore.set( + store.set( workflowSelectedNodeComponentState.atomFamily({ instanceId: workflowVersionId, }), @@ -180,7 +181,7 @@ export const useWorkflowCommandMenu = () => { pageId, }); }, - [navigateCommandMenu], + [navigateCommandMenu, store], ); const openWorkflowRunViewStepInCommandMenu = useCallback( @@ -201,26 +202,26 @@ export const useWorkflowCommandMenu = () => { }) => { const pageId = v4(); - jotaiStore.set( + store.set( commandMenuWorkflowIdComponentState.atomFamily({ instanceId: pageId, }), workflowId, ); - jotaiStore.set( + store.set( commandMenuWorkflowRunIdComponentState.atomFamily({ instanceId: pageId, }), workflowRunId, ); - jotaiStore.set( + store.set( commandMenuWorkflowStepIdComponentState.atomFamily({ instanceId: pageId, }), workflowSelectedNode, ); - jotaiStore.set( + store.set( workflowSelectedNodeComponentState.atomFamily({ instanceId: workflowRunId, }), @@ -239,7 +240,7 @@ export const useWorkflowCommandMenu = () => { stepExecutionStatus, }); }, - [navigateCommandMenu, setInitialWorkflowRunRightDrawerTab], + [navigateCommandMenu, setInitialWorkflowRunRightDrawerTab, store], ); return { diff --git a/packages/twenty-front/src/modules/command-menu/pages/page-layout/components/ChartFiltersSettings.tsx b/packages/twenty-front/src/modules/command-menu/pages/page-layout/components/ChartFiltersSettings.tsx index 93dc448c4c..493225bcf0 100644 --- a/packages/twenty-front/src/modules/command-menu/pages/page-layout/components/ChartFiltersSettings.tsx +++ b/packages/twenty-front/src/modules/command-menu/pages/page-layout/components/ChartFiltersSettings.tsx @@ -49,12 +49,12 @@ export const ChartFiltersSettings = ({ const { updateCurrentWidgetConfig } = useUpdateCurrentWidgetConfig(pageLayoutId); - const currentRecordFiltersAtom = useRecoilComponentStateCallbackStateV2( + const currentRecordFilters = useRecoilComponentStateCallbackStateV2( currentRecordFiltersComponentState, instanceId, ); - const currentRecordFilterGroupsAtom = useRecoilComponentStateCallbackStateV2( + const currentRecordFilterGroups = useRecoilComponentStateCallbackStateV2( currentRecordFilterGroupsComponentState, instanceId, ); @@ -63,15 +63,15 @@ export const ChartFiltersSettings = ({ const chartWidgetConfiguration = widget.configuration; const handleFiltersUpdate = () => { - const currentRecordFilters = store.get(currentRecordFiltersAtom); - const currentRecordFilterGroups = store.get(currentRecordFilterGroupsAtom); + const existingRecordFilters = store.get(currentRecordFilters); + const existingRecordFilterGroups = store.get(currentRecordFilterGroups); updateCurrentWidgetConfig({ objectMetadataId: objectMetadataItem.id, configToUpdate: { filter: { - recordFilters: currentRecordFilters, - recordFilterGroups: currentRecordFilterGroups, + recordFilters: existingRecordFilters, + recordFilterGroups: existingRecordFilterGroups, }, } satisfies Partial, }); diff --git a/packages/twenty-front/src/modules/command-menu/pages/page-layout/hooks/useResetChartDraftFiltersSettings.ts b/packages/twenty-front/src/modules/command-menu/pages/page-layout/hooks/useResetChartDraftFiltersSettings.ts index e1d9cb3ac8..40a305c983 100644 --- a/packages/twenty-front/src/modules/command-menu/pages/page-layout/hooks/useResetChartDraftFiltersSettings.ts +++ b/packages/twenty-front/src/modules/command-menu/pages/page-layout/hooks/useResetChartDraftFiltersSettings.ts @@ -5,11 +5,12 @@ 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 { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useCallback } from 'react'; import { isDefined } from 'twenty-shared/utils'; +import { useStore } from 'jotai'; export const useResetChartDraftFiltersSettings = () => { + const store = useStore(); const { pageLayoutId } = usePageLayoutIdFromContextStoreTargetedRecord(); const { widgetInEditMode } = useWidgetInEditMode(pageLayoutId); @@ -25,7 +26,7 @@ export const useResetChartDraftFiltersSettings = () => { objectMetadataItemId: objectMetadataItemId, }); - jotaiStore.set( + store.set( hasInitializedCurrentRecordFilterGroupsComponentFamilyState.atomFamily({ familyKey: {}, instanceId, @@ -33,7 +34,7 @@ export const useResetChartDraftFiltersSettings = () => { false, ); - jotaiStore.set( + store.set( hasInitializedCurrentRecordFiltersComponentFamilyState.atomFamily({ familyKey: {}, instanceId, @@ -41,16 +42,16 @@ export const useResetChartDraftFiltersSettings = () => { false, ); - jotaiStore.set( + store.set( currentRecordFiltersComponentState.atomFamily({ instanceId }), [], ); - jotaiStore.set( + store.set( currentRecordFilterGroupsComponentState.atomFamily({ instanceId }), [], ); }, - [widgetInEditMode], + [widgetInEditMode, store], ); return { diff --git a/packages/twenty-front/src/modules/command-menu/pages/page-layout/hooks/useUpdateCurrentWidgetConfig.ts b/packages/twenty-front/src/modules/command-menu/pages/page-layout/hooks/useUpdateCurrentWidgetConfig.ts index 63630dc614..133d52d7c1 100644 --- a/packages/twenty-front/src/modules/command-menu/pages/page-layout/hooks/useUpdateCurrentWidgetConfig.ts +++ b/packages/twenty-front/src/modules/command-menu/pages/page-layout/hooks/useUpdateCurrentWidgetConfig.ts @@ -7,7 +7,7 @@ import { useStore } from 'jotai'; import { useCallback } from 'react'; export const useUpdateCurrentWidgetConfig = (pageLayoutIdFromProps: string) => { - const pageLayoutDraftAtom = useRecoilComponentStateCallbackStateV2( + const pageLayoutDraft = useRecoilComponentStateCallbackStateV2( pageLayoutDraftComponentState, pageLayoutIdFromProps, ); @@ -27,8 +27,8 @@ export const useUpdateCurrentWidgetConfig = (pageLayoutIdFromProps: string) => { objectMetadataId?: string | null; configToUpdate?: Partial; }) => { - const prev = store.get(pageLayoutDraftAtom); - store.set(pageLayoutDraftAtom, { + const prev = store.get(pageLayoutDraft); + store.set(pageLayoutDraft, { ...prev, tabs: prev.tabs.map((tab) => ({ ...tab, @@ -47,7 +47,7 @@ export const useUpdateCurrentWidgetConfig = (pageLayoutIdFromProps: string) => { })), }); }, - [pageLayoutDraftAtom, currentlyEditingWidgetId, store], + [pageLayoutDraft, currentlyEditingWidgetId, store], ); return { updateCurrentWidgetConfig }; diff --git a/packages/twenty-front/src/modules/domain-manager/hooks/useBuildSearchParamsFromUrlSyncedStates.ts b/packages/twenty-front/src/modules/domain-manager/hooks/useBuildSearchParamsFromUrlSyncedStates.ts index 43626e6188..ced7328b83 100644 --- a/packages/twenty-front/src/modules/domain-manager/hooks/useBuildSearchParamsFromUrlSyncedStates.ts +++ b/packages/twenty-front/src/modules/domain-manager/hooks/useBuildSearchParamsFromUrlSyncedStates.ts @@ -2,13 +2,12 @@ import { useCallback } from 'react'; import { billingCheckoutSessionState } from '@/auth/states/billingCheckoutSessionState'; import { BILLING_CHECKOUT_SESSION_DEFAULT_VALUE } from '@/billing/constants/BillingCheckoutSessionDefaultValue'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; +import { useStore } from 'jotai'; export const useBuildSearchParamsFromUrlSyncedStates = () => { + const store = useStore(); const buildSearchParamsFromUrlSyncedStates = useCallback(async () => { - const billingCheckoutSession = jotaiStore.get( - billingCheckoutSessionState.atom, - ); + const billingCheckoutSession = store.get(billingCheckoutSessionState.atom); const output = { ...(billingCheckoutSession !== BILLING_CHECKOUT_SESSION_DEFAULT_VALUE @@ -19,7 +18,7 @@ export const useBuildSearchParamsFromUrlSyncedStates = () => { }; return output; - }, []); + }, [store]); return { buildSearchParamsFromUrlSyncedStates, diff --git a/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPickerEffect.tsx b/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPickerEffect.tsx index d5b92cef54..ea51b54b40 100644 --- a/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPickerEffect.tsx +++ b/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPickerEffect.tsx @@ -8,11 +8,11 @@ import { useFavorites } from '@/favorites/hooks/useFavorites'; import { usePrefetchedFavoritesFoldersData } from '@/favorites/hooks/usePrefetchedFavoritesFoldersData'; import { type FavoriteFolder } from '@/favorites/types/FavoriteFolder'; import { type ObjectRecord } from '@/object-record/types/ObjectRecord'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useRecoilComponentFamilyStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentFamilyStateCallbackStateV2'; import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2'; import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2'; import { isDefined } from 'twenty-shared/utils'; +import { useStore } from 'jotai'; type FavoriteFolderPickerEffectProps = { record?: ObjectRecord; @@ -21,10 +21,11 @@ type FavoriteFolderPickerEffectProps = { export const FavoriteFolderPickerEffect = ({ record, }: FavoriteFolderPickerEffectProps) => { + const store = useStore(); const [favoriteFolderIdsPicker, setFavoriteFolderIdsPicker] = useRecoilComponentStateV2(favoriteFolderIdsPickerComponentState); - const favoriteFolderPickerFamilyAtom = + const favoriteFolderPickerFamily = useRecoilComponentFamilyStateCallbackStateV2( favoriteFolderPickerComponentFamilyState, ); @@ -39,15 +40,15 @@ export const FavoriteFolderPickerEffect = ({ const updateFolders = useCallback( (folders: FavoriteFolder[]) => { folders.forEach((folder) => { - const atom = favoriteFolderPickerFamilyAtom(folder.id); - const currentFolder = jotaiStore.get(atom); + const atom = favoriteFolderPickerFamily(folder.id); + const currentFolder = store.get(atom); if (!isDeeplyEqual(folder, currentFolder)) { - jotaiStore.set(atom, folder); + store.set(atom, folder); } }); }, - [favoriteFolderPickerFamilyAtom], + [favoriteFolderPickerFamily, store], ); useEffect(() => { diff --git a/packages/twenty-front/src/modules/favorites/favorite-folder-picker/hooks/useFavoriteFolderPicker.ts b/packages/twenty-front/src/modules/favorites/favorite-folder-picker/hooks/useFavoriteFolderPicker.ts index 939ece2b61..852aa484e1 100644 --- a/packages/twenty-front/src/modules/favorites/favorite-folder-picker/hooks/useFavoriteFolderPicker.ts +++ b/packages/twenty-front/src/modules/favorites/favorite-folder-picker/hooks/useFavoriteFolderPicker.ts @@ -26,7 +26,7 @@ export const useFavoriteFolderPicker = ({ record, objectNameSingular, }: useFavoriteFolderPickerProps): useFavoriteFolderPickerReturnType => { - const favoriteFoldersMultiSelectCheckedAtom = + const favoriteFoldersMultiSelectChecked = useRecoilComponentStateCallbackStateV2( favoriteFolderPickerCheckedComponentState, ); @@ -70,7 +70,7 @@ export const useFavoriteFolderPicker = ({ await deleteFavorite(favoriteToDelete.id); }; - const checkedIds = store.get(favoriteFoldersMultiSelectCheckedAtom); + const checkedIds = store.get(favoriteFoldersMultiSelectChecked); const isAlreadyChecked = checkedIds.includes(folderId); @@ -78,7 +78,7 @@ export const useFavoriteFolderPicker = ({ await deleteFavoriteForRecord(folderId === 'no-folder'); const newCheckedIds = checkedIds.filter((id) => id !== folderId); - store.set(favoriteFoldersMultiSelectCheckedAtom, newCheckedIds); + store.set(favoriteFoldersMultiSelectChecked, newCheckedIds); return; } @@ -89,10 +89,10 @@ export const useFavoriteFolderPicker = ({ } const newCheckedIds = [...checkedIds, folderId]; - store.set(favoriteFoldersMultiSelectCheckedAtom, newCheckedIds); + store.set(favoriteFoldersMultiSelectChecked, newCheckedIds); }, [ - favoriteFoldersMultiSelectCheckedAtom, + favoriteFoldersMultiSelectChecked, createFavorite, deleteFavorite, favorites, diff --git a/packages/twenty-front/src/modules/front-components/hooks/useMountHeadlessFrontComponent.ts b/packages/twenty-front/src/modules/front-components/hooks/useMountHeadlessFrontComponent.ts index 2b2dfc5a02..999bef33f0 100644 --- a/packages/twenty-front/src/modules/front-components/hooks/useMountHeadlessFrontComponent.ts +++ b/packages/twenty-front/src/modules/front-components/hooks/useMountHeadlessFrontComponent.ts @@ -1,17 +1,17 @@ import { useCallback } from 'react'; import { mountedHeadlessFrontComponentIdsState } from '@/front-components/states/mountedHeadlessFrontComponentIdsState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; +import { useStore } from 'jotai'; export const useMountHeadlessFrontComponent = () => { + const store = useStore(); const mountHeadlessFrontComponent = useCallback( (frontComponentId: string) => { - jotaiStore.set( - mountedHeadlessFrontComponentIdsState.atom, - (previousIds) => new Set(previousIds).add(frontComponentId), + store.set(mountedHeadlessFrontComponentIdsState.atom, (previousIds) => + new Set(previousIds).add(frontComponentId), ); }, - [], + [store], ); return mountHeadlessFrontComponent; diff --git a/packages/twenty-front/src/modules/front-components/hooks/useUnmountHeadlessFrontComponent.ts b/packages/twenty-front/src/modules/front-components/hooks/useUnmountHeadlessFrontComponent.ts index 166d4eb9e4..99294969a3 100644 --- a/packages/twenty-front/src/modules/front-components/hooks/useUnmountHeadlessFrontComponent.ts +++ b/packages/twenty-front/src/modules/front-components/hooks/useUnmountHeadlessFrontComponent.ts @@ -1,21 +1,19 @@ import { useCallback } from 'react'; import { mountedHeadlessFrontComponentIdsState } from '@/front-components/states/mountedHeadlessFrontComponentIdsState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; +import { useStore } from 'jotai'; export const useUnmountHeadlessFrontComponent = () => { + const store = useStore(); const unmountHeadlessFrontComponent = useCallback( (frontComponentId: string) => { - jotaiStore.set( - mountedHeadlessFrontComponentIdsState.atom, - (previousIds) => { - const next = new Set(previousIds); - next.delete(frontComponentId); - return next; - }, - ); + store.set(mountedHeadlessFrontComponentIdsState.atom, (previousIds) => { + const next = new Set(previousIds); + next.delete(frontComponentId); + return next; + }); }, - [], + [store], ); return unmountHeadlessFrontComponent; diff --git a/packages/twenty-front/src/modules/metadata-store/effect-components/ObjectMetadataProviderInitialEffect.tsx b/packages/twenty-front/src/modules/metadata-store/effect-components/ObjectMetadataProviderInitialEffect.tsx index 5f29c3e4f2..c6d2ff7efb 100644 --- a/packages/twenty-front/src/modules/metadata-store/effect-components/ObjectMetadataProviderInitialEffect.tsx +++ b/packages/twenty-front/src/modules/metadata-store/effect-components/ObjectMetadataProviderInitialEffect.tsx @@ -20,8 +20,12 @@ export const ObjectMetadataProviderInitialEffect = () => { const { updateDraft, applyChanges } = useMetadataStore(); useEffect(() => { - if (isInitialized) return; - if (!isCurrentUserLoaded) return; + if (isInitialized) { + return; + } + if (!isCurrentUserLoaded) { + return; + } const shouldLoadReal = isWorkspaceActiveOrSuspended(currentWorkspace); diff --git a/packages/twenty-front/src/modules/metadata-store/effect-components/UserMetadataProviderInitialEffect.tsx b/packages/twenty-front/src/modules/metadata-store/effect-components/UserMetadataProviderInitialEffect.tsx index 6882dee2e7..a34d602c08 100644 --- a/packages/twenty-front/src/modules/metadata-store/effect-components/UserMetadataProviderInitialEffect.tsx +++ b/packages/twenty-front/src/modules/metadata-store/effect-components/UserMetadataProviderInitialEffect.tsx @@ -15,20 +15,17 @@ import { type ColorScheme } from '@/workspace-member/types/WorkspaceMember'; import { enUS } from 'date-fns/locale'; import { useStore } from 'jotai'; import { useCallback, useEffect, useState } from 'react'; -import { useLocation } from 'react-router-dom'; import { type APP_LOCALES, SOURCE_LOCALE } from 'twenty-shared/translations'; -import { AppPath, type ObjectPermissions } from 'twenty-shared/types'; +import { type ObjectPermissions } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; import { useGetCurrentUserQuery, type WorkspaceMember, } from '~/generated-metadata/graphql'; -import { dateLocaleStateV2 } from '~/localization/states/dateLocaleStateV2'; +import { dateLocaleState } from '~/localization/states/dateLocaleState'; import { dynamicActivate } from '~/utils/i18n/dynamicActivate'; -import { isMatchingLocation } from '~/utils/isMatchingLocation'; export const UserMetadataProviderInitialEffect = () => { - const location = useLocation(); const isLoggedIn = useIsLogged(); const currentUser = useRecoilValueV2(currentUserState); const store = useStore(); @@ -53,28 +50,23 @@ export const UserMetadataProviderInitialEffect = () => { const { initializeFormatPreferences } = useInitializeFormatPreferences(); - const isOnAuthPath = - isMatchingLocation(location, AppPath.Verify) || - isMatchingLocation(location, AppPath.VerifyEmail); - const updateLocaleCatalog = useCallback( async (newLocale: keyof typeof APP_LOCALES) => { - const localeValue = store.get(dateLocaleStateV2.atom); + const localeValue = store.get(dateLocaleState.atom); if (localeValue.locale !== newLocale) { getDateFnsLocale(newLocale).then((localeCatalog) => { const newValue = { locale: newLocale, localeCatalog: localeCatalog || enUS, }; - store.set(dateLocaleStateV2.atom, newValue); + store.set(dateLocaleState.atom, newValue); }); } }, [store], ); - const shouldSkipUserQuery = - !isLoggedIn || isDefined(currentUser) || isOnAuthPath; + const shouldSkipUserQuery = !isLoggedIn || isDefined(currentUser); const { data: userQueryData, loading: userQueryLoading } = useGetCurrentUserQuery({ @@ -82,7 +74,9 @@ export const UserMetadataProviderInitialEffect = () => { }); useEffect(() => { - if (isInitialized) return; + if (isInitialized) { + return; + } if (!isLoggedIn) { setIsCurrentUserLoaded(true); diff --git a/packages/twenty-front/src/modules/metadata-store/effect-components/ViewMetadataProviderInitialEffect.tsx b/packages/twenty-front/src/modules/metadata-store/effect-components/ViewMetadataProviderInitialEffect.tsx index f4a48dedd7..6c941a6c62 100644 --- a/packages/twenty-front/src/modules/metadata-store/effect-components/ViewMetadataProviderInitialEffect.tsx +++ b/packages/twenty-front/src/modules/metadata-store/effect-components/ViewMetadataProviderInitialEffect.tsx @@ -48,8 +48,12 @@ export const ViewMetadataProviderInitialEffect = () => { ); useEffect(() => { - if (isInitialized) return; - if (!isCurrentUserLoaded) return; + if (isInitialized) { + return; + } + if (!isCurrentUserLoaded) { + return; + } if (!isLoggedIn || !isWorkspaceActiveOrSuspended(currentWorkspace)) { setIsInitialized(true); diff --git a/packages/twenty-front/src/modules/navigation-menu-item/components/WorkspaceNavigationMenuItems.tsx b/packages/twenty-front/src/modules/navigation-menu-item/components/WorkspaceNavigationMenuItems.tsx index a32751dbf5..10557df85a 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/components/WorkspaceNavigationMenuItems.tsx +++ b/packages/twenty-front/src/modules/navigation-menu-item/components/WorkspaceNavigationMenuItems.tsx @@ -1,7 +1,6 @@ import styled from '@emotion/styled'; import { useLingui } from '@lingui/react/macro'; import { useNavigate } from 'react-router-dom'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { IconLink, IconPlus, IconTool, useIcons } from 'twenty-ui/display'; import { LightIconButton } from 'twenty-ui/input'; import { FeatureFlagKey } from '~/generated-metadata/graphql'; @@ -43,7 +42,7 @@ export const WorkspaceNavigationMenuItems = () => { const items = useWorkspaceSectionItems(); const store = useStore(); const enterEditMode = () => { - const prefetchNavigationMenuItems = jotaiStore.get( + const prefetchNavigationMenuItems = store.get( prefetchNavigationMenuItemsState.atom, ); const workspaceNavigationMenuItems = filterWorkspaceNavigationMenuItems( diff --git a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useHandleAddToNavigationDrop.ts b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useHandleAddToNavigationDrop.ts index cad85afaa3..022ac8da2d 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useHandleAddToNavigationDrop.ts +++ b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useHandleAddToNavigationDrop.ts @@ -20,14 +20,15 @@ import { openNavigationMenuItemFolderIdsStateV2 } from '@/navigation-menu-item/s import { selectedNavigationMenuItemInEditModeStateV2 } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeStateV2'; 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 { isWorkspaceDroppableId } from '@/navigation-menu-item/utils/isWorkspaceDroppableId'; import { validateAndExtractWorkspaceFolderId } from '@/navigation-menu-item/utils/validateAndExtractWorkspaceFolderId'; import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems'; import { coreViewsState } from '@/views/states/coreViewState'; import { convertCoreViewToView } from '@/views/utils/convertCoreViewToView'; +import { useStore } from 'jotai'; export const useHandleAddToNavigationDrop = () => { + const store = useStore(); const { addObjectToDraft } = useAddObjectToNavigationMenuDraft(); const { addViewToDraft } = useAddViewToNavigationMenuDraft(); const { addRecordToDraft } = useAddRecordToNavigationMenuDraft(); @@ -64,8 +65,7 @@ export const useHandleAddToNavigationDrop = () => { } const payload = - jotaiStore.get(addToNavPayloadRegistryStateV2.atom).get(draggableId) ?? - null; + store.get(addToNavPayloadRegistryStateV2.atom).get(draggableId) ?? null; if (!payload) { return; } @@ -203,6 +203,7 @@ export const useHandleAddToNavigationDrop = () => { setIsNavigationMenuInEditMode, setSelectedNavigationMenuItemInEditMode, workspaceNavigationMenuItems, + store, ], ); diff --git a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useRemoveNavigationMenuItemByTargetRecordId.ts b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useRemoveNavigationMenuItemByTargetRecordId.ts index 1d66044c0a..2e41f2cde0 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useRemoveNavigationMenuItemByTargetRecordId.ts +++ b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useRemoveNavigationMenuItemByTargetRecordId.ts @@ -3,11 +3,12 @@ import { useCallback } from 'react'; import { FIND_MANY_NAVIGATION_MENU_ITEMS } from '@/navigation-menu-item/graphql/queries/findManyNavigationMenuItems'; import { useApolloCoreClient } from '@/object-metadata/hooks/useApolloCoreClient'; import { prefetchNavigationMenuItemsState } from '@/prefetch/states/prefetchNavigationMenuItemsState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { isDefined } from 'twenty-shared/utils'; +import { useStore } from 'jotai'; export const useRemoveNavigationMenuItemByTargetRecordId = () => { + const store = useStore(); const apolloCoreClient = useApolloCoreClient(); const cache = apolloCoreClient.cache; @@ -18,7 +19,7 @@ export const useRemoveNavigationMenuItemByTargetRecordId = () => { const removeNavigationMenuItemsByTargetRecordIds = useCallback( (targetRecordIds: string[]) => { const targetRecordIdsSet = new Set(targetRecordIds); - const currentNavigationMenuItems = jotaiStore.get( + const currentNavigationMenuItems = store.get( prefetchNavigationMenuItemsState.atom, ); @@ -41,7 +42,7 @@ export const useRemoveNavigationMenuItemByTargetRecordId = () => { }; }); }, - [cache, setNavigationMenuItemsState], + [cache, setNavigationMenuItemsState, store], ); return { diff --git a/packages/twenty-front/src/modules/navigation/hooks/useDefaultHomePagePath.ts b/packages/twenty-front/src/modules/navigation/hooks/useDefaultHomePagePath.ts index cf3cfa4f4f..b4b7c3961c 100644 --- a/packages/twenty-front/src/modules/navigation/hooks/useDefaultHomePagePath.ts +++ b/packages/twenty-front/src/modules/navigation/hooks/useDefaultHomePagePath.ts @@ -1,6 +1,5 @@ import { currentUserState } from '@/auth/states/currentUserState'; import { lastVisitedObjectMetadataItemIdState } from '@/navigation/states/lastVisitedObjectMetadataItemIdState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { type ObjectPathInfo } from '@/navigation/types/ObjectPathInfo'; import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems'; import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions'; @@ -12,8 +11,10 @@ import isEmpty from 'lodash.isempty'; import { useCallback, useMemo } from 'react'; import { AppPath, SettingsPath } from 'twenty-shared/types'; import { getAppPath, getSettingsPath, isDefined } from 'twenty-shared/utils'; +import { useStore } from 'jotai'; export const useDefaultHomePagePath = () => { + const store = useStore(); const currentUser = useRecoilValueV2(currentUserState); const { objectPermissionsByObjectMetadataId } = useObjectPermissions(); @@ -69,7 +70,7 @@ export const useDefaultHomePagePath = () => { }, [getFirstView, readableAlphaSortedActiveNonSystemObjectMetadataItems]); const getDefaultObjectPathInfo = useCallback(() => { - const lastVisitedObjectMetadataItemId = jotaiStore.get( + const lastVisitedObjectMetadataItemId = store.get( lastVisitedObjectMetadataItemIdState.atom, ); @@ -91,6 +92,7 @@ export const useDefaultHomePagePath = () => { firstObjectPathInfo, getActiveObjectMetadataItemMatchingId, getFirstView, + store, ]); const defaultHomePagePath = useMemo(() => { diff --git a/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedObjectMetadataId.ts b/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedObjectMetadataId.ts index 9d9025aeba..91051ceebc 100644 --- a/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedObjectMetadataId.ts +++ b/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedObjectMetadataId.ts @@ -1,19 +1,20 @@ import { lastVisitedObjectMetadataItemIdState } from '@/navigation/states/lastVisitedObjectMetadataItemIdState'; import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useCallback } from 'react'; import { isDefined } from 'twenty-shared/utils'; +import { useStore } from 'jotai'; export const useSetLastVisitedObjectMetadataId = () => { + const store = useStore(); const setLastVisitedObjectMetadataId = useCallback( ({ objectMetadataItemId }: { objectMetadataItemId: string }) => { - const objectMetadataItems = jotaiStore.get(objectMetadataItemsState.atom); + const objectMetadataItems = store.get(objectMetadataItemsState.atom); const objectMetadataItem = objectMetadataItems.find( (item) => item.id === objectMetadataItemId, ); - const lastVisitedObjectMetadataItemId = jotaiStore.get( + const lastVisitedObjectMetadataItemId = store.get( lastVisitedObjectMetadataItemIdState.atom, ); @@ -21,13 +22,13 @@ export const useSetLastVisitedObjectMetadataId = () => { isDefined(objectMetadataItem) && lastVisitedObjectMetadataItemId !== objectMetadataItemId ) { - jotaiStore.set( + store.set( lastVisitedObjectMetadataItemIdState.atom, objectMetadataItemId, ); } }, - [], + [store], ); return { diff --git a/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts b/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts index 6fa1185aee..cafd038901 100644 --- a/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts +++ b/packages/twenty-front/src/modules/navigation/hooks/useSetLastVisitedViewForObjectMetadataNamePlural.ts @@ -1,12 +1,13 @@ import { lastVisitedViewPerObjectMetadataItemState } from '@/navigation/states/lastVisitedViewPerObjectMetadataItemState'; import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { coreViewsState } from '@/views/states/coreViewState'; import { type CoreViewWithRelations } from '@/views/types/CoreViewWithRelations'; import { useCallback } from 'react'; import { isDefined } from 'twenty-shared/utils'; +import { useStore } from 'jotai'; export const useSetLastVisitedViewForObjectMetadataNamePlural = () => { + const store = useStore(); const setLastVisitedViewForObjectMetadataNamePlural = useCallback( async ({ objectNamePlural, @@ -15,13 +16,13 @@ export const useSetLastVisitedViewForObjectMetadataNamePlural = () => { objectNamePlural: string; viewId: string; }) => { - const views = jotaiStore.get(coreViewsState.atom); + const views = store.get(coreViewsState.atom); const view = views.find( (view: CoreViewWithRelations) => view.id === viewId, ); - const objectMetadataItems = jotaiStore.get(objectMetadataItemsState.atom); + const objectMetadataItems = store.get(objectMetadataItemsState.atom); const objectMetadataItem = objectMetadataItems.find( (item) => item.namePlural === objectNamePlural, @@ -35,7 +36,7 @@ export const useSetLastVisitedViewForObjectMetadataNamePlural = () => { return; } - const lastVisitedViewPerObjectMetadataItem = jotaiStore.get( + const lastVisitedViewPerObjectMetadataItem = store.get( lastVisitedViewPerObjectMetadataItemState.atom, ); @@ -43,13 +44,13 @@ export const useSetLastVisitedViewForObjectMetadataNamePlural = () => { lastVisitedViewPerObjectMetadataItem?.[objectMetadataItem?.id]; if (isDefined(objectMetadataItem) && lastVisitedViewId !== viewId) { - jotaiStore.set(lastVisitedViewPerObjectMetadataItemState.atom, { + store.set(lastVisitedViewPerObjectMetadataItemState.atom, { ...lastVisitedViewPerObjectMetadataItem, [objectMetadataItem.id]: viewId, }); } }, - [], + [store], ); return { diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/useGetFieldMetadataItemById.ts b/packages/twenty-front/src/modules/object-metadata/hooks/useGetFieldMetadataItemById.ts index 3f39899f25..d6c22b64f9 100644 --- a/packages/twenty-front/src/modules/object-metadata/hooks/useGetFieldMetadataItemById.ts +++ b/packages/twenty-front/src/modules/object-metadata/hooks/useGetFieldMetadataItemById.ts @@ -1,10 +1,10 @@ import { useCallback } from 'react'; import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { getFieldMetadataItemByIdOrThrow } from '@/object-metadata/utils/getFieldMetadataItemByIdOrThrow'; +import { useStore } from 'jotai'; type GetFieldMetadataItemByIdOrThrowResult = { fieldMetadataItem: FieldMetadataItem; @@ -12,16 +12,17 @@ type GetFieldMetadataItemByIdOrThrowResult = { }; export const useGetFieldMetadataItemByIdOrThrow = () => { + const store = useStore(); const getFieldMetadataItemByIdOrThrowCallback = useCallback( (fieldMetadataId: string): GetFieldMetadataItemByIdOrThrowResult => { - const objectMetadataItems = jotaiStore.get(objectMetadataItemsState.atom); + const objectMetadataItems = store.get(objectMetadataItemsState.atom); return getFieldMetadataItemByIdOrThrow({ fieldMetadataId, objectMetadataItems, }); }, - [], + [store], ); return { diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/useGetRelationMetadata.ts b/packages/twenty-front/src/modules/object-metadata/hooks/useGetRelationMetadata.ts index ef4f00c026..697ed6606f 100644 --- a/packages/twenty-front/src/modules/object-metadata/hooks/useGetRelationMetadata.ts +++ b/packages/twenty-front/src/modules/object-metadata/hooks/useGetRelationMetadata.ts @@ -1,13 +1,15 @@ import { useCallback } from 'react'; import { objectMetadataItemFamilySelector } from '@/object-metadata/states/objectMetadataItemFamilySelector'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { FieldMetadataType } from '~/generated-metadata/graphql'; import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; +import { useStore } from 'jotai'; -export const useGetRelationMetadata = () => - useCallback( +export const useGetRelationMetadata = () => { + const store = useStore(); + + return useCallback( ({ fieldMetadataItem, }: { @@ -19,7 +21,7 @@ export const useGetRelationMetadata = () => if (!relation) return null; - const relationObjectMetadataItem = jotaiStore.get( + const relationObjectMetadataItem = store.get( objectMetadataItemFamilySelector.selectorFamily({ objectName: relation.targetObjectMetadata.nameSingular, objectNameType: 'singular', @@ -40,5 +42,6 @@ export const useGetRelationMetadata = () => relationType: relation.type, }; }, - [], + [store], ); +}; diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/useLoadMockedObjectMetadataItems.ts b/packages/twenty-front/src/modules/object-metadata/hooks/useLoadMockedObjectMetadataItems.ts index f8d3b6d5f3..779e3e10c0 100644 --- a/packages/twenty-front/src/modules/object-metadata/hooks/useLoadMockedObjectMetadataItems.ts +++ b/packages/twenty-front/src/modules/object-metadata/hooks/useLoadMockedObjectMetadataItems.ts @@ -1,28 +1,29 @@ import { isAppEffectRedirectEnabledState } from '@/app/states/isAppEffectRedirectEnabledState'; import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useCallback } from 'react'; import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; +import { useStore } from 'jotai'; export const useLoadMockedObjectMetadataItems = () => { + const store = useStore(); const loadMockedObjectMetadataItems = useCallback(async () => { if ( !isDeeplyEqual( - jotaiStore.get(objectMetadataItemsState.atom), + store.get(objectMetadataItemsState.atom), generatedMockObjectMetadataItems, ) ) { - jotaiStore.set( + store.set( objectMetadataItemsState.atom, generatedMockObjectMetadataItems, ); } - if (jotaiStore.get(isAppEffectRedirectEnabledState.atom) === false) { - jotaiStore.set(isAppEffectRedirectEnabledState.atom, true); + if (store.get(isAppEffectRedirectEnabledState.atom) === false) { + store.set(isAppEffectRedirectEnabledState.atom, true); } - }, []); + }, [store]); return { loadMockedObjectMetadataItems, diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/useRefreshObjectMetadataItems.ts b/packages/twenty-front/src/modules/object-metadata/hooks/useRefreshObjectMetadataItems.ts index 0296621f1c..ae37f9dee9 100644 --- a/packages/twenty-front/src/modules/object-metadata/hooks/useRefreshObjectMetadataItems.ts +++ b/packages/twenty-front/src/modules/object-metadata/hooks/useRefreshObjectMetadataItems.ts @@ -5,17 +5,18 @@ import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadat import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { enrichObjectMetadataItemsWithPermissions } from '@/object-metadata/utils/enrichObjectMetadataItemsWithPermissions'; import { mapPaginatedObjectMetadataItemsToObjectMetadataItems } from '@/object-metadata/utils/mapPaginatedObjectMetadataItemsToObjectMetadataItems'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { type FetchPolicy, useApolloClient } from '@apollo/client'; import { useCallback } from 'react'; import { type ObjectPermissions } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; import { type ObjectMetadataItemsQuery } from '~/generated-metadata/graphql'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; +import { useStore } from 'jotai'; export const useRefreshObjectMetadataItems = ( fetchPolicy: FetchPolicy = 'network-only', ) => { + const store = useStore(); const client = useApolloClient(); const replaceObjectMetadataItemIfDifferent = useCallback( @@ -25,9 +26,7 @@ export const useRefreshObjectMetadataItems = ( 'readableFields' | 'updatableFields' >[], ) => { - const currentUserWorkspace = jotaiStore.get( - currentUserWorkspaceState.atom, - ); + const currentUserWorkspace = store.get(currentUserWorkspaceState.atom); if (!isDefined(currentUserWorkspace)) { return; @@ -52,21 +51,21 @@ export const useRefreshObjectMetadataItems = ( if ( !isDeeplyEqual( - jotaiStore.get(objectMetadataItemsState.atom), + store.get(objectMetadataItemsState.atom), newObjectMetadataItems, ) && newObjectMetadataItems.length > 0 ) { - jotaiStore.set(objectMetadataItemsState.atom, newObjectMetadataItems); + store.set(objectMetadataItemsState.atom, newObjectMetadataItems); } - if (jotaiStore.get(isAppEffectRedirectEnabledState.atom) === false) { - jotaiStore.set(isAppEffectRedirectEnabledState.atom, true); + if (store.get(isAppEffectRedirectEnabledState.atom) === false) { + store.set(isAppEffectRedirectEnabledState.atom, true); } return newObjectMetadataItems; }, - [], + [store], ); const refreshObjectMetadataItems = async () => { diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/hooks/useGetDefaultFieldMetadataItemForFilter.ts b/packages/twenty-front/src/modules/object-record/advanced-filter/hooks/useGetDefaultFieldMetadataItemForFilter.ts index df49b213e0..04d39aa285 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/hooks/useGetDefaultFieldMetadataItemForFilter.ts +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/hooks/useGetDefaultFieldMetadataItemForFilter.ts @@ -1,13 +1,14 @@ import { availableFieldMetadataItemsForFilterFamilySelector } from '@/object-metadata/states/availableFieldMetadataItemsForFilterFamilySelector'; import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useCallback } from 'react'; +import { useStore } from 'jotai'; export const useGetDefaultFieldMetadataItemForFilter = () => { + const store = useStore(); const getDefaultFieldMetadataItemForFilter = useCallback( (objectMetadataItem: ObjectMetadataItem) => { - const availableFieldMetadataItemsForFilter = jotaiStore.get( + const availableFieldMetadataItemsForFilter = store.get( availableFieldMetadataItemsForFilterFamilySelector.selectorFamily({ objectMetadataItemId: objectMetadataItem.id, }), @@ -30,7 +31,7 @@ export const useGetDefaultFieldMetadataItemForFilter = () => { return { defaultFieldMetadataItemForFilter }; }, - [], + [store], ); return { diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/hooks/useSetAdvancedFilterDropdownAllRowsStates.ts b/packages/twenty-front/src/modules/object-record/advanced-filter/hooks/useSetAdvancedFilterDropdownAllRowsStates.ts index 3a16831725..2aa2683980 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/hooks/useSetAdvancedFilterDropdownAllRowsStates.ts +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/hooks/useSetAdvancedFilterDropdownAllRowsStates.ts @@ -6,12 +6,13 @@ import { subFieldNameUsedInDropdownComponentState } from '@/object-record/object import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState'; import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState'; import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useRecoilComponentSelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentSelectorValueV2'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2'; import { useCallback } from 'react'; +import { useStore } from 'jotai'; export const useSetAdvancedFilterDropdownStates = () => { + const store = useStore(); const rootLevelRecordFilterGroup = useRecoilComponentSelectorValueV2( rootLevelRecordFilterGroupComponentSelector, ); @@ -38,21 +39,21 @@ export const useSetAdvancedFilterDropdownStates = () => { recordFilter.id, ); - jotaiStore.set( + store.set( objectFilterDropdownCurrentRecordFilterComponentState.atomFamily({ instanceId, }), recordFilter, ); - jotaiStore.set( + store.set( fieldMetadataItemIdUsedInDropdownComponentState.atomFamily({ instanceId, }), recordFilter.fieldMetadataId, ); - jotaiStore.set( + store.set( subFieldNameUsedInDropdownComponentState.atomFamily({ instanceId, }), @@ -84,6 +85,7 @@ export const useSetAdvancedFilterDropdownStates = () => { currentRecordFilterGroups, currentRecordFilters, rootLevelRecordFilterGroup, + store, ]); return { diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/hooks/useSetRecordFilterUsedInAdvancedFilterDropdownRow.ts b/packages/twenty-front/src/modules/object-record/advanced-filter/hooks/useSetRecordFilterUsedInAdvancedFilterDropdownRow.ts index a666169d3b..cc1bdd8688 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/hooks/useSetRecordFilterUsedInAdvancedFilterDropdownRow.ts +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/hooks/useSetRecordFilterUsedInAdvancedFilterDropdownRow.ts @@ -3,10 +3,11 @@ import { fieldMetadataItemIdUsedInDropdownComponentState } from '@/object-record import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState'; import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState'; import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useCallback } from 'react'; +import { useStore } from 'jotai'; export const useSetRecordFilterUsedInAdvancedFilterDropdownRow = () => { + const store = useStore(); const setRecordFilterUsedInAdvancedFilterDropdownRow = useCallback( (recordFilter: RecordFilter) => { const advancedFilterRowObjectFilterDropdownComponentInstanceId = @@ -14,28 +15,28 @@ export const useSetRecordFilterUsedInAdvancedFilterDropdownRow = () => { recordFilter.id, ); - jotaiStore.set( + store.set( fieldMetadataItemIdUsedInDropdownComponentState.atomFamily({ instanceId: advancedFilterRowObjectFilterDropdownComponentInstanceId, }), recordFilter.fieldMetadataId, ); - jotaiStore.set( + store.set( selectedOperandInDropdownComponentState.atomFamily({ instanceId: advancedFilterRowObjectFilterDropdownComponentInstanceId, }), recordFilter.operand, ); - jotaiStore.set( + store.set( objectFilterDropdownCurrentRecordFilterComponentState.atomFamily({ instanceId: advancedFilterRowObjectFilterDropdownComponentInstanceId, }), recordFilter, ); }, - [], + [store], ); return { diff --git a/packages/twenty-front/src/modules/object-record/hooks/useFetchMoreRecordsWithPagination.ts b/packages/twenty-front/src/modules/object-record/hooks/useFetchMoreRecordsWithPagination.ts index e547b08ed0..286c52c8d3 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useFetchMoreRecordsWithPagination.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useFetchMoreRecordsWithPagination.ts @@ -31,8 +31,8 @@ import { hasNextPageFamilyState } from '@/object-record/states/hasNextPageFamily import { isFetchingMoreRecordsFamilyState } from '@/object-record/states/isFetchingMoreRecordsFamilyState'; import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2'; import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { capitalize, isDefined } from 'twenty-shared/utils'; +import { useStore } from 'jotai'; export type UseFindManyRecordsParams = ObjectMetadataItemIdentifier & RecordGqlOperationVariables & { @@ -81,6 +81,7 @@ export const useFetchMoreRecordsWithPagination = < objectMetadataItem, onCompleted, }: UseFindManyRecordsStateParams) => { + const store = useStore(); const queryIdentifier = getQueryIdentifier({ objectNameSingular, filter, @@ -105,11 +106,11 @@ export const useFetchMoreRecordsWithPagination = < // TODO: put this into a util inspired from https://github.com/apollographql/apollo-client/blob/master/src/utilities/policies/pagination.ts // This function is equivalent to merge function + read function in field policy const fetchMoreRecords = useCallback(async () => { - const hasNextPageLocal = jotaiStore.get( + const hasNextPageLocal = store.get( hasNextPageFamilyState.atomFamily(queryIdentifier), ); - const lastCursorLocal = jotaiStore.get( + const lastCursorLocal = store.get( cursorFamilyState.atomFamily(queryIdentifier), ); @@ -147,11 +148,11 @@ export const useFetchMoreRecordsWithPagination = < fetchMoreResult?.[objectMetadataItem.namePlural]?.pageInfo; if (isDefined(pageInfo)) { - jotaiStore.set( + store.set( cursorFamilyState.atomFamily(queryIdentifier), pageInfo.endCursor ?? '', ); - jotaiStore.set( + store.set( hasNextPageFamilyState.atomFamily(queryIdentifier), pageInfo.hasNextPage ?? false, ); @@ -205,6 +206,7 @@ export const useFetchMoreRecordsWithPagination = < onCompleted, handleFindManyRecordsError, queryIdentifier, + store, ]); const totalCount = data?.[objectMetadataItem.namePlural]?.totalCount; diff --git a/packages/twenty-front/src/modules/object-record/hooks/useHandleFindManyRecordsCompleted.ts b/packages/twenty-front/src/modules/object-record/hooks/useHandleFindManyRecordsCompleted.ts index 87cce36186..339b0a2198 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useHandleFindManyRecordsCompleted.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useHandleFindManyRecordsCompleted.ts @@ -4,9 +4,9 @@ import { type RecordGqlOperationFindManyResult } from '@/object-record/graphql/t import { cursorFamilyState } from '@/object-record/states/cursorFamilyState'; import { hasNextPageFamilyState } from '@/object-record/states/hasNextPageFamilyState'; import { type OnFindManyRecordsCompleted } from '@/object-record/types/OnFindManyRecordsCompleted'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useCallback } from 'react'; import { isDefined } from 'twenty-shared/utils'; +import { useStore } from 'jotai'; export const useHandleFindManyRecordsCompleted = ({ queryIdentifier, @@ -17,6 +17,7 @@ export const useHandleFindManyRecordsCompleted = ({ objectMetadataItem: ObjectMetadataItem; onCompleted?: OnFindManyRecordsCompleted; }) => { + const store = useStore(); const handleFindManyRecordsCompleted = useCallback( (data: RecordGqlOperationFindManyResult) => { const pageInfo = data?.[objectMetadataItem.namePlural]?.pageInfo; @@ -31,17 +32,17 @@ export const useHandleFindManyRecordsCompleted = ({ }); if (isDefined(data?.[objectMetadataItem.namePlural])) { - jotaiStore.set( + store.set( cursorFamilyState.atomFamily(queryIdentifier), pageInfo.endCursor ?? '', ); - jotaiStore.set( + store.set( hasNextPageFamilyState.atomFamily(queryIdentifier), pageInfo.hasNextPage ?? false, ); } }, - [objectMetadataItem.namePlural, onCompleted, queryIdentifier], + [objectMetadataItem.namePlural, onCompleted, queryIdentifier, store], ); return { diff --git a/packages/twenty-front/src/modules/object-record/hooks/useLazyFetchMoreRecordsWithPagination.ts b/packages/twenty-front/src/modules/object-record/hooks/useLazyFetchMoreRecordsWithPagination.ts index f7d60cfc46..884e3937af 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useLazyFetchMoreRecordsWithPagination.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useLazyFetchMoreRecordsWithPagination.ts @@ -29,8 +29,8 @@ import { import { DEFAULT_SEARCH_REQUEST_LIMIT } from '@/object-record/constants/DefaultSearchRequestLimit'; import { cursorFamilyState } from '@/object-record/states/cursorFamilyState'; import { hasNextPageFamilyState } from '@/object-record/states/hasNextPageFamilyState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { capitalize, isDefined } from 'twenty-shared/utils'; +import { useStore } from 'jotai'; export type UseFindManyRecordsParams = ObjectMetadataItemIdentifier & RecordGqlOperationVariables & { @@ -77,6 +77,7 @@ export const useLazyFetchMoreRecordsWithPagination = < fetchMore, objectMetadataItem, }: UseFindManyRecordsStateParams) => { + const store = useStore(); const queryIdentifier = getQueryIdentifier({ objectNameSingular, filter, @@ -92,11 +93,11 @@ export const useLazyFetchMoreRecordsWithPagination = < // This function is equivalent to merge function + read function in field policy const fetchMoreRecordsLazy = useCallback( async (limit = DEFAULT_SEARCH_REQUEST_LIMIT) => { - const hasNextPageLocal = jotaiStore.get( + const hasNextPageLocal = store.get( hasNextPageFamilyState.atomFamily(queryIdentifier), ); - const lastCursorLocal = jotaiStore.get( + const lastCursorLocal = store.get( cursorFamilyState.atomFamily(queryIdentifier), ); @@ -135,11 +136,11 @@ export const useLazyFetchMoreRecordsWithPagination = < fetchMoreResult?.[objectMetadataItem.namePlural]?.pageInfo; if (isDefined(pageInfo)) { - jotaiStore.set( + store.set( cursorFamilyState.atomFamily(queryIdentifier), pageInfo.endCursor ?? '', ); - jotaiStore.set( + store.set( hasNextPageFamilyState.atomFamily(queryIdentifier), pageInfo.hasNextPage ?? false, ); @@ -188,6 +189,7 @@ export const useLazyFetchMoreRecordsWithPagination = < filter, orderBy, handleFindManyRecordsError, + store, ], ); diff --git a/packages/twenty-front/src/modules/object-record/hooks/useLazyFindManyRecords.ts b/packages/twenty-front/src/modules/object-record/hooks/useLazyFindManyRecords.ts index 0a96c21687..620f079b17 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useLazyFindManyRecords.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useLazyFindManyRecords.ts @@ -13,10 +13,10 @@ import { useObjectPermissionsForObject } from '@/object-record/hooks/useObjectPe import { cursorFamilyState } from '@/object-record/states/cursorFamilyState'; import { hasNextPageFamilyState } from '@/object-record/states/hasNextPageFamilyState'; import { type ObjectRecord } from '@/object-record/types/ObjectRecord'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { getQueryIdentifier } from '@/object-record/utils/getQueryIdentifier'; import { QUERY_DEFAULT_LIMIT_RECORDS } from 'twenty-shared/constants'; import { isDefined } from 'twenty-shared/utils'; +import { useStore } from 'jotai'; type UseLazyFindManyRecordsParams = Omit< UseFindManyRecordsParams, @@ -31,6 +31,7 @@ export const useLazyFindManyRecords = ({ recordGqlFields, fetchPolicy = 'cache-first', }: UseLazyFindManyRecordsParams) => { + const store = useStore(); const { objectMetadataItem } = useObjectMetadataItem({ objectNameSingular, }); @@ -83,8 +84,8 @@ export const useLazyFindManyRecords = ({ const findManyRecordsLazy = useCallback(async () => { if (!hasReadPermission) { - jotaiStore.set(hasNextPageFamilyState.atomFamily(queryIdentifier), false); - jotaiStore.set(cursorFamilyState.atomFamily(queryIdentifier), ''); + store.set(hasNextPageFamilyState.atomFamily(queryIdentifier), false); + store.set(cursorFamilyState.atomFamily(queryIdentifier), ''); return { data: null, @@ -107,11 +108,8 @@ export const useLazyFindManyRecords = ({ const lastCursor = result?.data?.[objectMetadataItem.namePlural]?.pageInfo.endCursor ?? ''; - jotaiStore.set( - hasNextPageFamilyState.atomFamily(queryIdentifier), - hasNextPage, - ); - jotaiStore.set(cursorFamilyState.atomFamily(queryIdentifier), lastCursor); + store.set(hasNextPageFamilyState.atomFamily(queryIdentifier), hasNextPage); + store.set(cursorFamilyState.atomFamily(queryIdentifier), lastCursor); const records = getRecordsFromRecordConnection({ recordConnection: { @@ -141,6 +139,7 @@ export const useLazyFindManyRecords = ({ objectMetadataItem.namePlural, queryIdentifier, handleFindManyRecordsError, + store, ]); return { diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownDateInput.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownDateInput.tsx index 05ae600f86..cb7d9942c6 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownDateInput.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownDateInput.tsx @@ -18,12 +18,12 @@ import { type RelativeDateFilter, resolveDateFilter, } from 'twenty-shared/utils'; -import { dateLocaleStateV2 } from '~/localization/states/dateLocaleStateV2'; +import { dateLocaleState } from '~/localization/states/dateLocaleState'; import { formatDateString } from '~/utils/string/formatDateString'; export const ObjectFilterDropdownDateInput = () => { const { dateFormat, timeZone } = useContext(UserContext); - const dateLocale = useRecoilValueV2(dateLocaleStateV2); + const dateLocale = useRecoilValueV2(dateLocaleState); const currentWorkspaceMember = useRecoilValueV2(currentWorkspaceMemberState); const selectedOperandInDropdown = useRecoilComponentValueV2( diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownDateTimeInput.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownDateTimeInput.tsx index 20411b0555..cc0d06e0c9 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownDateTimeInput.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownDateTimeInput.tsx @@ -21,12 +21,12 @@ import { import { useUserTimezone } from '@/ui/input/components/internal/date/hooks/useUserTimezone'; import { isNonEmptyString } from '@sniptt/guards'; import { Temporal } from 'temporal-polyfill'; -import { dateLocaleStateV2 } from '~/localization/states/dateLocaleStateV2'; +import { dateLocaleState } from '~/localization/states/dateLocaleState'; import { formatDateTimeString } from '~/utils/string/formatDateTimeString'; export const ObjectFilterDropdownDateTimeInput = () => { const { dateFormat, timeFormat, timeZone } = useContext(UserContext); - const dateLocale = useRecoilValueV2(dateLocaleStateV2); + const dateLocale = useRecoilValueV2(dateLocaleState); const currentWorkspaceMember = useRecoilValueV2(currentWorkspaceMemberState); const { userTimezone } = useUserTimezone(); diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownFilterValue.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownFilterValue.ts index a08b199323..862d8140a3 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownFilterValue.ts +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownFilterValue.ts @@ -5,18 +5,19 @@ import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-recor import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState'; import { useCreateRecordFilterFromObjectFilterDropdownCurrentStates } from '@/object-record/record-filter/hooks/useCreateRecordFilterFromObjectFilterDropdownCurrentStates'; import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useRecoilComponentSelectorCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentSelectorCallbackStateV2'; import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2'; import { isDefined } from 'twenty-shared/utils'; +import { useStore } from 'jotai'; export const useApplyObjectFilterDropdownFilterValue = () => { - const objectFilterDropdownCurrentRecordFilterAtom = + const store = useStore(); + const objectFilterDropdownCurrentRecordFilter = useRecoilComponentStateCallbackStateV2( objectFilterDropdownCurrentRecordFilterComponentState, ); - const fieldMetadataItemUsedInDropdownAtom = + const fieldMetadataItemUsedInDropdown = useRecoilComponentSelectorCallbackStateV2( fieldMetadataItemUsedInDropdownComponentSelector, ); @@ -29,20 +30,20 @@ export const useApplyObjectFilterDropdownFilterValue = () => { const applyObjectFilterDropdownFilterValue = useCallback( (newFilterValue: string, newDisplayValue?: string) => { - const objectFilterDropdownCurrentRecordFilter = jotaiStore.get( - objectFilterDropdownCurrentRecordFilterAtom, + const existingObjectFilterDropdownCurrentRecordFilter = store.get( + objectFilterDropdownCurrentRecordFilter, ) as RecordFilter | undefined | null; - const fieldMetadataItemUsedInDropdown = jotaiStore.get( - fieldMetadataItemUsedInDropdownAtom, + const currentFieldMetadataItemUsedInDropdown = store.get( + fieldMetadataItemUsedInDropdown, ); const objectFilterDropdownFilterNotYetCreated = !isDefined( - objectFilterDropdownCurrentRecordFilter, + existingObjectFilterDropdownCurrentRecordFilter, ); if (objectFilterDropdownFilterNotYetCreated) { - if (!isDefined(fieldMetadataItemUsedInDropdown)) { + if (!isDefined(currentFieldMetadataItemUsedInDropdown)) { throw new Error( `Field metadata item is not defined in object filter dropdown when setting a filter value to create it, this should not happen.`, ); @@ -60,7 +61,7 @@ export const useApplyObjectFilterDropdownFilterValue = () => { upsertObjectFilterDropdownCurrentFilter(newCurrentRecordFilter); } else { const newCurrentRecordFilter = { - ...objectFilterDropdownCurrentRecordFilter, + ...existingObjectFilterDropdownCurrentRecordFilter, value: newFilterValue, displayValue: newDisplayValue ?? newFilterValue, } satisfies RecordFilter; @@ -69,10 +70,11 @@ export const useApplyObjectFilterDropdownFilterValue = () => { } }, [ - objectFilterDropdownCurrentRecordFilterAtom, - fieldMetadataItemUsedInDropdownAtom, + objectFilterDropdownCurrentRecordFilter, + fieldMetadataItemUsedInDropdown, createRecordFilterFromObjectFilterDropdownCurrentStates, upsertObjectFilterDropdownCurrentFilter, + store, ], ); diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/useEmptyRecordFilter.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/useEmptyRecordFilter.ts index 3df3c2be67..656d58c74d 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/useEmptyRecordFilter.ts +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/useEmptyRecordFilter.ts @@ -2,28 +2,30 @@ import { useCallback } from 'react'; import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState'; import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2'; +import { useStore } from 'jotai'; export const useEmptyRecordFilter = (componentInstanceId?: string) => { - const objectFilterDropdownSearchInputAtom = + const store = useStore(); + const objectFilterDropdownSearchInput = useRecoilComponentStateCallbackStateV2( objectFilterDropdownSearchInputComponentState, componentInstanceId, ); - const objectFilterDropdownCurrentRecordFilterAtom = + const objectFilterDropdownCurrentRecordFilter = useRecoilComponentStateCallbackStateV2( objectFilterDropdownCurrentRecordFilterComponentState, componentInstanceId, ); const emptyRecordFilter = useCallback(() => { - jotaiStore.set(objectFilterDropdownSearchInputAtom, ''); - jotaiStore.set(objectFilterDropdownCurrentRecordFilterAtom, undefined); + store.set(objectFilterDropdownSearchInput, ''); + store.set(objectFilterDropdownCurrentRecordFilter, undefined); }, [ - objectFilterDropdownSearchInputAtom, - objectFilterDropdownCurrentRecordFilterAtom, + objectFilterDropdownSearchInput, + objectFilterDropdownCurrentRecordFilter, + store, ]); return { diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/useResetFilterDropdown.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/useResetFilterDropdown.ts index 2981ca981d..5ff3a7b569 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/useResetFilterDropdown.ts +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/useResetFilterDropdown.ts @@ -7,67 +7,69 @@ import { objectFilterDropdownFilterIsSelectedComponentState } from '@/object-rec import { objectFilterDropdownIsSelectingCompositeFieldComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownIsSelectingCompositeFieldComponentState'; import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState'; import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2'; +import { useStore } from 'jotai'; export const useResetFilterDropdown = (componentInstanceId?: string) => { - const objectFilterDropdownSearchInputAtom = + const store = useStore(); + const objectFilterDropdownSearchInput = useRecoilComponentStateCallbackStateV2( objectFilterDropdownSearchInputComponentState, componentInstanceId, ); - const fieldMetadataItemIdUsedInDropdownAtom = + const fieldMetadataItemIdUsedInDropdown = useRecoilComponentStateCallbackStateV2( fieldMetadataItemIdUsedInDropdownComponentState, componentInstanceId, ); - const selectedOperandInDropdownAtom = useRecoilComponentStateCallbackStateV2( + const selectedOperandInDropdown = useRecoilComponentStateCallbackStateV2( selectedOperandInDropdownComponentState, componentInstanceId, ); - const objectFilterDropdownFilterIsSelectedAtom = + const objectFilterDropdownFilterIsSelected = useRecoilComponentStateCallbackStateV2( objectFilterDropdownFilterIsSelectedComponentState, componentInstanceId, ); - const objectFilterDropdownAnyFieldSearchIsSelectedAtom = + const objectFilterDropdownAnyFieldSearchIsSelected = useRecoilComponentStateCallbackStateV2( objectFilterDropdownAnyFieldSearchIsSelectedComponentState, componentInstanceId, ); - const objectFilterDropdownIsSelectingCompositeFieldAtom = + const objectFilterDropdownIsSelectingCompositeField = useRecoilComponentStateCallbackStateV2( objectFilterDropdownIsSelectingCompositeFieldComponentState, componentInstanceId, ); - const objectFilterDropdownCurrentRecordFilterAtom = + const objectFilterDropdownCurrentRecordFilter = useRecoilComponentStateCallbackStateV2( objectFilterDropdownCurrentRecordFilterComponentState, componentInstanceId, ); const resetFilterDropdown = useCallback(() => { - jotaiStore.set(objectFilterDropdownSearchInputAtom, ''); - jotaiStore.set(selectedOperandInDropdownAtom, null); - jotaiStore.set(objectFilterDropdownFilterIsSelectedAtom, false); - jotaiStore.set(objectFilterDropdownIsSelectingCompositeFieldAtom, false); - jotaiStore.set(fieldMetadataItemIdUsedInDropdownAtom, null); - jotaiStore.set(objectFilterDropdownCurrentRecordFilterAtom, null); - jotaiStore.set(objectFilterDropdownAnyFieldSearchIsSelectedAtom, false); + store.set(objectFilterDropdownSearchInput, ''); + store.set(selectedOperandInDropdown, null); + store.set(objectFilterDropdownFilterIsSelected, false); + store.set(objectFilterDropdownIsSelectingCompositeField, false); + store.set(fieldMetadataItemIdUsedInDropdown, null); + store.set(objectFilterDropdownCurrentRecordFilter, null); + store.set(objectFilterDropdownAnyFieldSearchIsSelected, false); }, [ - objectFilterDropdownSearchInputAtom, - selectedOperandInDropdownAtom, - objectFilterDropdownFilterIsSelectedAtom, - objectFilterDropdownIsSelectingCompositeFieldAtom, - fieldMetadataItemIdUsedInDropdownAtom, - objectFilterDropdownCurrentRecordFilterAtom, - objectFilterDropdownAnyFieldSearchIsSelectedAtom, + objectFilterDropdownSearchInput, + selectedOperandInDropdown, + objectFilterDropdownFilterIsSelected, + objectFilterDropdownIsSelectingCompositeField, + fieldMetadataItemIdUsedInDropdown, + objectFilterDropdownCurrentRecordFilter, + objectFilterDropdownAnyFieldSearchIsSelected, + store, ]); return { diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/useUpsertObjectFilterDropdownCurrentFilter.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/useUpsertObjectFilterDropdownCurrentFilter.ts index fae16e7e73..fb2bf59502 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/useUpsertObjectFilterDropdownCurrentFilter.ts +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/hooks/useUpsertObjectFilterDropdownCurrentFilter.ts @@ -3,11 +3,12 @@ import { useCallback } from 'react'; import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState'; import { useUpsertRecordFilter } from '@/object-record/record-filter/hooks/useUpsertRecordFilter'; import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2'; +import { useStore } from 'jotai'; export const useUpsertObjectFilterDropdownCurrentFilter = () => { - const objectFilterDropdownCurrentRecordFilterAtom = + const store = useStore(); + const objectFilterDropdownCurrentRecordFilter = useRecoilComponentStateCallbackStateV2( objectFilterDropdownCurrentRecordFilterComponentState, ); @@ -18,12 +19,9 @@ export const useUpsertObjectFilterDropdownCurrentFilter = () => { (recordFilterToUpsert: RecordFilter) => { upsertRecordFilter(recordFilterToUpsert); - jotaiStore.set( - objectFilterDropdownCurrentRecordFilterAtom, - recordFilterToUpsert, - ); + store.set(objectFilterDropdownCurrentRecordFilter, recordFilterToUpsert); }, - [objectFilterDropdownCurrentRecordFilterAtom, upsertRecordFilter], + [objectFilterDropdownCurrentRecordFilter, upsertRecordFilter, store], ); return { diff --git a/packages/twenty-front/src/modules/object-record/object-options-dropdown/hooks/__tests__/useSearchRecordGroupField.test.tsx b/packages/twenty-front/src/modules/object-record/object-options-dropdown/hooks/__tests__/useSearchRecordGroupField.test.tsx index 4eaa8defc1..22f38d0e19 100644 --- a/packages/twenty-front/src/modules/object-record/object-options-dropdown/hooks/__tests__/useSearchRecordGroupField.test.tsx +++ b/packages/twenty-front/src/modules/object-record/object-options-dropdown/hooks/__tests__/useSearchRecordGroupField.test.tsx @@ -1,24 +1,40 @@ import { useSearchRecordGroupField } from '@/object-record/object-options-dropdown/hooks/useSearchRecordGroupField'; +import { objectOptionsDropdownSearchInputComponentState } from '@/object-record/object-options-dropdown/states/objectOptionsDropdownSearchInputComponentState'; import { RecordIndexContextProvider } from '@/object-record/record-index/contexts/RecordIndexContext'; import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext'; +import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { renderHook } from '@testing-library/react'; +import { Provider as JotaiProvider } from 'jotai'; import { act } from 'react'; import { RecoilRoot } from 'recoil'; import { FieldMetadataType } from '~/generated-metadata/graphql'; +const INSTANCE_ID = 'myViewInstanceId'; + describe('useSearchRecordGroupField', () => { + beforeEach(() => { + jotaiStore.set( + objectOptionsDropdownSearchInputComponentState.atomFamily({ + instanceId: INSTANCE_ID, + }), + '', + ); + }); + const renderWithContext = (contextValue: any) => renderHook(() => useSearchRecordGroupField(), { wrapper: ({ children }) => ( - - - - {children} - - - + + + + + {children} + + + + ), }); diff --git a/packages/twenty-front/src/modules/object-record/object-options-dropdown/hooks/useSetViewTypeFromLayoutOptionsMenu.ts b/packages/twenty-front/src/modules/object-record/object-options-dropdown/hooks/useSetViewTypeFromLayoutOptionsMenu.ts index 0d181a3840..d762a994c8 100644 --- a/packages/twenty-front/src/modules/object-record/object-options-dropdown/hooks/useSetViewTypeFromLayoutOptionsMenu.ts +++ b/packages/twenty-front/src/modules/object-record/object-options-dropdown/hooks/useSetViewTypeFromLayoutOptionsMenu.ts @@ -4,7 +4,6 @@ import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/ import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext'; import { useLoadRecordIndexStates } from '@/object-record/record-index/hooks/useLoadRecordIndexStates'; import { recordIndexViewTypeState } from '@/object-record/record-index/states/recordIndexViewTypeState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useUpdateCurrentView } from '@/views/hooks/useUpdateCurrentView'; import { coreViewsState } from '@/views/states/coreViewState'; import { type GraphQLView } from '@/views/types/GraphQLView'; @@ -40,7 +39,7 @@ export const useSetViewTypeFromLayoutOptionsMenu = () => { }), ); - const existingCoreViews = jotaiStore.get(coreViewsState.atom); + const existingCoreViews = store.get(coreViewsState.atom); if (!isDefined(currentViewId)) { throw new Error('No view id found'); @@ -75,7 +74,7 @@ export const useSetViewTypeFromLayoutOptionsMenu = () => { } setRecordIndexViewType(viewType); - jotaiStore.set(coreViewsState.atom, [ + store.set(coreViewsState.atom, [ ...existingCoreViews.filter( (coreView) => coreView.id !== currentView.id, ), @@ -96,7 +95,7 @@ export const useSetViewTypeFromLayoutOptionsMenu = () => { updateCurrentViewParams.mainGroupByFieldMetadataId = null; await updateCurrentView(updateCurrentViewParams); setRecordIndexViewType(viewType); - jotaiStore.set(coreViewsState.atom, [ + store.set(coreViewsState.atom, [ ...existingCoreViews.filter( (coreView) => coreView.id !== currentView.id, ), @@ -116,7 +115,7 @@ export const useSetViewTypeFromLayoutOptionsMenu = () => { const calendarFieldMetadataId = availableFieldsForCalendar[0].id; setRecordIndexViewType(viewType); - jotaiStore.set(coreViewsState.atom, [ + store.set(coreViewsState.atom, [ ...existingCoreViews.filter( (coreView) => coreView.id !== currentView.id, ), diff --git a/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoardDataChangedEffect.tsx b/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoardDataChangedEffect.tsx index a63f1ec890..2936ef5e4a 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoardDataChangedEffect.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoardDataChangedEffect.tsx @@ -28,7 +28,7 @@ export const RecordBoardDataChangedEffect = () => { useRecoilComponentFamilySelectorCallbackStateV2( recordGroupFromGroupValueComponentFamilySelector, ); - const recordIndexGroupFieldMetadataItemAtom = + const recordIndexGroupFieldMetadataItem = useRecoilComponentStateCallbackStateV2( recordIndexGroupFieldMetadataItemComponentState, ); @@ -73,17 +73,17 @@ export const RecordBoardDataChangedEffect = () => { return; } - const recordIndexGroupFieldMetadataItem = store.get( - recordIndexGroupFieldMetadataItemAtom, + const currentRecordIndexGroupFieldMetadataItem = store.get( + recordIndexGroupFieldMetadataItem, ); - if (!isDefined(recordIndexGroupFieldMetadataItem)) { + if (!isDefined(currentRecordIndexGroupFieldMetadataItem)) { return; } const recordGroupValue = objectRecordOperation.createdRecord[ - recordIndexGroupFieldMetadataItem.name + currentRecordIndexGroupFieldMetadataItem.name ]; const recordGroupDefinitionFromGroupValue = store.get( @@ -157,7 +157,7 @@ export const RecordBoardDataChangedEffect = () => { store, triggerRecordBoardInitialQuery, getShouldInitializeRecordBoardForUpdateInputs, - recordIndexGroupFieldMetadataItemAtom, + recordIndexGroupFieldMetadataItem, recordGroupFromGroupValueCallbackState, recordIndexRecordIdsByGroupCallbackState, removeRecordsFromBoard, diff --git a/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoardDragDropContext.tsx b/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoardDragDropContext.tsx index a0f672e661..8923757fd0 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoardDragDropContext.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoardDragDropContext.tsx @@ -23,12 +23,12 @@ export const RecordBoardDragDropContext = ({ }: React.PropsWithChildren) => { const { recordBoardId } = useContext(RecordBoardContext); - const currentRecordSortsAtom = useRecoilComponentStateCallbackStateV2( + const currentRecordSorts = useRecoilComponentStateCallbackStateV2( currentRecordSortsComponentState, recordBoardId, ); - const recordBoardSelectedRecordIdsAtom = + const recordBoardSelectedRecordIds = useRecoilComponentSelectorCallbackStateV2( recordBoardSelectedRecordIdsComponentSelector, recordBoardId, @@ -36,7 +36,7 @@ export const RecordBoardDragDropContext = ({ const store = useStore(); - const originalDragSelectionAtom = useRecoilComponentStateCallbackStateV2( + const originalDragSelection = useRecoilComponentStateCallbackStateV2( originalDragSelectionComponentState, recordBoardId, ); @@ -50,13 +50,11 @@ export const RecordBoardDragDropContext = ({ const handleDragStart = useCallback( (start: DragStart) => { - const currentSelectedRecordIds = store.get( - recordBoardSelectedRecordIdsAtom, - ); + const currentSelectedRecordIds = store.get(recordBoardSelectedRecordIds); startRecordDrag(start, currentSelectedRecordIds); }, - [recordBoardSelectedRecordIdsAtom, startRecordDrag, store], + [recordBoardSelectedRecordIds, startRecordDrag, store], ); const handleDragEnd: OnDragEndResponder = useCallback( @@ -65,24 +63,22 @@ export const RecordBoardDragDropContext = ({ if (!result.destination) return; - const currentRecordSorts = store.get(currentRecordSortsAtom); + const existingRecordSorts = store.get(currentRecordSorts); - if (currentRecordSorts.length > 0) { + if (existingRecordSorts.length > 0) { openModal(RECORD_INDEX_REMOVE_SORTING_MODAL_ID); return; } - const originalSelection = store.get( - originalDragSelectionAtom, - ) as string[]; + const originalSelection = store.get(originalDragSelection) as string[]; processBoardCardDrop(result, originalSelection); }, [ processBoardCardDrop, - originalDragSelectionAtom, + originalDragSelection, endRecordDrag, - currentRecordSortsAtom, + currentRecordSorts, openModal, store, ], diff --git a/packages/twenty-front/src/modules/object-record/record-board/hooks/useActiveRecordBoardCard.ts b/packages/twenty-front/src/modules/object-record/record-board/hooks/useActiveRecordBoardCard.ts index 3ae0789b9f..ad4ae447fc 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/hooks/useActiveRecordBoardCard.ts +++ b/packages/twenty-front/src/modules/object-record/record-board/hooks/useActiveRecordBoardCard.ts @@ -22,10 +22,7 @@ export const useActiveRecordBoardCard = (recordBoardId?: string) => { const store = useStore(); const deactivateBoardCard = useCallback(() => { - const activeBoardCardIndexes = store.get(activeBoardCardIndexesState) as - | BoardCardIndexes - | null - | undefined; + const activeBoardCardIndexes = store.get(activeBoardCardIndexesState); if (!isDefined(activeBoardCardIndexes)) { return; @@ -37,10 +34,7 @@ export const useActiveRecordBoardCard = (recordBoardId?: string) => { const activateBoardCard = useCallback( (boardCardIndexes: BoardCardIndexes) => { - const activeBoardCardIndexes = store.get(activeBoardCardIndexesState) as - | BoardCardIndexes - | null - | undefined; + const activeBoardCardIndexes = store.get(activeBoardCardIndexesState); if ( activeBoardCardIndexes?.rowIndex === boardCardIndexes.rowIndex && diff --git a/packages/twenty-front/src/modules/object-record/record-board/hooks/useFocusedRecordBoardCard.ts b/packages/twenty-front/src/modules/object-record/record-board/hooks/useFocusedRecordBoardCard.ts index 33609eb683..d51709f2bb 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/hooks/useFocusedRecordBoardCard.ts +++ b/packages/twenty-front/src/modules/object-record/record-board/hooks/useFocusedRecordBoardCard.ts @@ -14,17 +14,17 @@ import { isDefined } from 'twenty-shared/utils'; export const useFocusedRecordBoardCard = (recordBoardId?: string) => { const store = useStore(); - const isCardFocusedAtom = useRecoilComponentFamilyStateCallbackStateV2( + const isCardFocused = useRecoilComponentFamilyStateCallbackStateV2( isRecordBoardCardFocusedComponentFamilyState, recordBoardId, ); - const focusedBoardCardIndexesAtom = useRecoilComponentStateCallbackStateV2( + const focusedBoardCardIndexes = useRecoilComponentStateCallbackStateV2( focusedRecordBoardCardIndexesComponentState, recordBoardId, ); - const isCardFocusActiveAtom = useRecoilComponentStateCallbackStateV2( + const isCardFocusActive = useRecoilComponentStateCallbackStateV2( isRecordBoardCardFocusActiveComponentState, recordBoardId, ); @@ -34,53 +34,49 @@ export const useFocusedRecordBoardCard = (recordBoardId?: string) => { useRemoveFocusItemFromFocusStackById(); const unfocusBoardCard = useCallback(() => { - const focusedBoardCardIndexes = store.get(focusedBoardCardIndexesAtom) as - | BoardCardIndexes - | null - | undefined; + const currentFocusedBoardCardIndexes = store.get(focusedBoardCardIndexes); - if (!isDefined(focusedBoardCardIndexes)) { + if (!isDefined(currentFocusedBoardCardIndexes)) { return; } const focusId = getRecordBoardCardFocusId({ recordBoardId: recordBoardId || '', - cardIndexes: focusedBoardCardIndexes, + cardIndexes: currentFocusedBoardCardIndexes, }); removeFocusItemFromFocusStackById({ focusId, }); - store.set(focusedBoardCardIndexesAtom, null); - store.set(isCardFocusedAtom(focusedBoardCardIndexes), false); - store.set(isCardFocusActiveAtom, false); + store.set(focusedBoardCardIndexes, null); + store.set(isCardFocused(currentFocusedBoardCardIndexes), false); + store.set(isCardFocusActive, false); }, [ store, - focusedBoardCardIndexesAtom, - isCardFocusedAtom, - isCardFocusActiveAtom, + focusedBoardCardIndexes, + isCardFocused, + isCardFocusActive, recordBoardId, removeFocusItemFromFocusStackById, ]); const focusBoardCard = useCallback( (boardCardIndexes: BoardCardIndexes) => { - const focusedBoardCardIndexes = store.get(focusedBoardCardIndexesAtom) as - | BoardCardIndexes - | null - | undefined; + const currentFocusedBoardCardIndexes = store.get(focusedBoardCardIndexes); if ( - isDefined(focusedBoardCardIndexes) && - (focusedBoardCardIndexes.rowIndex !== boardCardIndexes.rowIndex || - focusedBoardCardIndexes.columnIndex !== boardCardIndexes.columnIndex) + isDefined(currentFocusedBoardCardIndexes) && + (currentFocusedBoardCardIndexes.rowIndex !== + boardCardIndexes.rowIndex || + currentFocusedBoardCardIndexes.columnIndex !== + boardCardIndexes.columnIndex) ) { - store.set(isCardFocusedAtom(focusedBoardCardIndexes), false); + store.set(isCardFocused(currentFocusedBoardCardIndexes), false); const currentFocusId = getRecordBoardCardFocusId({ recordBoardId: recordBoardId || '', - cardIndexes: focusedBoardCardIndexes, + cardIndexes: currentFocusedBoardCardIndexes, }); removeFocusItemFromFocusStackById({ @@ -101,15 +97,15 @@ export const useFocusedRecordBoardCard = (recordBoardId?: string) => { }, }); - store.set(focusedBoardCardIndexesAtom, boardCardIndexes); - store.set(isCardFocusedAtom(boardCardIndexes), true); - store.set(isCardFocusActiveAtom, true); + store.set(focusedBoardCardIndexes, boardCardIndexes); + store.set(isCardFocused(boardCardIndexes), true); + store.set(isCardFocusActive, true); }, [ store, - focusedBoardCardIndexesAtom, - isCardFocusedAtom, - isCardFocusActiveAtom, + focusedBoardCardIndexes, + isCardFocused, + isCardFocusActive, recordBoardId, pushFocusItemToFocusStack, removeFocusItemFromFocusStackById, diff --git a/packages/twenty-front/src/modules/object-record/record-board/hooks/useRecordBoardCardNavigation.ts b/packages/twenty-front/src/modules/object-record/record-board/hooks/useRecordBoardCardNavigation.ts index 527b64112f..90564bd5cb 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/hooks/useRecordBoardCardNavigation.ts +++ b/packages/twenty-front/src/modules/object-record/record-board/hooks/useRecordBoardCardNavigation.ts @@ -17,7 +17,7 @@ export const useRecordBoardCardNavigation = (recordBoardId?: string) => { const store = useStore(); const { focusBoardCard } = useFocusedRecordBoardCard(recordBoardId); - const focusedBoardCardIndexesAtom = useRecoilComponentStateCallbackStateV2( + const focusedBoardCardIndexes = useRecoilComponentStateCallbackStateV2( focusedRecordBoardCardIndexesComponentState, recordBoardId, ); @@ -38,9 +38,7 @@ export const useRecordBoardCardNavigation = (recordBoardId?: string) => { const firstColumnWithRecords = visibleRecordGroupIds.findIndex( (groupId) => { - const recordIdsInGroup = store.get( - recordIdsByGroupState(groupId), - ) as string[]; + const recordIdsInGroup = store.get(recordIdsByGroupState(groupId)); return Array.isArray(recordIdsInGroup) && recordIdsInGroup.length > 0; }, ); @@ -55,12 +53,9 @@ export const useRecordBoardCardNavigation = (recordBoardId?: string) => { const moveHorizontally = useCallback( (direction: 'left' | 'right') => { - const focusedBoardCardIndexes = store.get(focusedBoardCardIndexesAtom) as - | { rowIndex: number; columnIndex: number } - | null - | undefined; + const currentFocusedBoardCardIndexes = store.get(focusedBoardCardIndexes); - if (!isDefined(focusedBoardCardIndexes)) { + if (!isDefined(currentFocusedBoardCardIndexes)) { focusFirstAvailableRecord(); return; } @@ -71,8 +66,8 @@ export const useRecordBoardCardNavigation = (recordBoardId?: string) => { let newColumnIndex = direction === 'right' - ? focusedBoardCardIndexes.columnIndex + 1 - : focusedBoardCardIndexes.columnIndex - 1; + ? currentFocusedBoardCardIndexes.columnIndex + 1 + : currentFocusedBoardCardIndexes.columnIndex - 1; if (newColumnIndex < 0) { newColumnIndex = 0; @@ -80,7 +75,7 @@ export const useRecordBoardCardNavigation = (recordBoardId?: string) => { newColumnIndex = visibleRecordGroupIds.length - 1; } - if (newColumnIndex === focusedBoardCardIndexes.columnIndex) { + if (newColumnIndex === currentFocusedBoardCardIndexes.columnIndex) { return; } @@ -91,7 +86,7 @@ export const useRecordBoardCardNavigation = (recordBoardId?: string) => { const currentGroupId = visibleRecordGroupIds[newColumnIndex]; const recordIdsInGroup = store.get( recordIdsByGroupState(currentGroupId), - ) as string[]; + ); if (Array.isArray(recordIdsInGroup) && recordIdsInGroup.length > 0) { foundColumnWithRecords = true; @@ -117,11 +112,9 @@ export const useRecordBoardCardNavigation = (recordBoardId?: string) => { } const currentGroupId = visibleRecordGroupIds[newColumnIndex]; - const recordIdsInGroup = store.get( - recordIdsByGroupState(currentGroupId), - ) as string[]; + const recordIdsInGroup = store.get(recordIdsByGroupState(currentGroupId)); - let newRowIndex = focusedBoardCardIndexes.rowIndex; + let newRowIndex = currentFocusedBoardCardIndexes.rowIndex; if (newRowIndex >= recordIdsInGroup.length) { newRowIndex = recordIdsInGroup.length - 1; } @@ -133,7 +126,7 @@ export const useRecordBoardCardNavigation = (recordBoardId?: string) => { }, [ store, - focusedBoardCardIndexesAtom, + focusedBoardCardIndexes, visibleRecordGroupIds, recordIdsByGroupState, focusBoardCard, @@ -143,12 +136,9 @@ export const useRecordBoardCardNavigation = (recordBoardId?: string) => { const moveVertically = useCallback( (direction: 'up' | 'down') => { - const focusedBoardCardIndexes = store.get(focusedBoardCardIndexesAtom) as - | { rowIndex: number; columnIndex: number } - | null - | undefined; + const currentFocusedBoardCardIndexes = store.get(focusedBoardCardIndexes); - if (!isDefined(focusedBoardCardIndexes)) { + if (!isDefined(currentFocusedBoardCardIndexes)) { focusFirstAvailableRecord(); return; } @@ -156,10 +146,8 @@ export const useRecordBoardCardNavigation = (recordBoardId?: string) => { if (visibleRecordGroupIds.length === 0) return; const currentGroupId = - visibleRecordGroupIds[focusedBoardCardIndexes.columnIndex]; - const recordIdsInGroup = store.get( - recordIdsByGroupState(currentGroupId), - ) as string[]; + visibleRecordGroupIds[currentFocusedBoardCardIndexes.columnIndex]; + const recordIdsInGroup = store.get(recordIdsByGroupState(currentGroupId)); if (!Array.isArray(recordIdsInGroup) || recordIdsInGroup.length === 0) { focusFirstAvailableRecord(); @@ -168,8 +156,8 @@ export const useRecordBoardCardNavigation = (recordBoardId?: string) => { let newRowIndex = direction === 'down' - ? focusedBoardCardIndexes.rowIndex + 1 - : focusedBoardCardIndexes.rowIndex - 1; + ? currentFocusedBoardCardIndexes.rowIndex + 1 + : currentFocusedBoardCardIndexes.rowIndex - 1; if (newRowIndex < 0) { newRowIndex = 0; @@ -177,18 +165,18 @@ export const useRecordBoardCardNavigation = (recordBoardId?: string) => { newRowIndex = recordIdsInGroup.length - 1; } - if (newRowIndex === focusedBoardCardIndexes.rowIndex) { + if (newRowIndex === currentFocusedBoardCardIndexes.rowIndex) { return; } focusBoardCard({ - columnIndex: focusedBoardCardIndexes.columnIndex, + columnIndex: currentFocusedBoardCardIndexes.columnIndex, rowIndex: newRowIndex, }); }, [ store, - focusedBoardCardIndexesAtom, + focusedBoardCardIndexes, visibleRecordGroupIds, recordIdsByGroupState, focusBoardCard, diff --git a/packages/twenty-front/src/modules/object-record/record-board/hooks/useRecordBoardSelection.ts b/packages/twenty-front/src/modules/object-record/record-board/hooks/useRecordBoardSelection.ts index 6e0cf62513..18328d1bb9 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/hooks/useRecordBoardSelection.ts +++ b/packages/twenty-front/src/modules/object-record/record-board/hooks/useRecordBoardSelection.ts @@ -22,7 +22,7 @@ export const useRecordBoardSelection = (recordBoardId?: string) => { recordBoardId, ); - const recordBoardSelectedRecordIdsAtom = + const recordBoardSelectedRecordIds = useRecoilComponentSelectorCallbackStateV2( recordBoardSelectedRecordIdsComponentSelector, recordBoardId, @@ -50,12 +50,12 @@ export const useRecordBoardSelection = (recordBoardId?: string) => { ); const checkIfLastUnselectAndCloseDropdown = useCallback(() => { - const recordIds = store.get(recordBoardSelectedRecordIdsAtom); + const recordIds = store.get(recordBoardSelectedRecordIds); if (recordIds.length === 0) { closeDropdown(dropdownId); } - }, [recordBoardSelectedRecordIdsAtom, store, closeDropdown, dropdownId]); + }, [recordBoardSelectedRecordIds, store, closeDropdown, dropdownId]); return { setRecordAsSelected, diff --git a/packages/twenty-front/src/modules/object-record/record-board/hooks/useRemoveRecordsFromBoard.ts b/packages/twenty-front/src/modules/object-record/record-board/hooks/useRemoveRecordsFromBoard.ts index e954ae5092..3c2b3f082c 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/hooks/useRemoveRecordsFromBoard.ts +++ b/packages/twenty-front/src/modules/object-record/record-board/hooks/useRemoveRecordsFromBoard.ts @@ -1,4 +1,3 @@ -import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; import { recordGroupFromGroupValueComponentFamilySelector } from '@/object-record/record-group/states/selectors/recordGroupFromGroupValueComponentFamilySelector'; import { recordIndexGroupFieldMetadataItemComponentState } from '@/object-record/record-index/states/recordIndexGroupFieldMetadataComponentState'; import { recordIndexRecordIdsByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexRecordIdsByGroupComponentFamilyState'; @@ -13,7 +12,7 @@ import { isDefined } from 'twenty-shared/utils'; export const useRemoveRecordsFromBoard = () => { const store = useStore(); - const recordIndexGroupFieldMetadataItemAtom = + const recordIndexGroupFieldMetadataItem = useRecoilComponentStateCallbackStateV2( recordIndexGroupFieldMetadataItemComponentState, ); @@ -35,22 +34,22 @@ export const useRemoveRecordsFromBoard = () => { for (const recordIdToRemove of recordIdsToRemove) { const recordToRemove = store.get( recordStoreFamilyState.atomFamily(recordIdToRemove), - ) as Record | null | undefined; + ); if (!isDefined(recordToRemove)) { continue; } - const recordIndexGroupFieldMetadataItem = store.get( - recordIndexGroupFieldMetadataItemAtom, - ) as FieldMetadataItem | undefined; + const currentRecordIndexGroupFieldMetadataItem = store.get( + recordIndexGroupFieldMetadataItem, + ); - if (!isDefined(recordIndexGroupFieldMetadataItem)) { + if (!isDefined(currentRecordIndexGroupFieldMetadataItem)) { continue; } const recordGroupValue = recordToRemove[ - recordIndexGroupFieldMetadataItem.name + currentRecordIndexGroupFieldMetadataItem.name ] as string | undefined; const recordGroupDefinitionFromGroupValue = store.get( @@ -76,7 +75,7 @@ export const useRemoveRecordsFromBoard = () => { ] of recordIdsToRemoveByGroup) { const currentRecordIdsForGroup = store.get( recordIndexRecordIdsByGroupFamilyCallbackState(groupId), - ) as string[]; + ); const recordIdsWithoutRemovedRecords = currentRecordIdsForGroup.filter( (recordId) => !recordIdsToRemoveInGroup.includes(recordId), @@ -90,7 +89,7 @@ export const useRemoveRecordsFromBoard = () => { }, [ store, - recordIndexGroupFieldMetadataItemAtom, + recordIndexGroupFieldMetadataItem, recordGroupFromGroupValueFamilyCallbackState, recordIndexRecordIdsByGroupFamilyCallbackState, ], diff --git a/packages/twenty-front/src/modules/object-record/record-board/hooks/useRemoveSelectedRecordsFromRecordBoard.ts b/packages/twenty-front/src/modules/object-record/record-board/hooks/useRemoveSelectedRecordsFromRecordBoard.ts index a9d1b793f9..89cb3dda9d 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/hooks/useRemoveSelectedRecordsFromRecordBoard.ts +++ b/packages/twenty-front/src/modules/object-record/record-board/hooks/useRemoveSelectedRecordsFromRecordBoard.ts @@ -29,9 +29,10 @@ export const useRemoveSelectedRecordsFromRecordBoard = ( const recordIndexRecordIdsByGroupCallbackState = useRecoilComponentFamilyStateCallbackStateV2( recordIndexRecordIdsByGroupComponentFamilyState, + recordBoardIndexId, ); - const recordBoardSelectedRecordIdsAtom = + const recordBoardSelectedRecordIds = useRecoilComponentSelectorCallbackStateV2( recordBoardSelectedRecordIdsComponentSelector, recordBoardIndexId, @@ -42,7 +43,7 @@ export const useRemoveSelectedRecordsFromRecordBoard = ( const removeSelectedRecordsFromRecordBoard = useCallback(() => { const deletedRecordIds = store.get( - recordBoardSelectedRecordIdsAtom, + recordBoardSelectedRecordIds, ) as string[]; if ( @@ -89,7 +90,7 @@ export const useRemoveSelectedRecordsFromRecordBoard = ( groupByFieldMetadataItem, recordIndexRecordIdsByGroupCallbackState, recordGroupDefinitions, - recordBoardSelectedRecordIdsAtom, + recordBoardSelectedRecordIds, resetRecordBoardSelection, ]); diff --git a/packages/twenty-front/src/modules/object-record/record-board/hooks/useResetRecordBoardSelection.ts b/packages/twenty-front/src/modules/object-record/record-board/hooks/useResetRecordBoardSelection.ts index 51ad6108dc..983e3c45f0 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/hooks/useResetRecordBoardSelection.ts +++ b/packages/twenty-front/src/modules/object-record/record-board/hooks/useResetRecordBoardSelection.ts @@ -22,7 +22,7 @@ export const useResetRecordBoardSelection = (recordBoardId?: string) => { recordBoardId, ); - const recordBoardSelectedRecordIdsAtom = + const recordBoardSelectedRecordIds = useRecoilComponentSelectorCallbackStateV2( recordBoardSelectedRecordIdsComponentSelector, recordBoardId, @@ -38,7 +38,7 @@ export const useResetRecordBoardSelection = (recordBoardId?: string) => { const resetRecordBoardSelection = useCallback(() => { closeDropdown(dropdownId); - const recordIds = store.get(recordBoardSelectedRecordIdsAtom); + const recordIds = store.get(recordBoardSelectedRecordIds); for (const recordId of recordIds) { store.set(isRecordBoardCardSelectedFamilyState(recordId), false); @@ -46,7 +46,7 @@ export const useResetRecordBoardSelection = (recordBoardId?: string) => { }, [ closeDropdown, dropdownId, - recordBoardSelectedRecordIdsAtom, + recordBoardSelectedRecordIds, isRecordBoardCardSelectedFamilyState, store, ]); diff --git a/packages/twenty-front/src/modules/object-record/record-board/hooks/useSelectAllCards.ts b/packages/twenty-front/src/modules/object-record/record-board/hooks/useSelectAllCards.ts index 7130ddecd6..a6a890796e 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/hooks/useSelectAllCards.ts +++ b/packages/twenty-front/src/modules/object-record/record-board/hooks/useSelectAllCards.ts @@ -8,7 +8,7 @@ import { useStore } from 'jotai'; import { useCallback } from 'react'; export const useSelectAllCards = (recordBoardId?: string) => { - const allCardsSelectedStatusAtom = useRecoilComponentSelectorCallbackStateV2( + const allCardsSelectedStatus = useRecoilComponentSelectorCallbackStateV2( allCardsSelectedStatusComponentSelector, recordBoardId, ); @@ -17,7 +17,7 @@ export const useSelectAllCards = (recordBoardId?: string) => { isRecordBoardCardSelectedComponentFamilyState, recordBoardId, ); - const allRecordIdsOfAllRecordGroupsAtom = + const allRecordIdsOfAllRecordGroups = useRecoilComponentSelectorCallbackStateV2( allRecordIdsOfAllRecordGroupsComponentSelector, recordBoardId, @@ -29,22 +29,23 @@ export const useSelectAllCards = (recordBoardId?: string) => { const store = useStore(); const selectAllCards = useCallback(() => { - const allCardsSelectedStatus = store.get(allCardsSelectedStatusAtom); - const allRecordIds = store.get(allRecordIdsOfAllRecordGroupsAtom); + const currentAllCardsSelectedStatus = store.get(allCardsSelectedStatus); + const allRecordIds = store.get(allRecordIdsOfAllRecordGroups); - if (allCardsSelectedStatus === 'all') { + if (currentAllCardsSelectedStatus === 'all') { resetRecordBoardSelection(); } for (const recordId of allRecordIds) { const isSelected = - allCardsSelectedStatus === 'none' || allCardsSelectedStatus === 'some'; + currentAllCardsSelectedStatus === 'none' || + currentAllCardsSelectedStatus === 'some'; store.set(isRecordBoardCardSelectedFamilyState(recordId), isSelected); } }, [ - allCardsSelectedStatusAtom, - allRecordIdsOfAllRecordGroupsAtom, + allCardsSelectedStatus, + allRecordIdsOfAllRecordGroups, resetRecordBoardSelection, isRecordBoardCardSelectedFamilyState, store, diff --git a/packages/twenty-front/src/modules/object-record/record-board/hooks/useSetRecordIdsForColumn.ts b/packages/twenty-front/src/modules/object-record/record-board/hooks/useSetRecordIdsForColumn.ts index ef9358d7cc..d6f09d6a63 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/hooks/useSetRecordIdsForColumn.ts +++ b/packages/twenty-front/src/modules/object-record/record-board/hooks/useSetRecordIdsForColumn.ts @@ -14,7 +14,7 @@ import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; export const useSetRecordIdsForColumn = (recordBoardId?: string) => { const store = useStore(); - const recordGroupFieldMetadataAtom = useRecoilComponentStateCallbackStateV2( + const recordGroupFieldMetadata = useRecoilComponentStateCallbackStateV2( recordIndexGroupFieldMetadataItemComponentState, recordBoardId, ); @@ -40,16 +40,18 @@ export const useSetRecordIdsForColumn = (recordBoardId?: string) => { recordIndexRecordIdsByGroupFamilyState(currentRecordGroupId), ); - const recordGroupFieldMetadata = store.get(recordGroupFieldMetadataAtom); + const currentRecordGroupFieldMetadata = store.get( + recordGroupFieldMetadata, + ); - if (!isDefined(recordGroupFieldMetadata)) { + if (!isDefined(currentRecordGroupFieldMetadata)) { return; } const recordGroupRowIds = records .filter( (record) => - record[recordGroupFieldMetadata.name] === recordGroup?.value, + record[currentRecordGroupFieldMetadata.name] === recordGroup?.value, ) .map((record) => record.id); @@ -75,7 +77,7 @@ export const useSetRecordIdsForColumn = (recordBoardId?: string) => { }, [ recordIndexRecordIdsByGroupFamilyState, - recordGroupFieldMetadataAtom, + recordGroupFieldMetadata, emptyRecordGroupByIdCallbackState, store, ], diff --git a/packages/twenty-front/src/modules/object-record/record-board/hooks/useTriggerRecordBoardFetchMore.ts b/packages/twenty-front/src/modules/object-record/record-board/hooks/useTriggerRecordBoardFetchMore.ts index be05a7ec59..eed8673d0a 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/hooks/useTriggerRecordBoardFetchMore.ts +++ b/packages/twenty-front/src/modules/object-record/record-board/hooks/useTriggerRecordBoardFetchMore.ts @@ -62,22 +62,22 @@ export const useTriggerRecordBoardFetchMore = () => { recordIndexRecordIdsByGroupComponentFamilyState, ); - const recordBoardIsFetchingMoreAtom = useRecoilComponentStateCallbackStateV2( + const recordBoardIsFetchingMore = useRecoilComponentStateCallbackStateV2( recordBoardIsFetchingMoreComponentState, ); const triggerRecordBoardFetchMore = useCallback(async () => { - const isAlreadyFetchingMore = store.get(recordBoardIsFetchingMoreAtom); + const isAlreadyFetchingMore = store.get(recordBoardIsFetchingMore); const cleanStateBeforeExit = () => { - store.set(recordBoardIsFetchingMoreAtom, false); + store.set(recordBoardIsFetchingMore, false); }; if (isAlreadyFetchingMore) { return; } - store.set(recordBoardIsFetchingMoreAtom, true); + store.set(recordBoardIsFetchingMore, true); const currentOffset = store.get( recordBoardCurrentGroupByQueryOffsetCallbackState, @@ -214,7 +214,7 @@ export const useTriggerRecordBoardFetchMore = () => { upsertRecordsInStore, executeRecordIndexGroupsRecordsLazyGroupBy, recordIndexRecordIdsByGroupCallbackState, - recordBoardIsFetchingMoreAtom, + recordBoardIsFetchingMore, recordBoardCurrentGroupByQueryOffsetCallbackState, recordBoardShouldFetchMoreInColumnFamilyCallbackState, combinedFilters, diff --git a/packages/twenty-front/src/modules/object-record/record-board/hooks/useTriggerRecordBoardInitialQuery.ts b/packages/twenty-front/src/modules/object-record/record-board/hooks/useTriggerRecordBoardInitialQuery.ts index 76f1ce1c08..ce833d2af4 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/hooks/useTriggerRecordBoardInitialQuery.ts +++ b/packages/twenty-front/src/modules/object-record/record-board/hooks/useTriggerRecordBoardInitialQuery.ts @@ -44,7 +44,7 @@ export const useTriggerRecordBoardInitialQuery = () => { recordBoardShouldFetchMoreInColumnComponentFamilyState, ); - const recordIndexRecordGroupsAreInInitialLoadingAtom = + const recordIndexRecordGroupsAreInInitialLoading = useRecoilComponentStateCallbackStateV2( recordIndexRecordGroupsAreInInitialLoadingComponentState, ); @@ -76,10 +76,10 @@ export const useTriggerRecordBoardInitialQuery = () => { }); const triggerRecordBoardInitialQuery = useCallback(async () => { - store.set(recordIndexRecordGroupsAreInInitialLoadingAtom, true); + store.set(recordIndexRecordGroupsAreInInitialLoading, true); const cleanStateBeforeExit = () => { - store.set(recordIndexRecordGroupsAreInInitialLoadingAtom, false); + store.set(recordIndexRecordGroupsAreInInitialLoading, false); setLastRecordBoardQueryIdentifier(queryIdentifier); @@ -165,7 +165,7 @@ export const useTriggerRecordBoardInitialQuery = () => { cleanStateBeforeExit(); }, [ - recordIndexRecordGroupsAreInInitialLoadingAtom, + recordIndexRecordGroupsAreInInitialLoading, store, executeRecordIndexGroupsRecordsLazyGroupBy, objectMetadataItem, diff --git a/packages/twenty-front/src/modules/object-record/record-calendar/month/hooks/useRecordCalendarMonthDaysRange.tsx b/packages/twenty-front/src/modules/object-record/record-calendar/month/hooks/useRecordCalendarMonthDaysRange.tsx index 780e3e93b5..e3f8f1b2b6 100644 --- a/packages/twenty-front/src/modules/object-record/record-calendar/month/hooks/useRecordCalendarMonthDaysRange.tsx +++ b/packages/twenty-front/src/modules/object-record/record-calendar/month/hooks/useRecordCalendarMonthDaysRange.tsx @@ -16,7 +16,7 @@ import { turnJSDateToPlainDate, turnPlainDateToShiftedDateInSystemTimeZone, } from 'twenty-shared/utils'; -import { dateLocaleStateV2 } from '~/localization/states/dateLocaleStateV2'; +import { dateLocaleState } from '~/localization/states/dateLocaleState'; // TODO: we could refactor this to use Temporal.PlainDate directly // But it would require recoding the utils here, not really worth it for now @@ -24,7 +24,7 @@ export const useRecordCalendarMonthDaysRange = ( selectedDate: Temporal.PlainDate, ) => { const currentWorkspaceMember = useRecoilValueV2(currentWorkspaceMemberState); - const dateLocale = useRecoilValueV2(dateLocaleStateV2); + const dateLocale = useRecoilValueV2(dateLocaleState); if (!currentWorkspaceMember) { throw new Error('Current workspace member not found'); diff --git a/packages/twenty-front/src/modules/object-record/record-calendar/states/selectors/useRecordCalendarSelection.ts b/packages/twenty-front/src/modules/object-record/record-calendar/states/selectors/useRecordCalendarSelection.ts index c56cdd493a..6374bfbb37 100644 --- a/packages/twenty-front/src/modules/object-record/record-calendar/states/selectors/useRecordCalendarSelection.ts +++ b/packages/twenty-front/src/modules/object-record/record-calendar/states/selectors/useRecordCalendarSelection.ts @@ -23,7 +23,7 @@ export const useRecordCalendarSelection = (recordCalendarId?: string) => { recordCalendarId, ); - const recordCalendarSelectedRecordIdsAtom = + const recordCalendarSelectedRecordIds = useRecoilComponentSelectorCallbackStateV2( recordCalendarSelectedRecordIdsComponentSelector, recordCalendarId, @@ -39,7 +39,7 @@ export const useRecordCalendarSelection = (recordCalendarId?: string) => { const resetRecordSelection = useCallback(() => { closeDropdown(dropdownId); - const recordIds = store.get(recordCalendarSelectedRecordIdsAtom); + const recordIds = store.get(recordCalendarSelectedRecordIds); for (const recordId of recordIds) { store.set(isRecordCalendarCardSelectedFamilyState(recordId), false); @@ -47,7 +47,7 @@ export const useRecordCalendarSelection = (recordCalendarId?: string) => { }, [ closeDropdown, dropdownId, - recordCalendarSelectedRecordIdsAtom, + recordCalendarSelectedRecordIds, isRecordCalendarCardSelectedFamilyState, store, ]); diff --git a/packages/twenty-front/src/modules/object-record/record-drag/hooks/useEndRecordDrag.ts b/packages/twenty-front/src/modules/object-record/record-drag/hooks/useEndRecordDrag.ts index b537812b48..7dc0b5baa7 100644 --- a/packages/twenty-front/src/modules/object-record/record-drag/hooks/useEndRecordDrag.ts +++ b/packages/twenty-front/src/modules/object-record/record-drag/hooks/useEndRecordDrag.ts @@ -32,7 +32,7 @@ export const useEndRecordDrag = (contextStoreInstanceId?: string) => { contextStoreInstanceId, ); - const originalSelectionAtom = useRecoilComponentStateCallbackStateV2( + const originalSelection = useRecoilComponentStateCallbackStateV2( originalDragSelectionComponentState, contextStoreInstanceId, ); @@ -49,13 +49,13 @@ export const useEndRecordDrag = (contextStoreInstanceId?: string) => { contextStoreInstanceId, ); - const isDraggingRecordAtom = useRecoilComponentStateCallbackStateV2( + const isDraggingRecord = useRecoilComponentStateCallbackStateV2( isDraggingRecordComponentState, contextStoreInstanceId, ); const endRecordDrag = useCallback(() => { - store.set(isDraggingRecordAtom, false); + store.set(isDraggingRecord, false); const currentlyDraggedRecordIds = store.get(draggedRecordIdsCallbackState); @@ -90,16 +90,16 @@ export const useEndRecordDrag = (contextStoreInstanceId?: string) => { store.set(isMultiDragActiveCallbackState, false); store.set(draggedRecordIdsCallbackState, []); store.set(primaryDraggedRecordIdCallbackState, null); - store.set(originalSelectionAtom, []); + store.set(originalSelection, []); }, [ store, isMultiDragActiveCallbackState, draggedRecordIdsCallbackState, primaryDraggedRecordIdCallbackState, - originalSelectionAtom, + originalSelection, isRecordIdPrimaryDragMultipleCallbackState, isRecordIdSecondaryDragMultipleCallbackState, - isDraggingRecordAtom, + isDraggingRecord, ]); return { endRecordDrag }; diff --git a/packages/twenty-front/src/modules/object-record/record-drag/hooks/useProcessCalendarCardDrop.ts b/packages/twenty-front/src/modules/object-record/record-drag/hooks/useProcessCalendarCardDrop.ts index ecb57903ef..9e5c2a63d9 100644 --- a/packages/twenty-front/src/modules/object-record/record-drag/hooks/useProcessCalendarCardDrop.ts +++ b/packages/twenty-front/src/modules/object-record/record-drag/hooks/useProcessCalendarCardDrop.ts @@ -43,10 +43,7 @@ export const useProcessCalendarCardDrop = () => { const destinationPlainDate = Temporal.PlainDate.from(destinationDate); - const record = store.get(recordStoreFamilyState.atomFamily(recordId)) as - | Record - | null - | undefined; + const record = store.get(recordStoreFamilyState.atomFamily(recordId)); if (!record) return; @@ -61,7 +58,7 @@ export const useProcessCalendarCardDrop = () => { day: destinationPlainDate, timeZone: userTimezone, }), - ) as string[]; + ); const targetDayIsEmpty = destinationRecordIds.length === 0; diff --git a/packages/twenty-front/src/modules/object-record/record-drag/hooks/useProcessTableWithGroupRecordDrop.ts b/packages/twenty-front/src/modules/object-record/record-drag/hooks/useProcessTableWithGroupRecordDrop.ts index b2dd31286b..dc981396c4 100644 --- a/packages/twenty-front/src/modules/object-record/record-drag/hooks/useProcessTableWithGroupRecordDrop.ts +++ b/packages/twenty-front/src/modules/object-record/record-drag/hooks/useProcessTableWithGroupRecordDrop.ts @@ -36,22 +36,22 @@ export const useProcessTableWithGroupRecordDrop = () => { recordIndexRecordIdsByGroupComponentFamilyState, ); - const currentRecordSortsAtom = useRecoilComponentStateCallbackStateV2( + const currentRecordSorts = useRecoilComponentStateCallbackStateV2( currentRecordSortsComponentState, recordTableId, ); - const selectedRowIdsAtom = useRecoilComponentSelectorCallbackStateV2( + const selectedRowIds = useRecoilComponentSelectorCallbackStateV2( selectedRowIdsComponentSelector, recordTableId, ); - const isDraggingRecordAtom = useRecoilComponentStateCallbackStateV2( + const isDraggingRecord = useRecoilComponentStateCallbackStateV2( isDraggingRecordComponentState, recordIndexId, ); - const originalDragSelectionAtom = useRecoilComponentStateCallbackStateV2( + const originalDragSelection = useRecoilComponentStateCallbackStateV2( originalDragSelectionComponentState, recordIndexId, ); @@ -81,19 +81,17 @@ export const useProcessTableWithGroupRecordDrop = () => { throw new Error('Field metadata is not defined'); } - const originalDragSelection = store.get( - originalDragSelectionAtom, - ) as string[]; + const existingOriginalDragSelection = store.get(originalDragSelection); - const isDraggingRecord = store.get(isDraggingRecordAtom); + const isCurrentlyDraggingRecord = store.get(isDraggingRecord); - const selectedRecordIds = isDraggingRecord - ? originalDragSelection - : (store.get(selectedRowIdsAtom) as string[]); + const selectedRecordIds = isCurrentlyDraggingRecord + ? existingOriginalDragSelection + : store.get(selectedRowIds); - const currentRecordSorts = store.get(currentRecordSortsAtom); + const existingRecordSorts = store.get(currentRecordSorts); - if (currentRecordSorts.length > 0) { + if (existingRecordSorts.length > 0) { openModal(RECORD_INDEX_REMOVE_SORTING_MODAL_ID); return; } @@ -116,13 +114,13 @@ export const useProcessTableWithGroupRecordDrop = () => { }); }, [ - currentRecordSortsAtom, + currentRecordSorts, store, objectNameSingular, objectMetadataItem.fields, - originalDragSelectionAtom, - isDraggingRecordAtom, - selectedRowIdsAtom, + originalDragSelection, + isDraggingRecord, + selectedRowIds, recordIdsByGroupFamilyState, groupFieldMetadata?.id, openModal, diff --git a/packages/twenty-front/src/modules/object-record/record-drag/hooks/useProcessTableWithoutGroupRecordDrop.ts b/packages/twenty-front/src/modules/object-record/record-drag/hooks/useProcessTableWithoutGroupRecordDrop.ts index 46776e4075..e5c51f7d16 100644 --- a/packages/twenty-front/src/modules/object-record/record-drag/hooks/useProcessTableWithoutGroupRecordDrop.ts +++ b/packages/twenty-front/src/modules/object-record/record-drag/hooks/useProcessTableWithoutGroupRecordDrop.ts @@ -31,16 +31,15 @@ export const useProcessTableWithoutGroupRecordDrop = () => { const { updateOneRecord } = useUpdateOneRecord(); - const allRecordIdsWithoutGroupAtom = - useRecoilComponentSelectorCallbackStateV2( - allRecordIdsWithoutGroupsComponentSelector, - ); + const allRecordIdsWithoutGroup = useRecoilComponentSelectorCallbackStateV2( + allRecordIdsWithoutGroupsComponentSelector, + ); - const selectedRowIdsAtom = useRecoilComponentSelectorCallbackStateV2( + const selectedRowIds = useRecoilComponentSelectorCallbackStateV2( selectedRowIdsComponentSelector, ); - const originalDragSelectionAtom = useRecoilComponentStateCallbackStateV2( + const originalDragSelection = useRecoilComponentStateCallbackStateV2( originalDragSelectionComponentState, recordIndexId, ); @@ -63,12 +62,10 @@ export const useProcessTableWithoutGroupRecordDrop = () => { return; } - const allSparseRecordIds = store.get( - allRecordIdsWithoutGroupAtom, - ) as string[]; + const allSparseRecordIds = store.get(allRecordIdsWithoutGroup); const draggedRecordId = tableRecordDropResult.draggableId; - const selectedRecordIds = store.get(selectedRowIdsAtom) as string[]; + const selectedRecordIds = store.get(selectedRowIds); const isDroppedAfterList = tableRecordDropResult.destination.index + 1 >= @@ -77,9 +74,7 @@ export const useProcessTableWithoutGroupRecordDrop = () => { const recordsWithPosition: RecordWithPosition[] = allSparseRecordIds .filter((recordId): recordId is string => isDefined(recordId)) .map((recordId: string) => { - const record = store.get( - recordStoreFamilyState.atomFamily(recordId), - ) as { position?: number } | null | undefined; + const record = store.get(recordStoreFamilyState.atomFamily(recordId)); return { id: recordId, position: record?.position ?? 0, @@ -136,14 +131,12 @@ export const useProcessTableWithoutGroupRecordDrop = () => { ); } - const originalDragSelection = store.get( - originalDragSelectionAtom, - ) as string[]; + const existingOriginalDragSelection = store.get(originalDragSelection); const multiDragResult = processMultiDrag({ draggedRecordId, targetRecordId: targetRecordId ?? '', - selectedRecordIds: originalDragSelection, + selectedRecordIds: existingOriginalDragSelection, recordsWithPosition: contiguousRecordsWithPosition, isDroppedAfterList, }); @@ -165,13 +158,13 @@ export const useProcessTableWithoutGroupRecordDrop = () => { }, [ objectNameSingular, - selectedRowIdsAtom, + selectedRowIds, store, updateOneRecord, openModal, currentRecordSorts, - originalDragSelectionAtom, - allRecordIdsWithoutGroupAtom, + originalDragSelection, + allRecordIdsWithoutGroup, triggerTableWithoutGroupDragAndDropOptimisticUpdate, ], ); diff --git a/packages/twenty-front/src/modules/object-record/record-drag/hooks/useStartRecordDrag.ts b/packages/twenty-front/src/modules/object-record/record-drag/hooks/useStartRecordDrag.ts index 095f1619f4..e7578a5c9e 100644 --- a/packages/twenty-front/src/modules/object-record/record-drag/hooks/useStartRecordDrag.ts +++ b/packages/twenty-front/src/modules/object-record/record-drag/hooks/useStartRecordDrag.ts @@ -44,19 +44,19 @@ export const useStartRecordDrag = (contextStoreInstanceId?: string) => { contextStoreInstanceId, ); - const originalSelectionAtom = useRecoilComponentStateCallbackStateV2( + const originalSelection = useRecoilComponentStateCallbackStateV2( originalDragSelectionComponentState, contextStoreInstanceId, ); - const isDraggingRecordAtom = useRecoilComponentStateCallbackStateV2( + const isDraggingRecord = useRecoilComponentStateCallbackStateV2( isDraggingRecordComponentState, contextStoreInstanceId, ); const startRecordDrag = useCallback( (start: DragStart, selectedRecordIds: string[]) => { - store.set(isDraggingRecordAtom, true); + store.set(isDraggingRecord, true); const draggedRecordId = start.draggableId; @@ -69,7 +69,7 @@ export const useStartRecordDrag = (contextStoreInstanceId?: string) => { store.set(isMultiDragActiveCallbackState, true); store.set(draggedRecordIdsCallbackState, selectedRecordIds); store.set(primaryDraggedRecordIdCallbackState, draggedRecordId); - store.set(originalSelectionAtom, selectedRecordIds); + store.set(originalSelection, selectedRecordIds); store.set( isRecordIdPrimaryDragMultipleCallbackState({ @@ -94,7 +94,7 @@ export const useStartRecordDrag = (contextStoreInstanceId?: string) => { store.set(isMultiDragActiveCallbackState, true); store.set(draggedRecordIdsCallbackState, [draggedRecordId]); store.set(primaryDraggedRecordIdCallbackState, draggedRecordId); - store.set(originalSelectionAtom, [draggedRecordId]); + store.set(originalSelection, [draggedRecordId]); } }, [ @@ -102,8 +102,8 @@ export const useStartRecordDrag = (contextStoreInstanceId?: string) => { isMultiDragActiveCallbackState, draggedRecordIdsCallbackState, primaryDraggedRecordIdCallbackState, - originalSelectionAtom, - isDraggingRecordAtom, + originalSelection, + isDraggingRecord, isRecordIdSecondaryDragMultipleCallbackState, isRecordIdPrimaryDragMultipleCallbackState, ], diff --git a/packages/twenty-front/src/modules/object-record/record-drag/hooks/useTriggerTableWithoutGroupDragAndDropOptimisticUpdate.ts b/packages/twenty-front/src/modules/object-record/record-drag/hooks/useTriggerTableWithoutGroupDragAndDropOptimisticUpdate.ts index f27042652e..b3a4043457 100644 --- a/packages/twenty-front/src/modules/object-record/record-drag/hooks/useTriggerTableWithoutGroupDragAndDropOptimisticUpdate.ts +++ b/packages/twenty-front/src/modules/object-record/record-drag/hooks/useTriggerTableWithoutGroupDragAndDropOptimisticUpdate.ts @@ -66,7 +66,7 @@ export const useTriggerTableWithoutGroupDragAndDropOptimisticUpdate = () => { const correspondingRecordInStore = store.get( recordStoreFamilyState.atomFamily(recordIdAtRealIndex), - ) as { id: string; position?: number } | null | undefined; + ); if ( isDefined(correspondingRecordInStore) && diff --git a/packages/twenty-front/src/modules/object-record/record-drag/utils/extractRecordPositions.ts b/packages/twenty-front/src/modules/object-record/record-drag/utils/extractRecordPositions.ts index d1e6f84122..b94fe27edf 100644 --- a/packages/twenty-front/src/modules/object-record/record-drag/utils/extractRecordPositions.ts +++ b/packages/twenty-front/src/modules/object-record/record-drag/utils/extractRecordPositions.ts @@ -8,10 +8,7 @@ export const extractRecordPositions = ( store: Store, ): RecordWithPosition[] => { return recordIds.map((recordId) => { - const record = store.get(recordStoreFamilyState.atomFamily(recordId)) as - | { position?: number } - | null - | undefined; + const record = store.get(recordStoreFamilyState.atomFamily(recordId)); return { id: recordId, diff --git a/packages/twenty-front/src/modules/object-record/record-field/hooks/useMoveRecordField.ts b/packages/twenty-front/src/modules/object-record/record-field/hooks/useMoveRecordField.ts index a7b60ac984..7b27b39f6c 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/hooks/useMoveRecordField.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/hooks/useMoveRecordField.ts @@ -1,14 +1,15 @@ import { useUpdateRecordField } from '@/object-record/record-field/hooks/useUpdateRecordField'; import { currentRecordFieldsComponentState } from '@/object-record/record-field/states/currentRecordFieldsComponentState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2'; import { useSaveCurrentViewFields } from '@/views/hooks/useSaveCurrentViewFields'; import { mapRecordFieldToViewField } from '@/views/utils/mapRecordFieldToViewField'; import { useCallback } from 'react'; import { sortByProperty } from '~/utils/array/sortByProperty'; +import { useStore } from 'jotai'; export const useMoveRecordField = (recordTableId?: string) => { - const currentRecordFieldsAtom = useRecoilComponentStateCallbackStateV2( + const store = useStore(); + const currentRecordFields = useRecoilComponentStateCallbackStateV2( currentRecordFieldsComponentState, recordTableId, ); @@ -25,11 +26,9 @@ export const useMoveRecordField = (recordTableId?: string) => { direction: 'before' | 'after'; fieldMetadataItemIdToMove: string; }) => { - const currentRecordFields = jotaiStore.get(currentRecordFieldsAtom); - - const sortedRecordFields = currentRecordFields.toSorted( - sortByProperty('position'), - ); + const sortedRecordFields = store + .get(currentRecordFields) + .toSorted(sortByProperty('position')); const indexOfRecordFieldToMove = sortedRecordFields.findIndex( (recordField) => @@ -81,7 +80,7 @@ export const useMoveRecordField = (recordTableId?: string) => { ]); } }, - [currentRecordFieldsAtom, saveViewFields, updateRecordField], + [currentRecordFields, saveViewFields, updateRecordField, store], ); return { moveRecordField }; diff --git a/packages/twenty-front/src/modules/object-record/record-field/hooks/useReorderVisibleRecordFields.ts b/packages/twenty-front/src/modules/object-record/record-field/hooks/useReorderVisibleRecordFields.ts index 706f2f03e7..1cb16395ac 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/hooks/useReorderVisibleRecordFields.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/hooks/useReorderVisibleRecordFields.ts @@ -3,18 +3,19 @@ import { currentRecordFieldsComponentState } from '@/object-record/record-field/ import { visibleRecordFieldsComponentSelector } from '@/object-record/record-field/states/visibleRecordFieldsComponentSelector'; import { type RecordField } from '@/object-record/record-field/types/RecordField'; import { computeNewPositionOfDraggedRecord } from '@/object-record/utils/computeNewPositionOfDraggedRecord'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useRecoilComponentSelectorCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentSelectorCallbackStateV2'; import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2'; import { useCallback } from 'react'; +import { useStore } from 'jotai'; export const useReorderVisibleRecordFields = (recordTableId: string) => { - const visibleRecordFieldsAtom = useRecoilComponentSelectorCallbackStateV2( + const store = useStore(); + const visibleRecordFields = useRecoilComponentSelectorCallbackStateV2( visibleRecordFieldsComponentSelector, recordTableId, ); - const currentRecordFieldsAtom = useRecoilComponentStateCallbackStateV2( + const currentRecordFields = useRecoilComponentStateCallbackStateV2( currentRecordFieldsComponentState, recordTableId, ); @@ -23,18 +24,18 @@ export const useReorderVisibleRecordFields = (recordTableId: string) => { const reorderVisibleRecordFields = useCallback( ({ fromIndex, toIndex }: { fromIndex: number; toIndex: number }) => { - const visibleRecordFields = jotaiStore.get(visibleRecordFieldsAtom); - const currentRecordFields = jotaiStore.get(currentRecordFieldsAtom); + const visibleRecordFieldsValue = store.get(visibleRecordFields); + const currentRecordFieldsValue = store.get(currentRecordFields); - const idOfRecordToMove = visibleRecordFields[fromIndex].id; - const idOfTargetRecord = visibleRecordFields[toIndex].id; + const idOfRecordToMove = visibleRecordFieldsValue[fromIndex].id; + const idOfTargetRecord = visibleRecordFieldsValue[toIndex].id; - const recordToMove = visibleRecordFields[fromIndex]; + const recordToMove = visibleRecordFieldsValue[fromIndex]; - const isDroppedAfterList = toIndex >= visibleRecordFields.length; + const isDroppedAfterList = toIndex >= visibleRecordFieldsValue.length; const newPositionOfTargetRecord = computeNewPositionOfDraggedRecord({ - arrayOfRecordsWithPosition: currentRecordFields, + arrayOfRecordsWithPosition: currentRecordFieldsValue, idOfItemToMove: idOfRecordToMove, idOfTargetItem: idOfTargetRecord, isDroppedAfterList, @@ -51,7 +52,7 @@ export const useReorderVisibleRecordFields = (recordTableId: string) => { return updatedRecordField; }, - [currentRecordFieldsAtom, visibleRecordFieldsAtom, updateRecordField], + [currentRecordFields, visibleRecordFields, updateRecordField, store], ); return { reorderVisibleRecordFields }; diff --git a/packages/twenty-front/src/modules/object-record/record-field/hooks/useUpdateRecordField.ts b/packages/twenty-front/src/modules/object-record/record-field/hooks/useUpdateRecordField.ts index 7e2fb0e0f1..43476a1830 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/hooks/useUpdateRecordField.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/hooks/useUpdateRecordField.ts @@ -1,14 +1,15 @@ import { currentRecordFieldsComponentState } from '@/object-record/record-field/states/currentRecordFieldsComponentState'; import { type RecordField } from '@/object-record/record-field/types/RecordField'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2'; import { useCallback } from 'react'; import { isDefined } from 'twenty-shared/utils'; +import { useStore } from 'jotai'; export const useUpdateRecordField = ( recordFieldComponentInstanceId?: string, ) => { - const currentRecordFieldsAtom = useRecoilComponentStateCallbackStateV2( + const store = useStore(); + const currentRecordFields = useRecoilComponentStateCallbackStateV2( currentRecordFieldsComponentState, recordFieldComponentInstanceId, ); @@ -20,9 +21,9 @@ export const useUpdateRecordField = ( Pick >, ) => { - const currentRecordFields = jotaiStore.get(currentRecordFieldsAtom); + const existingRecordFields = store.get(currentRecordFields); - const foundRecordFieldInCurrentRecordFields = currentRecordFields.find( + const foundRecordFieldInCurrentRecordFields = existingRecordFields.find( (existingRecordField) => existingRecordField.fieldMetadataItemId === fieldMetadataItemId, ); @@ -33,8 +34,8 @@ export const useUpdateRecordField = ( ); } - jotaiStore.set(currentRecordFieldsAtom, (currentRecordFields) => { - const newCurrentRecordFields = [...currentRecordFields]; + store.set(currentRecordFields, (previousRecordFields) => { + const newCurrentRecordFields = [...previousRecordFields]; const indexOfRecordFieldToUpdate = newCurrentRecordFields.findIndex( (existingRecordField) => @@ -54,7 +55,7 @@ export const useUpdateRecordField = ( ...partialRecordField, } satisfies RecordField as RecordField; }, - [currentRecordFieldsAtom], + [currentRecordFields, store], ); return { diff --git a/packages/twenty-front/src/modules/object-record/record-field/hooks/useUpsertRecordField.ts b/packages/twenty-front/src/modules/object-record/record-field/hooks/useUpsertRecordField.ts index 07b02d6027..f5fa5c5b08 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/hooks/useUpsertRecordField.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/hooks/useUpsertRecordField.ts @@ -1,32 +1,33 @@ import { currentRecordFieldsComponentState } from '@/object-record/record-field/states/currentRecordFieldsComponentState'; import { type RecordField } from '@/object-record/record-field/types/RecordField'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2'; import { useCallback } from 'react'; +import { useStore } from 'jotai'; export const useUpsertRecordField = (recordTableId?: string) => { - const currentRecordFieldsAtom = useRecoilComponentStateCallbackStateV2( + const store = useStore(); + const currentRecordFields = useRecoilComponentStateCallbackStateV2( currentRecordFieldsComponentState, recordTableId, ); const upsertRecordField = useCallback( (recordFieldToUpsert: RecordField) => { - const currentRecordFields = jotaiStore.get(currentRecordFieldsAtom); + const existingRecordFields = store.get(currentRecordFields); - const foundRecordFieldInCurrentRecordFields = currentRecordFields.some( + const foundRecordFieldInCurrentRecordFields = existingRecordFields.some( (existingRecordField) => existingRecordField.id === recordFieldToUpsert.id, ); if (!foundRecordFieldInCurrentRecordFields) { - jotaiStore.set(currentRecordFieldsAtom, [ - ...currentRecordFields, + store.set(currentRecordFields, [ + ...existingRecordFields, recordFieldToUpsert, ]); } else { - jotaiStore.set(currentRecordFieldsAtom, (currentRecordFields) => { - const newCurrentRecordFields = [...currentRecordFields]; + store.set(currentRecordFields, (previousRecordFields) => { + const newCurrentRecordFields = [...previousRecordFields]; const indexOfRecordFieldToUpdate = newCurrentRecordFields.findIndex( (existingRecordField) => @@ -41,7 +42,7 @@ export const useUpsertRecordField = (recordTableId?: string) => { }); } }, - [currentRecordFieldsAtom], + [currentRecordFields, store], ); return { diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/hooks/useClearField.ts b/packages/twenty-front/src/modules/object-record/record-field/ui/hooks/useClearField.ts index 6a8b20f84a..6ce7f15c18 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/hooks/useClearField.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/hooks/useClearField.ts @@ -3,7 +3,6 @@ import { useStore } from 'jotai'; import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; import { recordStoreFamilySelectorV2 } from '@/object-record/record-store/states/selectors/recordStoreFamilySelectorV2'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { generateEmptyFieldValue } from '@/object-record/utils/generateEmptyFieldValue'; import { FieldContext } from '@/object-record/record-field/ui/contexts/FieldContext'; @@ -21,7 +20,7 @@ export const useClearField = () => { const [updateRecord] = useUpdateRecord(); const clearField = useCallback(() => { - const objectMetadataItems = jotaiStore.get(objectMetadataItemsState.atom); + const objectMetadataItems = store.get(objectMetadataItemsState.atom); const foundObjectMetadataItem = objectMetadataItems.find( (item) => diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/hooks/useInitDraftValue.ts b/packages/twenty-front/src/modules/object-record/record-field/ui/hooks/useInitDraftValue.ts index aab258f7a8..5f344e33ca 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/hooks/useInitDraftValue.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/hooks/useInitDraftValue.ts @@ -32,17 +32,16 @@ export const useInitDraftValue = () => { }), ) as FieldValue; - const draftValueAtom = - recordFieldInputDraftValueComponentState.atomFamily({ - instanceId: fieldComponentInstanceId, - }); + const draftValue = recordFieldInputDraftValueComponentState.atomFamily({ + instanceId: fieldComponentInstanceId, + }); if ( isUndefined(value) || FIELD_NOT_OVERWRITTEN_AT_DRAFT.includes(fieldDefinition.type) ) { store.set( - draftValueAtom, + draftValue, computeDraftValueFromFieldValue({ fieldValue: recordFieldValue, fieldDefinition, @@ -50,7 +49,7 @@ export const useInitDraftValue = () => { ); } else { store.set( - draftValueAtom, + draftValue, computeDraftValueFromString({ value, fieldDefinition, diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/hooks/useOpenJunctionRelationFieldInput.ts b/packages/twenty-front/src/modules/object-record/record-field/ui/hooks/useOpenJunctionRelationFieldInput.ts index 6ea741b210..a3b1bb3f22 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/hooks/useOpenJunctionRelationFieldInput.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/hooks/useOpenJunctionRelationFieldInput.ts @@ -1,5 +1,4 @@ import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { type FieldDefinition } from '@/object-record/record-field/ui/types/FieldDefinition'; import { type FieldRelationFromManyValue, @@ -38,7 +37,7 @@ export const useOpenJunctionRelationFieldInput = () => { recordId: string; prefix?: string; }) => { - const objectMetadataItems = jotaiStore.get(objectMetadataItemsState.atom); + const objectMetadataItems = store.get(objectMetadataItemsState.atom); const sourceObjectMetadataId = objectMetadataItems.find( (item) => @@ -70,7 +69,7 @@ export const useOpenJunctionRelationFieldInput = () => { prefix, }); - const junctionRecords = jotaiStore.get( + const junctionRecords = store.get( recordStoreFamilySelectorV2.selectorFamily({ recordId, fieldName: fieldDefinition.metadata.fieldName, diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/hooks/useRecordFieldInput.ts b/packages/twenty-front/src/modules/object-record/record-field/ui/hooks/useRecordFieldInput.ts index eaa3af651d..31673de66b 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/hooks/useRecordFieldInput.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/hooks/useRecordFieldInput.ts @@ -5,7 +5,7 @@ import { useStore } from 'jotai'; import { useCallback } from 'react'; export const useRecordFieldInput = () => { - const recordFieldInputDraftValueAtom = useRecoilComponentStateCallbackStateV2( + const recordFieldInputDraftValue = useRecoilComponentStateCallbackStateV2( recordFieldInputDraftValueComponentState, ); @@ -13,9 +13,9 @@ export const useRecordFieldInput = () => { const setDraftValue = useCallback( (newValue: unknown) => { - store.set(recordFieldInputDraftValueAtom, newValue); + store.set(recordFieldInputDraftValue, newValue); }, - [store, recordFieldInputDraftValueAtom], + [store, recordFieldInputDraftValue], ); const isDraftValueEmpty = ( diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/hooks/useUpdateJunctionRelationFromCell.ts b/packages/twenty-front/src/modules/object-record/record-field/ui/hooks/useUpdateJunctionRelationFromCell.ts index 50792f88eb..21e5cb3ce2 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/hooks/useUpdateJunctionRelationFromCell.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/hooks/useUpdateJunctionRelationFromCell.ts @@ -22,7 +22,6 @@ import { searchRecordStoreFamilyState } from '@/object-record/record-picker/mult import { type RecordPickerPickableMorphItem } from '@/object-record/record-picker/types/RecordPickerPickableMorphItem'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; import { type ObjectRecord } from '@/object-record/types/ObjectRecord'; -import { type SearchRecord } from '~/generated/graphql'; type UseUpdateJunctionRelationFromCellArgs = { fieldMetadataItem: FieldMetadataItem; @@ -116,7 +115,7 @@ export const useUpdateJunctionRelationFromCell = ({ const recordFromStore = store.get( recordStoreFamilyState.atomFamily(recordId), - ) as Record | null | undefined; + ); const currentJunctionRecords = (recordFromStore?.[fieldName] as | FieldRelationValue @@ -138,7 +137,7 @@ export const useUpdateJunctionRelationFromCell = ({ const recordFromStoreForDelete = store.get( recordStoreFamilyState.atomFamily(recordId), - ) as Record | null | undefined; + ); const currentFieldValue = recordFromStoreForDelete?.[fieldName] as | FieldRelationValue | undefined; @@ -169,7 +168,7 @@ export const useUpdateJunctionRelationFromCell = ({ } else { const searchRecord = store.get( searchRecordStoreFamilyState.atomFamily(morphItem.recordId), - ) as (SearchRecord & { record?: ObjectRecord }) | undefined; + ); if (!isDefined(searchRecord?.record)) { return; diff --git a/packages/twenty-front/src/modules/object-record/record-filter-group/hooks/useRemoveRecordFilterGroup.ts b/packages/twenty-front/src/modules/object-record/record-filter-group/hooks/useRemoveRecordFilterGroup.ts index 615741ec55..5cf50ab0ec 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter-group/hooks/useRemoveRecordFilterGroup.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter-group/hooks/useRemoveRecordFilterGroup.ts @@ -5,7 +5,7 @@ import { useStore } from 'jotai'; import { useContext } from 'react'; export const useRemoveRecordFilterGroup = () => { - const currentRecordFilterGroupsAtom = useRecoilComponentStateCallbackStateV2( + const currentRecordFilterGroups = useRecoilComponentStateCallbackStateV2( currentRecordFilterGroupsComponentState, ); @@ -15,17 +15,17 @@ export const useRemoveRecordFilterGroup = () => { const removeRecordFilterGroupCallback = ( recordFilterGroupIdToRemove: string, ) => { - const currentRecordFilterGroups = store.get(currentRecordFilterGroupsAtom); + const existingRecordFilterGroups = store.get(currentRecordFilterGroups); const hasFoundRecordFilterGroupInCurrentRecordFilterGroups = - currentRecordFilterGroups.some( + existingRecordFilterGroups.some( (existingRecordFilterGroup) => existingRecordFilterGroup.id === recordFilterGroupIdToRemove, ); if (hasFoundRecordFilterGroupInCurrentRecordFilterGroups) { - store.set(currentRecordFilterGroupsAtom, (currentRecordFilterGroups) => { - const newCurrentRecordFilterGroups = [...currentRecordFilterGroups]; + store.set(currentRecordFilterGroups, (previousRecordFilterGroups) => { + const newCurrentRecordFilterGroups = [...previousRecordFilterGroups]; const indexOfRecordFilterGroupToRemove = newCurrentRecordFilterGroups.findIndex( diff --git a/packages/twenty-front/src/modules/object-record/record-filter-group/hooks/useRemoveRootRecordFilterGroupIfEmpty.ts b/packages/twenty-front/src/modules/object-record/record-filter-group/hooks/useRemoveRootRecordFilterGroupIfEmpty.ts index 0d1cb96e01..dbe38cc5bd 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter-group/hooks/useRemoveRootRecordFilterGroupIfEmpty.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter-group/hooks/useRemoveRootRecordFilterGroupIfEmpty.ts @@ -6,11 +6,11 @@ import { useStore } from 'jotai'; import { isDefined } from 'twenty-shared/utils'; export const useRemoveRootRecordFilterGroupIfEmpty = () => { - const currentRecordFilterGroupsAtom = useRecoilComponentStateCallbackStateV2( + const currentRecordFilterGroups = useRecoilComponentStateCallbackStateV2( currentRecordFilterGroupsComponentState, ); - const currentRecordFiltersAtom = useRecoilComponentStateCallbackStateV2( + const currentRecordFilters = useRecoilComponentStateCallbackStateV2( currentRecordFiltersComponentState, ); @@ -18,24 +18,24 @@ export const useRemoveRootRecordFilterGroupIfEmpty = () => { const { removeRecordFilterGroup } = useRemoveRecordFilterGroup(); const removeRootRecordFilterGroupIfEmpty = () => { - const currentRecordFilterGroups = store.get(currentRecordFilterGroupsAtom); + const existingRecordFilterGroups = store.get(currentRecordFilterGroups); - const currentRecordFilters = store.get(currentRecordFiltersAtom); + const existingRecordFilters = store.get(currentRecordFilters); - const rootRecordFilterGroup = currentRecordFilterGroups.find( + const rootRecordFilterGroup = existingRecordFilterGroups.find( (existingRecordFilterGroup) => !isDefined(existingRecordFilterGroup.parentRecordFilterGroupId), ); if (isDefined(rootRecordFilterGroup)) { const recordFilterGroupsInRootRecordFilterGroup = - currentRecordFilterGroups.filter( + existingRecordFilterGroups.filter( (recordFilterGroupToFilter) => recordFilterGroupToFilter.parentRecordFilterGroupId === rootRecordFilterGroup.id, ); - const recordFiltersInRootRecordFilterGroup = currentRecordFilters.filter( + const recordFiltersInRootRecordFilterGroup = existingRecordFilters.filter( (recordFilterToFilter) => recordFilterToFilter.recordFilterGroupId === rootRecordFilterGroup.id, ); diff --git a/packages/twenty-front/src/modules/object-record/record-filter-group/hooks/useUpsertRecordFilterGroup.ts b/packages/twenty-front/src/modules/object-record/record-filter-group/hooks/useUpsertRecordFilterGroup.ts index 86b7846972..b6be2ca495 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter-group/hooks/useUpsertRecordFilterGroup.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter-group/hooks/useUpsertRecordFilterGroup.ts @@ -6,7 +6,7 @@ import { useStore } from 'jotai'; import { useContext } from 'react'; export const useUpsertRecordFilterGroup = () => { - const currentRecordFilterGroupsAtom = useRecoilComponentStateCallbackStateV2( + const currentRecordFilterGroups = useRecoilComponentStateCallbackStateV2( currentRecordFilterGroupsComponentState, ); const store = useStore(); @@ -15,22 +15,22 @@ export const useUpsertRecordFilterGroup = () => { const upsertRecordFilterGroupCallback = ( recordFilterGroupToSet: RecordFilterGroup, ) => { - const currentRecordFilterGroups = store.get(currentRecordFilterGroupsAtom); + const existingRecordFilterGroups = store.get(currentRecordFilterGroups); const hasFoundRecordFilterGroupInCurrentRecordFilterGroups = - currentRecordFilterGroups.some( + existingRecordFilterGroups.some( (existingRecordFilterGroup) => existingRecordFilterGroup.id === recordFilterGroupToSet.id, ); if (!hasFoundRecordFilterGroupInCurrentRecordFilterGroups) { - store.set(currentRecordFilterGroupsAtom, [ - ...currentRecordFilterGroups, + store.set(currentRecordFilterGroups, [ + ...existingRecordFilterGroups, recordFilterGroupToSet, ]); } else { - store.set(currentRecordFilterGroupsAtom, (currentRecordFilterGroups) => { - const newCurrentRecordFilterGroups = [...currentRecordFilterGroups]; + store.set(currentRecordFilterGroups, (previousRecordFilterGroups) => { + const newCurrentRecordFilterGroups = [...previousRecordFilterGroups]; const indexOfRecordFilterGroupToUpdate = newCurrentRecordFilterGroups.findIndex( diff --git a/packages/twenty-front/src/modules/object-record/record-filter/hooks/useRemoveRecordFilter.ts b/packages/twenty-front/src/modules/object-record/record-filter/hooks/useRemoveRecordFilter.ts index b999d1e947..bf5b2633a1 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/hooks/useRemoveRecordFilter.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/hooks/useRemoveRecordFilter.ts @@ -7,7 +7,7 @@ import { useCallback, useContext } from 'react'; import { isDefined } from 'twenty-shared/utils'; export const useRemoveRecordFilter = () => { - const currentRecordFiltersAtom = useRecoilComponentStateCallbackStateV2( + const currentRecordFilters = useRecoilComponentStateCallbackStateV2( currentRecordFiltersComponentState, ); @@ -16,11 +16,11 @@ export const useRemoveRecordFilter = () => { const removeRecordFilterCallback = useCallback( ({ recordFilterId }: { recordFilterId: string }) => { - const currentRecordFilters = store.get( - currentRecordFiltersAtom, + const existingRecordFilters = store.get( + currentRecordFilters, ) as RecordFilter[]; - const filterToRemove = currentRecordFilters.find( + const filterToRemove = existingRecordFilters.find( (existingFilter) => existingFilter.id === recordFilterId, ); @@ -29,9 +29,9 @@ export const useRemoveRecordFilter = () => { } store.set( - currentRecordFiltersAtom, - (currentRecordFilters: RecordFilter[]) => { - const newCurrentRecordFilters = [...currentRecordFilters]; + currentRecordFilters, + (previousRecordFilters: RecordFilter[]) => { + const newCurrentRecordFilters = [...previousRecordFilters]; const indexOfFilterToRemove = newCurrentRecordFilters.findIndex( (existingFilter) => existingFilter.id === recordFilterId, @@ -43,7 +43,7 @@ export const useRemoveRecordFilter = () => { }, ); }, - [currentRecordFiltersAtom, store], + [currentRecordFilters, store], ); const removeRecordFilter = ({ diff --git a/packages/twenty-front/src/modules/object-record/record-filter/hooks/useUpsertRecordFilter.ts b/packages/twenty-front/src/modules/object-record/record-filter/hooks/useUpsertRecordFilter.ts index c23dd8a5e3..85e2f4f013 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/hooks/useUpsertRecordFilter.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/hooks/useUpsertRecordFilter.ts @@ -6,7 +6,7 @@ import { useStore } from 'jotai'; import { useCallback, useContext } from 'react'; export const useUpsertRecordFilter = () => { - const currentRecordFiltersAtom = useRecoilComponentStateCallbackStateV2( + const currentRecordFilters = useRecoilComponentStateCallbackStateV2( currentRecordFiltersComponentState, ); @@ -15,24 +15,25 @@ export const useUpsertRecordFilter = () => { const upsertRecordFilterCallback = useCallback( (recordFilterToSet: RecordFilter) => { - const currentRecordFilters = store.get( - currentRecordFiltersAtom, + const existingRecordFilters = store.get( + currentRecordFilters, ) as RecordFilter[]; - const foundRecordFilterInCurrentRecordFilters = currentRecordFilters.some( - (existingFilter) => existingFilter.id === recordFilterToSet.id, - ); + const foundRecordFilterInCurrentRecordFilters = + existingRecordFilters.some( + (existingFilter) => existingFilter.id === recordFilterToSet.id, + ); if (!foundRecordFilterInCurrentRecordFilters) { - store.set(currentRecordFiltersAtom, [ - ...currentRecordFilters, + store.set(currentRecordFilters, [ + ...existingRecordFilters, recordFilterToSet, ]); } else { store.set( - currentRecordFiltersAtom, - (currentRecordFilters: RecordFilter[]) => { - const newCurrentRecordFilters = [...currentRecordFilters]; + currentRecordFilters, + (previousRecordFilters: RecordFilter[]) => { + const newCurrentRecordFilters = [...previousRecordFilters]; const indexOfFilterToUpdate = newCurrentRecordFilters.findIndex( (existingFilter) => existingFilter.id === recordFilterToSet.id, @@ -47,7 +48,7 @@ export const useUpsertRecordFilter = () => { ); } }, - [currentRecordFiltersAtom, store], + [currentRecordFilters, store], ); const upsertRecordFilter = (recordFilterToSet: RecordFilter) => { diff --git a/packages/twenty-front/src/modules/object-record/record-group/hooks/useRecordGroupVisibility.ts b/packages/twenty-front/src/modules/object-record/record-group/hooks/useRecordGroupVisibility.ts index 4de015e99c..1f9ba4e904 100644 --- a/packages/twenty-front/src/modules/object-record/record-group/hooks/useRecordGroupVisibility.ts +++ b/packages/twenty-front/src/modules/object-record/record-group/hooks/useRecordGroupVisibility.ts @@ -12,7 +12,7 @@ import { useCallback } from 'react'; export const useRecordGroupVisibility = () => { const store = useStore(); - const recordIndexShouldHideEmptyRecordGroupsAtom = + const recordIndexShouldHideEmptyRecordGroups = useRecoilComponentStateCallbackStateV2( recordIndexShouldHideEmptyRecordGroupsComponentState, ); @@ -33,18 +33,16 @@ export const useRecordGroupVisibility = () => { ); const handleHideEmptyRecordGroupChange = useCallback(async () => { - const currentHideState = store.get( - recordIndexShouldHideEmptyRecordGroupsAtom, - ); + const currentHideState = store.get(recordIndexShouldHideEmptyRecordGroups); const newHideState = !currentHideState; - store.set(recordIndexShouldHideEmptyRecordGroupsAtom, newHideState); + store.set(recordIndexShouldHideEmptyRecordGroups, newHideState); await updateCurrentView({ shouldHideEmptyGroups: newHideState, }); - }, [store, recordIndexShouldHideEmptyRecordGroupsAtom, updateCurrentView]); + }, [store, recordIndexShouldHideEmptyRecordGroups, updateCurrentView]); return { handleVisibilityChange, diff --git a/packages/twenty-front/src/modules/object-record/record-group/hooks/useSetRecordGroups.ts b/packages/twenty-front/src/modules/object-record/record-group/hooks/useSetRecordGroups.ts index 674b8205f5..3b53fc9c4a 100644 --- a/packages/twenty-front/src/modules/object-record/record-group/hooks/useSetRecordGroups.ts +++ b/packages/twenty-front/src/modules/object-record/record-group/hooks/useSetRecordGroups.ts @@ -50,15 +50,15 @@ export const useSetRecordGroups = () => { (field) => field.id === fieldMetadataId, ) : undefined; - const recordIndexGroupFieldMetadataAtom = + const recordIndexGroupFieldMetadata = recordIndexGroupFieldMetadataItemComponentState.atomFamily({ instanceId: recordIndexId, }); - const currentFieldMetadata = store.get(recordIndexGroupFieldMetadataAtom); + const currentFieldMetadata = store.get(recordIndexGroupFieldMetadata); // Set the field metadata linked to the record groups if (!isDeeplyEqual(fieldMetadata, currentFieldMetadata)) { - store.set(recordIndexGroupFieldMetadataAtom, fieldMetadata); + store.set(recordIndexGroupFieldMetadata, fieldMetadata); } // Set the record groups by id diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainerGater.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainerGater.tsx index fb9a6b2581..8cc9421b8d 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainerGater.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainerGater.tsx @@ -8,7 +8,6 @@ import { RecordComponentInstanceContextsWrapper } from '@/object-record/componen import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions'; import { lastShowPageRecordIdState } from '@/object-record/record-field/ui/states/lastShowPageRecordId'; import { RecordIndexContainer } from '@/object-record/record-index/components/RecordIndexContainer'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { RecordIndexContainerContextStoreNumberOfSelectedRecordsEffect } from '@/object-record/record-index/components/RecordIndexContainerContextStoreNumberOfSelectedRecordsEffect'; import { RecordIndexLoadBaseOnContextStoreEffect } from '@/object-record/record-index/components/RecordIndexLoadBaseOnContextStoreEffect'; import { RecordIndexPageHeader } from '@/object-record/record-index/components/RecordIndexPageHeader'; @@ -21,6 +20,7 @@ import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewCompon import styled from '@emotion/styled'; import { useCallback } from 'react'; import { NotFound } from '~/pages/not-found/NotFound'; +import { useStore } from 'jotai'; const StyledIndexContainer = styled.div` display: flex; @@ -29,13 +29,14 @@ const StyledIndexContainer = styled.div` `; export const RecordIndexContainerGater = () => { + const store = useStore(); const { recordIndexId, objectMetadataItem } = useRecordIndexIdFromCurrentContextStore(); const handleIndexRecordsLoaded = useCallback(() => { // TODO: find a better way to reset this state ? - jotaiStore.set(lastShowPageRecordIdState.atom, null); - }, []); + store.set(lastShowPageRecordIdState.atom, null); + }, [store]); const { indexIdentifierUrl } = useHandleIndexIdentifierClick({ objectMetadataItem, diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexGroupAggregateQueryEffect.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexGroupAggregateQueryEffect.tsx index 6ea675b883..1385c6ae85 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexGroupAggregateQueryEffect.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexGroupAggregateQueryEffect.tsx @@ -40,7 +40,7 @@ export const RecordIndexGroupAggregateQueryEffect = ({ recordIndexGroupAggregateOperation, }); - const recordIndexAggregateDisplayLabelAtom = + const recordIndexAggregateDisplayLabel = useRecoilComponentStateCallbackStateV2( recordIndexAggregateDisplayLabelComponentState, ); @@ -112,7 +112,7 @@ export const RecordIndexGroupAggregateQueryEffect = ({ recordIndexGroupAggregateFieldMetadataItem, recordIndexGroupAggregateOperation, recordAggregateGqlField, - recordIndexAggregateDisplayLabelAtom, + recordIndexAggregateDisplayLabel, objectMetadataItem, recordGroupDefinitions, ]); diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexTableContainerEffect.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexTableContainerEffect.tsx index 38e06c5706..876c8f29c5 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexTableContainerEffect.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexTableContainerEffect.tsx @@ -5,12 +5,13 @@ import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadata import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext'; import { viewFieldAggregateOperationState } from '@/object-record/record-table/record-table-footer/states/viewFieldAggregateOperationState'; import { convertAggregateOperationToExtendedAggregateOperation } from '@/object-record/utils/convertAggregateOperationToExtendedAggregateOperation'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly'; import { type ViewField } from '@/views/types/ViewField'; import { isDefined } from 'twenty-shared/utils'; +import { useStore } from 'jotai'; export const RecordIndexTableContainerEffect = () => { + const store = useStore(); const { objectNameSingular } = useRecordIndexContextOrThrow(); const { objectMetadataItem } = useObjectMetadataItem({ @@ -24,7 +25,7 @@ export const RecordIndexTableContainerEffect = () => { const setViewFieldAggregateOperation = useCallback( (viewField: ViewField) => { - const aggregateOperationForViewField = jotaiStore.get( + const aggregateOperationForViewField = store.get( viewFieldAggregateOperationState.atomFamily({ viewFieldId: viewField.id, }), @@ -47,7 +48,7 @@ export const RecordIndexTableContainerEffect = () => { if ( aggregateOperationForViewField !== convertedViewFieldAggregateOperation ) { - jotaiStore.set( + store.set( viewFieldAggregateOperationState.atomFamily({ viewFieldId: viewField.id, }), @@ -55,7 +56,7 @@ export const RecordIndexTableContainerEffect = () => { ); } }, - [columnDefinitions], + [columnDefinitions, store], ); useEffect(() => { diff --git a/packages/twenty-front/src/modules/object-record/record-index/hooks/useFindManyRecordIndexTableParams.ts b/packages/twenty-front/src/modules/object-record/record-index/hooks/useFindManyRecordIndexTableParams.ts index 2e457e472f..ebe26c2e11 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/hooks/useFindManyRecordIndexTableParams.ts +++ b/packages/twenty-front/src/modules/object-record/record-index/hooks/useFindManyRecordIndexTableParams.ts @@ -66,9 +66,15 @@ export const useFindManyRecordIndexTableParams = ( objectMetadataItems, ); + const combinedFilter = combineFilters([ + currentFilters, + recordGroupFilter, + anyFieldFilter, + ]); + return { objectNameSingular, - filter: combineFilters([currentFilters, recordGroupFilter, anyFieldFilter]), + filter: combinedFilter, orderBy, // If we have a current record group definition, we only want to fetch 8 records by page ...(currentRecordGroupDefinition ? { limit: 8 } : {}), diff --git a/packages/twenty-front/src/modules/object-record/record-index/hooks/useLoadRecordIndexStates.ts b/packages/twenty-front/src/modules/object-record/record-index/hooks/useLoadRecordIndexStates.ts index e7a91418bd..388d1f5d16 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/hooks/useLoadRecordIndexStates.ts +++ b/packages/twenty-front/src/modules/object-record/record-index/hooks/useLoadRecordIndexStates.ts @@ -5,9 +5,12 @@ import { availableFieldMetadataItemsForSortFamilySelector } from '@/object-metad import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { formatFieldMetadataItemAsColumnDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsColumnDefinition'; import { isHiddenSystemField } from '@/object-metadata/utils/isHiddenSystemField'; +import { currentRecordFieldsComponentState } from '@/object-record/record-field/states/currentRecordFieldsComponentState'; import { type FieldMetadata } from '@/object-record/record-field/ui/types/FieldMetadata'; +import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState'; import { useSetRecordGroups } from '@/object-record/record-group/hooks/useSetRecordGroups'; import { recordIndexGroupFieldMetadataItemComponentState } from '@/object-record/record-index/states/recordIndexGroupFieldMetadataComponentState'; +import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState'; import { recordIndexCalendarFieldMetadataIdState } from '@/object-record/record-index/states/recordIndexCalendarFieldMetadataIdState'; import { recordIndexFieldDefinitionsState } from '@/object-record/record-index/states/recordIndexFieldDefinitionsState'; @@ -21,69 +24,67 @@ import { viewFieldAggregateOperationState } from '@/object-record/record-table/r import { type ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition'; import { convertAggregateOperationToExtendedAggregateOperation } from '@/object-record/utils/convertAggregateOperationToExtendedAggregateOperation'; import { filterAvailableTableColumns } from '@/object-record/utils/filterAvailableTableColumns'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; -import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2'; +import { getRecordIndexIdFromObjectNamePluralAndViewId } from '@/object-record/utils/getRecordIndexIdFromObjectNamePluralAndViewId'; +import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2'; +import { hasInitializedCurrentRecordFieldsComponentFamilyState } from '@/views/states/hasInitializedCurrentRecordFieldsComponentFamilyState'; +import { hasInitializedCurrentRecordFiltersComponentFamilyState } from '@/views/states/hasInitializedCurrentRecordFiltersComponentFamilyState'; +import { hasInitializedCurrentRecordSortsComponentFamilyState } from '@/views/states/hasInitializedCurrentRecordSortsComponentFamilyState'; import { type View } from '@/views/types/View'; -import { type ViewField } from '@/views/types/ViewField'; +import { getFilterableFields } from '@/views/utils/getFilterableFields'; +import { mapViewFieldToRecordField } from '@/views/utils/mapViewFieldToRecordField'; import { mapViewFieldsToColumnDefinitions } from '@/views/utils/mapViewFieldsToColumnDefinitions'; import { mapViewFiltersToFilters } from '@/views/utils/mapViewFiltersToFilters'; -import { useStore } from 'jotai'; +import { atom, useStore } from 'jotai'; import { useCallback } from 'react'; import { isDefined } from 'twenty-shared/utils'; -import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; export const useLoadRecordIndexStates = () => { const store = useStore(); - const setContextStoreTargetedRecordsRuleComponentState = - useSetRecoilComponentStateV2(contextStoreTargetedRecordsRuleComponentState); + const contextStoreTargetedRecordsRuleAtom = + useRecoilComponentStateCallbackStateV2( + contextStoreTargetedRecordsRuleComponentState, + ); - const setRecordIndexViewType = useSetRecoilStateV2(recordIndexViewTypeState); - const setRecordIndexOpenRecordIn = useSetRecoilStateV2( - recordIndexOpenRecordInState, - ); + const recordIndexGroupFieldMetadataItemAtom = + useRecoilComponentStateCallbackStateV2( + recordIndexGroupFieldMetadataItemComponentState, + ); - const setRecordIndexGroupFieldMetadataItem = useSetRecoilComponentStateV2( - recordIndexGroupFieldMetadataItemComponentState, - ); + const recordIndexGroupAggregateOperationAtom = + useRecoilComponentStateCallbackStateV2( + recordIndexGroupAggregateOperationComponentState, + ); - const setRecordIndexGroupAggregateOperation = useSetRecoilComponentStateV2( - recordIndexGroupAggregateOperationComponentState, - ); - - const setRecordIndexGroupAggregateFieldMetadataItem = - useSetRecoilComponentStateV2( + const recordIndexGroupAggregateFieldMetadataItemAtom = + useRecoilComponentStateCallbackStateV2( recordIndexGroupAggregateFieldMetadataItemComponentState, ); - const setRecordIndexShouldHideEmptyRecordGroups = - useSetRecoilComponentStateV2( + const recordIndexShouldHideEmptyRecordGroupsAtom = + useRecoilComponentStateCallbackStateV2( recordIndexShouldHideEmptyRecordGroupsComponentState, ); - const setRecordIndexCalendarFieldMetadataIdState = useSetRecoilStateV2( - recordIndexCalendarFieldMetadataIdState, - ); - const { getFieldMetadataItemByIdOrThrow } = useGetFieldMetadataItemByIdOrThrow(); const { setRecordGroupsFromViewGroups } = useSetRecordGroups(); - const onViewFieldsChange = useCallback( - (viewFields: ViewField[], objectMetadataItem: ObjectMetadataItem) => { + const loadRecordIndexStates = useCallback( + (view: View, objectMetadataItem: ObjectMetadataItem) => { const activeFieldMetadataItems = objectMetadataItem.fields.filter( (field) => field.isActive && !isHiddenSystemField(field), ); - const filterableFieldMetadataItems = jotaiStore.get( + const filterableFieldMetadataItems = store.get( availableFieldMetadataItemsForFilterFamilySelector.selectorFamily({ objectMetadataItemId: objectMetadataItem.id, }), ); - const sortableFieldMetadataItems = jotaiStore.get( + const sortableFieldMetadataItems = store.get( availableFieldMetadataItemsForSortFamilySelector.selectorFamily({ objectMetadataItemId: objectMetadataItem.id, }), @@ -118,137 +119,189 @@ export const useLoadRecordIndexStates = () => { }); const newFieldDefinitions = mapViewFieldsToColumnDefinitions({ - viewFields, + viewFields: view.viewFields, columnDefinitions, }); - const existingRecordIndexFieldDefinitions = jotaiStore.get( - recordIndexFieldDefinitionsState.atom, + const recordFields = view.viewFields + .map(mapViewFieldToRecordField) + .filter(isDefined); + + const allFilterableFields = getFilterableFields(objectMetadataItem); + const recordFilters = mapViewFiltersToFilters( + view.viewFilters, + allFilterableFields, ); - if ( - !isDeeplyEqual(existingRecordIndexFieldDefinitions, newFieldDefinitions) - ) { - jotaiStore.set( - recordIndexFieldDefinitionsState.atom, - newFieldDefinitions, + const contextStoreFilters = mapViewFiltersToFilters( + view.viewFilters, + filterableFieldMetadataItems, + ); + + let recordIndexGroupFieldMetadataItemValue = undefined; + if (isDefined(view.mainGroupByFieldMetadataId)) { + const { fieldMetadataItem } = getFieldMetadataItemByIdOrThrow( + view.mainGroupByFieldMetadataId, ); + recordIndexGroupFieldMetadataItemValue = fieldMetadataItem; } - for (const viewField of viewFields) { - const viewFieldMetadataType = objectMetadataItem.fields?.find( - (field) => field.id === viewField.fieldMetadataId, - )?.type; - - const aggregateOperationForViewField = jotaiStore.get( - viewFieldAggregateOperationState.atomFamily({ - viewFieldId: viewField.id, - }), + const recordIndexGroupAggregateFieldMetadataItemValue = + objectMetadataItem.fields?.find( + (field) => field.id === view.kanbanAggregateOperationFieldMetadataId, ); - const convertedViewFieldAggregateOperation = isDefined( - viewField.aggregateOperation, - ) - ? convertAggregateOperationToExtendedAggregateOperation( - viewField.aggregateOperation, - viewFieldMetadataType, - ) - : viewField.aggregateOperation; - if ( - aggregateOperationForViewField !== - convertedViewFieldAggregateOperation - ) { - jotaiStore.set( - viewFieldAggregateOperationState.atomFamily({ - viewFieldId: viewField.id, - }), - convertedViewFieldAggregateOperation, + let convertedAggregateOperation = undefined; + if (isDefined(view.kanbanAggregateOperation)) { + convertedAggregateOperation = + convertAggregateOperationToExtendedAggregateOperation( + view.kanbanAggregateOperation, + recordIndexGroupAggregateFieldMetadataItemValue?.type, ); - } } - }, - [], - ); - const loadRecordIndexStates = useCallback( - async (view: View, objectMetadataItem: ObjectMetadataItem) => { - const filterableFieldMetadataItems = jotaiStore.get( - availableFieldMetadataItemsForFilterFamilySelector.selectorFamily({ - objectMetadataItemId: objectMetadataItem.id, + const recordIndexId = getRecordIndexIdFromObjectNamePluralAndViewId( + objectMetadataItem.namePlural, + view.id, + ); + + const currentRecordFieldsAtom = + currentRecordFieldsComponentState.atomFamily({ + instanceId: recordIndexId, + }); + const currentRecordFiltersAtom = + currentRecordFiltersComponentState.atomFamily({ + instanceId: recordIndexId, + }); + const currentRecordSortsAtom = + currentRecordSortsComponentState.atomFamily({ + instanceId: recordIndexId, + }); + + const hasInitializedFieldsAtom = + hasInitializedCurrentRecordFieldsComponentFamilyState.atomFamily({ + instanceId: recordIndexId, + familyKey: { viewId: view.id }, + }); + const hasInitializedFiltersAtom = + hasInitializedCurrentRecordFiltersComponentFamilyState.atomFamily({ + instanceId: recordIndexId, + familyKey: { viewId: view.id }, + }); + const hasInitializedSortsAtom = + hasInitializedCurrentRecordSortsComponentFamilyState.atomFamily({ + instanceId: recordIndexId, + familyKey: { viewId: view.id }, + }); + + store.set( + atom(null, (get, batchSet) => { + const existingFieldDefs = get(recordIndexFieldDefinitionsState.atom); + if (!isDeeplyEqual(existingFieldDefs, newFieldDefinitions)) { + batchSet( + recordIndexFieldDefinitionsState.atom, + newFieldDefinitions, + ); + } + + for (const viewField of view.viewFields) { + const viewFieldMetadataType = objectMetadataItem.fields?.find( + (field) => field.id === viewField.fieldMetadataId, + )?.type; + + const existingAggregateOp = get( + viewFieldAggregateOperationState.atomFamily({ + viewFieldId: viewField.id, + }), + ); + + const convertedViewFieldAggregateOp = isDefined( + viewField.aggregateOperation, + ) + ? convertAggregateOperationToExtendedAggregateOperation( + viewField.aggregateOperation, + viewFieldMetadataType, + ) + : viewField.aggregateOperation; + + if (existingAggregateOp !== convertedViewFieldAggregateOp) { + batchSet( + viewFieldAggregateOperationState.atomFamily({ + viewFieldId: viewField.id, + }), + convertedViewFieldAggregateOp, + ); + } + } + + batchSet(currentRecordFieldsAtom, recordFields); + batchSet(hasInitializedFieldsAtom, true); + + batchSet(currentRecordFiltersAtom, recordFilters); + batchSet(hasInitializedFiltersAtom, true); + + batchSet(currentRecordSortsAtom, view.viewSorts); + batchSet(hasInitializedSortsAtom, true); + + const prevRule = get(contextStoreTargetedRecordsRuleAtom); + batchSet(contextStoreTargetedRecordsRuleAtom, { + ...prevRule, + filters: contextStoreFilters, + }); + + batchSet(recordIndexViewTypeState.atom, view.type); + batchSet(recordIndexOpenRecordInState.atom, view.openRecordIn); + batchSet(recordIndexOpenRecordInStateV2.atom, view.openRecordIn); + + batchSet( + recordIndexCalendarFieldMetadataIdState.atom, + view.calendarFieldMetadataId ?? null, + ); + + batchSet( + recordIndexShouldHideEmptyRecordGroupsAtom, + view.shouldHideEmptyGroups, + ); + + if (isDefined(recordIndexGroupFieldMetadataItemValue)) { + batchSet( + recordIndexGroupFieldMetadataItemAtom, + recordIndexGroupFieldMetadataItemValue, + ); + } + + if (isDefined(convertedAggregateOperation)) { + batchSet( + recordIndexGroupAggregateOperationAtom, + convertedAggregateOperation, + ); + } + + if (isDefined(recordIndexGroupAggregateFieldMetadataItemValue)) { + batchSet( + recordIndexGroupAggregateFieldMetadataItemAtom, + recordIndexGroupAggregateFieldMetadataItemValue, + ); + } }), ); - onViewFieldsChange(view.viewFields, objectMetadataItem); - setRecordGroupsFromViewGroups({ viewId: view.id, mainGroupByFieldMetadataId: view.mainGroupByFieldMetadataId ?? '', viewGroups: view.viewGroups, objectMetadataItem, }); - - setContextStoreTargetedRecordsRuleComponentState((prev) => ({ - ...prev, - filters: mapViewFiltersToFilters( - view.viewFilters, - filterableFieldMetadataItems, - ), - })); - - setRecordIndexViewType(view.type); - setRecordIndexOpenRecordIn(view.openRecordIn); - store.set(recordIndexOpenRecordInStateV2.atom, view.openRecordIn); - - setRecordIndexCalendarFieldMetadataIdState( - view.calendarFieldMetadataId ?? null, - ); - - setRecordIndexShouldHideEmptyRecordGroups(view.shouldHideEmptyGroups); - - if (isDefined(view.mainGroupByFieldMetadataId)) { - const recordIndexGroupFieldMetadataItemId = - view.mainGroupByFieldMetadataId; - - const { fieldMetadataItem: recordIndexGroupFieldMetadataItem } = - getFieldMetadataItemByIdOrThrow(recordIndexGroupFieldMetadataItemId); - - setRecordIndexGroupFieldMetadataItem(recordIndexGroupFieldMetadataItem); - } - - const recordIndexGroupAggregateFieldMetadataItem = - objectMetadataItem.fields?.find( - (field) => field.id === view.kanbanAggregateOperationFieldMetadataId, - ); - - if (isDefined(view.kanbanAggregateOperation)) { - const convertedAggregateOperation = - convertAggregateOperationToExtendedAggregateOperation( - view.kanbanAggregateOperation, - recordIndexGroupAggregateFieldMetadataItem?.type, - ); - - setRecordIndexGroupAggregateOperation(convertedAggregateOperation); - } - - if (isDefined(recordIndexGroupAggregateFieldMetadataItem)) { - setRecordIndexGroupAggregateFieldMetadataItem( - recordIndexGroupAggregateFieldMetadataItem, - ); - } }, [ - onViewFieldsChange, - setRecordGroupsFromViewGroups, - setContextStoreTargetedRecordsRuleComponentState, - setRecordIndexViewType, - setRecordIndexOpenRecordIn, - setRecordIndexCalendarFieldMetadataIdState, - setRecordIndexShouldHideEmptyRecordGroups, - setRecordIndexGroupAggregateFieldMetadataItem, - setRecordIndexGroupAggregateOperation, - getFieldMetadataItemByIdOrThrow, - setRecordIndexGroupFieldMetadataItem, store, + contextStoreTargetedRecordsRuleAtom, + recordIndexGroupFieldMetadataItemAtom, + recordIndexGroupAggregateOperationAtom, + recordIndexGroupAggregateFieldMetadataItemAtom, + recordIndexShouldHideEmptyRecordGroupsAtom, + getFieldMetadataItemByIdOrThrow, + setRecordGroupsFromViewGroups, ], ); diff --git a/packages/twenty-front/src/modules/object-record/record-index/hooks/useOpenRecordFromIndexView.ts b/packages/twenty-front/src/modules/object-record/record-index/hooks/useOpenRecordFromIndexView.ts index 25161a9060..4a27330467 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/hooks/useOpenRecordFromIndexView.ts +++ b/packages/twenty-front/src/modules/object-record/record-index/hooks/useOpenRecordFromIndexView.ts @@ -9,7 +9,6 @@ import { recordIndexOpenRecordInState } from '@/object-record/record-index/state import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState'; import { canOpenObjectInSidePanel } from '@/object-record/utils/canOpenObjectInSidePanel'; import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType'; import { useStore } from 'jotai'; import { useCallback } from 'react'; @@ -48,7 +47,7 @@ export const useOpenRecordFromIndexView = () => { const openRecordFromIndexView = useCallback( ({ recordId }: { recordId: string }) => { - const recordIndexOpenRecordIn = jotaiStore.get( + const recordIndexOpenRecordIn = store.get( recordIndexOpenRecordInState.atom, ); diff --git a/packages/twenty-front/src/modules/object-record/record-index/hooks/useSetRecordIndexAggregateDisplayLabel.ts b/packages/twenty-front/src/modules/object-record/record-index/hooks/useSetRecordIndexAggregateDisplayLabel.ts index b49918d0fb..1d9ebc0aec 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/hooks/useSetRecordIndexAggregateDisplayLabel.ts +++ b/packages/twenty-front/src/modules/object-record/record-index/hooks/useSetRecordIndexAggregateDisplayLabel.ts @@ -6,7 +6,7 @@ import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jot import { useStore } from 'jotai'; export const useSetRecordIndexAggregateDisplayLabel = () => { - const recordIndexAggregateDisplayLabelAtom = + const recordIndexAggregateDisplayLabel = useRecoilComponentStateCallbackStateV2( recordIndexAggregateDisplayLabelComponentState, ); @@ -22,7 +22,7 @@ export const useSetRecordIndexAggregateDisplayLabel = () => { aggregateFieldMetadataItem: recordIndexGroupAggregateFieldMetadataItem, }); - store.set(recordIndexAggregateDisplayLabelAtom, aggregateLabel); + store.set(recordIndexAggregateDisplayLabel, aggregateLabel); }; return { diff --git a/packages/twenty-front/src/modules/object-record/record-index/hooks/useSetRecordIndexAggregateDisplayValueForRecordGroupValue.ts b/packages/twenty-front/src/modules/object-record/record-index/hooks/useSetRecordIndexAggregateDisplayValueForRecordGroupValue.ts index cc3d2d41f1..a548a22bda 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/hooks/useSetRecordIndexAggregateDisplayValueForRecordGroupValue.ts +++ b/packages/twenty-front/src/modules/object-record/record-index/hooks/useSetRecordIndexAggregateDisplayValueForRecordGroupValue.ts @@ -8,11 +8,11 @@ import { UserContext } from '@/users/contexts/UserContext'; import { useStore } from 'jotai'; import { useCallback, useContext } from 'react'; import { type Nullable } from 'twenty-shared/types'; -import { dateLocaleStateV2 } from '~/localization/states/dateLocaleStateV2'; +import { dateLocaleState } from '~/localization/states/dateLocaleState'; export const useSetRecordIndexAggregateDisplayValueForRecordGroupValue = () => { const { dateFormat, timeFormat, timeZone } = useContext(UserContext); - const dateLocale = useRecoilValueV2(dateLocaleStateV2); + const dateLocale = useRecoilValueV2(dateLocaleState); const recordIndexAggregateValueByGroupValueCallbackState = useRecoilComponentFamilyStateCallbackStateV2( diff --git a/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/components/MultipleRecordPickerFetchMoreLoader.tsx b/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/components/MultipleRecordPickerFetchMoreLoader.tsx index 75ccc5d607..8a27c6c752 100644 --- a/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/components/MultipleRecordPickerFetchMoreLoader.tsx +++ b/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/components/MultipleRecordPickerFetchMoreLoader.tsx @@ -14,10 +14,10 @@ import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/com import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2'; import { useRecoilComponentSelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentSelectorValueV2'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import styled from '@emotion/styled'; import { useCallback } from 'react'; import { useInView } from 'react-intersection-observer'; +import { useStore } from 'jotai'; const StyledText = styled.div` align-items: center; @@ -34,6 +34,7 @@ const StyledIntersectionObserver = styled.div` `; export const MultipleRecordPickerFetchMoreLoader = () => { + const store = useStore(); const [ multipleRecordPickerIsFetchingMore, setMultipleRecordPickerIsFetchingMore, @@ -72,7 +73,7 @@ export const MultipleRecordPickerFetchMoreLoader = () => { const { performSearch } = useMultipleRecordPickerPerformSearch(); const fetchMore = useCallback(async () => { - const currentPaginationState = jotaiStore.get( + const currentPaginationState = store.get( multipleRecordPickerPaginationState.atomFamily({ instanceId: componentInstanceId, }), @@ -87,7 +88,7 @@ export const MultipleRecordPickerFetchMoreLoader = () => { forceSearchFilter: searchFilter, loadMore: true, }); - }, [componentInstanceId, performSearch, searchFilter, isLoading]); + }, [componentInstanceId, performSearch, searchFilter, isLoading, store]); const { ref } = useInView({ onChange: useCallback( diff --git a/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/components/MultipleRecordPickerMenuItems.tsx b/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/components/MultipleRecordPickerMenuItems.tsx index 78c3db4ec1..7a35937b3a 100644 --- a/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/components/MultipleRecordPickerMenuItems.tsx +++ b/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/components/MultipleRecordPickerMenuItems.tsx @@ -16,8 +16,8 @@ import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/com import { useRecoilComponentSelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentSelectorValueV2'; import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useCallback } from 'react'; +import { useStore } from 'jotai'; type MultipleRecordPickerMenuItemsProps = { onChange?: (morphItem: RecordPickerPickableMorphItem) => void; @@ -28,6 +28,7 @@ export const MultipleRecordPickerMenuItems = ({ onChange, focusId, }: MultipleRecordPickerMenuItemsProps) => { + const store = useStore(); const componentInstanceId = useAvailableComponentInstanceIdOrThrow( MultipleRecordPickerComponentInstanceContext, ); @@ -40,7 +41,7 @@ export const MultipleRecordPickerMenuItems = ({ componentInstanceId, ); - const multipleRecordPickerPickableMorphItemsAtom = + const multipleRecordPickerPickableMorphItems = useRecoilComponentStateCallbackStateV2( multipleRecordPickerPickableMorphItemsComponentState, componentInstanceId, @@ -48,8 +49,8 @@ export const MultipleRecordPickerMenuItems = ({ const handleChange = useCallback( (morphItem: RecordPickerPickableMorphItem) => { - const previousMorphItems = jotaiStore.get( - multipleRecordPickerPickableMorphItemsAtom, + const previousMorphItems = store.get( + multipleRecordPickerPickableMorphItems, ); const existingMorphItemIndex = previousMorphItems.findIndex( @@ -64,9 +65,9 @@ export const MultipleRecordPickerMenuItems = ({ newMorphItems[existingMorphItemIndex] = morphItem; } - jotaiStore.set(multipleRecordPickerPickableMorphItemsAtom, newMorphItems); + store.set(multipleRecordPickerPickableMorphItems, newMorphItems); }, - [multipleRecordPickerPickableMorphItemsAtom], + [multipleRecordPickerPickableMorphItems, store], ); const multipleRecordPickerShouldShowInitialLoading = diff --git a/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/hooks/useMultipleRecordPickerOpen.ts b/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/hooks/useMultipleRecordPickerOpen.ts index 80640b1a08..f5495f8701 100644 --- a/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/hooks/useMultipleRecordPickerOpen.ts +++ b/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/hooks/useMultipleRecordPickerOpen.ts @@ -1,25 +1,26 @@ import { multipleRecordPickerShouldShowInitialLoadingComponentState } from '@/object-record/record-picker/multiple-record-picker/states/multipleRecordPickerShouldShowInitialLoadingComponentState'; import { multipleRecordPickerShouldShowSkeletonComponentState } from '@/object-record/record-picker/multiple-record-picker/states/multipleRecordPickerShouldShowSkeletonComponentState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useCallback } from 'react'; +import { useStore } from 'jotai'; export const useMultipleRecordPickerOpen = () => { + const store = useStore(); const setInitialLoading = useCallback( (recordPickerComponentInstanceId: string, value: boolean) => { - jotaiStore.set( + store.set( multipleRecordPickerShouldShowInitialLoadingComponentState.atomFamily({ instanceId: recordPickerComponentInstanceId, }), value, ); }, - [], + [store], ); const openMultipleRecordPicker = useCallback( (recordPickerComponentInstanceId: string) => { setInitialLoading(recordPickerComponentInstanceId, true); - jotaiStore.set( + store.set( multipleRecordPickerShouldShowSkeletonComponentState.atomFamily({ instanceId: recordPickerComponentInstanceId, }), @@ -29,7 +30,7 @@ export const useMultipleRecordPickerOpen = () => { setInitialLoading(recordPickerComponentInstanceId, false); }, 100); }, - [setInitialLoading], + [setInitialLoading, store], ); return { diff --git a/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/hooks/useMultipleRecordPickerPerformSearch.ts b/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/hooks/useMultipleRecordPickerPerformSearch.ts index 3fb760f656..0fa306ce3e 100644 --- a/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/hooks/useMultipleRecordPickerPerformSearch.ts +++ b/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/hooks/useMultipleRecordPickerPerformSearch.ts @@ -15,7 +15,6 @@ import { getObjectPermissionsFromMapByObjectMetadataId } from '@/settings/roles/ import { type ApolloClient } from '@apollo/client'; import { isNonEmptyArray } from '@sniptt/guards'; import { useStore } from 'jotai'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useCallback } from 'react'; import { capitalize, isDefined } from 'twenty-shared/utils'; import { type SearchRecord, type SearchResultEdge } from '~/generated/graphql'; @@ -47,25 +46,22 @@ export const useMultipleRecordPickerPerformSearch = () => { }) => { const atomFamilyKey = { instanceId: multipleRecordPickerInstanceId }; - const paginationState = jotaiStore.get( + const paginationState = store.get( multipleRecordPickerPaginationState.atomFamily(atomFamilyKey), ); - jotaiStore.set( + store.set( multipleRecordPickerIsLoadingComponentState.atomFamily(atomFamilyKey), true, ); - jotaiStore.set( - multipleRecordPickerPaginationState.atomFamily(atomFamilyKey), - { - ...paginationState, - endCursor: loadMore ? paginationState.endCursor : null, - hasNextPage: loadMore ? paginationState.hasNextPage : true, - }, - ); + store.set(multipleRecordPickerPaginationState.atomFamily(atomFamilyKey), { + ...paginationState, + endCursor: loadMore ? paginationState.endCursor : null, + hasNextPage: loadMore ? paginationState.hasNextPage : true, + }); - const recordPickerSearchFilter = jotaiStore.get( + const recordPickerSearchFilter = store.get( multipleRecordPickerSearchFilterComponentState.atomFamily( atomFamilyKey, ), @@ -73,7 +69,7 @@ export const useMultipleRecordPickerPerformSearch = () => { const searchFilter = forceSearchFilter ?? recordPickerSearchFilter; - const recordPickerSearchableObjectMetadataItems = jotaiStore.get( + const recordPickerSearchableObjectMetadataItems = store.get( multipleRecordPickerSearchableObjectMetadataItemsComponentState.atomFamily( atomFamilyKey, ), @@ -84,7 +80,7 @@ export const useMultipleRecordPickerPerformSearch = () => { ? forceSearchableObjectMetadataItems : recordPickerSearchableObjectMetadataItems; - const recordPickerPickableMorphItems = jotaiStore.get( + const recordPickerPickableMorphItems = store.get( multipleRecordPickerPickableMorphItemsComponentState.atomFamily( atomFamilyKey, ), @@ -121,7 +117,7 @@ export const useMultipleRecordPickerPerformSearch = () => { after: loadMore ? paginationState.endCursor : null, }); - const existingMorphItems = jotaiStore.get( + const existingMorphItems = store.get( multipleRecordPickerPickableMorphItemsComponentState.atomFamily( atomFamilyKey, ), @@ -261,7 +257,7 @@ export const useMultipleRecordPickerPerformSearch = () => { ...searchRecordsExcludingPickedRecords, ]); - jotaiStore.set( + store.set( multipleRecordPickerPickableMorphItemsComponentState.atomFamily( atomFamilyKey, ), @@ -350,16 +346,13 @@ export const useMultipleRecordPickerPerformSearch = () => { ); } - jotaiStore.set( - multipleRecordPickerPaginationState.atomFamily(atomFamilyKey), - { - ...paginationState, - endCursor: pageInfo.endCursor, - hasNextPage: pageInfo.hasNextPage, - }, - ); + store.set(multipleRecordPickerPaginationState.atomFamily(atomFamilyKey), { + ...paginationState, + endCursor: pageInfo.endCursor, + hasNextPage: pageInfo.hasNextPage, + }); - jotaiStore.set( + store.set( multipleRecordPickerIsLoadingComponentState.atomFamily(atomFamilyKey), false, ); diff --git a/packages/twenty-front/src/modules/object-record/record-picker/single-record-picker/hooks/useSingleRecordPickerOpen.ts b/packages/twenty-front/src/modules/object-record/record-picker/single-record-picker/hooks/useSingleRecordPickerOpen.ts index 002f11ad8c..b021011ad1 100644 --- a/packages/twenty-front/src/modules/object-record/record-picker/single-record-picker/hooks/useSingleRecordPickerOpen.ts +++ b/packages/twenty-front/src/modules/object-record/record-picker/single-record-picker/hooks/useSingleRecordPickerOpen.ts @@ -1,25 +1,26 @@ import { singleRecordPickerShouldShowInitialLoadingComponentState } from '@/object-record/record-picker/single-record-picker/states/singleRecordPickerShouldShowInitialLoadingComponentState'; import { singleRecordPickerShouldShowSkeletonComponentState } from '@/object-record/record-picker/single-record-picker/states/singleRecordPickerShouldShowSkeletonComponentState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useCallback } from 'react'; +import { useStore } from 'jotai'; export const useSingleRecordPickerOpen = () => { + const store = useStore(); const setInitialLoading = useCallback( (recordPickerComponentInstanceId: string, value: boolean) => { - jotaiStore.set( + store.set( singleRecordPickerShouldShowInitialLoadingComponentState.atomFamily({ instanceId: recordPickerComponentInstanceId, }), value, ); }, - [], + [store], ); const openSingleRecordPicker = useCallback( (recordPickerComponentInstanceId: string) => { setInitialLoading(recordPickerComponentInstanceId, true); - jotaiStore.set( + store.set( singleRecordPickerShouldShowSkeletonComponentState.atomFamily({ instanceId: recordPickerComponentInstanceId, }), @@ -29,7 +30,7 @@ export const useSingleRecordPickerOpen = () => { setInitialLoading(recordPickerComponentInstanceId, false); }, 100); }, - [setInitialLoading], + [setInitialLoading, store], ); return { diff --git a/packages/twenty-front/src/modules/object-record/record-sort/hooks/useRemoveRecordSort.ts b/packages/twenty-front/src/modules/object-record/record-sort/hooks/useRemoveRecordSort.ts index 9d956b9d24..21176c524a 100644 --- a/packages/twenty-front/src/modules/object-record/record-sort/hooks/useRemoveRecordSort.ts +++ b/packages/twenty-front/src/modules/object-record/record-sort/hooks/useRemoveRecordSort.ts @@ -5,7 +5,7 @@ import { useStore } from 'jotai'; import { useCallback } from 'react'; export const useRemoveRecordSort = () => { - const currentRecordSortsAtom = useRecoilComponentStateCallbackStateV2( + const currentRecordSorts = useRecoilComponentStateCallbackStateV2( currentRecordSortsComponentState, ); @@ -13,37 +13,31 @@ export const useRemoveRecordSort = () => { const removeRecordSort = useCallback( (fieldMetadataId: string) => { - const currentRecordSorts = store.get( - currentRecordSortsAtom, - ) as RecordSort[]; + const existingRecordSorts = store.get(currentRecordSorts) as RecordSort[]; - const hasFoundRecordSortInCurrentRecordSorts = currentRecordSorts.some( + const hasFoundRecordSortInCurrentRecordSorts = existingRecordSorts.some( (existingSort) => existingSort.fieldMetadataId === fieldMetadataId, ); if (hasFoundRecordSortInCurrentRecordSorts) { - store.set( - currentRecordSortsAtom, - (currentRecordSorts: RecordSort[]) => { - const newCurrentRecordSorts = [...currentRecordSorts]; + store.set(currentRecordSorts, (previousRecordSorts: RecordSort[]) => { + const newCurrentRecordSorts = [...previousRecordSorts]; - const indexOfSortToRemove = newCurrentRecordSorts.findIndex( - (existingSort) => - existingSort.fieldMetadataId === fieldMetadataId, - ); - - if (indexOfSortToRemove < 0) { - return newCurrentRecordSorts; - } - - newCurrentRecordSorts.splice(indexOfSortToRemove, 1); + const indexOfSortToRemove = newCurrentRecordSorts.findIndex( + (existingSort) => existingSort.fieldMetadataId === fieldMetadataId, + ); + if (indexOfSortToRemove < 0) { return newCurrentRecordSorts; - }, - ); + } + + newCurrentRecordSorts.splice(indexOfSortToRemove, 1); + + return newCurrentRecordSorts; + }); } }, - [currentRecordSortsAtom, store], + [currentRecordSorts, store], ); return { diff --git a/packages/twenty-front/src/modules/object-record/record-sort/hooks/useUpsertRecordSort.ts b/packages/twenty-front/src/modules/object-record/record-sort/hooks/useUpsertRecordSort.ts index c957f5fde3..31752067c6 100644 --- a/packages/twenty-front/src/modules/object-record/record-sort/hooks/useUpsertRecordSort.ts +++ b/packages/twenty-front/src/modules/object-record/record-sort/hooks/useUpsertRecordSort.ts @@ -5,7 +5,7 @@ import { useStore } from 'jotai'; import { useCallback } from 'react'; export const useUpsertRecordSort = () => { - const currentRecordSortsAtom = useRecoilComponentStateCallbackStateV2( + const currentRecordSorts = useRecoilComponentStateCallbackStateV2( currentRecordSortsComponentState, ); @@ -13,46 +13,40 @@ export const useUpsertRecordSort = () => { const upsertRecordSort = useCallback( (recordSortToSet: RecordSort) => { - const currentRecordSorts = store.get( - currentRecordSortsAtom, - ) as RecordSort[]; + const existingRecordSorts = store.get(currentRecordSorts) as RecordSort[]; - const hasFoundRecordSortInCurrentRecordSorts = currentRecordSorts.some( + const hasFoundRecordSortInCurrentRecordSorts = existingRecordSorts.some( (existingSort) => existingSort.fieldMetadataId === recordSortToSet.fieldMetadataId, ); if (!hasFoundRecordSortInCurrentRecordSorts) { - store.set(currentRecordSortsAtom, [ - ...currentRecordSorts, + store.set(currentRecordSorts, [ + ...existingRecordSorts, recordSortToSet, ]); } else { - store.set( - currentRecordSortsAtom, - (currentRecordSorts: RecordSort[]) => { - const newCurrentRecordSorts = [...currentRecordSorts]; + store.set(currentRecordSorts, (previousRecordSorts: RecordSort[]) => { + const newCurrentRecordSorts = [...previousRecordSorts]; - const indexOfSortToUpdate = newCurrentRecordSorts.findIndex( - (existingSort) => - existingSort.fieldMetadataId === - recordSortToSet.fieldMetadataId, - ); - - if (indexOfSortToUpdate < 0) { - return newCurrentRecordSorts; - } - - newCurrentRecordSorts[indexOfSortToUpdate] = { - ...recordSortToSet, - }; + const indexOfSortToUpdate = newCurrentRecordSorts.findIndex( + (existingSort) => + existingSort.fieldMetadataId === recordSortToSet.fieldMetadataId, + ); + if (indexOfSortToUpdate < 0) { return newCurrentRecordSorts; - }, - ); + } + + newCurrentRecordSorts[indexOfSortToUpdate] = { + ...recordSortToSet, + }; + + return newCurrentRecordSorts; + }); } }, - [currentRecordSortsAtom, store], + [currentRecordSorts, store], ); return { diff --git a/packages/twenty-front/src/modules/object-record/record-store/hooks/useRecordFieldValue.tsx b/packages/twenty-front/src/modules/object-record/record-store/hooks/useRecordFieldValue.tsx index a4b7455696..497200827a 100644 --- a/packages/twenty-front/src/modules/object-record/record-store/hooks/useRecordFieldValue.tsx +++ b/packages/twenty-front/src/modules/object-record/record-store/hooks/useRecordFieldValue.tsx @@ -9,7 +9,7 @@ export const useRecordFieldValue = ( fieldName: string, fieldDefinition: Pick, 'type' | 'metadata'>, ) => { - const fieldValueAtom = recordStoreFieldValueSelectorV2({ + const fieldValue = recordStoreFieldValueSelectorV2({ recordId, fieldName, fieldDefinition: { @@ -18,5 +18,5 @@ export const useRecordFieldValue = ( }, }); - return useAtomValue(fieldValueAtom) as T | undefined; + return useAtomValue(fieldValue) as T | undefined; }; diff --git a/packages/twenty-front/src/modules/object-record/record-store/hooks/useRecordFieldValueV2.ts b/packages/twenty-front/src/modules/object-record/record-store/hooks/useRecordFieldValueV2.ts index 371ad7f994..a4ec67219a 100644 --- a/packages/twenty-front/src/modules/object-record/record-store/hooks/useRecordFieldValueV2.ts +++ b/packages/twenty-front/src/modules/object-record/record-store/hooks/useRecordFieldValueV2.ts @@ -9,7 +9,7 @@ export const useRecordFieldValueV2 = ( fieldName: string, fieldDefinition: Pick, 'type' | 'metadata'>, ) => { - const fieldValueAtom = recordStoreFieldValueSelectorV2({ + const fieldValue = recordStoreFieldValueSelectorV2({ recordId, fieldName, fieldDefinition: { @@ -18,5 +18,5 @@ export const useRecordFieldValueV2 = ( }, }); - return useAtomValue(fieldValueAtom) as T | undefined; + return useAtomValue(fieldValue) as T | undefined; }; diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTable.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTable.tsx index f5249b8df8..56e6bc417f 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTable.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTable.tsx @@ -16,10 +16,15 @@ import { isRecordTableInitialLoadingComponentState } from '@/object-record/recor import { useClickOutsideListener } from '@/ui/utilities/pointer-event/hooks/useClickOutsideListener'; import { useRecoilComponentSelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentSelectorValueV2'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2'; +import isEmpty from 'lodash.isempty'; export const RecordTable = () => { - const { recordTableId, objectNameSingular, objectMetadataItem } = - useRecordTableContextOrThrow(); + const { + recordTableId, + objectNameSingular, + objectMetadataItem, + visibleRecordFields, + } = useRecordTableContextOrThrow(); const objectPermissions = useObjectPermissionsForObject( objectMetadataItem.id, @@ -76,7 +81,9 @@ export const RecordTable = () => { )} - {recordTableIsEmpty && !hasRecordGroups ? ( + {isRecordTableInitialLoading && + isEmpty(visibleRecordFields) ? null : recordTableIsEmpty && + !hasRecordGroups ? ( ) : ( { - const isSomeCellInEditMode = store.get(isSomeCellInEditModeAtom); + const cellInEditMode = store.get(isSomeCellInEditMode); - if (!isSomeCellInEditMode) { + if (!cellInEditMode) { setRecordTableHoverPosition(null); } - }, [store, isSomeCellInEditModeAtom, setRecordTableHoverPosition]); + }, [store, isSomeCellInEditMode, setRecordTableHoverPosition]); return ( diff --git a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useCloseCurrentTableCellInEditMode.ts b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useCloseCurrentTableCellInEditMode.ts index 2b7c824ba2..ca38d5f7b0 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useCloseCurrentTableCellInEditMode.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useCloseCurrentTableCellInEditMode.ts @@ -9,7 +9,7 @@ import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jot export const useCloseCurrentTableCellInEditMode = (recordTableId?: string) => { const store = useStore(); - const currentTableCellInEditModePositionAtom = + const currentTableCellInEditModePosition = useRecoilComponentStateCallbackStateV2( recordTableCellEditModePositionComponentState, recordTableId, @@ -22,7 +22,7 @@ export const useCloseCurrentTableCellInEditMode = (recordTableId?: string) => { useRemoveLastFocusItemFromFocusStackByComponentType(); return useCallback(() => { - store.set(currentTableCellInEditModePositionAtom, null); + store.set(currentTableCellInEditModePosition, null); goBackToPreviousDropdownFocusId(); @@ -31,7 +31,7 @@ export const useCloseCurrentTableCellInEditMode = (recordTableId?: string) => { }); }, [ store, - currentTableCellInEditModePositionAtom, + currentTableCellInEditModePosition, goBackToPreviousDropdownFocusId, removeLastFocusItemFromFocusStackByComponentType, ]); diff --git a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useResetTableRowSelection.ts b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useResetTableRowSelection.ts index 829fe2edf4..138c49b527 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useResetTableRowSelection.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useResetTableRowSelection.ts @@ -20,7 +20,7 @@ export const useResetTableRowSelection = (recordTableId?: string) => { recordTableId, ); - const recordIndexAllRecordIdsAtom = useRecoilComponentSelectorCallbackStateV2( + const recordIndexAllRecordIds = useRecoilComponentSelectorCallbackStateV2( recordIndexAllRecordIdsComponentSelector, recordTableIdFromContext, ); @@ -30,7 +30,7 @@ export const useResetTableRowSelection = (recordTableId?: string) => { recordTableIdFromContext, ); - const hasUserSelectedAllRowsAtom = useRecoilComponentStateCallbackStateV2( + const hasUserSelectedAllRows = useRecoilComponentStateCallbackStateV2( hasUserSelectedAllRowsComponentState, recordTableIdFromContext, ); @@ -45,13 +45,13 @@ export const useResetTableRowSelection = (recordTableId?: string) => { const store = useStore(); const resetTableRowSelection = useCallback(() => { - const allRecordIds = store.get(recordIndexAllRecordIdsAtom); + const allRecordIds = store.get(recordIndexAllRecordIds); for (const recordId of allRecordIds) { store.set(isRowSelectedFamilyState(recordId), false); } - store.set(hasUserSelectedAllRowsAtom, false); + store.set(hasUserSelectedAllRows, false); store.set(lastSelectedRowIndexComponentCallbackState, null); closeDropdown( @@ -60,8 +60,8 @@ export const useResetTableRowSelection = (recordTableId?: string) => { ), ); }, [ - recordIndexAllRecordIdsAtom, - hasUserSelectedAllRowsAtom, + recordIndexAllRecordIds, + hasUserSelectedAllRows, lastSelectedRowIndexComponentCallbackState, isRowSelectedFamilyState, closeDropdown, diff --git a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSelectAllRows.ts b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSelectAllRows.ts index d2ccd08cf9..d80d93890f 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSelectAllRows.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSelectAllRows.ts @@ -11,12 +11,12 @@ import { useRecoilComponentSelectorCallbackStateV2 } from '@/ui/utilities/state/ import { useStore } from 'jotai'; export const useSelectAllRows = (recordTableId?: string) => { - const hasUserSelectedAllRowsAtom = useRecoilComponentStateCallbackStateV2( + const hasUserSelectedAllRows = useRecoilComponentStateCallbackStateV2( hasUserSelectedAllRowsComponentState, recordTableId, ); - const allRowsSelectedStatusAtom = useRecoilComponentSelectorCallbackStateV2( + const allRowsSelectedStatus = useRecoilComponentSelectorCallbackStateV2( allRowsSelectedStatusComponentSelector, recordTableId, ); @@ -26,7 +26,7 @@ export const useSelectAllRows = (recordTableId?: string) => { recordTableId, ); - const recordIndexAllRecordIdsAtom = useRecoilComponentSelectorCallbackStateV2( + const recordIndexAllRecordIds = useRecoilComponentSelectorCallbackStateV2( recordIndexAllRecordIdsComponentSelector, recordTableId, ); @@ -36,27 +36,28 @@ export const useSelectAllRows = (recordTableId?: string) => { const store = useStore(); const selectAllRows = useCallback(() => { - const allRowsSelectedStatus = store.get(allRowsSelectedStatusAtom); - const allRecordIds = store.get(recordIndexAllRecordIdsAtom); + const currentAllRowsSelectedStatus = store.get(allRowsSelectedStatus); + const allRecordIds = store.get(recordIndexAllRecordIds); - if (allRowsSelectedStatus === 'all') { + if (currentAllRowsSelectedStatus === 'all') { resetTableRowSelection(); } for (const recordId of allRecordIds) { const isSelected = - allRowsSelectedStatus === 'none' || allRowsSelectedStatus === 'some'; + currentAllRowsSelectedStatus === 'none' || + currentAllRowsSelectedStatus === 'some'; store.set(isRowSelectedFamilyState(recordId), isSelected); } - store.set(hasUserSelectedAllRowsAtom, true); + store.set(hasUserSelectedAllRows, true); }, [ - allRowsSelectedStatusAtom, - recordIndexAllRecordIdsAtom, + allRowsSelectedStatus, + recordIndexAllRecordIds, resetTableRowSelection, isRowSelectedFamilyState, - hasUserSelectedAllRowsAtom, + hasUserSelectedAllRows, store, ]); diff --git a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSetAllRowSelectedState.ts b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSetAllRowSelectedState.ts index a8e8675820..14110bcf89 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSetAllRowSelectedState.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSetAllRowSelectedState.ts @@ -3,7 +3,7 @@ import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jot import { useStore } from 'jotai'; export const useSetHasUserSelectedAllRows = (recordTableId?: string) => { - const hasUserSelectedAllRowsAtom = useRecoilComponentStateCallbackStateV2( + const hasUserSelectedAllRows = useRecoilComponentStateCallbackStateV2( hasUserSelectedAllRowsComponentState, recordTableId, ); @@ -11,6 +11,6 @@ export const useSetHasUserSelectedAllRows = (recordTableId?: string) => { const store = useStore(); return (selected: boolean) => { - store.set(hasUserSelectedAllRowsAtom, selected); + store.set(hasUserSelectedAllRows, selected); }; }; diff --git a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSetRecordTableData.ts b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSetRecordTableData.ts index 5ee6b002ff..06e9a3e5eb 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSetRecordTableData.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSetRecordTableData.ts @@ -48,18 +48,17 @@ export const useSetRecordTableData = ({ recordTableId, ); - const hasUserSelectedAllRowsAtom = useRecoilComponentStateCallbackStateV2( + const hasUserSelectedAllRows = useRecoilComponentStateCallbackStateV2( hasUserSelectedAllRowsComponentState, recordTableId, ); - const isRecordTableInitialLoadingAtom = - useRecoilComponentStateCallbackStateV2( - isRecordTableInitialLoadingComponentState, - recordTableId, - ); + const isRecordTableInitialLoading = useRecoilComponentStateCallbackStateV2( + isRecordTableInitialLoadingComponentState, + recordTableId, + ); - const recordIdByRealIndexAtom = useRecoilComponentStateCallbackStateV2( + const recordIdByRealIndex = useRecoilComponentStateCallbackStateV2( recordIdByRealIndexComponentState, recordTableId, ); @@ -84,7 +83,7 @@ export const useSetRecordTableData = ({ for (const record of records) { const currentRecord = store.get( recordStoreFamilyState.atomFamily(record.id), - ) as ObjectRecord | null | undefined; + ); if (JSON.stringify(currentRecord) !== JSON.stringify(record)) { const newRecord = { @@ -98,12 +97,12 @@ export const useSetRecordTableData = ({ } const currentRowIds = currentRecordGroupId - ? (store.get( + ? store.get( recordIndexRecordIdsByGroupFamilyState(currentRecordGroupId), - ) as string[]) - : (store.get(recordIndexAllRecordIdsSelector) as string[]); + ) + : store.get(recordIndexAllRecordIdsSelector); - const hasUserSelectedAllRows = store.get(hasUserSelectedAllRowsAtom); + const isAllRowsSelected = store.get(hasUserSelectedAllRows); const recordIds = records.map((record) => record.id); @@ -112,7 +111,7 @@ export const useSetRecordTableData = ({ unfocusRecordTableRow(); setRecordTableHoverPosition(null); - if (hasUserSelectedAllRows) { + if (isAllRowsSelected) { for (const rowId of recordIds) { store.set(isRowSelectedFamilyState(rowId), true); } @@ -130,12 +129,10 @@ export const useSetRecordTableData = ({ ); } - const isTableInitialLoading = store.get( - isRecordTableInitialLoadingAtom, - ); + const isTableInitialLoading = store.get(isRecordTableInitialLoading); if (isTableInitialLoading) { - const currentMap = store.get(recordIdByRealIndexAtom); + const currentMap = store.get(recordIdByRealIndex); const newMap = new Map(currentMap); let mapChanged = false; @@ -147,7 +144,7 @@ export const useSetRecordTableData = ({ } if (mapChanged) { - store.set(recordIdByRealIndexAtom, newMap); + store.set(recordIdByRealIndex, newMap); } } } @@ -155,13 +152,13 @@ export const useSetRecordTableData = ({ [ recordIndexRecordIdsByGroupFamilyState, recordIndexAllRecordIdsSelector, - hasUserSelectedAllRowsAtom, + hasUserSelectedAllRows, unfocusRecordTableCell, unfocusRecordTableRow, setRecordTableHoverPosition, isRowSelectedFamilyState, - recordIdByRealIndexAtom, - isRecordTableInitialLoadingAtom, + recordIdByRealIndex, + isRecordTableInitialLoading, store, ], ); diff --git a/packages/twenty-front/src/modules/object-record/record-table/hooks/useActiveRecordTableRow.ts b/packages/twenty-front/src/modules/object-record/record-table/hooks/useActiveRecordTableRow.ts index 0a51bcf358..cc441f8a12 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/hooks/useActiveRecordTableRow.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/hooks/useActiveRecordTableRow.ts @@ -21,10 +21,7 @@ export const useActiveRecordTableRow = (recordTableId?: string) => { const store = useStore(); const deactivateRecordTableRow = useCallback(() => { - const activeRowIndex = store.get(activeRowIndexState) as - | number - | null - | undefined; + const activeRowIndex = store.get(activeRowIndexState); if (!isDefined(activeRowIndex)) { return; @@ -37,10 +34,7 @@ export const useActiveRecordTableRow = (recordTableId?: string) => { const activateRecordTableRow = useCallback( (rowIndex: number) => { - const activeRowIndex = store.get(activeRowIndexState) as - | number - | null - | undefined; + const activeRowIndex = store.get(activeRowIndexState); if (activeRowIndex === rowIndex) { return; diff --git a/packages/twenty-front/src/modules/object-record/record-table/hooks/useCreateNewIndexRecord.ts b/packages/twenty-front/src/modules/object-record/record-table/hooks/useCreateNewIndexRecord.ts index 546002b184..e70fd6f58d 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/hooks/useCreateNewIndexRecord.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/hooks/useCreateNewIndexRecord.ts @@ -19,7 +19,6 @@ import { useRecoilComponentFamilyStateCallbackStateV2 } from '@/ui/utilities/sta import { useRecoilComponentSelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentSelectorValueV2'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2'; import { useStore } from 'jotai'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType'; import { useCallback } from 'react'; import { AppPath } from 'twenty-shared/types'; @@ -84,7 +83,7 @@ export const useCreateNewIndexRecord = ({ ...recordInput, }; - const recordIndexOpenRecordIn = jotaiStore.get( + const recordIndexOpenRecordIn = store.get( recordIndexOpenRecordInState.atom, ); @@ -150,7 +149,7 @@ export const useCreateNewIndexRecord = ({ if (isDefined(recordGroup)) { const currentRecordIds = store.get( recordIndexRecordIdsByGroupCallbackState(recordGroup.id), - ) as string[]; + ); if (recordInput?.position === 'first') { const newRecordIds = [createdRecord.id, ...currentRecordIds]; diff --git a/packages/twenty-front/src/modules/object-record/record-table/hooks/useFocusedRecordTableRow.ts b/packages/twenty-front/src/modules/object-record/record-table/hooks/useFocusedRecordTableRow.ts index a6ebdfc12a..23976368bb 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/hooks/useFocusedRecordTableRow.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/hooks/useFocusedRecordTableRow.ts @@ -29,26 +29,25 @@ export const useFocusedRecordTableRow = (recordTableId?: string) => { ); const store = useStore(); - const focusedRowIndexAtom = useRecoilComponentStateCallbackStateV2( + const focusedRowIndex = useRecoilComponentStateCallbackStateV2( focusedRecordTableRowIndexComponentState, recordTableIdFromContext, ); - const isRowFocusActiveAtom = useRecoilComponentStateCallbackStateV2( + const isRowFocusActive = useRecoilComponentStateCallbackStateV2( isRecordTableRowFocusActiveComponentState, recordTableIdFromContext, ); - const focusedCellPositionAtom = useRecoilComponentStateCallbackStateV2( + const focusedCellPosition = useRecoilComponentStateCallbackStateV2( recordTableFocusPositionComponentState, recordTableIdFromContext, ); - const isRecordTableCellFocusActiveAtom = - useRecoilComponentStateCallbackStateV2( - isRecordTableCellFocusActiveComponentState, - recordTableIdFromContext, - ); + const isRecordTableCellFocusActive = useRecoilComponentStateCallbackStateV2( + isRecordTableCellFocusActiveComponentState, + recordTableIdFromContext, + ); const { pushFocusItemToFocusStack } = usePushFocusItemToFocusStack(); @@ -60,49 +59,46 @@ export const useFocusedRecordTableRow = (recordTableId?: string) => { ); const unfocusRecordTableRow = useCallback(() => { - const focusedRowIndex = store.get(focusedRowIndexAtom) as - | number - | null - | undefined; + const currentFocusedRowIndex = store.get(focusedRowIndex); - if (!isDefined(focusedRowIndex)) { + if (!isDefined(currentFocusedRowIndex)) { return; } const focusId = getRecordTableRowFocusId({ recordTableId: recordTableIdFromContext, - rowIndex: focusedRowIndex, + rowIndex: currentFocusedRowIndex, }); removeFocusItemFromFocusStackById({ focusId, }); - store.set(focusedRowIndexAtom, null); - store.set(isRowFocusedState(focusedRowIndex), false); - store.set(isRowFocusActiveAtom, false); + store.set(focusedRowIndex, null); + store.set(isRowFocusedState(currentFocusedRowIndex), false); + store.set(isRowFocusActive, false); }, [ store, - focusedRowIndexAtom, + focusedRowIndex, isRowFocusedState, - isRowFocusActiveAtom, + isRowFocusActive, recordTableIdFromContext, removeFocusItemFromFocusStackById, ]); const focusRecordTableRow = useCallback( (rowIndex: number) => { - const focusedRowIndex = store.get(focusedRowIndexAtom) as - | number - | null - | undefined; + const currentFocusedRowIndex = store.get(focusedRowIndex); - if (isDefined(focusedRowIndex) && focusedRowIndex !== rowIndex) { - store.set(isRowFocusedState(focusedRowIndex), false); + if ( + isDefined(currentFocusedRowIndex) && + currentFocusedRowIndex !== rowIndex + ) { + store.set(isRowFocusedState(currentFocusedRowIndex), false); const focusId = getRecordTableRowFocusId({ recordTableId: recordTableIdFromContext, - rowIndex: focusedRowIndex, + rowIndex: currentFocusedRowIndex, }); removeFocusItemFromFocusStackById({ @@ -123,50 +119,47 @@ export const useFocusedRecordTableRow = (recordTableId?: string) => { }, }); - store.set(focusedRowIndexAtom, rowIndex); + store.set(focusedRowIndex, rowIndex); store.set(isRowFocusedState(rowIndex), true); - store.set(isRowFocusActiveAtom, true); + store.set(isRowFocusActive, true); }, [ store, - focusedRowIndexAtom, + focusedRowIndex, recordTableIdFromContext, pushFocusItemToFocusStack, isRowFocusedState, - isRowFocusActiveAtom, + isRowFocusActive, removeFocusItemFromFocusStackById, ], ); const restoreRecordTableRowFocusFromCellPosition = useCallback(() => { - const focusedRowIndex = store.get(focusedRowIndexAtom) as - | number - | null - | undefined; + const currentFocusedRowIndex = store.get(focusedRowIndex); - const focusedCellPosition = store.get(focusedCellPositionAtom) as - | { row: number; column: number } - | null - | undefined; + const currentFocusedCellPosition = store.get(focusedCellPosition); - const isRecordTableCellFocusActive = store.get( - isRecordTableCellFocusActiveAtom, + const currentIsRecordTableCellFocusActive = store.get( + isRecordTableCellFocusActive, ); - if (!isDefined(focusedCellPosition) || !isRecordTableCellFocusActive) { + if ( + !isDefined(currentFocusedCellPosition) || + !currentIsRecordTableCellFocusActive + ) { return; } unfocusRecordTableCell(); - if (isDefined(focusedRowIndex)) { - focusRecordTableRow(focusedCellPosition.row); + if (isDefined(currentFocusedRowIndex)) { + focusRecordTableRow(currentFocusedCellPosition.row); } }, [ store, - focusedRowIndexAtom, - focusedCellPositionAtom, - isRecordTableCellFocusActiveAtom, + focusedRowIndex, + focusedCellPosition, + isRecordTableCellFocusActive, unfocusRecordTableCell, focusRecordTableRow, ]); diff --git a/packages/twenty-front/src/modules/object-record/record-table/hooks/useRecordTableMoveFocusedCell.ts b/packages/twenty-front/src/modules/object-record/record-table/hooks/useRecordTableMoveFocusedCell.ts index e3fbe90967..479d1f7827 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/hooks/useRecordTableMoveFocusedCell.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/hooks/useRecordTableMoveFocusedCell.ts @@ -14,12 +14,12 @@ import { isDefined } from 'twenty-shared/utils'; export const useRecordTableMoveFocusedCell = (recordTableId?: string) => { const { focusRecordTableCell } = useFocusRecordTableCell(recordTableId); - const focusPositionAtom = useRecoilComponentStateCallbackStateV2( + const focusPosition = useRecoilComponentStateCallbackStateV2( recordTableFocusPositionComponentState, recordTableId, ); - const recordIndexAllRecordIdsAtom = useRecoilComponentSelectorCallbackStateV2( + const recordIndexAllRecordIds = useRecoilComponentSelectorCallbackStateV2( recordIndexAllRecordIdsComponentSelector, recordTableId, ); @@ -27,67 +27,62 @@ export const useRecordTableMoveFocusedCell = (recordTableId?: string) => { const store = useStore(); const moveUp = useCallback(() => { - const focusPosition = store.get(focusPositionAtom); + const currentFocusPosition = store.get(focusPosition); - if (!isDefined(focusPosition)) { + if (!isDefined(currentFocusPosition)) { return; } - let newRowIndex = focusPosition.row - 1; + let newRowIndex = currentFocusPosition.row - 1; if (newRowIndex < 0) { newRowIndex = 0; } focusRecordTableCell({ - ...focusPosition, + ...currentFocusPosition, row: newRowIndex, }); - }, [store, focusPositionAtom, focusRecordTableCell]); + }, [store, focusPosition, focusRecordTableCell]); const moveDown = useCallback(() => { - const allRecordIds = store.get(recordIndexAllRecordIdsAtom); - const focusPosition = store.get(focusPositionAtom); + const allRecordIds = store.get(recordIndexAllRecordIds); + const currentFocusPosition = store.get(focusPosition); - if (!isDefined(focusPosition)) { + if (!isDefined(currentFocusPosition)) { return; } - let newRowIndex = focusPosition.row + 1; + let newRowIndex = currentFocusPosition.row + 1; if (newRowIndex >= allRecordIds.length) { newRowIndex = allRecordIds.length - 1; } focusRecordTableCell({ - ...focusPosition, + ...currentFocusPosition, row: newRowIndex, }); - }, [ - recordIndexAllRecordIdsAtom, - focusRecordTableCell, - focusPositionAtom, - store, - ]); + }, [recordIndexAllRecordIds, focusRecordTableCell, focusPosition, store]); - const currentRecordFieldsAtom = useRecoilComponentStateCallbackStateV2( + const currentRecordFields = useRecoilComponentStateCallbackStateV2( currentRecordFieldsComponentState, recordTableId, ); const moveRight = useCallback(() => { - const allRecordIds = store.get(recordIndexAllRecordIdsAtom); + const allRecordIds = store.get(recordIndexAllRecordIds); - const focusPosition = store.get(focusPositionAtom); + const currentFocusPosition = store.get(focusPosition); - if (!isDefined(focusPosition)) { + if (!isDefined(currentFocusPosition)) { return; } - const numberOfRecordFields = store.get(currentRecordFieldsAtom).length; + const numberOfRecordFields = store.get(currentRecordFields).length; - const currentColumnIndex = focusPosition.column; - const currentRowIndex = focusPosition.row; + const currentColumnIndex = currentFocusPosition.column; + const currentRowIndex = currentFocusPosition.row; const isLastRowAndLastColumn = currentColumnIndex === numberOfRecordFields - 1 && @@ -115,24 +110,24 @@ export const useRecordTableMoveFocusedCell = (recordTableId?: string) => { }); } }, [ - recordIndexAllRecordIdsAtom, + recordIndexAllRecordIds, store, - focusPositionAtom, - currentRecordFieldsAtom, + focusPosition, + currentRecordFields, focusRecordTableCell, ]); const moveLeft = useCallback(() => { - const focusPosition = store.get(focusPositionAtom); + const currentFocusPosition = store.get(focusPosition); - if (!isDefined(focusPosition)) { + if (!isDefined(currentFocusPosition)) { return; } - const numberOfRecordFields = store.get(currentRecordFieldsAtom).length; + const numberOfRecordFields = store.get(currentRecordFields).length; - const currentColumnIndex = focusPosition.column; - const currentRowIndex = focusPosition.row; + const currentColumnIndex = currentFocusPosition.column; + const currentRowIndex = currentFocusPosition.row; const isFirstRowAndFirstColumn = currentColumnIndex === 0 && currentRowIndex === 0; @@ -157,7 +152,7 @@ export const useRecordTableMoveFocusedCell = (recordTableId?: string) => { column: numberOfRecordFields - 1, }); } - }, [currentRecordFieldsAtom, focusPositionAtom, focusRecordTableCell, store]); + }, [currentRecordFields, focusPosition, focusRecordTableCell, store]); const moveFocus = (direction: MoveFocusDirection) => { switch (direction) { diff --git a/packages/twenty-front/src/modules/object-record/record-table/hooks/useRecordTableMoveFocusedRow.ts b/packages/twenty-front/src/modules/object-record/record-table/hooks/useRecordTableMoveFocusedRow.ts index 6cd636d4d8..939f57cec3 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/hooks/useRecordTableMoveFocusedRow.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/hooks/useRecordTableMoveFocusedRow.ts @@ -11,12 +11,12 @@ import { isDefined } from 'twenty-shared/utils'; export const useRecordTableMoveFocusedRow = (recordTableId?: string) => { const { focusRecordTableRow } = useFocusedRecordTableRow(recordTableId); - const focusedRowIndexAtom = useRecoilComponentStateCallbackStateV2( + const focusedRowIndex = useRecoilComponentStateCallbackStateV2( focusedRecordTableRowIndexComponentState, recordTableId, ); - const recordIndexAllRecordIdsAtom = useRecoilComponentSelectorCallbackStateV2( + const recordIndexAllRecordIds = useRecoilComponentSelectorCallbackStateV2( recordIndexAllRecordIdsComponentSelector, recordTableId, ); @@ -24,50 +24,39 @@ export const useRecordTableMoveFocusedRow = (recordTableId?: string) => { const store = useStore(); const moveFocusedRowUp = useCallback(() => { - const focusedRowIndex = store.get(focusedRowIndexAtom) as - | number - | null - | undefined; + const currentFocusedRowIndex = store.get(focusedRowIndex); - if (!isDefined(focusedRowIndex)) { + if (!isDefined(currentFocusedRowIndex)) { focusRecordTableRow(0); return; } - let newRowIndex = focusedRowIndex - 1; + let newRowIndex = currentFocusedRowIndex - 1; if (newRowIndex < 0) { newRowIndex = 0; } focusRecordTableRow(newRowIndex); - }, [store, focusedRowIndexAtom, focusRecordTableRow]); + }, [store, focusedRowIndex, focusRecordTableRow]); const moveFocusedRowDown = useCallback(() => { - const allRecordIds = store.get(recordIndexAllRecordIdsAtom); - const focusedRowIndex = store.get(focusedRowIndexAtom) as - | number - | null - | undefined; + const allRecordIds = store.get(recordIndexAllRecordIds); + const currentFocusedRowIndex = store.get(focusedRowIndex); - if (!isDefined(focusedRowIndex)) { + if (!isDefined(currentFocusedRowIndex)) { focusRecordTableRow(0); return; } - let newRowIndex = focusedRowIndex + 1; + let newRowIndex = currentFocusedRowIndex + 1; if (newRowIndex >= allRecordIds.length) { newRowIndex = allRecordIds.length - 1; } focusRecordTableRow(newRowIndex); - }, [ - recordIndexAllRecordIdsAtom, - focusedRowIndexAtom, - focusRecordTableRow, - store, - ]); + }, [recordIndexAllRecordIds, focusedRowIndex, focusRecordTableRow, store]); const moveFocusedRow = (direction: MoveFocusDirection) => { if (direction === 'up') { diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBodyNoRecordGroupDragDropContextProvider.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBodyNoRecordGroupDragDropContextProvider.tsx index b4bca62b5f..31fabb6a32 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBodyNoRecordGroupDragDropContextProvider.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBodyNoRecordGroupDragDropContextProvider.tsx @@ -23,7 +23,7 @@ export const RecordTableBodyNoRecordGroupDragDropContextProvider = ({ const { recordIndexId } = useRecordIndexContextOrThrow(); const { recordTableId } = useRecordTableContextOrThrow(); - const selectedRowIdsAtom = useRecoilComponentSelectorCallbackStateV2( + const selectedRowIds = useRecoilComponentSelectorCallbackStateV2( selectedRowIdsComponentSelector, recordTableId, ); @@ -37,13 +37,11 @@ export const RecordTableBodyNoRecordGroupDragDropContextProvider = ({ const handleDragStart = useCallback( (start: DragStart) => { - const currentSelectedRecordIds = store.get( - selectedRowIdsAtom, - ) as string[]; + const currentSelectedRecordIds = store.get(selectedRowIds) as string[]; startRecordDrag(start, currentSelectedRecordIds); }, - [selectedRowIdsAtom, startRecordDrag, store], + [selectedRowIds, startRecordDrag, store], ); const handleDragEnd = useCallback( diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBodyRecordGroupDragDropContextProvider.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBodyRecordGroupDragDropContextProvider.tsx index bafff7d382..5640290c10 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBodyRecordGroupDragDropContextProvider.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBodyRecordGroupDragDropContextProvider.tsx @@ -21,7 +21,7 @@ export const RecordTableBodyRecordGroupDragDropContextProvider = ({ const { recordIndexId } = useRecordIndexContextOrThrow(); const { recordTableId } = useRecordTableContextOrThrow(); - const selectedRowIdsAtom = useRecoilComponentSelectorCallbackStateV2( + const selectedRowIds = useRecoilComponentSelectorCallbackStateV2( selectedRowIdsComponentSelector, recordTableId, ); @@ -36,13 +36,11 @@ export const RecordTableBodyRecordGroupDragDropContextProvider = ({ const handleDragStart = useCallback( (start: DragStart) => { - const currentSelectedRecordIds = store.get( - selectedRowIdsAtom, - ) as string[]; + const currentSelectedRecordIds = store.get(selectedRowIds) as string[]; startRecordDrag(start, currentSelectedRecordIds); }, - [selectedRowIdsAtom, startRecordDrag, store], + [selectedRowIds, startRecordDrag, store], ); const handleDragEnd = useCallback( diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useFocusRecordTableCell.ts b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useFocusRecordTableCell.ts index 18183c4b23..db81a8c54c 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useFocusRecordTableCell.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useFocusRecordTableCell.ts @@ -19,7 +19,7 @@ export const useFocusRecordTableCell = (recordTableId?: string) => { ); const store = useStore(); - const focusPositionAtom = useRecoilComponentStateCallbackStateV2( + const focusPosition = useRecoilComponentStateCallbackStateV2( recordTableFocusPositionComponentState, recordTableIdFromProps, ); @@ -33,10 +33,7 @@ export const useFocusRecordTableCell = (recordTableId?: string) => { const focusRecordTableCell = useCallback( (newPosition: TableCellPosition) => { - const currentPosition = store.get(focusPositionAtom) as - | TableCellPosition - | null - | undefined; + const currentPosition = store.get(focusPosition); if (isDefined(currentPosition)) { const currentCellFocusId = getRecordTableCellFocusId({ @@ -69,7 +66,7 @@ export const useFocusRecordTableCell = (recordTableId?: string) => { }, [ store, - focusPositionAtom, + focusPosition, recordTableIdFromProps, removeFocusItemFromFocusStackById, setIsRecordTableCellFocusActive, diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useMoveHoverToCurrentCell.ts b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useMoveHoverToCurrentCell.ts index 77f944d0b7..26a7dc9116 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useMoveHoverToCurrentCell.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useMoveHoverToCurrentCell.ts @@ -14,7 +14,7 @@ export const useMoveHoverToCurrentCell = (recordTableId: string) => { recordTableId, ); - const isSomeCellInEditModeAtom = useRecoilComponentSelectorCallbackStateV2( + const isSomeCellInEditMode = useRecoilComponentSelectorCallbackStateV2( isSomeCellInEditModeComponentSelector, recordTableId, ); @@ -23,13 +23,13 @@ export const useMoveHoverToCurrentCell = (recordTableId: string) => { const moveHoverToCurrentCell = useCallback( (cellPosition: TableCellPosition) => { - const isSomeCellInEditMode = store.get(isSomeCellInEditModeAtom); + const cellInEditMode = store.get(isSomeCellInEditMode); - if (!isSomeCellInEditMode) { + if (!cellInEditMode) { setHoverPosition(cellPosition); } }, - [store, isSomeCellInEditModeAtom, setHoverPosition], + [store, isSomeCellInEditMode, setHoverPosition], ); return { moveHoverToCurrentCell }; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useOpenRecordTableCell.ts b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useOpenRecordTableCell.ts index b39a63693a..3925560272 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useOpenRecordTableCell.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useOpenRecordTableCell.ts @@ -11,7 +11,6 @@ import { useDragSelect } from '@/ui/utilities/drag-select/hooks/useDragSelect'; import { useClickOutsideListener } from '@/ui/utilities/pointer-event/hooks/useClickOutsideListener'; import { useOpenFieldInputEditMode } from '@/object-record/record-field/ui/hooks/useOpenFieldInputEditMode'; import { recordIndexOpenRecordInState } from '@/object-record/record-index/states/recordIndexOpenRecordInState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { RECORD_TABLE_CLICK_OUTSIDE_LISTENER_ID } from '@/object-record/record-table/constants/RecordTableClickOutsideListenerId'; import { recordTableCellEditModePositionComponentState } from '@/object-record/record-table/states/recordTableCellEditModePositionComponentState'; import { getDropdownFocusIdForRecordField } from '@/object-record/utils/getDropdownFocusIdForRecordField'; @@ -109,7 +108,7 @@ export const useOpenRecordTableCell = (recordTableId: string) => { if ((isFirstColumnCell && !isEmpty) || isNavigating) { leaveTableFocus(); - const openRecordIn = jotaiStore.get(recordIndexOpenRecordInState.atom); + const openRecordIn = store.get(recordIndexOpenRecordInState.atom); if (openRecordIn === ViewOpenRecordInType.SIDE_PANEL) { activateRecordTableRow(cellPosition.row); diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useSetIsRecordTableCellFocusActive.ts b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useSetIsRecordTableCellFocusActive.ts index 69af691336..16f5e133e9 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useSetIsRecordTableCellFocusActive.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useSetIsRecordTableCellFocusActive.ts @@ -8,13 +8,12 @@ import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jot export const useSetIsRecordTableCellFocusActive = (recordTableId?: string) => { const store = useStore(); - const isRecordTableCellFocusActiveAtom = - useRecoilComponentStateCallbackStateV2( - isRecordTableCellFocusActiveComponentState, - recordTableId, - ); + const isRecordTableCellFocusActive = useRecoilComponentStateCallbackStateV2( + isRecordTableCellFocusActiveComponentState, + recordTableId, + ); - const recordTableFocusPositionAtom = useRecoilComponentStateCallbackStateV2( + const recordTableFocusPosition = useRecoilComponentStateCallbackStateV2( recordTableFocusPositionComponentState, recordTableId, ); @@ -28,14 +27,14 @@ export const useSetIsRecordTableCellFocusActive = (recordTableId?: string) => { cellPosition: TableCellPosition; }) => { if (isRecordTableFocusActive) { - store.set(isRecordTableCellFocusActiveAtom, true); - store.set(recordTableFocusPositionAtom, cellPosition); + store.set(isRecordTableCellFocusActive, true); + store.set(recordTableFocusPosition, cellPosition); } else { - store.set(isRecordTableCellFocusActiveAtom, false); - store.set(recordTableFocusPositionAtom, null); + store.set(isRecordTableCellFocusActive, false); + store.set(recordTableFocusPosition, null); } }, - [store, isRecordTableCellFocusActiveAtom, recordTableFocusPositionAtom], + [store, isRecordTableCellFocusActive, recordTableFocusPosition], ); return { diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useUnfocusRecordTableCell.ts b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useUnfocusRecordTableCell.ts index bdb98e2063..cce95485aa 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useUnfocusRecordTableCell.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useUnfocusRecordTableCell.ts @@ -17,7 +17,7 @@ export const useUnfocusRecordTableCell = (recordTableId?: string) => { ); const store = useStore(); - const focusPositionAtom = useRecoilComponentStateCallbackStateV2( + const focusPosition = useRecoilComponentStateCallbackStateV2( recordTableFocusPositionComponentState, recordTableIdFromProps, ); @@ -29,10 +29,7 @@ export const useUnfocusRecordTableCell = (recordTableId?: string) => { useRemoveFocusItemFromFocusStackById(); const unfocusRecordTableCell = useCallback(() => { - const currentPosition = store.get(focusPositionAtom) as - | { row: number; column: number } - | null - | undefined; + const currentPosition = store.get(focusPosition); if (!isDefined(currentPosition)) { return; @@ -53,7 +50,7 @@ export const useUnfocusRecordTableCell = (recordTableId?: string) => { }); }, [ store, - focusPositionAtom, + focusPosition, recordTableIdFromProps, removeFocusItemFromFocusStackById, setIsRecordTableCellFocusActive, diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/hooks/useAggregateRecordsForRecordTableColumnFooter.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/hooks/useAggregateRecordsForRecordTableColumnFooter.tsx index c64d90cc6d..14be085972 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/hooks/useAggregateRecordsForRecordTableColumnFooter.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/hooks/useAggregateRecordsForRecordTableColumnFooter.tsx @@ -27,7 +27,7 @@ import { isFieldMetadataDateKind, turnAnyFieldFilterIntoRecordGqlFilter, } from 'twenty-shared/utils'; -import { dateLocaleStateV2 } from '~/localization/states/dateLocaleStateV2'; +import { dateLocaleState } from '~/localization/states/dateLocaleState'; export const useAggregateRecordsForRecordTableColumnFooter = ( aggregateFieldMetadataId: string, @@ -43,7 +43,7 @@ export const useAggregateRecordsForRecordTableColumnFooter = ( currentRecordFiltersComponentState, ); - const dateLocale = useRecoilValueV2(dateLocaleStateV2); + const dateLocale = useRecoilValueV2(dateLocaleState); const { filterValueDependencies } = useFilterValueDependencies(); diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/hooks/useResizeTableHeader.ts b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/hooks/useResizeTableHeader.ts index 6c0c1a9a6f..92bd7e522b 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/hooks/useResizeTableHeader.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/hooks/useResizeTableHeader.ts @@ -32,7 +32,7 @@ import { export const useResizeTableHeader = () => { const { recordTableId, visibleRecordFields } = useRecordTableContextOrThrow(); - const resizeFieldOffsetAtom = useRecoilComponentStateCallbackStateV2( + const resizeFieldOffset = useRecoilComponentStateCallbackStateV2( resizeFieldOffsetComponentState, recordTableId, ); @@ -146,16 +146,16 @@ export const useResizeTableHeader = () => { if (!resizedFieldMetadataItemId) return; - const resizeFieldOffset = store.get(resizeFieldOffsetAtom); + const currentResizeFieldOffset = store.get(resizeFieldOffset); const nextWidth = Math.round( Math.max( - recordField.size + resizeFieldOffset, + recordField.size + currentResizeFieldOffset, RECORD_TABLE_COLUMN_MIN_WIDTH, ), ); - store.set(resizeFieldOffsetAtom, 0); + store.set(resizeFieldOffset, 0); setInitialPointerPositionX(null); setResizedFieldMetadataItemId(null); @@ -171,7 +171,7 @@ export const useResizeTableHeader = () => { }, [ saveRecordFields, resizedFieldMetadataItemId, - resizeFieldOffsetAtom, + resizeFieldOffset, store, setResizedFieldMetadataItemId, updateRecordField, diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-row/hooks/useSetCurrentRowSelected.ts b/packages/twenty-front/src/modules/object-record/record-table/record-table-row/hooks/useSetCurrentRowSelected.ts index fea9d6c68f..ec1d53a42d 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-row/hooks/useSetCurrentRowSelected.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-row/hooks/useSetCurrentRowSelected.ts @@ -17,7 +17,7 @@ export const useSetCurrentRowSelected = () => { isRowSelectedComponentFamilyState, ); - const recordIndexAllRecordIdsAtom = useRecoilComponentSelectorCallbackStateV2( + const recordIndexAllRecordIds = useRecoilComponentSelectorCallbackStateV2( recordIndexAllRecordIdsComponentSelector, ); @@ -34,7 +34,7 @@ export const useSetCurrentRowSelected = () => { newSelectedState: boolean; shouldSelectRange?: boolean; }) => { - const allRecordIds = store.get(recordIndexAllRecordIdsAtom); + const allRecordIds = store.get(recordIndexAllRecordIds); const isCurrentRowSelected = store.get( isRowSelectedFamilyState(recordId), @@ -68,7 +68,7 @@ export const useSetCurrentRowSelected = () => { } }, [ - recordIndexAllRecordIdsAtom, + recordIndexAllRecordIds, isRowSelectedFamilyState, recordId, lastSelectedRowIndexComponentCallbackState, diff --git a/packages/twenty-front/src/modules/object-record/record-table/virtualization/components/RecordTableVirtualizedInitialDataLoadEffect.tsx b/packages/twenty-front/src/modules/object-record/record-table/virtualization/components/RecordTableVirtualizedInitialDataLoadEffect.tsx index bc8a52ca40..4d65ac56e2 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/virtualization/components/RecordTableVirtualizedInitialDataLoadEffect.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/virtualization/components/RecordTableVirtualizedInitialDataLoadEffect.tsx @@ -8,9 +8,9 @@ import { lastContextStoreVirtualizedViewIdComponentState } from '@/object-record import { lastContextStoreVirtualizedVisibleRecordFieldsComponentState } from '@/object-record/record-table/virtualization/states/lastContextStoreVirtualizedVisibleRecordFieldsComponentState'; import { lastRecordTableQueryIdentifierComponentState } from '@/object-record/record-table/virtualization/states/lastRecordTableQueryIdentifierComponentState'; import { isFetchingMoreRecordsFamilyState } from '@/object-record/states/isFetchingMoreRecordsFamilyState'; -import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2'; -import { useRecoilComponentSelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentSelectorValueV2'; import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2'; +import { useRecoilComponentSelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentSelectorValueV2'; +import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2'; import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly'; import isEmpty from 'lodash.isempty'; import { useEffect } from 'react'; @@ -62,7 +62,16 @@ export const RecordTableVirtualizedInitialDataLoadEffect = () => { (async () => { if ((currentView?.id ?? null) !== lastContextStoreVirtualizedViewId) { + // Wait for the atomic batch from loadRecordIndexStates to populate + // visibleRecordFields before triggering a fetch. On the next render + // after the batch, fields will be populated and we'll proceed. + if (isEmpty(visibleRecordFields)) { + return; + } + setLastContextStoreVirtualizedViewId(currentView?.id ?? null); + setLastRecordTableQueryIdentifier(queryIdentifier); + setLastContextStoreVisibleRecordFields(visibleRecordFields); await triggerInitialRecordTableDataLoad(); } else if ( @@ -76,11 +85,11 @@ export const RecordTableVirtualizedInitialDataLoadEffect = () => { JSON.stringify(lastContextStoreVisibleRecordFields) !== JSON.stringify(visibleRecordFields) ) { - setLastContextStoreVisibleRecordFields(visibleRecordFields); - const lastFields = lastContextStoreVisibleRecordFields || []; const currentFields = visibleRecordFields || []; + setLastContextStoreVisibleRecordFields(visibleRecordFields); + const shouldRefetchData = currentFields.length > lastFields.length; if (shouldRefetchData) { diff --git a/packages/twenty-front/src/modules/object-record/record-table/virtualization/hooks/useLoadRecordsToVirtualRows.ts b/packages/twenty-front/src/modules/object-record/record-table/virtualization/hooks/useLoadRecordsToVirtualRows.ts index 26b4e41f40..18f28e7965 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/virtualization/hooks/useLoadRecordsToVirtualRows.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/virtualization/hooks/useLoadRecordsToVirtualRows.ts @@ -12,21 +12,20 @@ import { useRecoilComponentFamilyStateCallbackStateV2 } from '@/ui/utilities/sta import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2'; export const useLoadRecordsToVirtualRows = () => { - const recordIdByRealIndexAtom = useRecoilComponentStateCallbackStateV2( + const recordIdByRealIndex = useRecoilComponentStateCallbackStateV2( recordIdByRealIndexComponentState, ); - const dataLoadingStatusByRealIndexAtom = - useRecoilComponentStateCallbackStateV2( - dataLoadingStatusByRealIndexComponentState, - ); + const dataLoadingStatusByRealIndex = useRecoilComponentStateCallbackStateV2( + dataLoadingStatusByRealIndexComponentState, + ); const recordIndexRecordIdsByGroupFamilyState = useRecoilComponentFamilyStateCallbackStateV2( recordIndexRecordIdsByGroupComponentFamilyState, ); - const hasUserSelectedAllRowsAtom = useRecoilComponentStateCallbackStateV2( + const hasUserSelectedAllRows = useRecoilComponentStateCallbackStateV2( hasUserSelectedAllRowsComponentState, ); @@ -44,11 +43,11 @@ export const useLoadRecordsToVirtualRows = () => { records: ObjectRecord[]; startingRealIndex: number; }) => { - const hasUserSelectedAllRows = store.get(hasUserSelectedAllRowsAtom); + const isAllRowsSelected = store.get(hasUserSelectedAllRows); - const currentRecordIdMap = store.get(recordIdByRealIndexAtom); + const currentRecordIdMap = store.get(recordIdByRealIndex); const newRecordIdMap = new Map(currentRecordIdMap); - const currentStatusMap = store.get(dataLoadingStatusByRealIndexAtom); + const currentStatusMap = store.get(dataLoadingStatusByRealIndex); const newStatusMap = new Map(currentStatusMap); for (const [recordIndex, record] of records.entries()) { @@ -61,8 +60,8 @@ export const useLoadRecordsToVirtualRows = () => { newStatusMap.set(realIndex, 'loaded'); } - store.set(recordIdByRealIndexAtom, newRecordIdMap); - store.set(dataLoadingStatusByRealIndexAtom, newStatusMap); + store.set(recordIdByRealIndex, newRecordIdMap); + store.set(dataLoadingStatusByRealIndex, newStatusMap); const currentAllRecordIds = store.get( recordIndexRecordIdsByGroupFamilyState(NO_RECORD_GROUP_FAMILY_KEY), @@ -75,7 +74,7 @@ export const useLoadRecordsToVirtualRows = () => { for (let i = 0; i < records.length; i++) { newAllRecordIds[i + startingRealIndex] = recordIds[i]; - if (hasUserSelectedAllRows) { + if (isAllRowsSelected) { store.set(isRowSelectedFamilyState(recordIds[i]), true); } } @@ -86,11 +85,11 @@ export const useLoadRecordsToVirtualRows = () => { ); }, [ - recordIdByRealIndexAtom, - dataLoadingStatusByRealIndexAtom, + recordIdByRealIndex, + dataLoadingStatusByRealIndex, recordIndexRecordIdsByGroupFamilyState, isRowSelectedFamilyState, - hasUserSelectedAllRowsAtom, + hasUserSelectedAllRows, store, ], ); diff --git a/packages/twenty-front/src/modules/object-record/record-table/virtualization/hooks/useTriggerInitialRecordTableDataLoad.ts b/packages/twenty-front/src/modules/object-record/record-table/virtualization/hooks/useTriggerInitialRecordTableDataLoad.ts index d323566c95..ea661f8f0c 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/virtualization/hooks/useTriggerInitialRecordTableDataLoad.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/virtualization/hooks/useTriggerInitialRecordTableDataLoad.ts @@ -50,13 +50,12 @@ export const useTriggerInitialRecordTableDataLoad = () => { dataPagesLoadedComponentState, ); - const isRecordTableInitialLoadingAtom = - useRecoilComponentStateCallbackStateV2( - isRecordTableInitialLoadingComponentState, - recordTableId, - ); + const isRecordTableInitialLoading = useRecoilComponentStateCallbackStateV2( + isRecordTableInitialLoadingComponentState, + recordTableId, + ); - const recordIndexAllRecordIdsAtom = useRecoilComponentSelectorCallbackStateV2( + const recordIndexAllRecordIds = useRecoilComponentSelectorCallbackStateV2( recordIndexAllRecordIdsComponentSelector, recordTableId, ); @@ -134,7 +133,7 @@ export const useTriggerInitialRecordTableDataLoad = () => { 'hidden', ); - const currentRecordIds = store.get(recordIndexAllRecordIdsAtom); + const currentRecordIds = store.get(recordIndexAllRecordIds); let records: ObjectRecord[] | null = null; let totalCount = 0; @@ -184,7 +183,7 @@ export const useTriggerInitialRecordTableDataLoad = () => { store.set(dataPagesLoadedCallbackState, []); store.set(isInitializingVirtualTableDataLoadingCallbackState, false); - store.set(isRecordTableInitialLoadingAtom, false); + store.set(isRecordTableInitialLoading, false); store.set(lastScrollPositionCallbackState, 0); store.set(lastRealIndexSetCallbackState, null); @@ -205,11 +204,11 @@ export const useTriggerInitialRecordTableDataLoad = () => { isInitializingVirtualTableDataLoadingCallbackState, resetTableFocuses, resetVirtualizedRowTreadmill, - recordIndexAllRecordIdsAtom, + recordIndexAllRecordIds, store, showAuthModal, dataPagesLoadedCallbackState, - isRecordTableInitialLoadingAtom, + isRecordTableInitialLoading, lastScrollPositionCallbackState, lastRealIndexSetCallbackState, scrollAtRealIndexCallbackState, diff --git a/packages/twenty-front/src/modules/onboarding/hooks/useSetNextOnboardingStatus.ts b/packages/twenty-front/src/modules/onboarding/hooks/useSetNextOnboardingStatus.ts index 18109ca934..591bb6af77 100644 --- a/packages/twenty-front/src/modules/onboarding/hooks/useSetNextOnboardingStatus.ts +++ b/packages/twenty-front/src/modules/onboarding/hooks/useSetNextOnboardingStatus.ts @@ -11,13 +11,13 @@ import { import { calendarBookingPageIdState } from '@/client-config/states/calendarBookingPageIdState'; import { usePermissionFlagMap } from '@/settings/roles/hooks/usePermissionFlagMap'; import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useCallback } from 'react'; import { OnboardingStatus, PermissionFlagType, } from '~/generated-metadata/graphql'; +import { useStore } from 'jotai'; type GetNextOnboardingStatusArgs = { currentUser: CurrentUser | null; @@ -63,6 +63,7 @@ const getNextOnboardingStatus = ({ }; export const useSetNextOnboardingStatus = () => { + const store = useStore(); const currentUser = useRecoilValueV2(currentUserState); const currentWorkspace = useRecoilValueV2(currentWorkspaceState); const calendarBookingPageId = useRecoilValueV2(calendarBookingPageIdState); @@ -77,7 +78,7 @@ export const useSetNextOnboardingStatus = () => { calendarBookingPageId, isAccountSyncEnabled, }); - jotaiStore.set(currentUserState.atom, (current) => { + store.set(currentUserState.atom, (current) => { if (isDefined(current)) { return { ...current, @@ -91,5 +92,6 @@ export const useSetNextOnboardingStatus = () => { currentWorkspace, calendarBookingPageId, isAccountSyncEnabled, + store, ]); }; diff --git a/packages/twenty-front/src/modules/page-layout/hooks/useDuplicatePageLayoutTab.ts b/packages/twenty-front/src/modules/page-layout/hooks/useDuplicatePageLayoutTab.ts index 372030ac3c..b6ecb3e50b 100644 --- a/packages/twenty-front/src/modules/page-layout/hooks/useDuplicatePageLayoutTab.ts +++ b/packages/twenty-front/src/modules/page-layout/hooks/useDuplicatePageLayoutTab.ts @@ -25,12 +25,12 @@ export const useDuplicatePageLayoutTab = (pageLayoutIdFromProps?: string) => { pageLayoutIdFromProps, ); - const pageLayoutDraftAtom = useRecoilComponentStateCallbackStateV2( + const pageLayoutDraft = useRecoilComponentStateCallbackStateV2( pageLayoutDraftComponentState, pageLayoutId, ); - const pageLayoutCurrentLayoutsAtom = useRecoilComponentStateCallbackStateV2( + const pageLayoutCurrentLayouts = useRecoilComponentStateCallbackStateV2( pageLayoutCurrentLayoutsComponentState, pageLayoutId, ); @@ -54,11 +54,11 @@ export const useDuplicatePageLayoutTab = (pageLayoutIdFromProps?: string) => { const duplicateTab = useCallback( (tabId: string): string => { - const pageLayoutDraft = store.get(pageLayoutDraftAtom); + const currentPageLayoutDraft = store.get(pageLayoutDraft); - const allTabLayouts = store.get(pageLayoutCurrentLayoutsAtom); + const allTabLayouts = store.get(pageLayoutCurrentLayouts); - const sourceTab = pageLayoutDraft.tabs.find((t) => t.id === tabId); + const sourceTab = currentPageLayoutDraft.tabs.find((t) => t.id === tabId); if (!isDefined(sourceTab)) { throw new Error(`Tab with id ${tabId} not found`); @@ -79,7 +79,7 @@ export const useDuplicatePageLayoutTab = (pageLayoutIdFromProps?: string) => { }; }); - const sortedTabs = sortTabsByPosition(pageLayoutDraft.tabs); + const sortedTabs = sortTabsByPosition(currentPageLayoutDraft.tabs); const sourceIndex = sortedTabs.findIndex((t) => t.id === tabId); const newTabPosition = calculateNewPosition({ @@ -113,13 +113,13 @@ export const useDuplicatePageLayoutTab = (pageLayoutIdFromProps?: string) => { })), }; - store.set(pageLayoutCurrentLayoutsAtom, { + store.set(pageLayoutCurrentLayouts, { ...allTabLayouts, [newTabId]: newLayouts, }); - const prev = store.get(pageLayoutDraftAtom); - store.set(pageLayoutDraftAtom, { + const prev = store.get(pageLayoutDraft); + store.set(pageLayoutDraft, { ...prev, tabs: [...prev.tabs, newTab], }); @@ -141,8 +141,8 @@ export const useDuplicatePageLayoutTab = (pageLayoutIdFromProps?: string) => { [ closeCommandMenu, navigatePageLayoutCommandMenu, - pageLayoutCurrentLayoutsAtom, - pageLayoutDraftAtom, + pageLayoutCurrentLayouts, + pageLayoutDraft, setActiveTabId, setTabSettingsOpenTabId, store, diff --git a/packages/twenty-front/src/modules/page-layout/hooks/useResetDraftPageLayoutToPersistedPageLayout.ts b/packages/twenty-front/src/modules/page-layout/hooks/useResetDraftPageLayoutToPersistedPageLayout.ts index 2d343e554b..6e427d2360 100644 --- a/packages/twenty-front/src/modules/page-layout/hooks/useResetDraftPageLayoutToPersistedPageLayout.ts +++ b/packages/twenty-front/src/modules/page-layout/hooks/useResetDraftPageLayoutToPersistedPageLayout.ts @@ -40,7 +40,7 @@ export const useResetDraftPageLayoutToPersistedPageLayout = ( componentInstanceId, ); - const activeTabIdAtom = activeTabIdComponentState.atomFamily({ + const activeTabId = activeTabIdComponentState.atomFamily({ instanceId: tabListComponentInstanceId, }); @@ -59,14 +59,14 @@ export const useResetDraftPageLayoutToPersistedPageLayout = ( const pageLayoutPersisted = store.get(pageLayoutPersistedState); if (isDefined(pageLayoutPersisted)) { - const currentActiveTabId = store.get(activeTabIdAtom); + const currentActiveTabId = store.get(activeTabId); const persistedTabIds = pageLayoutPersisted.tabs.map((tab) => tab.id); const isActiveTabInPersistedTabs = currentActiveTabId && persistedTabIds.includes(currentActiveTabId); if (!isActiveTabInPersistedTabs && pageLayoutPersisted.tabs.length > 0) { - store.set(activeTabIdAtom, pageLayoutPersisted.tabs[0].id); + store.set(activeTabId, pageLayoutPersisted.tabs[0].id); } store.set(pageLayoutDraftState, { @@ -91,7 +91,7 @@ export const useResetDraftPageLayoutToPersistedPageLayout = ( pageLayoutCurrentLayoutsState, fieldsWidgetGroupsDraftState, fieldsWidgetGroupsPersistedState, - activeTabIdAtom, + activeTabId, store, ]); diff --git a/packages/twenty-front/src/modules/page-layout/hooks/useSetIsPageLayoutInEditMode.ts b/packages/twenty-front/src/modules/page-layout/hooks/useSetIsPageLayoutInEditMode.ts index fc210c33f1..dcc191738d 100644 --- a/packages/twenty-front/src/modules/page-layout/hooks/useSetIsPageLayoutInEditMode.ts +++ b/packages/twenty-front/src/modules/page-layout/hooks/useSetIsPageLayoutInEditMode.ts @@ -1,6 +1,5 @@ import { COMMAND_MENU_COMPONENT_INSTANCE_ID } from '@/command-menu/constants/CommandMenuComponentInstanceId'; import { isCommandMenuOpenedStateV2 } from '@/command-menu/states/isCommandMenuOpenedStateV2'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { MAIN_CONTEXT_STORE_INSTANCE_ID } from '@/context-store/constants/MainContextStoreInstanceId'; import { contextStoreIsPageInEditModeComponentState } from '@/context-store/states/contextStoreIsPageInEditModeComponentState'; import { PageLayoutComponentInstanceContext } from '@/page-layout/states/contexts/PageLayoutComponentInstanceContext'; @@ -36,14 +35,9 @@ export const useSetIsPageLayoutInEditMode = (pageLayoutIdFromProps: string) => { store.set(contextStoreIsFullTabWidgetInEditModeState, value); - jotaiStore.set( - currentPageLayoutIdState.atom, - value ? pageLayoutId : null, - ); + store.set(currentPageLayoutIdState.atom, value ? pageLayoutId : null); - const isCommandMenuOpened = jotaiStore.get( - isCommandMenuOpenedStateV2.atom, - ); + const isCommandMenuOpened = store.get(isCommandMenuOpenedStateV2.atom); if (isCommandMenuOpened) { store.set( diff --git a/packages/twenty-front/src/modules/page-layout/widgets/field/hooks/useOpenFieldWidgetFieldInputEditMode.ts b/packages/twenty-front/src/modules/page-layout/widgets/field/hooks/useOpenFieldWidgetFieldInputEditMode.ts index e38bcf8f74..257a108332 100644 --- a/packages/twenty-front/src/modules/page-layout/widgets/field/hooks/useOpenFieldWidgetFieldInputEditMode.ts +++ b/packages/twenty-front/src/modules/page-layout/widgets/field/hooks/useOpenFieldWidgetFieldInputEditMode.ts @@ -23,15 +23,16 @@ import { isFieldRelationManyToOne } from '@/object-record/record-field/ui/types/ import { isFieldRelationOneToMany } from '@/object-record/record-field/ui/types/guards/isFieldRelationOneToMany'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; import { recordStoreFamilySelectorV2 } from '@/object-record/record-store/states/selectors/recordStoreFamilySelectorV2'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePushFocusItemToFocusStack'; import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById'; import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType'; import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow'; import { useCallback } from 'react'; import { isDefined } from 'twenty-shared/utils'; +import { useStore } from 'jotai'; export const useOpenFieldWidgetFieldInputEditMode = () => { + const store = useStore(); const { openRelationToOneFieldInput } = useOpenRelationToOneFieldInput(); const { openRelationFromManyFieldInput } = useOpenRelationFromManyFieldInput(); @@ -65,20 +66,16 @@ export const useOpenFieldWidgetFieldInputEditMode = () => { fieldDefinition.metadata.relationObjectMetadataNameSingular, ) ) { - const fieldValue = jotaiStore.get( + const fieldValue = store.get( recordStoreFamilySelectorV2.selectorFamily({ recordId, fieldName: fieldDefinition.metadata.fieldName, }), ) as FieldRelationValue; - const activity = jotaiStore.get( - recordStoreFamilyState.atomFamily(recordId), - ); + const activity = store.get(recordStoreFamilyState.atomFamily(recordId)); - const objectMetadataItems = jotaiStore.get( - objectMetadataItemsState.atom, - ); + const objectMetadataItems = store.get(objectMetadataItemsState.atom); const activityTargetObjectRecords = getActivityTargetObjectRecords({ activityRecord: activity as Task | Note, @@ -159,6 +156,7 @@ export const useOpenFieldWidgetFieldInputEditMode = () => { openRelationFromManyFieldInput, openRelationToOneFieldInput, pushFocusItemToFocusStack, + store, ], ); diff --git a/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetBarChart/hooks/__tests__/useBarChartData.test.ts b/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetBarChart/hooks/__tests__/useBarChartData.test.ts index 678cb421d4..50291a62b1 100644 --- a/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetBarChart/hooks/__tests__/useBarChartData.test.ts +++ b/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetBarChart/hooks/__tests__/useBarChartData.test.ts @@ -4,12 +4,9 @@ import { type GraphColorRegistry } from '@/page-layout/widgets/graph/types/Graph import { renderHook } from '@testing-library/react'; const mockUseRecoilComponentValue = jest.fn(); -jest.mock( - '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue', - () => ({ - useRecoilComponentValue: () => mockUseRecoilComponentValue(), - }), -); +jest.mock('@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2', () => ({ + useRecoilComponentValueV2: () => mockUseRecoilComponentValue(), +})); describe('useBarChartData', () => { beforeEach(() => { diff --git a/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetLineChart/hooks/__tests__/useLineChartData.test.ts b/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetLineChart/hooks/__tests__/useLineChartData.test.ts index 8a5d2a4a2d..f217b87091 100644 --- a/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetLineChart/hooks/__tests__/useLineChartData.test.ts +++ b/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetLineChart/hooks/__tests__/useLineChartData.test.ts @@ -6,12 +6,9 @@ import { useLineChartData } from '@/page-layout/widgets/graph/graphWidgetLineCha import { type LineChartSeries } from '~/generated-metadata/graphql'; const mockUseRecoilComponentValue = jest.fn(); -jest.mock( - '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue', - () => ({ - useRecoilComponentValue: () => mockUseRecoilComponentValue(), - }), -); +jest.mock('@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2', () => ({ + useRecoilComponentValueV2: () => mockUseRecoilComponentValue(), +})); describe('useLineChartData', () => { beforeEach(() => { diff --git a/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetPieChart/hooks/__tests__/usePieChartData.test.ts b/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetPieChart/hooks/__tests__/usePieChartData.test.ts index 74a6753d7f..22d227522d 100644 --- a/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetPieChart/hooks/__tests__/usePieChartData.test.ts +++ b/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetPieChart/hooks/__tests__/usePieChartData.test.ts @@ -5,12 +5,9 @@ import { renderHook } from '@testing-library/react'; import { type PieChartDataItem } from '~/generated-metadata/graphql'; const mockUseRecoilComponentValue = jest.fn(); -jest.mock( - '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue', - () => ({ - useRecoilComponentValue: () => mockUseRecoilComponentValue(), - }), -); +jest.mock('@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2', () => ({ + useRecoilComponentValueV2: () => mockUseRecoilComponentValue(), +})); describe('usePieChartData', () => { beforeEach(() => { diff --git a/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetPieChart/hooks/usePieChartCenterMetricData.ts b/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetPieChart/hooks/usePieChartCenterMetricData.ts index 9747ee8e8b..0e5a83b0d8 100644 --- a/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetPieChart/hooks/usePieChartCenterMetricData.ts +++ b/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetPieChart/hooks/usePieChartCenterMetricData.ts @@ -12,7 +12,7 @@ import { useContext, useMemo } from 'react'; import { FIELD_FOR_TOTAL_COUNT_AGGREGATE_OPERATION } from 'twenty-shared/constants'; import { findById, isDefined } from 'twenty-shared/utils'; import { type PieChartConfiguration } from '~/generated-metadata/graphql'; -import { dateLocaleStateV2 } from '~/localization/states/dateLocaleStateV2'; +import { dateLocaleState } from '~/localization/states/dateLocaleState'; type UsePieChartCenterMetricDataProps = { objectMetadataItemId: string; @@ -80,7 +80,7 @@ export const usePieChartCenterMetricData = ({ }); const { dateFormat, timeFormat, timeZone } = useContext(UserContext); - const dateLocale = useRecoilValueV2(dateLocaleStateV2); + const dateLocale = useRecoilValueV2(dateLocaleState); const aggregateFieldMetadataItem = objectMetadataItem.readableFields.find( findById(configuration.aggregateFieldMetadataId), diff --git a/packages/twenty-front/src/modules/page-layout/widgets/graph/hooks/useGraphWidgetAggregateQuery.ts b/packages/twenty-front/src/modules/page-layout/widgets/graph/hooks/useGraphWidgetAggregateQuery.ts index f4148fb4a5..aa44e29863 100644 --- a/packages/twenty-front/src/modules/page-layout/widgets/graph/hooks/useGraphWidgetAggregateQuery.ts +++ b/packages/twenty-front/src/modules/page-layout/widgets/graph/hooks/useGraphWidgetAggregateQuery.ts @@ -15,7 +15,7 @@ import { useContext } from 'react'; import { FIELD_FOR_TOTAL_COUNT_AGGREGATE_OPERATION } from 'twenty-shared/constants'; import { findById, isDefined } from 'twenty-shared/utils'; import { type AggregateChartConfiguration } from '~/generated-metadata/graphql'; -import { dateLocaleStateV2 } from '~/localization/states/dateLocaleStateV2'; +import { dateLocaleState } from '~/localization/states/dateLocaleState'; export const useGraphWidgetAggregateQuery = ({ objectMetadataItemId, @@ -88,7 +88,7 @@ export const useGraphWidgetAggregateQuery = ({ }); const { dateFormat, timeFormat, timeZone } = useContext(UserContext); - const dateLocale = useRecoilValueV2(dateLocaleStateV2); + const dateLocale = useRecoilValueV2(dateLocaleState); if (isRatioQuery) { const isRatioLoading = ratioNumeratorLoading || ratioDenominatorLoading; diff --git a/packages/twenty-front/src/modules/prefetch/components/PrefetchRunFavoriteQueriesEffect.tsx b/packages/twenty-front/src/modules/prefetch/components/PrefetchRunFavoriteQueriesEffect.tsx index 11281bb70d..0d50932101 100644 --- a/packages/twenty-front/src/modules/prefetch/components/PrefetchRunFavoriteQueriesEffect.tsx +++ b/packages/twenty-front/src/modules/prefetch/components/PrefetchRunFavoriteQueriesEffect.tsx @@ -11,7 +11,6 @@ import { prefetchFavoritesState } from '@/prefetch/states/prefetchFavoritesState import { prefetchIsLoadedFamilyState } from '@/prefetch/states/prefetchIsLoadedFamilyState'; import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; import { useShowAuthModal } from '@/ui/layout/hooks/useShowAuthModal'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2'; import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; @@ -23,8 +22,10 @@ import { type Favorite } from '@/favorites/types/Favorite'; import { type FavoriteFolder } from '@/favorites/types/FavoriteFolder'; import { FeatureFlagKey } from '~/generated-metadata/graphql'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; +import { useStore } from 'jotai'; export const PrefetchRunFavoriteQueriesEffect = () => { + const store = useStore(); const isNavigationMenuItemEditingEnabled = useIsFeatureEnabled( FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED, ); @@ -89,24 +90,24 @@ export const PrefetchRunFavoriteQueriesEffect = () => { const setPrefetchFavoritesStateIfChanged = useCallback( (newFavorites: Favorite[]) => { - const existingFavorites = jotaiStore.get(prefetchFavoritesState.atom); + const existingFavorites = store.get(prefetchFavoritesState.atom); if (!isDeeplyEqual(existingFavorites, newFavorites)) { setFavoritesState(newFavorites); } }, - [setFavoritesState], + [setFavoritesState, store], ); const setPrefetchFavoriteFoldersStateIfChanged = useCallback( (newFavoriteFolders: FavoriteFolder[]) => { - const existingFavoriteFolders = jotaiStore.get( + const existingFavoriteFolders = store.get( prefetchFavoriteFoldersState.atom, ); if (!isDeeplyEqual(existingFavoriteFolders, newFavoriteFolders)) { setFavoriteFoldersState(newFavoriteFolders); } }, - [setFavoriteFoldersState], + [setFavoriteFoldersState, store], ); useEffect(() => { diff --git a/packages/twenty-front/src/modules/prefetch/components/PrefetchRunNavigationMenuItemQueriesEffect.tsx b/packages/twenty-front/src/modules/prefetch/components/PrefetchRunNavigationMenuItemQueriesEffect.tsx index 7889bd7d2e..d9b4a24c65 100644 --- a/packages/twenty-front/src/modules/prefetch/components/PrefetchRunNavigationMenuItemQueriesEffect.tsx +++ b/packages/twenty-front/src/modules/prefetch/components/PrefetchRunNavigationMenuItemQueriesEffect.tsx @@ -4,7 +4,6 @@ import { prefetchIsLoadedFamilyState } from '@/prefetch/states/prefetchIsLoadedF import { prefetchNavigationMenuItemsState } from '@/prefetch/states/prefetchNavigationMenuItemsState'; import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; import { useShowAuthModal } from '@/ui/layout/hooks/useShowAuthModal'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2'; import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; @@ -18,8 +17,10 @@ import { type NavigationMenuItem, } from '~/generated-metadata/graphql'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; +import { useStore } from 'jotai'; export const PrefetchRunNavigationMenuItemQueriesEffect = () => { + const store = useStore(); const isNavigationMenuItemEditingEnabled = useIsFeatureEnabled( FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED, ); @@ -50,14 +51,14 @@ export const PrefetchRunNavigationMenuItemQueriesEffect = () => { const setPrefetchNavigationMenuItemsStateIfChanged = useCallback( (navigationMenuItems: NavigationMenuItem[]) => { - const existingNavigationMenuItems = jotaiStore.get( + const existingNavigationMenuItems = store.get( prefetchNavigationMenuItemsState.atom, ); if (!isDeeplyEqual(existingNavigationMenuItems, navigationMenuItems)) { setNavigationMenuItemsState(navigationMenuItems); } }, - [setNavigationMenuItemsState], + [setNavigationMenuItemsState, store], ); useEffect(() => { diff --git a/packages/twenty-front/src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTableRow.tsx b/packages/twenty-front/src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTableRow.tsx index 2ac4affd4c..d873053085 100644 --- a/packages/twenty-front/src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTableRow.tsx +++ b/packages/twenty-front/src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTableRow.tsx @@ -14,7 +14,7 @@ import { useIcons, } from 'twenty-ui/display'; import { type Agent, type ApiKeyForRole } from '~/generated-metadata/graphql'; -import { dateLocaleStateV2 } from '~/localization/states/dateLocaleStateV2'; +import { dateLocaleState } from '~/localization/states/dateLocaleState'; import { formatDateString } from '~/utils/string/formatDateString'; import { type PartialWorkspaceMember } from '@/settings/roles/types/RoleWithPartialMembers'; @@ -60,7 +60,7 @@ export const SettingsRoleAssignmentTableRow = ({ ); const { getIcon } = useIcons(); const { dateFormat, timeZone } = useContext(UserContext); - const dateLocale = useRecoilValueV2(dateLocaleStateV2); + const dateLocale = useRecoilValueV2(dateLocaleState); const renderIcon = () => { switch (roleTarget.type) { diff --git a/packages/twenty-front/src/modules/settings/security/components/approvedAccessDomains/SettingsApprovedAccessDomainsListCard.tsx b/packages/twenty-front/src/modules/settings/security/components/approvedAccessDomains/SettingsApprovedAccessDomainsListCard.tsx index ee8f51b6d0..037de9999b 100644 --- a/packages/twenty-front/src/modules/settings/security/components/approvedAccessDomains/SettingsApprovedAccessDomainsListCard.tsx +++ b/packages/twenty-front/src/modules/settings/security/components/approvedAccessDomains/SettingsApprovedAccessDomainsListCard.tsx @@ -16,7 +16,7 @@ import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValu import { getSettingsPath } from 'twenty-shared/utils'; import { IconAt, IconMailCog, Status } from 'twenty-ui/display'; import { useGetApprovedAccessDomainsQuery } from '~/generated-metadata/graphql'; -import { dateLocaleStateV2 } from '~/localization/states/dateLocaleStateV2'; +import { dateLocaleState } from '~/localization/states/dateLocaleState'; import { beautifyPastDateRelativeToNow } from '~/utils/date-utils'; const StyledLink = styled(Link)` @@ -27,7 +27,7 @@ export const SettingsApprovedAccessDomainsListCard = () => { const { enqueueErrorSnackBar } = useSnackBar(); const navigate = useNavigate(); const { t } = useLingui(); - const { localeCatalog } = useRecoilValueV2(dateLocaleStateV2); + const { localeCatalog } = useRecoilValueV2(dateLocaleState); const [approvedAccessDomains, setApprovedAccessDomains] = useRecoilStateV2( approvedAccessDomainsState, diff --git a/packages/twenty-front/src/modules/spreadsheet-import/hooks/useComputeColumnSuggestionsAndAutoMatch.ts b/packages/twenty-front/src/modules/spreadsheet-import/hooks/useComputeColumnSuggestionsAndAutoMatch.ts index ab0ed2301f..4dfebbda08 100644 --- a/packages/twenty-front/src/modules/spreadsheet-import/hooks/useComputeColumnSuggestionsAndAutoMatch.ts +++ b/packages/twenty-front/src/modules/spreadsheet-import/hooks/useComputeColumnSuggestionsAndAutoMatch.ts @@ -8,9 +8,10 @@ import { import { suggestedFieldsByColumnHeaderState } from '@/spreadsheet-import/steps/components/MatchColumnsStep/components/states/suggestedFieldsByColumnHeaderState'; import { type ImportedRow } from '@/spreadsheet-import/types'; import { getMatchedColumnsWithFuse } from '@/spreadsheet-import/utils/getMatchedColumnsWithFuse'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; +import { useStore } from 'jotai'; export const useComputeColumnSuggestionsAndAutoMatch = () => { + const store = useStore(); const { spreadsheetImportFields: fields, autoMapHeaders } = useSpreadsheetImportInternal(); @@ -23,21 +24,21 @@ export const useComputeColumnSuggestionsAndAutoMatch = () => { data: ImportedRow[]; }) => { if (autoMapHeaders) { - const columns = jotaiStore.get( + const columns = store.get( initialComputedColumnsSelector.selectorFamily(headerValues), ); const { matchedColumns, suggestedFieldsByColumnHeader } = getMatchedColumnsWithFuse({ columns, fields, data }); - jotaiStore.set(matchColumnsState.atom, matchedColumns); - jotaiStore.set( + store.set(matchColumnsState.atom, matchedColumns); + store.set( suggestedFieldsByColumnHeaderState.atom, suggestedFieldsByColumnHeader, ); } }, - [autoMapHeaders, fields], + [autoMapHeaders, fields, store], ); return computeColumnSuggestionsAndAutoMatch; diff --git a/packages/twenty-front/src/modules/spreadsheet-import/hooks/useHideStepBar.ts b/packages/twenty-front/src/modules/spreadsheet-import/hooks/useHideStepBar.ts index 2dce527e11..c2c2b4150e 100644 --- a/packages/twenty-front/src/modules/spreadsheet-import/hooks/useHideStepBar.ts +++ b/packages/twenty-front/src/modules/spreadsheet-import/hooks/useHideStepBar.ts @@ -1,20 +1,21 @@ import { spreadsheetImportDialogState } from '@/spreadsheet-import/states/spreadsheetImportDialogState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useCallback } from 'react'; +import { useStore } from 'jotai'; export const useHideStepBar = () => { + const store = useStore(); const hideStepBar = useCallback(() => { - const isStepBarVisible = jotaiStore.get( + const isStepBarVisible = store.get( spreadsheetImportDialogState.atom, ).isStepBarVisible; if (isStepBarVisible) { - jotaiStore.set(spreadsheetImportDialogState.atom, (state) => ({ + store.set(spreadsheetImportDialogState.atom, (state) => ({ ...state, isStepBarVisible: false, })); } - }, []); + }, [store]); return hideStepBar; }; diff --git a/packages/twenty-front/src/modules/sse-db-event/components/SSEClientEffect.tsx b/packages/twenty-front/src/modules/sse-db-event/components/SSEClientEffect.tsx index 2cd892447b..032283c1b8 100644 --- a/packages/twenty-front/src/modules/sse-db-event/components/SSEClientEffect.tsx +++ b/packages/twenty-front/src/modules/sse-db-event/components/SSEClientEffect.tsx @@ -3,7 +3,6 @@ import { tokenPairState } from '@/auth/states/tokenPairState'; import { useHandleSseClientConnectionRetry } from '@/sse-db-event/hooks/useHandleSseClientConnectionRetry'; import { activeQueryListenersState } from '@/sse-db-event/states/activeQueryListenersState'; import { sseClientState } from '@/sse-db-event/states/sseClientState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { isNonEmptyArray } from '@sniptt/guards'; @@ -11,21 +10,23 @@ import { createClient } from 'graphql-sse'; import { useCallback, useEffect } from 'react'; import { isDefined } from 'twenty-shared/utils'; import { REACT_APP_SERVER_BASE_URL } from '~/config'; +import { useStore } from 'jotai'; export const SSEClientEffect = () => { + const store = useStore(); const isLoggedIn = useIsLogged(); const [sseClient, setSseClient] = useRecoilStateV2(sseClientState); const tokenPair = useRecoilValueV2(tokenPairState); const handleSSEClientConnected = useCallback(() => { - const currentActiveQueryListeners = jotaiStore.get( + const currentActiveQueryListeners = store.get( activeQueryListenersState.atom, ); if (isNonEmptyArray(currentActiveQueryListeners)) { - jotaiStore.set(activeQueryListenersState.atom, []); + store.set(activeQueryListenersState.atom, []); } - }, []); + }, [store]); const { handleSseClientConnectionRetry } = useHandleSseClientConnectionRetry(); diff --git a/packages/twenty-front/src/modules/sse-db-event/components/SSEQuerySubscribeEffect.tsx b/packages/twenty-front/src/modules/sse-db-event/components/SSEQuerySubscribeEffect.tsx index e460aa142d..0b7ebab529 100644 --- a/packages/twenty-front/src/modules/sse-db-event/components/SSEQuerySubscribeEffect.tsx +++ b/packages/twenty-front/src/modules/sse-db-event/components/SSEQuerySubscribeEffect.tsx @@ -5,7 +5,6 @@ import { requiredQueryListenersState } from '@/sse-db-event/states/requiredQuery import { shouldDestroyEventStreamState } from '@/sse-db-event/states/shouldDestroyEventStreamState'; import { sseEventStreamIdState } from '@/sse-db-event/states/sseEventStreamIdState'; import { sseEventStreamReadyState } from '@/sse-db-event/states/sseEventStreamReadyState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { ApolloError, useMutation } from '@apollo/client'; import { isNonEmptyString } from '@sniptt/guards'; @@ -19,8 +18,10 @@ import { type AddQuerySubscriptionInput, type RemoveQueryFromEventStreamInput, } from '~/generated-metadata/graphql'; +import { useStore } from 'jotai'; export const SSEQuerySubscribeEffect = () => { + const store = useStore(); const sseEventStreamId = useRecoilValueV2(sseEventStreamIdState); const sseEventStreamReady = useRecoilValueV2(sseEventStreamReadyState); @@ -42,11 +43,9 @@ export const SSEQuerySubscribeEffect = () => { return; } - const requiredQueryListeners = jotaiStore.get( - requiredQueryListenersState.atom, - ); + const requiredQueryListeners = store.get(requiredQueryListenersState.atom); - const activeQueryListeners = jotaiStore.get(activeQueryListenersState.atom); + const activeQueryListeners = store.get(activeQueryListenersState.atom); const queryListenersToAdd = requiredQueryListeners.filter( (listener) => @@ -92,8 +91,8 @@ export const SSEQuerySubscribeEffect = () => { switch (subCode) { case 'EVENT_STREAM_DOES_NOT_EXIST': case 'EVENT_STREAM_ALREADY_EXISTS': { - jotaiStore.set(activeQueryListenersState.atom, []); - jotaiStore.set(shouldDestroyEventStreamState.atom, true); + store.set(activeQueryListenersState.atom, []); + store.set(shouldDestroyEventStreamState.atom, true); return; } default: { @@ -105,8 +104,13 @@ export const SSEQuerySubscribeEffect = () => { } } - jotaiStore.set(activeQueryListenersState.atom, requiredQueryListeners); - }, [addQueryToEventStream, removeQueryFromEventStream, sseEventStreamId]); + store.set(activeQueryListenersState.atom, requiredQueryListeners); + }, [ + addQueryToEventStream, + removeQueryFromEventStream, + sseEventStreamId, + store, + ]); const debouncedUpdateQueryListeners = useDebouncedCallback( updateQueryListeners, diff --git a/packages/twenty-front/src/modules/sse-db-event/hooks/useHandleSseClientConnectionRetry.ts b/packages/twenty-front/src/modules/sse-db-event/hooks/useHandleSseClientConnectionRetry.ts index 7103966645..c538d0408b 100644 --- a/packages/twenty-front/src/modules/sse-db-event/hooks/useHandleSseClientConnectionRetry.ts +++ b/packages/twenty-front/src/modules/sse-db-event/hooks/useHandleSseClientConnectionRetry.ts @@ -4,16 +4,17 @@ import { SSE_CONNECTION_RETRY_WAIT_TIME_IN_MS_FOR_DEV_MODE } from '@/sse-db-even import { SSE_CONNECTION_RETRY_WAIT_TIME_IN_MS_TO_AVOID_RACE_CONDITIONS } from '@/sse-db-event/constants/SseConnectionRetryWaitTimeInMsToAvoidRaceConditions'; import { shouldDestroyEventStreamState } from '@/sse-db-event/states/shouldDestroyEventStreamState'; import { sseClientState } from '@/sse-db-event/states/sseClientState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useCallback } from 'react'; import { isDefined } from 'twenty-shared/utils'; import { getIsDevelopmentEnvironment } from '~/utils/getIsDevelopmentEnvironment'; import { sleep } from '~/utils/sleep'; +import { useStore } from 'jotai'; export const useHandleSseClientConnectionRetry = () => { + const store = useStore(); const handleSseClientConnectionRetry = useCallback( async (retryCount: number, initialTokenForSseClient: string) => { - const sseClient = jotaiStore.get(sseClientState.atom); + const sseClient = store.get(sseClientState.atom); if (!isDefined(sseClient)) { await sleep( @@ -23,7 +24,7 @@ export const useHandleSseClientConnectionRetry = () => { return; } - const tokenPair = jotaiStore.get(tokenPairState.atom); + const tokenPair = store.get(tokenPairState.atom); const currentAppToken = tokenPair?.accessOrWorkspaceAgnosticToken?.token; const shouldResetSseClient = @@ -37,8 +38,8 @@ export const useHandleSseClientConnectionRetry = () => { ); sseClient.dispose(); - jotaiStore.set(shouldDestroyEventStreamState.atom, true); - jotaiStore.set(sseClientState.atom, null); + store.set(shouldDestroyEventStreamState.atom, true); + store.set(sseClientState.atom, null); return; } @@ -54,7 +55,7 @@ export const useHandleSseClientConnectionRetry = () => { await sleep(waitTimeInMs); }, - [], + [store], ); return { handleSseClientConnectionRetry }; diff --git a/packages/twenty-front/src/modules/sse-db-event/hooks/useListenToEventsForQuery.ts b/packages/twenty-front/src/modules/sse-db-event/hooks/useListenToEventsForQuery.ts index 41f3d0ec72..5e0e5af52d 100644 --- a/packages/twenty-front/src/modules/sse-db-event/hooks/useListenToEventsForQuery.ts +++ b/packages/twenty-front/src/modules/sse-db-event/hooks/useListenToEventsForQuery.ts @@ -1,10 +1,10 @@ import { requiredQueryListenersState } from '@/sse-db-event/states/requiredQueryListenersState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useCallback, useEffect } from 'react'; import { type MetadataGqlOperationSignature, type RecordGqlOperationSignature, } from 'twenty-shared/types'; +import { useStore } from 'jotai'; export const useListenToEventsForQuery = ({ queryId, @@ -15,6 +15,7 @@ export const useListenToEventsForQuery = ({ | RecordGqlOperationSignature | MetadataGqlOperationSignature; }) => { + const store = useStore(); const changeQueryIdListenState = useCallback( ( shouldListen: boolean, @@ -23,7 +24,7 @@ export const useListenToEventsForQuery = ({ | RecordGqlOperationSignature | MetadataGqlOperationSignature, ) => { - const currentRequiredQueryListeners = jotaiStore.get( + const currentRequiredQueryListeners = store.get( requiredQueryListenersState.atom, ); @@ -36,7 +37,7 @@ export const useListenToEventsForQuery = ({ } if (shouldListen) { - jotaiStore.set(requiredQueryListenersState.atom, [ + store.set(requiredQueryListenersState.atom, [ ...currentRequiredQueryListeners, { queryId: targetQueryId, @@ -44,7 +45,7 @@ export const useListenToEventsForQuery = ({ }, ]); } else { - jotaiStore.set( + store.set( requiredQueryListenersState.atom, currentRequiredQueryListeners.filter( (listener) => listener.queryId !== targetQueryId, @@ -52,7 +53,7 @@ export const useListenToEventsForQuery = ({ ); } }, - [], + [store], ); useEffect(() => { diff --git a/packages/twenty-front/src/modules/sse-db-event/hooks/useTriggerEventStreamCreation.ts b/packages/twenty-front/src/modules/sse-db-event/hooks/useTriggerEventStreamCreation.ts index fe1c97a87b..27b8347c6e 100644 --- a/packages/twenty-front/src/modules/sse-db-event/hooks/useTriggerEventStreamCreation.ts +++ b/packages/twenty-front/src/modules/sse-db-event/hooks/useTriggerEventStreamCreation.ts @@ -9,7 +9,6 @@ import { shouldDestroyEventStreamState } from '@/sse-db-event/states/shouldDestr import { sseClientState } from '@/sse-db-event/states/sseClientState'; import { sseEventStreamIdState } from '@/sse-db-event/states/sseEventStreamIdState'; import { sseEventStreamReadyState } from '@/sse-db-event/states/sseEventStreamReadyState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { captureException } from '@sentry/react'; import { isNonEmptyString } from '@sniptt/guards'; @@ -19,8 +18,10 @@ import { useCallback } from 'react'; import { isDefined } from 'twenty-shared/utils'; import { v4 } from 'uuid'; import { type EventSubscription } from '~/generated-metadata/graphql'; +import { useStore } from 'jotai'; export const useTriggerEventStreamCreation = () => { + const store = useStore(); const setIsCreatingSseEventStream = useSetRecoilStateV2( isCreatingSseEventStreamState, ); @@ -35,17 +36,17 @@ export const useTriggerEventStreamCreation = () => { useTriggerOptimisticEffectFromSseEvents(); const triggerEventStreamCreation = useCallback(() => { - const sseClient = jotaiStore.get(sseClientState.atom); + const sseClient = store.get(sseClientState.atom); - const isCreatingSseEventStream = jotaiStore.get( + const isCreatingSseEventStream = store.get( isCreatingSseEventStreamState.atom, ); - const isDestroyingEventStream = jotaiStore.get( + const isDestroyingEventStream = store.get( isDestroyingEventStreamState.atom, ); - const currentSseEventStreamId = jotaiStore.get(sseEventStreamIdState.atom); + const currentSseEventStreamId = store.get(sseEventStreamIdState.atom); if ( isCreatingSseEventStream || @@ -60,8 +61,8 @@ export const useTriggerEventStreamCreation = () => { const newSseEventStreamId = v4(); - jotaiStore.set(sseEventStreamIdState.atom, newSseEventStreamId); - jotaiStore.set(sseEventStreamReadyState.atom, false); + store.set(sseEventStreamIdState.atom, newSseEventStreamId); + store.set(sseEventStreamReadyState.atom, false); let hasReceivedFirstEvent = false; @@ -82,14 +83,14 @@ export const useTriggerEventStreamCreation = () => { captureException( new Error(`SSE subscription error: ${value.errors[0]?.message}`), ); - jotaiStore.set(shouldDestroyEventStreamState.atom, true); + store.set(shouldDestroyEventStreamState.atom, true); return; } if (!hasReceivedFirstEvent) { hasReceivedFirstEvent = true; - jotaiStore.set(sseEventStreamReadyState.atom, true); + store.set(sseEventStreamReadyState.atom, true); } const eventSubscription = value?.data?.onEventSubscription; @@ -134,7 +135,7 @@ export const useTriggerEventStreamCreation = () => { switch (subCode) { case 'EVENT_STREAM_ALREADY_EXISTS': { - jotaiStore.set(shouldDestroyEventStreamState.atom, true); + store.set(shouldDestroyEventStreamState.atom, true); break; } default: { @@ -144,11 +145,11 @@ export const useTriggerEventStreamCreation = () => { } } - jotaiStore.set(shouldDestroyEventStreamState.atom, true); + store.set(shouldDestroyEventStreamState.atom, true); } else { if (!hasReceivedFirstEvent) { hasReceivedFirstEvent = true; - jotaiStore.set(sseEventStreamReadyState.atom, true); + store.set(sseEventStreamReadyState.atom, true); } const objectRecordEventsWithQueryIds = @@ -182,7 +183,7 @@ export const useTriggerEventStreamCreation = () => { }, ); - jotaiStore.set(disposeFunctionForEventStreamState.atom, { dispose }); + store.set(disposeFunctionForEventStreamState.atom, { dispose }); setIsCreatingSseEventStream(false); }, [ @@ -190,6 +191,7 @@ export const useTriggerEventStreamCreation = () => { dispatchObjectRecordEventsFromSseToBrowserEvents, setIsCreatingSseEventStream, triggerOptimisticEffectFromSseEvents, + store, ]); return { diff --git a/packages/twenty-front/src/modules/sse-db-event/hooks/useTriggerEventStreamDestroy.ts b/packages/twenty-front/src/modules/sse-db-event/hooks/useTriggerEventStreamDestroy.ts index c0a1807ab6..a107b9cb15 100644 --- a/packages/twenty-front/src/modules/sse-db-event/hooks/useTriggerEventStreamDestroy.ts +++ b/packages/twenty-front/src/modules/sse-db-event/hooks/useTriggerEventStreamDestroy.ts @@ -4,22 +4,23 @@ import { isDestroyingEventStreamState } from '@/sse-db-event/states/isDestroying import { shouldDestroyEventStreamState } from '@/sse-db-event/states/shouldDestroyEventStreamState'; import { sseEventStreamIdState } from '@/sse-db-event/states/sseEventStreamIdState'; import { sseEventStreamReadyState } from '@/sse-db-event/states/sseEventStreamReadyState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { isNonEmptyString } from '@sniptt/guards'; import { useCallback } from 'react'; +import { useStore } from 'jotai'; export const useTriggerEventStreamDestroy = () => { + const store = useStore(); const setIsDestroyingEventStream = useSetRecoilStateV2( isDestroyingEventStreamState, ); const triggerEventStreamDestroy = useCallback(() => { - const isDestroyingEventStream = jotaiStore.get( + const isDestroyingEventStream = store.get( isDestroyingEventStreamState.atom, ); - const isCreatingSseEventStream = jotaiStore.get( + const isCreatingSseEventStream = store.get( isCreatingSseEventStreamState.atom, ); @@ -29,23 +30,23 @@ export const useTriggerEventStreamDestroy = () => { setIsDestroyingEventStream(true); - const eventStreamId = jotaiStore.get(sseEventStreamIdState.atom); + const eventStreamId = store.get(sseEventStreamIdState.atom); - const disposeFunctionForEventStream = jotaiStore.get( + const disposeFunctionForEventStream = store.get( disposeFunctionForEventStreamState.atom, ); if (isNonEmptyString(eventStreamId)) { disposeFunctionForEventStream?.dispose(); - jotaiStore.set(sseEventStreamIdState.atom, null); - jotaiStore.set(sseEventStreamReadyState.atom, false); - jotaiStore.set(disposeFunctionForEventStreamState.atom, null); - jotaiStore.set(shouldDestroyEventStreamState.atom, false); + store.set(sseEventStreamIdState.atom, null); + store.set(sseEventStreamReadyState.atom, false); + store.set(disposeFunctionForEventStreamState.atom, null); + store.set(shouldDestroyEventStreamState.atom, false); } setIsDestroyingEventStream(false); - }, [setIsDestroyingEventStream]); + }, [setIsDestroyingEventStream, store]); return { triggerEventStreamDestroy, diff --git a/packages/twenty-front/src/modules/ui/field/display/components/DateDisplay.tsx b/packages/twenty-front/src/modules/ui/field/display/components/DateDisplay.tsx index 06ce165674..549fb48adf 100644 --- a/packages/twenty-front/src/modules/ui/field/display/components/DateDisplay.tsx +++ b/packages/twenty-front/src/modules/ui/field/display/components/DateDisplay.tsx @@ -2,7 +2,7 @@ import { type FieldDateMetadataSettings } from '@/object-record/record-field/ui/ import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { UserContext } from '@/users/contexts/UserContext'; import { useContext } from 'react'; -import { dateLocaleStateV2 } from '~/localization/states/dateLocaleStateV2'; +import { dateLocaleState } from '~/localization/states/dateLocaleState'; import { formatDateString } from '~/utils/string/formatDateString'; import { EllipsisDisplay } from './EllipsisDisplay'; @@ -12,7 +12,7 @@ type DateDisplayProps = { }; export const DateDisplay = ({ value, dateFieldSettings }: DateDisplayProps) => { const { dateFormat } = useContext(UserContext); - const dateLocale = useRecoilValueV2(dateLocaleStateV2); + const dateLocale = useRecoilValueV2(dateLocaleState); const formattedDate = formatDateString({ value, diff --git a/packages/twenty-front/src/modules/ui/field/display/components/DateTimeDisplay.tsx b/packages/twenty-front/src/modules/ui/field/display/components/DateTimeDisplay.tsx index 2adc3bd1a7..d75bb2f442 100644 --- a/packages/twenty-front/src/modules/ui/field/display/components/DateTimeDisplay.tsx +++ b/packages/twenty-front/src/modules/ui/field/display/components/DateTimeDisplay.tsx @@ -6,7 +6,7 @@ import styled from '@emotion/styled'; import { isNonEmptyString } from '@sniptt/guards'; import { useContext } from 'react'; import { Temporal } from 'temporal-polyfill'; -import { dateLocaleStateV2 } from '~/localization/states/dateLocaleStateV2'; +import { dateLocaleState } from '~/localization/states/dateLocaleState'; import { formatDateTimeString } from '~/utils/string/formatDateTimeString'; import { EllipsisDisplay } from './EllipsisDisplay'; @@ -24,7 +24,7 @@ export const DateTimeDisplay = ({ dateFieldSettings, }: DateTimeDisplayProps) => { const { dateFormat, timeFormat, timeZone } = useContext(UserContext); - const dateLocale = useRecoilValueV2(dateLocaleStateV2); + const dateLocale = useRecoilValueV2(dateLocaleState); const formattedDate = formatDateTimeString({ value, diff --git a/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageSummaryCard.tsx b/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageSummaryCard.tsx index 6a017ef89f..c76d07b68c 100644 --- a/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageSummaryCard.tsx +++ b/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageSummaryCard.tsx @@ -13,7 +13,7 @@ import { } from 'twenty-ui/display'; import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { v4 as uuidV4 } from 'uuid'; -import { dateLocaleStateV2 } from '~/localization/states/dateLocaleStateV2'; +import { dateLocaleState } from '~/localization/states/dateLocaleState'; import { beautifyExactDateTime, beautifyPastDateRelativeToNow, @@ -123,7 +123,7 @@ export const ShowPageSummaryCard = ({ loading, isMobile = false, }: ShowPageSummaryCardProps) => { - const { localeCatalog } = useRecoilValueV2(dateLocaleStateV2); + const { localeCatalog } = useRecoilValueV2(dateLocaleState); const beautifiedCreatedAt = date !== '' ? beautifyPastDateRelativeToNow(date, localeCatalog) : ''; const exactCreatedAt = date !== '' ? beautifyExactDateTime(date) : ''; diff --git a/packages/twenty-front/src/modules/views/hooks/__tests__/useApplyCurrentViewSortsToCurrentRecordSorts.test.tsx b/packages/twenty-front/src/modules/views/hooks/__tests__/useApplyCurrentViewSortsToCurrentRecordSorts.test.tsx index 6c6a1d2227..37caaf282f 100644 --- a/packages/twenty-front/src/modules/views/hooks/__tests__/useApplyCurrentViewSortsToCurrentRecordSorts.test.tsx +++ b/packages/twenty-front/src/modules/views/hooks/__tests__/useApplyCurrentViewSortsToCurrentRecordSorts.test.tsx @@ -6,7 +6,10 @@ import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useR import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; +import { + jotaiStore, + resetJotaiStore, +} from '@/ui/utilities/state/jotai/jotaiStore'; import { coreViewsState } from '@/views/states/coreViewState'; import { type CoreViewSortEssential } from '@/views/types/CoreViewSortEssential'; import { type CoreViewWithRelations } from '@/views/types/CoreViewWithRelations'; @@ -35,7 +38,7 @@ describe('useApplyCurrentViewSortsToCurrentRecordSorts', () => { } afterEach(() => { - jotaiStore.set(coreViewsState.atom, []); + resetJotaiStore(); }); const mockFieldMetadataItem = mockObjectMetadataItem.fields.find( diff --git a/packages/twenty-front/src/modules/views/hooks/useApplyCurrentViewFilterGroupsToCurrentRecordFilterGroups.ts b/packages/twenty-front/src/modules/views/hooks/useApplyCurrentViewFilterGroupsToCurrentRecordFilterGroups.ts index 7ef442498b..dae077e4b3 100644 --- a/packages/twenty-front/src/modules/views/hooks/useApplyCurrentViewFilterGroupsToCurrentRecordFilterGroups.ts +++ b/packages/twenty-front/src/modules/views/hooks/useApplyCurrentViewFilterGroupsToCurrentRecordFilterGroups.ts @@ -20,10 +20,9 @@ export const useApplyCurrentViewFilterGroupsToCurrentRecordFilterGroups = currentRecordFilterGroupsComponentState, ); - const currentRecordFilterGroupsAtom = - useRecoilComponentStateCallbackStateV2( - currentRecordFilterGroupsComponentState, - ); + const currentRecordFilterGroups = useRecoilComponentStateCallbackStateV2( + currentRecordFilterGroupsComponentState, + ); const store = useStore(); @@ -36,8 +35,8 @@ export const useApplyCurrentViewFilterGroupsToCurrentRecordFilterGroups = ); if (isDefined(currentView)) { - const currentRecordFilterGroups = store.get( - currentRecordFilterGroupsAtom, + const existingRecordFilterGroups = store.get( + currentRecordFilterGroups, ); const newRecordFilterGroups = mapViewFilterGroupsToRecordFilterGroups( @@ -45,7 +44,7 @@ export const useApplyCurrentViewFilterGroupsToCurrentRecordFilterGroups = ); if ( - !isDeeplyEqual(currentRecordFilterGroups, newRecordFilterGroups) + !isDeeplyEqual(existingRecordFilterGroups, newRecordFilterGroups) ) { setCurrentRecordFilterGroups(newRecordFilterGroups); } @@ -53,7 +52,7 @@ export const useApplyCurrentViewFilterGroupsToCurrentRecordFilterGroups = }, [ currentViewId, setCurrentRecordFilterGroups, - currentRecordFilterGroupsAtom, + currentRecordFilterGroups, store, ]); diff --git a/packages/twenty-front/src/modules/views/hooks/useCreateViewFromCurrentView.ts b/packages/twenty-front/src/modules/views/hooks/useCreateViewFromCurrentView.ts index 51f791a4e3..bbb18113a1 100644 --- a/packages/twenty-front/src/modules/views/hooks/useCreateViewFromCurrentView.ts +++ b/packages/twenty-front/src/modules/views/hooks/useCreateViewFromCurrentView.ts @@ -33,7 +33,7 @@ export const useCreateViewFromCurrentView = (viewBarComponentId?: string) => { const { objectMetadataItem, recordIndexId } = useRecordIndexContextOrThrow(); - const currentViewIdAtom = useRecoilComponentStateCallbackStateV2( + const currentViewId = useRecoilComponentStateCallbackStateV2( contextStoreCurrentViewIdComponentState, viewBarComponentId, ); @@ -96,15 +96,15 @@ export const useCreateViewFromCurrentView = (viewBarComponentId?: string) => { >, shouldCopyFiltersAndSortsAndAggregate?: boolean, ): Promise => { - const currentViewId = store.get(currentViewIdAtom); + const existingCurrentViewId = store.get(currentViewId); - if (!isDefined(currentViewId)) { + if (!isDefined(existingCurrentViewId)) { return undefined; } const sourceView = store.get( coreViewFromViewIdFamilySelector.selectorFamily({ - viewId: currentViewId, + viewId: existingCurrentViewId, }), ); @@ -238,7 +238,7 @@ export const useCreateViewFromCurrentView = (viewBarComponentId?: string) => { return newViewId; }, [ - currentViewIdAtom, + currentViewId, performViewAPICreate, anyFieldFilterValue, objectMetadataItem, diff --git a/packages/twenty-front/src/modules/views/hooks/useRefreshAllCoreViews.ts b/packages/twenty-front/src/modules/views/hooks/useRefreshAllCoreViews.ts index ead5a1121c..e00dfd63e8 100644 --- a/packages/twenty-front/src/modules/views/hooks/useRefreshAllCoreViews.ts +++ b/packages/twenty-front/src/modules/views/hooks/useRefreshAllCoreViews.ts @@ -1,15 +1,16 @@ import { FIND_ALL_CORE_VIEWS } from '@/views/graphql/queries/findAllCoreViews'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { coreViewsState } from '@/views/states/coreViewState'; import { type FetchPolicy, useApolloClient } from '@apollo/client'; import { useCallback } from 'react'; import { isDefined } from 'twenty-shared/utils'; import { type FindAllCoreViewsQuery } from '~/generated-metadata/graphql'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; +import { useStore } from 'jotai'; export const useRefreshAllCoreViews = ( fetchPolicy: FetchPolicy = 'network-only', ) => { + const store = useStore(); const client = useApolloClient(); const refreshAllCoreViews = useCallback(async () => { @@ -19,7 +20,7 @@ export const useRefreshAllCoreViews = ( fetchPolicy, }); - const currentCoreViews = jotaiStore.get(coreViewsState.atom); + const currentCoreViews = store.get(coreViewsState.atom); const coreViewsFromResult = result.data.getCoreViews; @@ -27,11 +28,11 @@ export const useRefreshAllCoreViews = ( isDefined(result.data?.getCoreViews) && !isDeeplyEqual(currentCoreViews, coreViewsFromResult) ) { - jotaiStore.set(coreViewsState.atom, coreViewsFromResult); + store.set(coreViewsState.atom, coreViewsFromResult); } return result.data?.getCoreViews; - }, [client, fetchPolicy]); + }, [client, fetchPolicy, store]); return { refreshAllCoreViews, diff --git a/packages/twenty-front/src/modules/views/hooks/useRefreshCoreViewsByObjectMetadataId.ts b/packages/twenty-front/src/modules/views/hooks/useRefreshCoreViewsByObjectMetadataId.ts index 1e1c0045a1..a193643173 100644 --- a/packages/twenty-front/src/modules/views/hooks/useRefreshCoreViewsByObjectMetadataId.ts +++ b/packages/twenty-front/src/modules/views/hooks/useRefreshCoreViewsByObjectMetadataId.ts @@ -4,7 +4,6 @@ import { currentRecordFiltersComponentState } from '@/object-record/record-filte import { recordIndexShouldHideEmptyRecordGroupsComponentState } from '@/object-record/record-index/states/recordIndexShouldHideEmptyRecordGroupsComponentState'; import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState'; import { getRecordIndexIdFromObjectNamePluralAndViewId } from '@/object-record/utils/getRecordIndexIdFromObjectNamePluralAndViewId'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { coreViewsByObjectMetadataIdFamilySelector } from '@/views/states/selectors/coreViewsByObjectMetadataIdFamilySelector'; import { convertCoreViewToView } from '@/views/utils/convertCoreViewToView'; import { getFilterableFields } from '@/views/utils/getFilterableFields'; @@ -15,8 +14,10 @@ import { useCallback } from 'react'; import { isDefined, removePropertiesFromRecord } from 'twenty-shared/utils'; import { useFindManyCoreViewsLazyQuery } from '~/generated-metadata/graphql'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; +import { useStore } from 'jotai'; export const useRefreshCoreViewsByObjectMetadataId = () => { + const store = useStore(); const [findManyCoreViewsLazy] = useFindManyCoreViewsLazyQuery(); const refreshCoreViewsByObjectMetadataId = useCallback( @@ -32,7 +33,7 @@ export const useRefreshCoreViewsByObjectMetadataId = () => { return; } - const objectMetadataItems = jotaiStore.get(objectMetadataItemsState.atom); + const objectMetadataItems = store.get(objectMetadataItemsState.atom); const objectMetadataItem = objectMetadataItems.find( (objectMetadataItem) => objectMetadataItem.id === objectMetadataId, @@ -42,7 +43,7 @@ export const useRefreshCoreViewsByObjectMetadataId = () => { return; } - const coreViewsForObjectMetadataId = jotaiStore.get( + const coreViewsForObjectMetadataId = store.get( coreViewsByObjectMetadataIdFamilySelector.selectorFamily( objectMetadataId, ), @@ -54,7 +55,7 @@ export const useRefreshCoreViewsByObjectMetadataId = () => { return; } - jotaiStore.set( + store.set( coreViewsByObjectMetadataIdFamilySelector.selectorFamily( objectMetadataId, ), @@ -80,7 +81,7 @@ export const useRefreshCoreViewsByObjectMetadataId = () => { ) ) { const view = convertCoreViewToView(coreView); - jotaiStore.set( + store.set( currentRecordFieldsComponentState.atomFamily({ instanceId: getRecordIndexIdFromObjectNamePluralAndViewId( objectMetadataItem.namePlural, @@ -105,7 +106,7 @@ export const useRefreshCoreViewsByObjectMetadataId = () => { ) ) { const view = convertCoreViewToView(coreView); - jotaiStore.set( + store.set( currentRecordFiltersComponentState.atomFamily({ instanceId: getRecordIndexIdFromObjectNamePluralAndViewId( objectMetadataItem.namePlural, @@ -121,7 +122,7 @@ export const useRefreshCoreViewsByObjectMetadataId = () => { if (!isDeeplyEqual(coreView.viewSorts, existingView.viewSorts)) { const view = convertCoreViewToView(coreView); - jotaiStore.set( + store.set( currentRecordSortsComponentState.atomFamily({ instanceId: getRecordIndexIdFromObjectNamePluralAndViewId( objectMetadataItem.namePlural, @@ -136,7 +137,7 @@ export const useRefreshCoreViewsByObjectMetadataId = () => { coreView.shouldHideEmptyGroups !== existingView.shouldHideEmptyGroups ) { const view = convertCoreViewToView(coreView); - jotaiStore.set( + store.set( recordIndexShouldHideEmptyRecordGroupsComponentState.atomFamily({ instanceId: getRecordIndexIdFromObjectNamePluralAndViewId( objectMetadataItem.namePlural, @@ -148,7 +149,7 @@ export const useRefreshCoreViewsByObjectMetadataId = () => { } } }, - [findManyCoreViewsLazy], + [findManyCoreViewsLazy, store], ); return { diff --git a/packages/twenty-front/src/modules/views/hooks/useUpdateViewAggregate.ts b/packages/twenty-front/src/modules/views/hooks/useUpdateViewAggregate.ts index 8a7eae3224..730ecbde48 100644 --- a/packages/twenty-front/src/modules/views/hooks/useUpdateViewAggregate.ts +++ b/packages/twenty-front/src/modules/views/hooks/useUpdateViewAggregate.ts @@ -4,7 +4,6 @@ import { useLoadRecordIndexStates } from '@/object-record/record-index/hooks/use import { type ExtendedAggregateOperations } from '@/object-record/record-table/types/ExtendedAggregateOperations'; import { convertExtendedAggregateOperationToAggregateOperation } from '@/object-record/utils/convertExtendedAggregateOperationToAggregateOperation'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { usePerformViewAPIUpdate } from '@/views/hooks/internal/usePerformViewAPIUpdate'; import { useCanPersistViewChanges } from '@/views/hooks/useCanPersistViewChanges'; import { coreViewsState } from '@/views/states/coreViewState'; @@ -15,8 +14,10 @@ import { upsertIntoArrayOfObjectsComparingId, } from 'twenty-shared/utils'; import { type CoreView } from '~/generated-metadata/graphql'; +import { useStore } from 'jotai'; export const useUpdateViewAggregate = () => { + const store = useStore(); const { canPersistChanges } = useCanPersistViewChanges(); const currentViewId = useRecoilComponentValueV2( contextStoreCurrentViewIdComponentState, @@ -66,7 +67,7 @@ export const useUpdateViewAggregate = () => { return; } - jotaiStore.set(coreViewsState.atom, (currentCoreViews) => + store.set(coreViewsState.atom, (currentCoreViews) => upsertIntoArrayOfObjectsComparingId( currentCoreViews, updatedCoreView, @@ -83,6 +84,7 @@ export const useUpdateViewAggregate = () => { currentViewId, performViewAPIUpdate, loadRecordIndexStates, + store, ], ); diff --git a/packages/twenty-front/src/modules/views/optimistic-effects/hooks/useTriggerViewFieldGroupOptimisticEffect.ts b/packages/twenty-front/src/modules/views/optimistic-effects/hooks/useTriggerViewFieldGroupOptimisticEffect.ts index 38a327577c..37e5ff841e 100644 --- a/packages/twenty-front/src/modules/views/optimistic-effects/hooks/useTriggerViewFieldGroupOptimisticEffect.ts +++ b/packages/twenty-front/src/modules/views/optimistic-effects/hooks/useTriggerViewFieldGroupOptimisticEffect.ts @@ -1,4 +1,3 @@ -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { coreViewsState } from '@/views/states/coreViewState'; import { type CoreViewWithRelations } from '@/views/types/CoreViewWithRelations'; import { useApolloClient } from '@apollo/client'; @@ -6,6 +5,7 @@ import { useCallback } from 'react'; import { isDefined } from 'twenty-shared/utils'; import { type CoreViewFieldGroup } from '~/generated-metadata/graphql'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; +import { useStore } from 'jotai'; type ViewFieldGroupForOptimisticEffect = Omit< CoreViewFieldGroup, @@ -13,6 +13,7 @@ type ViewFieldGroupForOptimisticEffect = Omit< >; export const useTriggerViewFieldGroupOptimisticEffect = () => { + const store = useStore(); const apolloClient = useApolloClient(); const cache = apolloClient.cache; @@ -27,7 +28,7 @@ export const useTriggerViewFieldGroupOptimisticEffect = () => { updatedViewFieldGroups?: ViewFieldGroupForOptimisticEffect[]; deletedViewFieldGroups?: Pick[]; }) => { - const coreViews = jotaiStore.get(coreViewsState.atom); + const coreViews = store.get(coreViewsState.atom); let newCoreViews = [...coreViews]; createdViewFieldGroups.forEach((createdViewFieldGroup) => { @@ -147,10 +148,10 @@ export const useTriggerViewFieldGroupOptimisticEffect = () => { ); if (!isDeeplyEqual(coreViews, newCoreViews)) { - jotaiStore.set(coreViewsState.atom, newCoreViews); + store.set(coreViewsState.atom, newCoreViews); } }, - [cache], + [cache, store], ); return { diff --git a/packages/twenty-front/src/modules/views/optimistic-effects/hooks/useTriggerViewFieldOptimisticEffect.ts b/packages/twenty-front/src/modules/views/optimistic-effects/hooks/useTriggerViewFieldOptimisticEffect.ts index 867e52e7b2..d1ae8e1fad 100644 --- a/packages/twenty-front/src/modules/views/optimistic-effects/hooks/useTriggerViewFieldOptimisticEffect.ts +++ b/packages/twenty-front/src/modules/views/optimistic-effects/hooks/useTriggerViewFieldOptimisticEffect.ts @@ -1,4 +1,3 @@ -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { coreViewsState } from '@/views/states/coreViewState'; import { type CoreViewWithRelations } from '@/views/types/CoreViewWithRelations'; import { useApolloClient } from '@apollo/client'; @@ -6,8 +5,10 @@ import { useCallback } from 'react'; import { isDefined } from 'twenty-shared/utils'; import { type CoreViewField } from '~/generated-metadata/graphql'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; +import { useStore } from 'jotai'; export const useTriggerViewFieldOptimisticEffect = () => { + const store = useStore(); const apolloClient = useApolloClient(); const cache = apolloClient.cache; @@ -22,7 +23,7 @@ export const useTriggerViewFieldOptimisticEffect = () => { updatedViewFields?: Omit[]; deletedViewFields?: Pick[]; }) => { - const coreViews = jotaiStore.get(coreViewsState.atom); + const coreViews = store.get(coreViewsState.atom); let newCoreViews = [...coreViews]; createdViewFields.forEach((createdViewField) => { @@ -131,10 +132,10 @@ export const useTriggerViewFieldOptimisticEffect = () => { ); if (!isDeeplyEqual(coreViews, newCoreViews)) { - jotaiStore.set(coreViewsState.atom, newCoreViews); + store.set(coreViewsState.atom, newCoreViews); } }, - [cache], + [cache, store], ); return { diff --git a/packages/twenty-front/src/modules/views/optimistic-effects/hooks/useTriggerViewFilterOptimisticEffect.ts b/packages/twenty-front/src/modules/views/optimistic-effects/hooks/useTriggerViewFilterOptimisticEffect.ts index b4750e1b00..895fa44166 100644 --- a/packages/twenty-front/src/modules/views/optimistic-effects/hooks/useTriggerViewFilterOptimisticEffect.ts +++ b/packages/twenty-front/src/modules/views/optimistic-effects/hooks/useTriggerViewFilterOptimisticEffect.ts @@ -1,4 +1,3 @@ -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { coreViewsState } from '@/views/states/coreViewState'; import { type CoreViewWithRelations } from '@/views/types/CoreViewWithRelations'; import { useApolloClient } from '@apollo/client'; @@ -6,12 +5,14 @@ import { useCallback } from 'react'; import { isDefined } from 'twenty-shared/utils'; import { type CoreViewFilter } from '~/generated-metadata/graphql'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; +import { useStore } from 'jotai'; type UpdatedDeletedCoreViewFilter = { createdViewFilters?: Omit[]; updatedViewFilters?: Omit[]; deletedViewFilters?: Pick[]; }; export const useTriggerViewFilterOptimisticEffect = () => { + const store = useStore(); const apolloClient = useApolloClient(); const cache = apolloClient.cache; @@ -22,7 +23,7 @@ export const useTriggerViewFilterOptimisticEffect = () => { updatedViewFilters = [], deletedViewFilters = [], }: UpdatedDeletedCoreViewFilter) => { - const coreViews = jotaiStore.get(coreViewsState.atom); + const coreViews = store.get(coreViewsState.atom); let newCoreViews = [...coreViews]; createdViewFilters.forEach((createdViewFilter) => { @@ -131,10 +132,10 @@ export const useTriggerViewFilterOptimisticEffect = () => { ); if (!isDeeplyEqual(coreViews, newCoreViews)) { - jotaiStore.set(coreViewsState.atom, newCoreViews); + store.set(coreViewsState.atom, newCoreViews); } }, - [cache], + [cache, store], ); return { diff --git a/packages/twenty-front/src/modules/views/optimistic-effects/hooks/useTriggerViewGroupOptimisticEffect.ts b/packages/twenty-front/src/modules/views/optimistic-effects/hooks/useTriggerViewGroupOptimisticEffect.ts index bf24ffce2e..fa5c4989a4 100644 --- a/packages/twenty-front/src/modules/views/optimistic-effects/hooks/useTriggerViewGroupOptimisticEffect.ts +++ b/packages/twenty-front/src/modules/views/optimistic-effects/hooks/useTriggerViewGroupOptimisticEffect.ts @@ -1,4 +1,3 @@ -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { coreViewsState } from '@/views/states/coreViewState'; import { type CoreViewWithRelations } from '@/views/types/CoreViewWithRelations'; import { useApolloClient } from '@apollo/client'; @@ -6,6 +5,7 @@ import { useCallback } from 'react'; import { isDefined } from 'twenty-shared/utils'; import { type CoreViewGroup } from '~/generated-metadata/graphql'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; +import { useStore } from 'jotai'; type UpdatedDeletedCoreViewGroup = { createdViewGroups?: Omit[]; @@ -13,6 +13,7 @@ type UpdatedDeletedCoreViewGroup = { deletedViewGroups?: Pick[]; }; export const useTriggerViewGroupOptimisticEffect = () => { + const store = useStore(); const apolloClient = useApolloClient(); const cache = apolloClient.cache; @@ -23,7 +24,7 @@ export const useTriggerViewGroupOptimisticEffect = () => { updatedViewGroups = [], deletedViewGroups = [], }: UpdatedDeletedCoreViewGroup) => { - const coreViews = jotaiStore.get(coreViewsState.atom); + const coreViews = store.get(coreViewsState.atom); let newCoreViews = [...coreViews]; createdViewGroups.forEach((createdViewGroup) => { @@ -130,10 +131,10 @@ export const useTriggerViewGroupOptimisticEffect = () => { }); if (!isDeeplyEqual(coreViews, newCoreViews)) { - jotaiStore.set(coreViewsState.atom, newCoreViews); + store.set(coreViewsState.atom, newCoreViews); } }, - [cache], + [cache, store], ); return { diff --git a/packages/twenty-front/src/modules/views/optimistic-effects/hooks/useTriggerViewSortOptimisticEffect.ts b/packages/twenty-front/src/modules/views/optimistic-effects/hooks/useTriggerViewSortOptimisticEffect.ts index 13a8a12fb5..2662acd56c 100644 --- a/packages/twenty-front/src/modules/views/optimistic-effects/hooks/useTriggerViewSortOptimisticEffect.ts +++ b/packages/twenty-front/src/modules/views/optimistic-effects/hooks/useTriggerViewSortOptimisticEffect.ts @@ -1,4 +1,3 @@ -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { coreViewsState } from '@/views/states/coreViewState'; import { type CoreViewWithRelations } from '@/views/types/CoreViewWithRelations'; import { useApolloClient } from '@apollo/client'; @@ -6,8 +5,10 @@ import { useCallback } from 'react'; import { isDefined } from 'twenty-shared/utils'; import { type CoreViewSort } from '~/generated-metadata/graphql'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; +import { useStore } from 'jotai'; export const useTriggerViewSortOptimisticEffect = () => { + const store = useStore(); const apolloClient = useApolloClient(); const cache = apolloClient.cache; @@ -22,7 +23,7 @@ export const useTriggerViewSortOptimisticEffect = () => { updatedViewSorts?: Omit[]; deletedViewSorts?: Pick[]; }) => { - const coreViews = jotaiStore.get(coreViewsState.atom); + const coreViews = store.get(coreViewsState.atom); let newCoreViews = [...coreViews]; createdViewSorts.forEach((createdViewSort) => { @@ -128,10 +129,10 @@ export const useTriggerViewSortOptimisticEffect = () => { ); if (!isDeeplyEqual(coreViews, newCoreViews)) { - jotaiStore.set(coreViewsState.atom, newCoreViews); + store.set(coreViewsState.atom, newCoreViews); } }, - [cache], + [cache, store], ); return { diff --git a/packages/twenty-front/src/modules/workflow/hooks/__tests__/useGetUpdatableWorkflowVersion.test.ts b/packages/twenty-front/src/modules/workflow/hooks/__tests__/useGetUpdatableWorkflowVersion.test.ts index 92c93f2ae9..e40af536e3 100644 --- a/packages/twenty-front/src/modules/workflow/hooks/__tests__/useGetUpdatableWorkflowVersion.test.ts +++ b/packages/twenty-front/src/modules/workflow/hooks/__tests__/useGetUpdatableWorkflowVersion.test.ts @@ -18,12 +18,9 @@ jest.mock('@/workflow/hooks/useCreateDraftFromWorkflowVersion', () => ({ }), })); -jest.mock( - '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue', - () => ({ - useRecoilComponentValue: jest.fn(() => mockWorkflowId), - }), -); +jest.mock('@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2', () => ({ + useRecoilComponentValueV2: jest.fn(() => mockWorkflowId), +})); jest.mock('@/workflow/hooks/useWorkflowWithCurrentVersion', () => ({ useWorkflowWithCurrentVersion: jest.fn((workflowId) => diff --git a/packages/twenty-front/src/modules/workflow/hooks/useRunWorkflowRunOpeningInCommandMenuSideEffects.ts b/packages/twenty-front/src/modules/workflow/hooks/useRunWorkflowRunOpeningInCommandMenuSideEffects.ts index 27d58fbaa5..ad86323673 100644 --- a/packages/twenty-front/src/modules/workflow/hooks/useRunWorkflowRunOpeningInCommandMenuSideEffects.ts +++ b/packages/twenty-front/src/modules/workflow/hooks/useRunWorkflowRunOpeningInCommandMenuSideEffects.ts @@ -4,7 +4,6 @@ import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadat import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { getRecordFromCache } from '@/object-record/cache/utils/getRecordFromCache'; import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { flowComponentState } from '@/workflow/states/flowComponentState'; import { workflowVisualizerWorkflowIdComponentState } from '@/workflow/states/workflowVisualizerWorkflowIdComponentState'; import { workflowVisualizerWorkflowRunIdComponentState } from '@/workflow/states/workflowVisualizerWorkflowRunIdComponentState'; @@ -17,8 +16,10 @@ import { getWorkflowNodeIconKey } from '@/workflow/workflow-diagram/utils/getWor import { useCallback } from 'react'; import { isDefined } from 'twenty-shared/utils'; import { useIcons } from 'twenty-ui/display'; +import { useStore } from 'jotai'; export const useRunWorkflowRunOpeningInCommandMenuSideEffects = () => { + const store = useStore(); const apolloCoreClient = useApolloCoreClient(); const { openWorkflowRunViewStepInCommandMenu } = useWorkflowCommandMenu(); const { getIcon } = useIcons(); @@ -33,7 +34,7 @@ export const useRunWorkflowRunOpeningInCommandMenuSideEffects = () => { objectMetadataItem: ObjectMetadataItem; recordId: string; }) => { - const objectMetadataItems = jotaiStore.get(objectMetadataItemsState.atom); + const objectMetadataItems = store.get(objectMetadataItemsState.atom); const workflowRunRecord = getRecordFromCache({ objectMetadataItem, @@ -62,19 +63,19 @@ export const useRunWorkflowRunOpeningInCommandMenuSideEffects = () => { recordId, }); - jotaiStore.set( + store.set( workflowVisualizerWorkflowRunIdComponentState.atomFamily({ instanceId, }), workflowRunRecord.id, ); - jotaiStore.set( + store.set( workflowVisualizerWorkflowIdComponentState.atomFamily({ instanceId, }), workflowRunRecord.workflowId, ); - jotaiStore.set( + store.set( flowComponentState.atomFamily({ instanceId, }), @@ -84,14 +85,14 @@ export const useRunWorkflowRunOpeningInCommandMenuSideEffects = () => { steps: workflowRunRecord.state.flow.steps, }, ); - jotaiStore.set( + store.set( workflowSelectedNodeComponentState.atomFamily({ instanceId, }), stepToOpenByDefault.id, ); - jotaiStore.set( + store.set( workflowRunDiagramAutomaticallyOpenedStepsComponentState.atomFamily({ instanceId, }), @@ -117,6 +118,7 @@ export const useRunWorkflowRunOpeningInCommandMenuSideEffects = () => { objectPermissionsByObjectMetadataId, openWorkflowRunViewStepInCommandMenu, getIcon, + store, ], ); diff --git a/packages/twenty-front/src/modules/workflow/hooks/useRunWorkflowVersion.tsx b/packages/twenty-front/src/modules/workflow/hooks/useRunWorkflowVersion.tsx index 9da8c4186f..7b18a8ed35 100644 --- a/packages/twenty-front/src/modules/workflow/hooks/useRunWorkflowVersion.tsx +++ b/packages/twenty-front/src/modules/workflow/hooks/useRunWorkflowVersion.tsx @@ -13,7 +13,6 @@ import { useGenerateDepthRecordGqlFieldsFromObject } from '@/object-record/graph import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions'; import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { computeOptimisticCreateRecordBaseRecordInput } from '@/object-record/utils/computeOptimisticCreateRecordBaseRecordInput'; import { computeOptimisticRecordFromInput } from '@/object-record/utils/computeOptimisticRecordFromInput'; import { RUN_WORKFLOW_VERSION } from '@/workflow/graphql/mutations/runWorkflowVersion'; @@ -27,8 +26,10 @@ import { type RunWorkflowVersionMutation, type RunWorkflowVersionMutationVariables, } from '~/generated/graphql'; +import { useStore } from 'jotai'; export const useRunWorkflowVersion = () => { + const store = useStore(); const apolloCoreClient = useApolloCoreClient(); const { upsertRecordsInStore } = useUpsertRecordsInStore(); @@ -63,12 +64,12 @@ export const useRunWorkflowVersion = () => { const { openRecordInCommandMenu } = useOpenRecordInCommandMenu(); - const setRecordInStore = useCallback((workflowRun: WorkflowRun) => { - jotaiStore.set( - recordStoreFamilyState.atomFamily(workflowRun.id), - workflowRun, - ); - }, []); + const setRecordInStore = useCallback( + (workflowRun: WorkflowRun) => { + store.set(recordStoreFamilyState.atomFamily(workflowRun.id), workflowRun); + }, + [store], + ); const runWorkflowVersion = async ({ workflowId, diff --git a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramCanvasBase.tsx b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramCanvasBase.tsx index 359f7f4509..361acb3076 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramCanvasBase.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramCanvasBase.tsx @@ -1,7 +1,6 @@ import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext'; import { commandMenuWidthState } from '@/command-menu/states/commandMenuWidthState'; import { isCommandMenuOpenedStateV2 } from '@/command-menu/states/isCommandMenuOpenedStateV2'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useListenToSidePanelClosing } from '@/ui/layout/right-drawer/hooks/useListenToSidePanelClosing'; import { useRecoilComponentStateCallbackStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateCallbackStateV2'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2'; @@ -64,6 +63,7 @@ import React, { import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { isDefined } from 'twenty-shared/utils'; import { Tag, type TagColor } from 'twenty-ui/components'; +import { useStore } from 'jotai'; const StyledResetReactflowStyles = styled.div` height: 100%; @@ -165,17 +165,18 @@ export const WorkflowDiagramCanvasBase = ({ event: MouseEvent | React.MouseEvent; }) => void; }) => { + const store = useStore(); const theme = useTheme(); const reactflow = useReactFlow(); - const workflowDiagram = useRecoilComponentValueV2( + const currentWorkflowDiagram = useRecoilComponentValueV2( workflowDiagramComponentState, ); const workflowDiagramPanOnDrag = useRecoilComponentValueV2( workflowDiagramPanOnDragComponentState, ); - const workflowDiagramAtom = useRecoilComponentStateCallbackStateV2( + const workflowDiagram = useRecoilComponentStateCallbackStateV2( workflowDiagramComponentState, ); const setWorkflowDiagram = useSetRecoilComponentStateV2( @@ -185,7 +186,7 @@ export const WorkflowDiagramCanvasBase = ({ workflowSelectedNodeComponentState, ); const { resetWorkflowInsertStepIds } = useResetWorkflowInsertStepIds(); - const workflowDiagramWaitingNodesDimensionsAtom = + const workflowDiagramWaitingNodesDimensions = useRecoilComponentStateCallbackStateV2( workflowDiagramWaitingNodesDimensionsComponentState, ); @@ -212,12 +213,12 @@ export const WorkflowDiagramCanvasBase = ({ } | null>(null); const { nodes, edges } = useMemo(() => { - if (!isDefined(workflowDiagram)) { + if (!isDefined(currentWorkflowDiagram)) { return { nodes: [], edges: [] }; } - const nodes = [...workflowDiagram.nodes]; - const edges = [...workflowDiagram.edges]; + const nodes = [...currentWorkflowDiagram.nodes]; + const edges = [...currentWorkflowDiagram.edges]; if ( isDefined(workflowInsertStepIds.position) && @@ -254,7 +255,7 @@ export const WorkflowDiagramCanvasBase = ({ } return { nodes, edges }; - }, [workflowDiagram, workflowInsertStepIds]); + }, [currentWorkflowDiagram, workflowInsertStepIds]); const isCommandMenuOpened = useRecoilValueV2(isCommandMenuOpenedStateV2); const { isInRightDrawer } = useContext(ActionMenuContext); @@ -318,7 +319,7 @@ export const WorkflowDiagramCanvasBase = ({ let adjustedContainerWidth = baseContainerWidth; - const commandMenuWidth = jotaiStore.get(commandMenuWidthState.atom); + const commandMenuWidth = store.get(commandMenuWidthState.atom); if (!isInRightDrawer && isCommandMenuOpened) { adjustedContainerWidth = baseContainerWidth - commandMenuWidth; @@ -339,7 +340,7 @@ export const WorkflowDiagramCanvasBase = ({ { duration: hasViewportBeenMoved ? 300 : 0 }, ); }, - [reactflow, setWorkflowDiagramWaitingNodesDimensions], + [reactflow, setWorkflowDiagramWaitingNodesDimensions, store], ); const handleSetFlowViewportOnChange = useCallback( @@ -356,10 +357,10 @@ export const WorkflowDiagramCanvasBase = ({ isInRightDrawer, isCommandMenuOpened, workflowDiagramFlowInitialized, - workflowDiagram: jotaiStore.get(workflowDiagramAtom), + workflowDiagram: store.get(workflowDiagram), }); }, - [setFlowViewport, workflowDiagramAtom], + [setFlowViewport, workflowDiagram, store], ); useEffect(() => { @@ -377,7 +378,7 @@ export const WorkflowDiagramCanvasBase = ({ const handleNodesChanges = useCallback( (changes: NodeChange[]) => { - const workflowDiagram = jotaiStore.get(workflowDiagramAtom); + const existingWorkflowDiagram = store.get(workflowDiagram); const filteredChanges = changes.filter( (change) => @@ -387,20 +388,23 @@ export const WorkflowDiagramCanvasBase = ({ ), ); - let updatedWorkflowDiagram = workflowDiagram; - if (isDefined(workflowDiagram) && filteredChanges.length > 0) { + let updatedWorkflowDiagram = existingWorkflowDiagram; + if (isDefined(existingWorkflowDiagram) && filteredChanges.length > 0) { updatedWorkflowDiagram = { - ...workflowDiagram, - nodes: applyNodeChanges(filteredChanges, workflowDiagram.nodes), + ...existingWorkflowDiagram, + nodes: applyNodeChanges( + filteredChanges, + existingWorkflowDiagram.nodes, + ), }; } - jotaiStore.set(workflowDiagramAtom, updatedWorkflowDiagram); + store.set(workflowDiagram, updatedWorkflowDiagram); - const workflowDiagramWaitingNodesDimensions = jotaiStore.get( - workflowDiagramWaitingNodesDimensionsAtom, + const currentWorkflowDiagramWaitingNodesDimensions = store.get( + workflowDiagramWaitingNodesDimensions, ); - if (!workflowDiagramWaitingNodesDimensions) { + if (!currentWorkflowDiagramWaitingNodesDimensions) { return; } @@ -415,9 +419,10 @@ export const WorkflowDiagramCanvasBase = ({ isCommandMenuOpened, setFlowViewport, workflowDiagramFlowInitialized, - workflowDiagramAtom, - workflowDiagramWaitingNodesDimensionsAtom, + workflowDiagram, + workflowDiagramWaitingNodesDimensions, isInRightDrawer, + store, ], ); diff --git a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramEffect.tsx b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramEffect.tsx index 4e29214ea2..e1ce38f7a7 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramEffect.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramEffect.tsx @@ -24,13 +24,13 @@ export const WorkflowDiagramEffect = () => { workflowVisualizerWorkflowId, ); - const workflowDiagramAtom = useRecoilComponentStateCallbackStateV2( + const workflowDiagram = useRecoilComponentStateCallbackStateV2( workflowDiagramComponentState, ); const setFlow = useSetRecoilComponentStateV2(flowComponentState); const { populateStepsOutputSchema } = useStepsOutputSchema(); - const workflowLastCreatedStepIdAtom = useRecoilComponentStateCallbackStateV2( + const workflowLastCreatedStepId = useRecoilComponentStateCallbackStateV2( workflowLastCreatedStepIdComponentState, ); @@ -39,7 +39,7 @@ export const WorkflowDiagramEffect = () => { const computeAndMergeNewWorkflowDiagram = useCallback( (version: WorkflowVersion) => { - const previousWorkflowDiagram = store.get(workflowDiagramAtom); + const previousWorkflowDiagram = store.get(workflowDiagram); const nextWorkflowDiagram = getWorkflowVersionDiagram({ workflowVersion: version, @@ -55,7 +55,7 @@ export const WorkflowDiagramEffect = () => { ); } - const lastCreatedStepId = store.get(workflowLastCreatedStepIdAtom); + const lastCreatedStepId = store.get(workflowLastCreatedStepId); if (isDefined(lastCreatedStepId)) { mergedWorkflowDiagram.nodes = mergedWorkflowDiagram.nodes.map( @@ -67,12 +67,12 @@ export const WorkflowDiagramEffect = () => { }, ); - store.set(workflowLastCreatedStepIdAtom, undefined); + store.set(workflowLastCreatedStepId, undefined); } - store.set(workflowDiagramAtom, mergedWorkflowDiagram); + store.set(workflowDiagram, mergedWorkflowDiagram); }, - [workflowDiagramAtom, workflowLastCreatedStepIdAtom, store], + [workflowDiagram, workflowLastCreatedStepId, store], ); useEffect(() => { diff --git a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowRunVisualizerEffect.tsx b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowRunVisualizerEffect.tsx index 2d7869abbb..ce5a2722c7 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowRunVisualizerEffect.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowRunVisualizerEffect.tsx @@ -40,19 +40,18 @@ export const WorkflowRunVisualizerEffect = ({ workflowVisualizerWorkflowVersionIdComponentState, ); - const workflowVisualizerWorkflowIdAtom = - useRecoilComponentStateCallbackStateV2( - workflowVisualizerWorkflowIdComponentState, - ); + const workflowVisualizerWorkflowId = useRecoilComponentStateCallbackStateV2( + workflowVisualizerWorkflowIdComponentState, + ); const setWorkflowVisualizerWorkflowId = useSetRecoilComponentStateV2( workflowVisualizerWorkflowIdComponentState, ); - const flowAtom = useRecoilComponentStateCallbackStateV2(flowComponentState); - const workflowDiagramAtom = useRecoilComponentStateCallbackStateV2( + const flow = useRecoilComponentStateCallbackStateV2(flowComponentState); + const workflowDiagram = useRecoilComponentStateCallbackStateV2( workflowDiagramComponentState, ); - const workflowSelectedNodeAtom = useRecoilComponentStateCallbackStateV2( + const workflowSelectedNode = useRecoilComponentStateCallbackStateV2( workflowSelectedNodeComponentState, ); @@ -103,8 +102,8 @@ export const WorkflowRunVisualizerEffect = ({ isInRightDrawer: boolean; }) => { if (!(isDefined(workflowRunState) && isDefined(versionId))) { - store.set(flowAtom, undefined); - store.set(workflowDiagramAtom, undefined); + store.set(flow, undefined); + store.set(workflowDiagram, undefined); return; } @@ -115,7 +114,7 @@ export const WorkflowRunVisualizerEffect = ({ store.set(workflowDiagramStatusState, 'computing-diagram'); } - store.set(flowAtom, { + store.set(flow, { workflowVersionId: versionId, trigger: workflowRunState.flow.trigger, steps: workflowRunState.flow.steps, @@ -133,7 +132,7 @@ export const WorkflowRunVisualizerEffect = ({ } if (!isDefined(stepToOpenByDefault)) { - store.set(workflowDiagramAtom, baseWorkflowRunDiagram); + store.set(workflowDiagram, baseWorkflowRunDiagram); return; } @@ -148,31 +147,31 @@ export const WorkflowRunVisualizerEffect = ({ step.isInRightDrawer === inRightDrawer, ); - const workflowVisualizerWorkflowId = store.get( - workflowVisualizerWorkflowIdAtom, + const currentWorkflowVisualizerWorkflowId = store.get( + workflowVisualizerWorkflowId, ); - if (!isDefined(workflowVisualizerWorkflowId)) { + if (!isDefined(currentWorkflowVisualizerWorkflowId)) { throw new Error( 'The workflow id must be set; ensure the workflow id is always set before rendering the workflow diagram.', ); } if (inRightDrawer) { - store.set(workflowDiagramAtom, baseWorkflowRunDiagram); + store.set(workflowDiagram, baseWorkflowRunDiagram); } else { const workflowRunDiagram = selectWorkflowDiagramNode({ diagram: baseWorkflowRunDiagram, nodeIdToSelect: stepToOpenByDefault.id, }); - store.set(workflowDiagramAtom, workflowRunDiagram); + store.set(workflowDiagram, workflowRunDiagram); } if (hasStepAlreadyBeenOpenedAutomatically) { return; } - store.set(workflowSelectedNodeAtom, stepToOpenByDefault.id); + store.set(workflowSelectedNode, stepToOpenByDefault.id); store.set(workflowRunDiagramAutomaticallyOpenedStepsState, [ ...workflowRunDiagramAutomaticallyOpenedSteps, @@ -183,7 +182,7 @@ export const WorkflowRunVisualizerEffect = ({ ]); openWorkflowRunViewStepInCommandMenu({ - workflowId: workflowVisualizerWorkflowId, + workflowId: currentWorkflowVisualizerWorkflowId, workflowRunId, title: stepToOpenByDefault.data.name, icon: getIcon(getWorkflowNodeIconKey(stepToOpenByDefault.data)), @@ -192,15 +191,15 @@ export const WorkflowRunVisualizerEffect = ({ }); }, [ - flowAtom, + flow, getIcon, openWorkflowRunViewStepInCommandMenu, - workflowDiagramAtom, + workflowDiagram, workflowDiagramStatusState, workflowRunDiagramAutomaticallyOpenedStepsState, workflowRunId, - workflowSelectedNodeAtom, - workflowVisualizerWorkflowIdAtom, + workflowSelectedNode, + workflowVisualizerWorkflowId, store, ], ); diff --git a/packages/twenty-front/src/modules/workflow/workflow-diagram/hooks/useSetInitialWorkflowRunRightDrawerTab.ts b/packages/twenty-front/src/modules/workflow/workflow-diagram/hooks/useSetInitialWorkflowRunRightDrawerTab.ts index 7b350687fb..7511299e32 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-diagram/hooks/useSetInitialWorkflowRunRightDrawerTab.ts +++ b/packages/twenty-front/src/modules/workflow/workflow-diagram/hooks/useSetInitialWorkflowRunRightDrawerTab.ts @@ -2,13 +2,14 @@ import { getIsInputTabDisabled } from '@/command-menu/pages/workflow/step/view-r import { getIsOutputTabDisabled } from '@/command-menu/pages/workflow/step/view-run/utils/getIsOutputTabDisabled'; import { commandMenuPageInfoState } from '@/command-menu/states/commandMenuPageInfoState'; import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState'; -import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { WorkflowRunTabId } from '@/workflow/workflow-steps/types/WorkflowRunTabId'; import { useCallback } from 'react'; import { isDefined } from 'twenty-shared/utils'; import { type WorkflowRunStepStatus } from '@/workflow/types/Workflow'; +import { useStore } from 'jotai'; export const useSetInitialWorkflowRunRightDrawerTab = () => { + const store = useStore(); const setInitialWorkflowRunRightDrawerTab = useCallback( ({ workflowSelectedNode, @@ -17,14 +18,14 @@ export const useSetInitialWorkflowRunRightDrawerTab = () => { workflowSelectedNode: string; stepExecutionStatus: WorkflowRunStepStatus; }) => { - const commandMenuPageInfo = jotaiStore.get(commandMenuPageInfoState.atom); + const commandMenuPageInfo = store.get(commandMenuPageInfoState.atom); - const activeTabIdAtom = activeTabIdComponentState.atomFamily({ + const activeTabId = activeTabIdComponentState.atomFamily({ instanceId: commandMenuPageInfo.instanceId, }); - const activeWorkflowRunRightDrawerTab = jotaiStore.get( - activeTabIdAtom, + const activeWorkflowRunRightDrawerTab = store.get( + activeTabId, ) as WorkflowRunTabId | null; const isInputTabDisabled = getIsInputTabDisabled({ @@ -40,7 +41,7 @@ export const useSetInitialWorkflowRunRightDrawerTab = () => { ? WorkflowRunTabId.NODE : WorkflowRunTabId.OUTPUT; - jotaiStore.set(activeTabIdAtom, defaultTabId); + store.set(activeTabId, defaultTabId); return; } @@ -51,10 +52,10 @@ export const useSetInitialWorkflowRunRightDrawerTab = () => { (isOutputTabDisabled && activeWorkflowRunRightDrawerTab === WorkflowRunTabId.OUTPUT) ) { - jotaiStore.set(activeTabIdAtom, WorkflowRunTabId.NODE); + store.set(activeTabId, WorkflowRunTabId.NODE); } }, - [], + [store], ); return { diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/filters/hooks/useAddRootStepFilter.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/filters/hooks/useAddRootStepFilter.ts index 9f34fb3a7e..edae5bb58b 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/filters/hooks/useAddRootStepFilter.ts +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/filters/hooks/useAddRootStepFilter.ts @@ -19,11 +19,11 @@ export const useAddRootStepFilter = () => { const { stepId, onFilterSettingsUpdate } = useContext( WorkflowStepFilterContext, ); - const currentStepFilterGroupsAtom = useRecoilComponentStateCallbackStateV2( + const currentStepFilterGroups = useRecoilComponentStateCallbackStateV2( currentStepFilterGroupsComponentState, ); - const currentStepFiltersAtom = useRecoilComponentStateCallbackStateV2( + const currentStepFilters = useRecoilComponentStateCallbackStateV2( currentStepFiltersComponentState, ); @@ -57,8 +57,8 @@ export const useAddRootStepFilter = () => { positionInStepFilterGroup: 0, }; - store.set(currentStepFilterGroupsAtom, [newStepFilterGroup]); - store.set(currentStepFiltersAtom, [newStepFilter]); + store.set(currentStepFilterGroups, [newStepFilterGroup]); + store.set(currentStepFilters, [newStepFilter]); setHasInitializedCurrentStepFilters(true); setHasInitializedCurrentStepFilterGroups(true); @@ -69,8 +69,8 @@ export const useAddRootStepFilter = () => { }); }, [ onFilterSettingsUpdate, - currentStepFilterGroupsAtom, - currentStepFiltersAtom, + currentStepFilterGroups, + currentStepFilters, setHasInitializedCurrentStepFilters, setHasInitializedCurrentStepFilterGroups, store, diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/filters/hooks/useRemoveStepFilter.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/filters/hooks/useRemoveStepFilter.ts index 5940afe300..318aa56382 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/filters/hooks/useRemoveStepFilter.ts +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/filters/hooks/useRemoveStepFilter.ts @@ -9,11 +9,11 @@ import { WorkflowStepFilterContext } from '@/workflow/workflow-steps/filters/sta export const useRemoveStepFilter = () => { const { onFilterSettingsUpdate } = useContext(WorkflowStepFilterContext); - const currentStepFiltersAtom = useRecoilComponentStateCallbackStateV2( + const currentStepFilters = useRecoilComponentStateCallbackStateV2( currentStepFiltersComponentState, ); - const currentStepFilterGroupsAtom = useRecoilComponentStateCallbackStateV2( + const currentStepFilterGroups = useRecoilComponentStateCallbackStateV2( currentStepFilterGroupsComponentState, ); @@ -21,8 +21,8 @@ export const useRemoveStepFilter = () => { const removeStepFilter = useCallback( (stepFilterId: string) => { - const stepFilters = store.get(currentStepFiltersAtom); - const stepFilterGroups = store.get(currentStepFilterGroupsAtom); + const stepFilters = store.get(currentStepFilters); + const stepFilterGroups = store.get(currentStepFilterGroups); const rootStepFilterGroup = stepFilterGroups.find( (filterGroup) => !isDefined(filterGroup.parentStepFilterGroupId), @@ -69,16 +69,16 @@ export const useRemoveStepFilter = () => { updatedStepFilters.length === 0; if (shouldResetStepFilterSettings) { - store.set(currentStepFilterGroupsAtom, []); - store.set(currentStepFiltersAtom, []); + store.set(currentStepFilterGroups, []); + store.set(currentStepFilters, []); onFilterSettingsUpdate({ stepFilterGroups: [], stepFilters: [], }); } else { - store.set(currentStepFilterGroupsAtom, updatedStepFilterGroups); - store.set(currentStepFiltersAtom, updatedStepFilters); + store.set(currentStepFilterGroups, updatedStepFilterGroups); + store.set(currentStepFilters, updatedStepFilters); onFilterSettingsUpdate({ stepFilters: updatedStepFilters, @@ -88,8 +88,8 @@ export const useRemoveStepFilter = () => { }, [ onFilterSettingsUpdate, - currentStepFilterGroupsAtom, - currentStepFiltersAtom, + currentStepFilterGroups, + currentStepFilters, store, ], ); diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/filters/hooks/useRemoveStepFilterGroup.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/filters/hooks/useRemoveStepFilterGroup.ts index 4f46831d79..81f81edf72 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/filters/hooks/useRemoveStepFilterGroup.ts +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/filters/hooks/useRemoveStepFilterGroup.ts @@ -9,11 +9,11 @@ import { isDefined } from 'twenty-shared/utils'; export const useRemoveStepFilterGroup = () => { const { onFilterSettingsUpdate } = useContext(WorkflowStepFilterContext); - const currentStepFilterGroupsAtom = useRecoilComponentStateCallbackStateV2( + const currentStepFilterGroups = useRecoilComponentStateCallbackStateV2( currentStepFilterGroupsComponentState, ); - const currentStepFiltersAtom = useRecoilComponentStateCallbackStateV2( + const currentStepFilters = useRecoilComponentStateCallbackStateV2( currentStepFiltersComponentState, ); @@ -21,8 +21,8 @@ export const useRemoveStepFilterGroup = () => { const removeStepFilterGroup = useCallback( (stepFilterGroupId: string) => { - const stepFilterGroups = store.get(currentStepFilterGroupsAtom); - const stepFilters = store.get(currentStepFiltersAtom); + const stepFilterGroups = store.get(currentStepFilterGroups); + const stepFilters = store.get(currentStepFilters); const rootStepFilterGroup = stepFilterGroups.find( (filterGroup) => !isDefined(filterGroup.parentStepFilterGroupId), @@ -42,16 +42,16 @@ export const useRemoveStepFilterGroup = () => { updatedStepFilters.length === 0; if (shouldResetStepFilterSettings) { - store.set(currentStepFilterGroupsAtom, []); - store.set(currentStepFiltersAtom, []); + store.set(currentStepFilterGroups, []); + store.set(currentStepFilters, []); onFilterSettingsUpdate({ stepFilterGroups: [], stepFilters: [], }); } else { - store.set(currentStepFilterGroupsAtom, updatedStepFilterGroups); - store.set(currentStepFiltersAtom, updatedStepFilters); + store.set(currentStepFilterGroups, updatedStepFilterGroups); + store.set(currentStepFilters, updatedStepFilters); onFilterSettingsUpdate({ stepFilterGroups: updatedStepFilterGroups, @@ -61,8 +61,8 @@ export const useRemoveStepFilterGroup = () => { }, [ onFilterSettingsUpdate, - currentStepFilterGroupsAtom, - currentStepFiltersAtom, + currentStepFilterGroups, + currentStepFilters, store, ], ); diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/filters/hooks/useUpsertStepFilterSettings.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/filters/hooks/useUpsertStepFilterSettings.ts index 36e54ec861..c320298341 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/filters/hooks/useUpsertStepFilterSettings.ts +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/filters/hooks/useUpsertStepFilterSettings.ts @@ -8,11 +8,11 @@ import { type StepFilter, type StepFilterGroup } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; export const useUpsertStepFilterSettings = () => { - const currentStepFilterGroupsAtom = useRecoilComponentStateCallbackStateV2( + const currentStepFilterGroups = useRecoilComponentStateCallbackStateV2( currentStepFilterGroupsComponentState, ); - const currentStepFiltersAtom = useRecoilComponentStateCallbackStateV2( + const currentStepFilters = useRecoilComponentStateCallbackStateV2( currentStepFiltersComponentState, ); const { onFilterSettingsUpdate } = useContext(WorkflowStepFilterContext); @@ -27,8 +27,8 @@ export const useUpsertStepFilterSettings = () => { stepFilterGroupToUpsert?: StepFilterGroup; stepFilterToUpsert?: StepFilter; }) => { - const stepFilterGroups = store.get(currentStepFilterGroupsAtom); - const stepFilters = store.get(currentStepFiltersAtom); + const stepFilterGroups = store.get(currentStepFilterGroups); + const stepFilters = store.get(currentStepFilters); const updatedStepFilterGroups = [...stepFilterGroups]; const updatedStepFilters = [...stepFilters]; @@ -43,7 +43,7 @@ export const useUpsertStepFilterSettings = () => { } else { updatedStepFilterGroups.push(stepFilterGroupToUpsert); } - store.set(currentStepFilterGroupsAtom, updatedStepFilterGroups); + store.set(currentStepFilterGroups, updatedStepFilterGroups); } if (isDefined(stepFilterToUpsert)) { @@ -56,7 +56,7 @@ export const useUpsertStepFilterSettings = () => { } else { updatedStepFilters.push(stepFilterToUpsert); } - store.set(currentStepFiltersAtom, updatedStepFilters); + store.set(currentStepFilters, updatedStepFilters); } onFilterSettingsUpdate({ @@ -66,8 +66,8 @@ export const useUpsertStepFilterSettings = () => { }, [ onFilterSettingsUpdate, - currentStepFilterGroupsAtom, - currentStepFiltersAtom, + currentStepFilterGroups, + currentStepFilters, store, ], ); diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowFindRecordsFilters.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowFindRecordsFilters.tsx index 786c798f1e..a2de48a135 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowFindRecordsFilters.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowFindRecordsFilters.tsx @@ -20,33 +20,28 @@ export const WorkflowFindRecordsFilters = ({ onChange: (filter: FindRecordsActionFilter) => void; readonly?: boolean; }) => { - const currentRecordFilterGroupsAtom = useRecoilComponentStateCallbackStateV2( + const currentRecordFilterGroups = useRecoilComponentStateCallbackStateV2( currentRecordFilterGroupsComponentState, ); - const currentRecordFiltersAtom = useRecoilComponentStateCallbackStateV2( + const currentRecordFilters = useRecoilComponentStateCallbackStateV2( currentRecordFiltersComponentState, ); const store = useStore(); const onUpdate = useCallback(() => { - const currentRecordFilterGroups = store.get(currentRecordFilterGroupsAtom); + const existingRecordFilterGroups = store.get(currentRecordFilterGroups); - const currentRecordFilters = store.get(currentRecordFiltersAtom); + const existingRecordFilters = store.get(currentRecordFilters); const newFilter = { - recordFilterGroups: currentRecordFilterGroups, - recordFilters: currentRecordFilters, + recordFilterGroups: existingRecordFilterGroups, + recordFilters: existingRecordFilters, } satisfies FindRecordsActionFilter; onChange(newFilter); - }, [ - currentRecordFilterGroupsAtom, - currentRecordFiltersAtom, - onChange, - store, - ]); + }, [currentRecordFilterGroups, currentRecordFilters, onChange, store]); return ( { const { timeZone, dateFormat, timeFormat } = useDateTimeFormat(); - const dateLocale = useRecoilValueV2(dateLocaleStateV2); + const dateLocale = useRecoilValueV2(dateLocaleState); if (!isVisible) { return null; diff --git a/packages/twenty-front/src/modules/workflow/workflow-trigger/components/WorkflowEditTriggerCronForm.tsx b/packages/twenty-front/src/modules/workflow/workflow-trigger/components/WorkflowEditTriggerCronForm.tsx index 822d8842e9..977a53c4d6 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-trigger/components/WorkflowEditTriggerCronForm.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-trigger/components/WorkflowEditTriggerCronForm.tsx @@ -17,7 +17,7 @@ import { isNumber } from '@sniptt/guards'; import { useState } from 'react'; import { isDefined } from 'twenty-shared/utils'; import { TRIGGER_STEP_ID } from 'twenty-shared/workflow'; -import { dateLocaleStateV2 } from '~/localization/states/dateLocaleStateV2'; +import { dateLocaleState } from '~/localization/states/dateLocaleState'; type WorkflowEditTriggerCronFormProps = { trigger: WorkflowCronTrigger; @@ -48,7 +48,7 @@ export const WorkflowEditTriggerCronForm = ({ }: WorkflowEditTriggerCronFormProps) => { const [errorMessages, setErrorMessages] = useState({}); const [errorMessagesVisible, setErrorMessagesVisible] = useState(false); - const dateLocale = useRecoilValueV2(dateLocaleStateV2); + const dateLocale = useRecoilValueV2(dateLocaleState); const customDescription = getTriggerScheduleDescription( trigger, diff --git a/packages/twenty-front/src/pages/settings/emailing-domains/SettingsEmailingDomains.tsx b/packages/twenty-front/src/pages/settings/emailing-domains/SettingsEmailingDomains.tsx index 255336c49c..174a2df0cd 100644 --- a/packages/twenty-front/src/pages/settings/emailing-domains/SettingsEmailingDomains.tsx +++ b/packages/twenty-front/src/pages/settings/emailing-domains/SettingsEmailingDomains.tsx @@ -12,7 +12,7 @@ import { SettingsPath } from 'twenty-shared/types'; import { getSettingsPath } from 'twenty-shared/utils'; import { IconMail, Status } from 'twenty-ui/display'; import { useGetEmailingDomainsQuery } from '~/generated-metadata/graphql'; -import { dateLocaleStateV2 } from '~/localization/states/dateLocaleStateV2'; +import { dateLocaleState } from '~/localization/states/dateLocaleState'; import { getColorByEmailingDomainStatus } from '~/pages/settings/emailing-domains/utils/getEmailingDomainStatusColor'; import { getTextByEmailingDomainStatus } from '~/pages/settings/emailing-domains/utils/getEmailingDomainStatusText'; import { beautifyPastDateRelativeToNow } from '~/utils/date-utils'; @@ -23,7 +23,7 @@ const StyledLink = styled(Link)` export const SettingsEmailingDomains = () => { const { t } = useLingui(); - const { localeCatalog } = useRecoilValueV2(dateLocaleStateV2); + const { localeCatalog } = useRecoilValueV2(dateLocaleState); const navigate = useNavigate(); const { data, loading: isLoading } = useGetEmailingDomainsQuery(); diff --git a/packages/twenty-front/src/pages/settings/profile/appearance/components/LocalePicker.tsx b/packages/twenty-front/src/pages/settings/profile/appearance/components/LocalePicker.tsx index 2d75d98312..8dfbd75c8d 100644 --- a/packages/twenty-front/src/pages/settings/profile/appearance/components/LocalePicker.tsx +++ b/packages/twenty-front/src/pages/settings/profile/appearance/components/LocalePicker.tsx @@ -14,7 +14,7 @@ import { useLingui } from '@lingui/react/macro'; import { enUS } from 'date-fns/locale'; import { APP_LOCALES } from 'twenty-shared/translations'; import { isDefined } from 'twenty-shared/utils'; -import { dateLocaleStateV2 } from '~/localization/states/dateLocaleStateV2'; +import { dateLocaleState } from '~/localization/states/dateLocaleState'; import { dynamicActivate } from '~/utils/i18n/dynamicActivate'; import { logError } from '~/utils/logError'; @@ -67,7 +67,7 @@ export const LocalePicker = () => { locale: value, localeCatalog: dateFnsLocale || enUS, }; - store.set(dateLocaleStateV2.atom, newDateLocale); + store.set(dateLocaleState.atom, newDateLocale); await dynamicActivate(value); try {