From 0fa87af634663deb26f8952e3d0f82a3b0358156 Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Tue, 1 Oct 2024 14:13:59 +0200 Subject: [PATCH 01/52] create states --- .../modules/context-store/states/currentObjectMetadataId.ts | 6 ++++++ .../src/modules/context-store/states/currentViewIdState.ts | 6 ++++++ .../src/modules/context-store/states/targetedRecordIds.ts | 6 ++++++ 3 files changed, 18 insertions(+) create mode 100644 packages/twenty-front/src/modules/context-store/states/currentObjectMetadataId.ts create mode 100644 packages/twenty-front/src/modules/context-store/states/currentViewIdState.ts create mode 100644 packages/twenty-front/src/modules/context-store/states/targetedRecordIds.ts diff --git a/packages/twenty-front/src/modules/context-store/states/currentObjectMetadataId.ts b/packages/twenty-front/src/modules/context-store/states/currentObjectMetadataId.ts new file mode 100644 index 000000000000..3ad781d2de1c --- /dev/null +++ b/packages/twenty-front/src/modules/context-store/states/currentObjectMetadataId.ts @@ -0,0 +1,6 @@ +import { createState } from 'twenty-ui'; + +export const currentObjectMetadataId = createState({ + key: 'currentObjectMetadataId', + defaultValue: null, +}); diff --git a/packages/twenty-front/src/modules/context-store/states/currentViewIdState.ts b/packages/twenty-front/src/modules/context-store/states/currentViewIdState.ts new file mode 100644 index 000000000000..3856cb66af22 --- /dev/null +++ b/packages/twenty-front/src/modules/context-store/states/currentViewIdState.ts @@ -0,0 +1,6 @@ +import { createState } from 'twenty-ui'; + +export const currentViewIdState = createState({ + key: 'currentViewIdState', + defaultValue: null, +}); diff --git a/packages/twenty-front/src/modules/context-store/states/targetedRecordIds.ts b/packages/twenty-front/src/modules/context-store/states/targetedRecordIds.ts new file mode 100644 index 000000000000..940eee9c720d --- /dev/null +++ b/packages/twenty-front/src/modules/context-store/states/targetedRecordIds.ts @@ -0,0 +1,6 @@ +import { createState } from 'twenty-ui'; + +export const targetedRecordIds = createState({ + key: 'targetedRecordIds', + defaultValue: [], +}); From fdd40280bfabf478c9200d9f9730dce06595cf8f Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Tue, 1 Oct 2024 14:29:35 +0200 Subject: [PATCH 02/52] create hooks --- .../context-store/hooks/useCurrentObjectMetadataId.ts | 7 +++++++ .../src/modules/context-store/hooks/useCurrentViewId.ts | 7 +++++++ .../context-store/hooks/useSetCurrentObjectMetadataId.ts | 9 +++++++++ .../modules/context-store/hooks/useSetCurrentViewId.ts | 7 +++++++ .../context-store/hooks/useSetTargetedRecordIds.ts | 7 +++++++ .../modules/context-store/hooks/useTargetedRecordIds.ts | 7 +++++++ .../context-store/states/currentObjectMetadataId.ts | 6 ------ .../context-store/states/currentObjectMetadataIdState.ts | 6 ++++++ .../modules/context-store/states/targetedRecordIds.ts | 6 ------ .../context-store/states/targetedRecordIdsState.ts | 6 ++++++ 10 files changed, 56 insertions(+), 12 deletions(-) create mode 100644 packages/twenty-front/src/modules/context-store/hooks/useCurrentObjectMetadataId.ts create mode 100644 packages/twenty-front/src/modules/context-store/hooks/useCurrentViewId.ts create mode 100644 packages/twenty-front/src/modules/context-store/hooks/useSetCurrentObjectMetadataId.ts create mode 100644 packages/twenty-front/src/modules/context-store/hooks/useSetCurrentViewId.ts create mode 100644 packages/twenty-front/src/modules/context-store/hooks/useSetTargetedRecordIds.ts create mode 100644 packages/twenty-front/src/modules/context-store/hooks/useTargetedRecordIds.ts delete mode 100644 packages/twenty-front/src/modules/context-store/states/currentObjectMetadataId.ts create mode 100644 packages/twenty-front/src/modules/context-store/states/currentObjectMetadataIdState.ts delete mode 100644 packages/twenty-front/src/modules/context-store/states/targetedRecordIds.ts create mode 100644 packages/twenty-front/src/modules/context-store/states/targetedRecordIdsState.ts diff --git a/packages/twenty-front/src/modules/context-store/hooks/useCurrentObjectMetadataId.ts b/packages/twenty-front/src/modules/context-store/hooks/useCurrentObjectMetadataId.ts new file mode 100644 index 000000000000..d3ee8b5f234a --- /dev/null +++ b/packages/twenty-front/src/modules/context-store/hooks/useCurrentObjectMetadataId.ts @@ -0,0 +1,7 @@ +import { currentObjectMetadataIdState } from '@/context-store/states/currentObjectMetadataIdState'; +import { useRecoilValue } from 'recoil'; + +export const useCurrentObjectMetadataId = () => { + const currentObjectMetadataId = useRecoilValue(currentObjectMetadataIdState); + return { currentObjectMetadataId }; +}; diff --git a/packages/twenty-front/src/modules/context-store/hooks/useCurrentViewId.ts b/packages/twenty-front/src/modules/context-store/hooks/useCurrentViewId.ts new file mode 100644 index 000000000000..dc3163e17006 --- /dev/null +++ b/packages/twenty-front/src/modules/context-store/hooks/useCurrentViewId.ts @@ -0,0 +1,7 @@ +import { currentViewIdState } from '@/context-store/states/currentViewIdState'; +import { useRecoilValue } from 'recoil'; + +export const useCurrentViewId = () => { + const currentViewId = useRecoilValue(currentViewIdState); + return { currentViewId }; +}; diff --git a/packages/twenty-front/src/modules/context-store/hooks/useSetCurrentObjectMetadataId.ts b/packages/twenty-front/src/modules/context-store/hooks/useSetCurrentObjectMetadataId.ts new file mode 100644 index 000000000000..cb3d00aaadd8 --- /dev/null +++ b/packages/twenty-front/src/modules/context-store/hooks/useSetCurrentObjectMetadataId.ts @@ -0,0 +1,9 @@ +import { currentObjectMetadataIdState } from '@/context-store/states/currentObjectMetadataIdState'; +import { useSetRecoilState } from 'recoil'; + +export const useSetCurrentObjectMetadataId = () => { + const setCurrentObjectMetadataId = useSetRecoilState( + currentObjectMetadataIdState, + ); + return { setCurrentObjectMetadataId }; +}; diff --git a/packages/twenty-front/src/modules/context-store/hooks/useSetCurrentViewId.ts b/packages/twenty-front/src/modules/context-store/hooks/useSetCurrentViewId.ts new file mode 100644 index 000000000000..f50abe9773df --- /dev/null +++ b/packages/twenty-front/src/modules/context-store/hooks/useSetCurrentViewId.ts @@ -0,0 +1,7 @@ +import { currentViewIdState } from '@/context-store/states/currentViewIdState'; +import { useSetRecoilState } from 'recoil'; + +export const useSetCurrentViewId = () => { + const setCurrentViewId = useSetRecoilState(currentViewIdState); + return { setCurrentViewId }; +}; diff --git a/packages/twenty-front/src/modules/context-store/hooks/useSetTargetedRecordIds.ts b/packages/twenty-front/src/modules/context-store/hooks/useSetTargetedRecordIds.ts new file mode 100644 index 000000000000..813c7fb613ce --- /dev/null +++ b/packages/twenty-front/src/modules/context-store/hooks/useSetTargetedRecordIds.ts @@ -0,0 +1,7 @@ +import { targetedRecordIdsState } from '@/context-store/states/targetedRecordIdsState'; +import { useSetRecoilState } from 'recoil'; + +export const useSetTargetedRecordIds = () => { + const setTargetedRecordIds = useSetRecoilState(targetedRecordIdsState); + return { setTargetedRecordIds }; +}; diff --git a/packages/twenty-front/src/modules/context-store/hooks/useTargetedRecordIds.ts b/packages/twenty-front/src/modules/context-store/hooks/useTargetedRecordIds.ts new file mode 100644 index 000000000000..f9a6b7e091a1 --- /dev/null +++ b/packages/twenty-front/src/modules/context-store/hooks/useTargetedRecordIds.ts @@ -0,0 +1,7 @@ +import { targetedRecordIdsState } from '@/context-store/states/targetedRecordIdsState'; +import { useRecoilValue } from 'recoil'; + +export const useTargetedRecordIds = () => { + const targetedRecordIds = useRecoilValue(targetedRecordIdsState); + return { targetedRecordIds }; +}; diff --git a/packages/twenty-front/src/modules/context-store/states/currentObjectMetadataId.ts b/packages/twenty-front/src/modules/context-store/states/currentObjectMetadataId.ts deleted file mode 100644 index 3ad781d2de1c..000000000000 --- a/packages/twenty-front/src/modules/context-store/states/currentObjectMetadataId.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { createState } from 'twenty-ui'; - -export const currentObjectMetadataId = createState({ - key: 'currentObjectMetadataId', - defaultValue: null, -}); diff --git a/packages/twenty-front/src/modules/context-store/states/currentObjectMetadataIdState.ts b/packages/twenty-front/src/modules/context-store/states/currentObjectMetadataIdState.ts new file mode 100644 index 000000000000..b7922370ce19 --- /dev/null +++ b/packages/twenty-front/src/modules/context-store/states/currentObjectMetadataIdState.ts @@ -0,0 +1,6 @@ +import { createState } from 'twenty-ui'; + +export const currentObjectMetadataIdState = createState({ + key: 'currentObjectMetadataIdState', + defaultValue: null, +}); diff --git a/packages/twenty-front/src/modules/context-store/states/targetedRecordIds.ts b/packages/twenty-front/src/modules/context-store/states/targetedRecordIds.ts deleted file mode 100644 index 940eee9c720d..000000000000 --- a/packages/twenty-front/src/modules/context-store/states/targetedRecordIds.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { createState } from 'twenty-ui'; - -export const targetedRecordIds = createState({ - key: 'targetedRecordIds', - defaultValue: [], -}); diff --git a/packages/twenty-front/src/modules/context-store/states/targetedRecordIdsState.ts b/packages/twenty-front/src/modules/context-store/states/targetedRecordIdsState.ts new file mode 100644 index 000000000000..372b050568a6 --- /dev/null +++ b/packages/twenty-front/src/modules/context-store/states/targetedRecordIdsState.ts @@ -0,0 +1,6 @@ +import { createState } from 'twenty-ui'; + +export const targetedRecordIdsState = createState({ + key: 'targetedRecordIdsState', + defaultValue: [], +}); From 7b96e35a48f2de07e522c06f5922d749df51bb9f Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Tue, 1 Oct 2024 14:40:40 +0200 Subject: [PATCH 03/52] remove hooks --- .../context-store/hooks/useCurrentObjectMetadataId.ts | 7 ------- .../src/modules/context-store/hooks/useCurrentViewId.ts | 7 ------- .../context-store/hooks/useSetCurrentObjectMetadataId.ts | 9 --------- .../modules/context-store/hooks/useSetCurrentViewId.ts | 7 ------- .../context-store/hooks/useSetTargetedRecordIds.ts | 7 ------- .../modules/context-store/hooks/useTargetedRecordIds.ts | 7 ------- .../states/contextStoreCurrentObjectMetadataIdState.ts | 8 ++++++++ .../states/contextStoreCurrentViewIdState.ts | 6 ++++++ .../states/contextStoreTargetedRecordIdsState.ts | 6 ++++++ .../context-store/states/currentObjectMetadataIdState.ts | 6 ------ .../modules/context-store/states/currentViewIdState.ts | 6 ------ .../context-store/states/targetedRecordIdsState.ts | 6 ------ 12 files changed, 20 insertions(+), 62 deletions(-) delete mode 100644 packages/twenty-front/src/modules/context-store/hooks/useCurrentObjectMetadataId.ts delete mode 100644 packages/twenty-front/src/modules/context-store/hooks/useCurrentViewId.ts delete mode 100644 packages/twenty-front/src/modules/context-store/hooks/useSetCurrentObjectMetadataId.ts delete mode 100644 packages/twenty-front/src/modules/context-store/hooks/useSetCurrentViewId.ts delete mode 100644 packages/twenty-front/src/modules/context-store/hooks/useSetTargetedRecordIds.ts delete mode 100644 packages/twenty-front/src/modules/context-store/hooks/useTargetedRecordIds.ts create mode 100644 packages/twenty-front/src/modules/context-store/states/contextStoreCurrentObjectMetadataIdState.ts create mode 100644 packages/twenty-front/src/modules/context-store/states/contextStoreCurrentViewIdState.ts create mode 100644 packages/twenty-front/src/modules/context-store/states/contextStoreTargetedRecordIdsState.ts delete mode 100644 packages/twenty-front/src/modules/context-store/states/currentObjectMetadataIdState.ts delete mode 100644 packages/twenty-front/src/modules/context-store/states/currentViewIdState.ts delete mode 100644 packages/twenty-front/src/modules/context-store/states/targetedRecordIdsState.ts diff --git a/packages/twenty-front/src/modules/context-store/hooks/useCurrentObjectMetadataId.ts b/packages/twenty-front/src/modules/context-store/hooks/useCurrentObjectMetadataId.ts deleted file mode 100644 index d3ee8b5f234a..000000000000 --- a/packages/twenty-front/src/modules/context-store/hooks/useCurrentObjectMetadataId.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { currentObjectMetadataIdState } from '@/context-store/states/currentObjectMetadataIdState'; -import { useRecoilValue } from 'recoil'; - -export const useCurrentObjectMetadataId = () => { - const currentObjectMetadataId = useRecoilValue(currentObjectMetadataIdState); - return { currentObjectMetadataId }; -}; diff --git a/packages/twenty-front/src/modules/context-store/hooks/useCurrentViewId.ts b/packages/twenty-front/src/modules/context-store/hooks/useCurrentViewId.ts deleted file mode 100644 index dc3163e17006..000000000000 --- a/packages/twenty-front/src/modules/context-store/hooks/useCurrentViewId.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { currentViewIdState } from '@/context-store/states/currentViewIdState'; -import { useRecoilValue } from 'recoil'; - -export const useCurrentViewId = () => { - const currentViewId = useRecoilValue(currentViewIdState); - return { currentViewId }; -}; diff --git a/packages/twenty-front/src/modules/context-store/hooks/useSetCurrentObjectMetadataId.ts b/packages/twenty-front/src/modules/context-store/hooks/useSetCurrentObjectMetadataId.ts deleted file mode 100644 index cb3d00aaadd8..000000000000 --- a/packages/twenty-front/src/modules/context-store/hooks/useSetCurrentObjectMetadataId.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { currentObjectMetadataIdState } from '@/context-store/states/currentObjectMetadataIdState'; -import { useSetRecoilState } from 'recoil'; - -export const useSetCurrentObjectMetadataId = () => { - const setCurrentObjectMetadataId = useSetRecoilState( - currentObjectMetadataIdState, - ); - return { setCurrentObjectMetadataId }; -}; diff --git a/packages/twenty-front/src/modules/context-store/hooks/useSetCurrentViewId.ts b/packages/twenty-front/src/modules/context-store/hooks/useSetCurrentViewId.ts deleted file mode 100644 index f50abe9773df..000000000000 --- a/packages/twenty-front/src/modules/context-store/hooks/useSetCurrentViewId.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { currentViewIdState } from '@/context-store/states/currentViewIdState'; -import { useSetRecoilState } from 'recoil'; - -export const useSetCurrentViewId = () => { - const setCurrentViewId = useSetRecoilState(currentViewIdState); - return { setCurrentViewId }; -}; diff --git a/packages/twenty-front/src/modules/context-store/hooks/useSetTargetedRecordIds.ts b/packages/twenty-front/src/modules/context-store/hooks/useSetTargetedRecordIds.ts deleted file mode 100644 index 813c7fb613ce..000000000000 --- a/packages/twenty-front/src/modules/context-store/hooks/useSetTargetedRecordIds.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { targetedRecordIdsState } from '@/context-store/states/targetedRecordIdsState'; -import { useSetRecoilState } from 'recoil'; - -export const useSetTargetedRecordIds = () => { - const setTargetedRecordIds = useSetRecoilState(targetedRecordIdsState); - return { setTargetedRecordIds }; -}; diff --git a/packages/twenty-front/src/modules/context-store/hooks/useTargetedRecordIds.ts b/packages/twenty-front/src/modules/context-store/hooks/useTargetedRecordIds.ts deleted file mode 100644 index f9a6b7e091a1..000000000000 --- a/packages/twenty-front/src/modules/context-store/hooks/useTargetedRecordIds.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { targetedRecordIdsState } from '@/context-store/states/targetedRecordIdsState'; -import { useRecoilValue } from 'recoil'; - -export const useTargetedRecordIds = () => { - const targetedRecordIds = useRecoilValue(targetedRecordIdsState); - return { targetedRecordIds }; -}; diff --git a/packages/twenty-front/src/modules/context-store/states/contextStoreCurrentObjectMetadataIdState.ts b/packages/twenty-front/src/modules/context-store/states/contextStoreCurrentObjectMetadataIdState.ts new file mode 100644 index 000000000000..3227e53807df --- /dev/null +++ b/packages/twenty-front/src/modules/context-store/states/contextStoreCurrentObjectMetadataIdState.ts @@ -0,0 +1,8 @@ +import { createState } from 'twenty-ui'; + +export const contextStoreCurrentObjectMetadataIdState = createState< + string | null +>({ + key: 'contextStoreCurrentObjectMetadataIdState', + defaultValue: null, +}); diff --git a/packages/twenty-front/src/modules/context-store/states/contextStoreCurrentViewIdState.ts b/packages/twenty-front/src/modules/context-store/states/contextStoreCurrentViewIdState.ts new file mode 100644 index 000000000000..41af1cc1357b --- /dev/null +++ b/packages/twenty-front/src/modules/context-store/states/contextStoreCurrentViewIdState.ts @@ -0,0 +1,6 @@ +import { createState } from 'twenty-ui'; + +export const contextStoreCurrentViewIdState = createState({ + key: 'contextStoreCurrentViewIdState', + defaultValue: null, +}); diff --git a/packages/twenty-front/src/modules/context-store/states/contextStoreTargetedRecordIdsState.ts b/packages/twenty-front/src/modules/context-store/states/contextStoreTargetedRecordIdsState.ts new file mode 100644 index 000000000000..df0c3451172c --- /dev/null +++ b/packages/twenty-front/src/modules/context-store/states/contextStoreTargetedRecordIdsState.ts @@ -0,0 +1,6 @@ +import { createState } from 'twenty-ui'; + +export const contextStoreTargetedRecordIdsState = createState({ + key: 'contextStoreTargetedRecordIdsState', + defaultValue: [], +}); diff --git a/packages/twenty-front/src/modules/context-store/states/currentObjectMetadataIdState.ts b/packages/twenty-front/src/modules/context-store/states/currentObjectMetadataIdState.ts deleted file mode 100644 index b7922370ce19..000000000000 --- a/packages/twenty-front/src/modules/context-store/states/currentObjectMetadataIdState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { createState } from 'twenty-ui'; - -export const currentObjectMetadataIdState = createState({ - key: 'currentObjectMetadataIdState', - defaultValue: null, -}); diff --git a/packages/twenty-front/src/modules/context-store/states/currentViewIdState.ts b/packages/twenty-front/src/modules/context-store/states/currentViewIdState.ts deleted file mode 100644 index 3856cb66af22..000000000000 --- a/packages/twenty-front/src/modules/context-store/states/currentViewIdState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { createState } from 'twenty-ui'; - -export const currentViewIdState = createState({ - key: 'currentViewIdState', - defaultValue: null, -}); diff --git a/packages/twenty-front/src/modules/context-store/states/targetedRecordIdsState.ts b/packages/twenty-front/src/modules/context-store/states/targetedRecordIdsState.ts deleted file mode 100644 index 372b050568a6..000000000000 --- a/packages/twenty-front/src/modules/context-store/states/targetedRecordIdsState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { createState } from 'twenty-ui'; - -export const targetedRecordIdsState = createState({ - key: 'targetedRecordIdsState', - defaultValue: [], -}); From d84ccd85bbb40148d961b441987b10d5eba75b78 Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Tue, 1 Oct 2024 15:16:14 +0200 Subject: [PATCH 04/52] setContextStoreCurrentViewId --- .../views/components/QueryParamsViewIdEffect.tsx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/twenty-front/src/modules/views/components/QueryParamsViewIdEffect.tsx b/packages/twenty-front/src/modules/views/components/QueryParamsViewIdEffect.tsx index 2ee24d43fdc3..5779e6575481 100644 --- a/packages/twenty-front/src/modules/views/components/QueryParamsViewIdEffect.tsx +++ b/packages/twenty-front/src/modules/views/components/QueryParamsViewIdEffect.tsx @@ -1,3 +1,4 @@ +import { contextStoreCurrentViewIdState } from '@/context-store/states/contextStoreCurrentViewIdState'; import { useLastVisitedObjectMetadataItem } from '@/navigation/hooks/useLastVisitedObjectMetadataItem'; import { useLastVisitedView } from '@/navigation/hooks/useLastVisitedView'; import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems'; @@ -7,6 +8,7 @@ import { useGetCurrentView } from '@/views/hooks/useGetCurrentView'; import { currentViewIdComponentState } from '@/views/states/currentViewIdComponentState'; import { isUndefined } from '@sniptt/guards'; import { useEffect } from 'react'; +import { useSetRecoilState } from 'recoil'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; import { isDefined } from '~/utils/isDefined'; @@ -21,6 +23,10 @@ export const QueryParamsViewIdEffect = () => { currentViewIdComponentState, ); + const setContextStoreCurrentViewId = useSetRecoilState( + contextStoreCurrentViewIdState, + ); + const { viewsOnCurrentObject } = useGetCurrentView(); const { findObjectMetadataItemByNamePlural } = useFilteredObjectMetadataItems(); @@ -59,6 +65,7 @@ export const QueryParamsViewIdEffect = () => { }); } setCurrentViewId(lastVisitedViewId); + setContextStoreCurrentViewId(lastVisitedViewId); return; } @@ -73,6 +80,7 @@ export const QueryParamsViewIdEffect = () => { }); } setCurrentViewId(viewIdQueryParam); + setContextStoreCurrentViewId(viewIdQueryParam); return; } @@ -87,6 +95,7 @@ export const QueryParamsViewIdEffect = () => { }); } setCurrentViewId(indexView.id); + setContextStoreCurrentViewId(indexView.id); return; } }, [ @@ -96,6 +105,7 @@ export const QueryParamsViewIdEffect = () => { lastVisitedViewId, objectMetadataItemId?.id, objectNamePlural, + setContextStoreCurrentViewId, setCurrentViewId, setLastVisitedObjectMetadataItem, setLastVisitedView, From b24fa66228be668950259e426b026e747d4348e8 Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Tue, 1 Oct 2024 15:44:23 +0200 Subject: [PATCH 05/52] setContextStoreCurrentViewId on page change effect --- .../src/effect-components/PageChangeEffect.tsx | 16 ++++++++++++++-- .../views/components/QueryParamsViewIdEffect.tsx | 13 +++---------- .../src/modules/views/hooks/useChangeView.ts | 12 ++---------- .../src/modules/views/hooks/useSetViewInUrl.ts | 15 +++++++++++++++ 4 files changed, 34 insertions(+), 22 deletions(-) create mode 100644 packages/twenty-front/src/modules/views/hooks/useSetViewInUrl.ts diff --git a/packages/twenty-front/src/effect-components/PageChangeEffect.tsx b/packages/twenty-front/src/effect-components/PageChangeEffect.tsx index 05c99cc89d56..5deb1c7d0d79 100644 --- a/packages/twenty-front/src/effect-components/PageChangeEffect.tsx +++ b/packages/twenty-front/src/effect-components/PageChangeEffect.tsx @@ -1,6 +1,6 @@ import { useEffect, useState } from 'react'; -import { useLocation, useNavigate } from 'react-router-dom'; -import { useRecoilValue } from 'recoil'; +import { useLocation, useNavigate, useSearchParams } from 'react-router-dom'; +import { useRecoilValue, useSetRecoilState } from 'recoil'; import { IconCheckbox } from 'twenty-ui'; import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer'; @@ -12,6 +12,7 @@ import { useRequestFreshCaptchaToken } from '@/captcha/hooks/useRequestFreshCapt import { isCaptchaScriptLoadedState } from '@/captcha/states/isCaptchaScriptLoadedState'; import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu'; import { CommandType } from '@/command-menu/types/Command'; +import { contextStoreCurrentViewIdState } from '@/context-store/states/contextStoreCurrentViewIdState'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope'; import { AppBasePath } from '@/types/AppBasePath'; @@ -49,6 +50,12 @@ export const PageChangeEffect = () => { activityObjectNameSingular: CoreObjectNameSingular.Task, }); + const [searchParams] = useSearchParams(); + + const setContextStoreCurrentViewId = useSetRecoilState( + contextStoreCurrentViewIdState, + ); + useEffect(() => { cleanRecoilState(); }, [cleanRecoilState]); @@ -67,6 +74,11 @@ export const PageChangeEffect = () => { } }, [navigate, pageChangeEffectNavigateLocation]); + useEffect(() => { + const viewId = searchParams.get('viewId'); + setContextStoreCurrentViewId(viewId); + }, [searchParams, setContextStoreCurrentViewId]); + useEffect(() => { switch (true) { case isMatchingLocation(AppPath.RecordIndexPage): { diff --git a/packages/twenty-front/src/modules/views/components/QueryParamsViewIdEffect.tsx b/packages/twenty-front/src/modules/views/components/QueryParamsViewIdEffect.tsx index 5779e6575481..39692aa8fcc0 100644 --- a/packages/twenty-front/src/modules/views/components/QueryParamsViewIdEffect.tsx +++ b/packages/twenty-front/src/modules/views/components/QueryParamsViewIdEffect.tsx @@ -1,14 +1,13 @@ -import { contextStoreCurrentViewIdState } from '@/context-store/states/contextStoreCurrentViewIdState'; import { useLastVisitedObjectMetadataItem } from '@/navigation/hooks/useLastVisitedObjectMetadataItem'; import { useLastVisitedView } from '@/navigation/hooks/useLastVisitedView'; import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems'; import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2'; import { useViewFromQueryParams } from '@/views/hooks/internal/useViewFromQueryParams'; import { useGetCurrentView } from '@/views/hooks/useGetCurrentView'; +import { useSetViewInUrl } from '@/views/hooks/useSetViewInUrl'; import { currentViewIdComponentState } from '@/views/states/currentViewIdComponentState'; import { isUndefined } from '@sniptt/guards'; import { useEffect } from 'react'; -import { useSetRecoilState } from 'recoil'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; import { isDefined } from '~/utils/isDefined'; @@ -23,10 +22,6 @@ export const QueryParamsViewIdEffect = () => { currentViewIdComponentState, ); - const setContextStoreCurrentViewId = useSetRecoilState( - contextStoreCurrentViewIdState, - ); - const { viewsOnCurrentObject } = useGetCurrentView(); const { findObjectMetadataItemByNamePlural } = useFilteredObjectMetadataItems(); @@ -43,6 +38,7 @@ export const QueryParamsViewIdEffect = () => { objectMetadataItemId?.id, lastVisitedObjectMetadataItemId, ); + const { setViewInUrl } = useSetViewInUrl(); // // TODO: scope view bar per view id if possible // const { resetCurrentView } = useResetCurrentView(); @@ -65,7 +61,7 @@ export const QueryParamsViewIdEffect = () => { }); } setCurrentViewId(lastVisitedViewId); - setContextStoreCurrentViewId(lastVisitedViewId); + setViewInUrl(lastVisitedViewId); return; } @@ -80,7 +76,6 @@ export const QueryParamsViewIdEffect = () => { }); } setCurrentViewId(viewIdQueryParam); - setContextStoreCurrentViewId(viewIdQueryParam); return; } @@ -95,7 +90,6 @@ export const QueryParamsViewIdEffect = () => { }); } setCurrentViewId(indexView.id); - setContextStoreCurrentViewId(indexView.id); return; } }, [ @@ -105,7 +99,6 @@ export const QueryParamsViewIdEffect = () => { lastVisitedViewId, objectMetadataItemId?.id, objectNamePlural, - setContextStoreCurrentViewId, setCurrentViewId, setLastVisitedObjectMetadataItem, setLastVisitedView, diff --git a/packages/twenty-front/src/modules/views/hooks/useChangeView.ts b/packages/twenty-front/src/modules/views/hooks/useChangeView.ts index 669de5157b1b..9ed9aeeff420 100644 --- a/packages/twenty-front/src/modules/views/hooks/useChangeView.ts +++ b/packages/twenty-front/src/modules/views/hooks/useChangeView.ts @@ -1,19 +1,11 @@ import { useResetUnsavedViewStates } from '@/views/hooks/useResetUnsavedViewStates'; -import { useSearchParams } from 'react-router-dom'; +import { useSetViewInUrl } from '@/views/hooks/useSetViewInUrl'; export const useChangeView = (viewBarComponentId?: string) => { const { resetUnsavedViewStates } = useResetUnsavedViewStates(viewBarComponentId); - const [, setSearchParams] = useSearchParams(); - - const setViewInUrl = (viewId: string) => { - setSearchParams(() => { - const searchParams = new URLSearchParams(); - searchParams.set('view', viewId); - return searchParams; - }); - }; + const { setViewInUrl } = useSetViewInUrl(); const changeView = async (viewId: string) => { setViewInUrl(viewId); diff --git a/packages/twenty-front/src/modules/views/hooks/useSetViewInUrl.ts b/packages/twenty-front/src/modules/views/hooks/useSetViewInUrl.ts new file mode 100644 index 000000000000..01e0397ffd6d --- /dev/null +++ b/packages/twenty-front/src/modules/views/hooks/useSetViewInUrl.ts @@ -0,0 +1,15 @@ +import { useSearchParams } from 'react-router-dom'; + +export const useSetViewInUrl = () => { + const [, setSearchParams] = useSearchParams(); + + const setViewInUrl = (viewId: string) => { + setSearchParams(() => { + const searchParams = new URLSearchParams(); + searchParams.set('view', viewId); + return searchParams; + }); + }; + + return { setViewInUrl }; +}; From ad6947ecd7666533d5fcf6cd9a04483cc81d5844 Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Tue, 1 Oct 2024 16:43:10 +0200 Subject: [PATCH 06/52] setContextStoreCurrentObjectMetadataId inside PageChangeEffect --- .../effect-components/PageChangeEffect.tsx | 28 ++++++++++++++++++- .../components/QueryParamsViewIdEffect.tsx | 1 + 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/packages/twenty-front/src/effect-components/PageChangeEffect.tsx b/packages/twenty-front/src/effect-components/PageChangeEffect.tsx index 5deb1c7d0d79..42077b3c7835 100644 --- a/packages/twenty-front/src/effect-components/PageChangeEffect.tsx +++ b/packages/twenty-front/src/effect-components/PageChangeEffect.tsx @@ -1,5 +1,10 @@ import { useEffect, useState } from 'react'; -import { useLocation, useNavigate, useSearchParams } from 'react-router-dom'; +import { + useLocation, + useNavigate, + useParams, + useSearchParams, +} from 'react-router-dom'; import { useRecoilValue, useSetRecoilState } from 'recoil'; import { IconCheckbox } from 'twenty-ui'; @@ -12,7 +17,9 @@ import { useRequestFreshCaptchaToken } from '@/captcha/hooks/useRequestFreshCapt import { isCaptchaScriptLoadedState } from '@/captcha/states/isCaptchaScriptLoadedState'; import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu'; import { CommandType } from '@/command-menu/types/Command'; +import { contextStoreCurrentObjectMetadataIdState } from '@/context-store/states/contextStoreCurrentObjectMetadataIdState'; import { contextStoreCurrentViewIdState } from '@/context-store/states/contextStoreCurrentViewIdState'; +import { objectMetadataItemFamilySelector } from '@/object-metadata/states/objectMetadataItemFamilySelector'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope'; import { AppBasePath } from '@/types/AppBasePath'; @@ -51,10 +58,24 @@ export const PageChangeEffect = () => { }); const [searchParams] = useSearchParams(); + const { objectNameSingular, objectNamePlural } = useParams(); + + const objectMetadataItem = useRecoilValue( + objectMetadataItemFamilySelector( + objectNameSingular + ? { objectName: objectNameSingular, objectNameType: 'singular' } + : objectNamePlural + ? { objectName: objectNamePlural, objectNameType: 'plural' } + : { objectName: '', objectNameType: 'singular' }, + ), + ); const setContextStoreCurrentViewId = useSetRecoilState( contextStoreCurrentViewIdState, ); + const setContextStoreCurrentObjectMetadataId = useSetRecoilState( + contextStoreCurrentObjectMetadataIdState, + ); useEffect(() => { cleanRecoilState(); @@ -79,6 +100,10 @@ export const PageChangeEffect = () => { setContextStoreCurrentViewId(viewId); }, [searchParams, setContextStoreCurrentViewId]); + useEffect(() => { + setContextStoreCurrentObjectMetadataId(objectMetadataItem?.id ?? null); + }, [objectMetadataItem, setContextStoreCurrentObjectMetadataId]); + useEffect(() => { switch (true) { case isMatchingLocation(AppPath.RecordIndexPage): { @@ -86,6 +111,7 @@ export const PageChangeEffect = () => { goto: true, keyboardShortcutMenu: true, }); + break; } case isMatchingLocation(AppPath.RecordShowPage): { diff --git a/packages/twenty-front/src/modules/views/components/QueryParamsViewIdEffect.tsx b/packages/twenty-front/src/modules/views/components/QueryParamsViewIdEffect.tsx index 39692aa8fcc0..2f92db1cea8a 100644 --- a/packages/twenty-front/src/modules/views/components/QueryParamsViewIdEffect.tsx +++ b/packages/twenty-front/src/modules/views/components/QueryParamsViewIdEffect.tsx @@ -102,6 +102,7 @@ export const QueryParamsViewIdEffect = () => { setCurrentViewId, setLastVisitedObjectMetadataItem, setLastVisitedView, + setViewInUrl, viewIdQueryParam, viewsOnCurrentObject, ]); From dd5b1bed2659c5982e19ec3369e7eddc071bd94e Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Tue, 1 Oct 2024 18:05:54 +0200 Subject: [PATCH 07/52] set contextStoreTargetedRecordIdsState --- .../src/effect-components/PageChangeEffect.tsx | 13 +++++++++++-- .../components/RecordIndexBoardDataLoaderEffect.tsx | 9 +++++++++ .../components/RecordIndexTableContainerEffect.tsx | 11 ++++++++++- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/packages/twenty-front/src/effect-components/PageChangeEffect.tsx b/packages/twenty-front/src/effect-components/PageChangeEffect.tsx index 42077b3c7835..e0a5276be735 100644 --- a/packages/twenty-front/src/effect-components/PageChangeEffect.tsx +++ b/packages/twenty-front/src/effect-components/PageChangeEffect.tsx @@ -19,6 +19,7 @@ import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu'; import { CommandType } from '@/command-menu/types/Command'; import { contextStoreCurrentObjectMetadataIdState } from '@/context-store/states/contextStoreCurrentObjectMetadataIdState'; import { contextStoreCurrentViewIdState } from '@/context-store/states/contextStoreCurrentViewIdState'; +import { contextStoreTargetedRecordIdsState } from '@/context-store/states/contextStoreTargetedRecordIdsState'; import { objectMetadataItemFamilySelector } from '@/object-metadata/states/objectMetadataItemFamilySelector'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope'; @@ -76,6 +77,9 @@ export const PageChangeEffect = () => { const setContextStoreCurrentObjectMetadataId = useSetRecoilState( contextStoreCurrentObjectMetadataIdState, ); + const setContextStoreTargetedRecordIds = useSetRecoilState( + contextStoreTargetedRecordIdsState, + ); useEffect(() => { cleanRecoilState(); @@ -96,9 +100,14 @@ export const PageChangeEffect = () => { }, [navigate, pageChangeEffectNavigateLocation]); useEffect(() => { - const viewId = searchParams.get('viewId'); + const viewId = searchParams.get('view'); setContextStoreCurrentViewId(viewId); - }, [searchParams, setContextStoreCurrentViewId]); + setContextStoreTargetedRecordIds([]); + }, [ + searchParams, + setContextStoreCurrentViewId, + setContextStoreTargetedRecordIds, + ]); useEffect(() => { setContextStoreCurrentObjectMetadataId(objectMetadataItem?.id ?? null); diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardDataLoaderEffect.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardDataLoaderEffect.tsx index ba3abec91e75..fbbc80aee5de 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardDataLoaderEffect.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardDataLoaderEffect.tsx @@ -2,6 +2,7 @@ import { useCallback, useEffect } from 'react'; import { useLocation, useNavigate } from 'react-router-dom'; import { useRecoilValue, useSetRecoilState } from 'recoil'; +import { contextStoreTargetedRecordIdsState } from '@/context-store/states/contextStoreTargetedRecordIdsState'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; import { getObjectSlug } from '@/object-metadata/utils/getObjectSlug'; import { useRecordActionBar } from '@/object-record/record-action-bar/hooks/useRecordActionBar'; @@ -129,10 +130,18 @@ export const RecordIndexBoardDataLoaderEffect = ({ callback: resetRecordSelection, }); + const setContextStoreTargetedRecordIds = useSetRecoilState( + contextStoreTargetedRecordIdsState, + ); + useEffect(() => { setActionBarEntries?.(); setContextMenuEntries?.(); }, [setActionBarEntries, setContextMenuEntries]); + useEffect(() => { + setContextStoreTargetedRecordIds(selectedRecordIds); + }, [selectedRecordIds, setContextStoreTargetedRecordIds]); + return <>; }; 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 428537f69467..63a2d367a8ca 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 @@ -1,6 +1,7 @@ import { useEffect } from 'react'; -import { useRecoilValue } from 'recoil'; +import { useRecoilValue, useSetRecoilState } from 'recoil'; +import { contextStoreTargetedRecordIdsState } from '@/context-store/states/contextStoreTargetedRecordIdsState'; import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; import { useRecordActionBar } from '@/object-record/record-action-bar/hooks/useRecordActionBar'; @@ -34,6 +35,10 @@ export const RecordIndexTableContainerEffect = ({ recordTableId, }); + const setContextStoreTargetedRecordIds = useSetRecoilState( + contextStoreTargetedRecordIdsState, + ); + const { objectMetadataItem } = useObjectMetadataItem({ objectNameSingular, }); @@ -111,5 +116,9 @@ export const RecordIndexTableContainerEffect = ({ ); }, [setRecordCountInCurrentView, setOnEntityCountChange]); + useEffect(() => { + setContextStoreTargetedRecordIds(selectedRowIds); + }, [selectedRowIds, setContextStoreTargetedRecordIds]); + return <>; }; From 5cf71b3ab82bdbbf405ffbfc6d1f3cb27aa4cc5b Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Tue, 1 Oct 2024 18:13:24 +0200 Subject: [PATCH 08/52] introduce RecordShowPageEffect to set contextStoreTargetedRecordIds --- .../src/pages/object-record/RecordShowPage.tsx | 3 +++ .../pages/object-record/RecordShowPageEffect.tsx | 15 +++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 packages/twenty-front/src/pages/object-record/RecordShowPageEffect.tsx diff --git a/packages/twenty-front/src/pages/object-record/RecordShowPage.tsx b/packages/twenty-front/src/pages/object-record/RecordShowPage.tsx index 3f697c21f07a..fd9fce4fd9aa 100644 --- a/packages/twenty-front/src/pages/object-record/RecordShowPage.tsx +++ b/packages/twenty-front/src/pages/object-record/RecordShowPage.tsx @@ -11,6 +11,7 @@ import { PageContainer } from '@/ui/layout/page/PageContainer'; import { PageTitle } from '@/ui/utilities/page-title/PageTitle'; import { RecordShowPageWorkflowHeader } from '@/workflow/components/RecordShowPageWorkflowHeader'; import { RecordShowPageBaseHeader } from '~/pages/object-record/RecordShowPageBaseHeader'; +import { RecordShowPageEffect } from '~/pages/object-record/RecordShowPageEffect'; import { RecordShowPageHeader } from '~/pages/object-record/RecordShowPageHeader'; export const RecordShowPage = () => { @@ -38,6 +39,8 @@ export const RecordShowPage = () => { return ( + + { + const setContextStoreTargetedRecordIds = useSetRecoilState( + contextStoreTargetedRecordIdsState, + ); + + useEffect(() => { + setContextStoreTargetedRecordIds([recordId]); + }, [recordId, setContextStoreTargetedRecordIds]); + + return null; +}; From 1f329d28ebbc2106c349fa9687a8c2f87657eefe Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Tue, 1 Oct 2024 18:25:20 +0200 Subject: [PATCH 09/52] remove line breaks --- packages/twenty-front/src/effect-components/PageChangeEffect.tsx | 1 - packages/twenty-front/src/pages/object-record/RecordShowPage.tsx | 1 - 2 files changed, 2 deletions(-) diff --git a/packages/twenty-front/src/effect-components/PageChangeEffect.tsx b/packages/twenty-front/src/effect-components/PageChangeEffect.tsx index e0a5276be735..6d95af651f4d 100644 --- a/packages/twenty-front/src/effect-components/PageChangeEffect.tsx +++ b/packages/twenty-front/src/effect-components/PageChangeEffect.tsx @@ -120,7 +120,6 @@ export const PageChangeEffect = () => { goto: true, keyboardShortcutMenu: true, }); - break; } case isMatchingLocation(AppPath.RecordShowPage): { diff --git a/packages/twenty-front/src/pages/object-record/RecordShowPage.tsx b/packages/twenty-front/src/pages/object-record/RecordShowPage.tsx index fd9fce4fd9aa..94ade895985d 100644 --- a/packages/twenty-front/src/pages/object-record/RecordShowPage.tsx +++ b/packages/twenty-front/src/pages/object-record/RecordShowPage.tsx @@ -40,7 +40,6 @@ export const RecordShowPage = () => { - Date: Wed, 2 Oct 2024 15:01:50 +0200 Subject: [PATCH 10/52] refactor action bar --- .../components/RecordBoardActionBar.tsx | 22 --------- .../components/RecordIndexBoardContainer.tsx | 2 - .../components/RecordIndexContainer.tsx | 2 + .../components/RecordIndexTableContainer.tsx | 2 - .../components/RecordTableActionBar.tsx | 47 ------------------- .../components/SignInBackgroundMockPage.tsx | 2 - .../modules/ui/layout/page/DefaultLayout.tsx | 10 ++-- .../action-bar/components/ActionBar.tsx | 43 ++++++----------- 8 files changed, 21 insertions(+), 109 deletions(-) delete mode 100644 packages/twenty-front/src/modules/object-record/record-board/action-bar/components/RecordBoardActionBar.tsx delete mode 100644 packages/twenty-front/src/modules/object-record/record-table/action-bar/components/RecordTableActionBar.tsx diff --git a/packages/twenty-front/src/modules/object-record/record-board/action-bar/components/RecordBoardActionBar.tsx b/packages/twenty-front/src/modules/object-record/record-board/action-bar/components/RecordBoardActionBar.tsx deleted file mode 100644 index 584cbeab3b5f..000000000000 --- a/packages/twenty-front/src/modules/object-record/record-board/action-bar/components/RecordBoardActionBar.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { useRecoilValue } from 'recoil'; - -import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates'; -import { ActionBar } from '@/ui/navigation/action-bar/components/ActionBar'; - -type RecordBoardActionBarProps = { - recordBoardId: string; -}; - -export const RecordBoardActionBar = ({ - recordBoardId, -}: RecordBoardActionBarProps) => { - const { selectedRecordIdsSelector } = useRecordBoardStates(recordBoardId); - - const selectedRecordIds = useRecoilValue(selectedRecordIdsSelector()); - - if (!selectedRecordIds.length) { - return null; - } - - return ; -}; diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardContainer.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardContainer.tsx index 8bca151080a2..7658a4e9c1d8 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardContainer.tsx @@ -4,7 +4,6 @@ import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadata import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord'; import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord'; import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord'; -import { RecordBoardActionBar } from '@/object-record/record-board/action-bar/components/RecordBoardActionBar'; import { RecordBoard } from '@/object-record/record-board/components/RecordBoard'; import { RecordBoardContextMenu } from '@/object-record/record-board/context-menu/components/RecordBoardContextMenu'; import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext'; @@ -51,7 +50,6 @@ export const RecordIndexBoardContainer = ({ }} > - ); diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx index 3af3237929f4..029a9a319778 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx @@ -23,6 +23,7 @@ import { RecordIndexRootPropsContext } from '@/object-record/record-index/contex import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext'; import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable'; import { SpreadsheetImportProvider } from '@/spreadsheet-import/provider/components/SpreadsheetImportProvider'; +import { ActionBar } from '@/ui/navigation/action-bar/components/ActionBar'; import { ViewBar } from '@/views/components/ViewBar'; import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext'; import { ViewField } from '@/views/types/ViewField'; @@ -191,6 +192,7 @@ export const RecordIndexContainer = () => { /> )} + diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexTableContainer.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexTableContainer.tsx index 50bb639f5237..0f9c228629c4 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexTableContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexTableContainer.tsx @@ -2,7 +2,6 @@ import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord'; import { RecordUpdateHookParams } from '@/object-record/record-field/contexts/FieldContext'; import { RecordIndexRemoveSortingModal } from '@/object-record/record-index/components/RecordIndexRemoveSortingModal'; import { RecordIndexRootPropsContext } from '@/object-record/record-index/contexts/RecordIndexRootPropsContext'; -import { RecordTableActionBar } from '@/object-record/record-table/action-bar/components/RecordTableActionBar'; import { RecordTableWithWrappers } from '@/object-record/record-table/components/RecordTableWithWrappers'; import { RecordTableContextMenu } from '@/object-record/record-table/context-menu/components/RecordTableContextMenu'; import { useContext } from 'react'; @@ -37,7 +36,6 @@ export const RecordIndexTableContainer = ({ viewBarId={viewBarId} updateRecordMutation={updateEntity} /> - diff --git a/packages/twenty-front/src/modules/object-record/record-table/action-bar/components/RecordTableActionBar.tsx b/packages/twenty-front/src/modules/object-record/record-table/action-bar/components/RecordTableActionBar.tsx deleted file mode 100644 index 0b2c810bc15c..000000000000 --- a/packages/twenty-front/src/modules/object-record/record-table/action-bar/components/RecordTableActionBar.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { useRecoilValue } from 'recoil'; - -import { useRecordTableStates } from '@/object-record/record-table/hooks/internal/useRecordTableStates'; -import { ActionBar } from '@/ui/navigation/action-bar/components/ActionBar'; -import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; -import { entityCountInCurrentViewComponentState } from '@/views/states/entityCountInCurrentViewComponentState'; - -export const RecordTableActionBar = ({ - recordTableId, -}: { - recordTableId: string; -}) => { - const { - selectedRowIdsSelector, - tableRowIdsState, - hasUserSelectedAllRowsState, - } = useRecordTableStates(recordTableId); - - // TODO: verify this instance id works - const entityCountInCurrentView = useRecoilComponentValueV2( - entityCountInCurrentViewComponentState, - recordTableId, - ); - - const hasUserSelectedAllRows = useRecoilValue(hasUserSelectedAllRowsState); - const tableRowIds = useRecoilValue(tableRowIdsState); - const selectedRowIds = useRecoilValue(selectedRowIdsSelector()); - - const totalNumberOfSelectedRecords = - hasUserSelectedAllRows && entityCountInCurrentView - ? selectedRowIds.length === tableRowIds.length - ? entityCountInCurrentView - : entityCountInCurrentView - - (tableRowIds.length - selectedRowIds.length) // unselected row Ids - : selectedRowIds.length; - - if (!selectedRowIds.length) { - return null; - } - - return ( - - ); -}; diff --git a/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockPage.tsx b/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockPage.tsx index 6ce3a80a5d4a..c1a325563caf 100644 --- a/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockPage.tsx +++ b/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockPage.tsx @@ -2,7 +2,6 @@ import styled from '@emotion/styled'; import { IconBuildingSkyscraper } from 'twenty-ui'; import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext'; -import { RecordTableActionBar } from '@/object-record/record-table/action-bar/components/RecordTableActionBar'; import { RecordTableContextMenu } from '@/object-record/record-table/context-menu/components/RecordTableContextMenu'; import { SignInBackgroundMockContainer } from '@/sign-in-background-mock/components/SignInBackgroundMockContainer'; import { PageAddButton } from '@/ui/layout/page/PageAddButton'; @@ -29,7 +28,6 @@ export const SignInBackgroundMockPage = () => { - diff --git a/packages/twenty-front/src/modules/ui/layout/page/DefaultLayout.tsx b/packages/twenty-front/src/modules/ui/layout/page/DefaultLayout.tsx index 4108f6a5cee6..0a05da36515e 100644 --- a/packages/twenty-front/src/modules/ui/layout/page/DefaultLayout.tsx +++ b/packages/twenty-front/src/modules/ui/layout/page/DefaultLayout.tsx @@ -1,7 +1,4 @@ -import { css, Global, useTheme } from '@emotion/react'; -import styled from '@emotion/styled'; -import { AnimatePresence, LayoutGroup, motion } from 'framer-motion'; -import { Outlet } from 'react-router-dom'; +import { AuthModal } from '@/auth/components/AuthModal'; import { CommandMenu } from '@/command-menu/components/CommandMenu'; import { AppErrorBoundary } from '@/error-handler/components/AppErrorBoundary'; import { KeyboardShortcutMenu } from '@/keyboard-shortcut-menu/components/KeyboardShortcutMenu'; @@ -14,7 +11,10 @@ import { useShowAuthModal } from '@/ui/layout/hooks/useShowAuthModal'; import { DESKTOP_NAV_DRAWER_WIDTHS } from '@/ui/navigation/navigation-drawer/constants/DesktopNavDrawerWidths'; import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; import { useScreenSize } from '@/ui/utilities/screen-size/hooks/useScreenSize'; -import { AuthModal } from '@/auth/components/AuthModal'; +import { css, Global, useTheme } from '@emotion/react'; +import styled from '@emotion/styled'; +import { AnimatePresence, LayoutGroup, motion } from 'framer-motion'; +import { Outlet } from 'react-router-dom'; const StyledLayout = styled.div` background: ${({ theme }) => theme.background.noisy}; diff --git a/packages/twenty-front/src/modules/ui/navigation/action-bar/components/ActionBar.tsx b/packages/twenty-front/src/modules/ui/navigation/action-bar/components/ActionBar.tsx index c020f42709c6..3eb9fc0d96fa 100644 --- a/packages/twenty-front/src/modules/ui/navigation/action-bar/components/ActionBar.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/action-bar/components/ActionBar.tsx @@ -1,19 +1,14 @@ import styled from '@emotion/styled'; -import { useEffect, useRef } from 'react'; +import { useEffect } from 'react'; import { useRecoilValue, useSetRecoilState } from 'recoil'; import { actionBarEntriesState } from '@/ui/navigation/action-bar/states/actionBarEntriesState'; import { contextMenuIsOpenState } from '@/ui/navigation/context-menu/states/contextMenuIsOpenState'; import SharedNavigationModal from '@/ui/navigation/shared/components/NavigationModal'; -import { isDefined } from '~/utils/isDefined'; +import { contextStoreTargetedRecordIdsState } from '@/context-store/states/contextStoreTargetedRecordIdsState'; import { ActionBarItem } from './ActionBarItem'; -type ActionBarProps = { - selectedIds?: string[]; - totalNumberOfSelectedRecords?: number; -}; - const StyledContainerActionBar = styled.div` align-items: center; background: ${({ theme }) => theme.background.secondary}; @@ -42,42 +37,32 @@ const StyledLabel = styled.div` padding-right: ${({ theme }) => theme.spacing(2)}; `; -export const ActionBar = ({ - selectedIds = [], - totalNumberOfSelectedRecords, -}: ActionBarProps) => { +export const ActionBar = () => { const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState); + const contextStoreTargetedRecordIds = useRecoilValue( + contextStoreTargetedRecordIdsState, + ); + useEffect(() => { - if (selectedIds && selectedIds.length > 1) { + if (contextStoreTargetedRecordIds.length > 1) { setContextMenuOpenState(false); } - }, [selectedIds, setContextMenuOpenState]); + }, [contextStoreTargetedRecordIds, setContextMenuOpenState]); const contextMenuIsOpen = useRecoilValue(contextMenuIsOpenState); const actionBarEntries = useRecoilValue(actionBarEntriesState); - const wrapperRef = useRef(null); - if (contextMenuIsOpen) { + if (contextMenuIsOpen || !contextStoreTargetedRecordIds.length) { return null; } - const selectedNumberLabel = - totalNumberOfSelectedRecords ?? selectedIds?.length; - - const showSelectedNumberLabel = - isDefined(totalNumberOfSelectedRecords) || Array.isArray(selectedIds); - return ( <> - - {showSelectedNumberLabel && ( - {selectedNumberLabel} selected: - )} + + + {contextStoreTargetedRecordIds?.length} selected: + {actionBarEntries.map((item, index) => ( ))} From bca53ed5a16e64f87f455dad3151494443cc61a9 Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Wed, 2 Oct 2024 16:43:49 +0200 Subject: [PATCH 11/52] create ActionMenu component --- .../hooks/useRecordActionBar.tsx | 45 +++++-------------- .../components/RecordBoardContextMenu.tsx | 22 --------- .../hooks/useRecordBoardSelection.ts | 2 +- .../components/RecordBoardCard.tsx | 4 +- .../components/RecordIndexBoardContainer.tsx | 2 - .../RecordIndexBoardDataLoaderEffect.tsx | 7 ++- .../components/RecordIndexContainer.tsx | 5 ++- .../components/RecordIndexTableContainer.tsx | 2 - .../RecordIndexTableContainerEffect.tsx | 7 ++- .../components/RecordTableContextMenu.tsx | 20 --------- .../components/RecordTableCellCheckbox.tsx | 2 +- .../hooks/useTriggerContextMenu.ts | 4 +- .../SignInBackgroundMockContainerEffect.tsx | 7 ++- .../components/SignInBackgroundMockPage.tsx | 2 - .../states/actionBarEntriesState.ts | 8 ---- .../action-bar/types/ActionBarEntry.ts | 5 --- .../components/ActionBar.tsx | 14 ++---- .../components/ActionBarItem.tsx | 4 +- .../action-menu/components/ActionMenu.tsx | 13 ++++++ .../components/ContextMenu.tsx | 22 +++------ .../components/ContextMenuItem.tsx | 4 +- .../components/NavigationModal.tsx | 21 +++++++++ .../__stories__/ActionBar.stories.tsx | 0 .../__stories__/ContextMenu.stories.tsx | 0 .../__stories__/NavigationModal.stories.tsx | 12 ++--- .../states/actionBarIsOpenState.ts | 0 .../states/actionMenuEntriesState.ts | 8 ++++ .../states/contextMenuIsOpenState.ts | 0 .../states/contextMenuPositionState.ts | 3 +- .../types/ActionBarItemAccent.ts | 0 .../types/ActionMenuEntry.ts} | 3 +- .../types/PositionType.ts | 0 .../states/contextMenuEntriesState.ts | 8 ---- .../types/ContextMenuItemAccent.ts | 1 - .../shared/components/NavigationModal.tsx | 23 ---------- 35 files changed, 94 insertions(+), 186 deletions(-) delete mode 100644 packages/twenty-front/src/modules/object-record/record-board/context-menu/components/RecordBoardContextMenu.tsx delete mode 100644 packages/twenty-front/src/modules/object-record/record-table/context-menu/components/RecordTableContextMenu.tsx delete mode 100644 packages/twenty-front/src/modules/ui/navigation/action-bar/states/actionBarEntriesState.ts delete mode 100644 packages/twenty-front/src/modules/ui/navigation/action-bar/types/ActionBarEntry.ts rename packages/twenty-front/src/modules/ui/navigation/{action-bar => action-menu}/components/ActionBar.tsx (79%) rename packages/twenty-front/src/modules/ui/navigation/{action-bar => action-menu}/components/ActionBarItem.tsx (96%) create mode 100644 packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenu.tsx rename packages/twenty-front/src/modules/ui/navigation/{context-menu => action-menu}/components/ContextMenu.tsx (65%) rename packages/twenty-front/src/modules/ui/navigation/{context-menu => action-menu}/components/ContextMenuItem.tsx (72%) create mode 100644 packages/twenty-front/src/modules/ui/navigation/action-menu/components/NavigationModal.tsx rename packages/twenty-front/src/modules/ui/navigation/{action-bar => action-menu}/components/__stories__/ActionBar.stories.tsx (100%) rename packages/twenty-front/src/modules/ui/navigation/{context-menu => action-menu}/components/__stories__/ContextMenu.stories.tsx (100%) rename packages/twenty-front/src/modules/ui/navigation/{shared => action-menu/components}/__stories__/NavigationModal.stories.tsx (68%) rename packages/twenty-front/src/modules/ui/navigation/{action-bar => action-menu}/states/actionBarIsOpenState.ts (100%) create mode 100644 packages/twenty-front/src/modules/ui/navigation/action-menu/states/actionMenuEntriesState.ts rename packages/twenty-front/src/modules/ui/navigation/{context-menu => action-menu}/states/contextMenuIsOpenState.ts (100%) rename packages/twenty-front/src/modules/ui/navigation/{context-menu => action-menu}/states/contextMenuPositionState.ts (70%) rename packages/twenty-front/src/modules/ui/navigation/{action-bar => action-menu}/types/ActionBarItemAccent.ts (100%) rename packages/twenty-front/src/modules/ui/navigation/{context-menu/types/ContextMenuEntry.ts => action-menu/types/ActionMenuEntry.ts} (83%) rename packages/twenty-front/src/modules/ui/navigation/{context-menu => action-menu}/types/PositionType.ts (100%) delete mode 100644 packages/twenty-front/src/modules/ui/navigation/context-menu/states/contextMenuEntriesState.ts delete mode 100644 packages/twenty-front/src/modules/ui/navigation/context-menu/types/ContextMenuItemAccent.ts delete mode 100644 packages/twenty-front/src/modules/ui/navigation/shared/components/NavigationModal.tsx diff --git a/packages/twenty-front/src/modules/object-record/record-action-bar/hooks/useRecordActionBar.tsx b/packages/twenty-front/src/modules/object-record/record-action-bar/hooks/useRecordActionBar.tsx index b7cce8057efb..57b241243869 100644 --- a/packages/twenty-front/src/modules/object-record/record-action-bar/hooks/useRecordActionBar.tsx +++ b/packages/twenty-front/src/modules/object-record/record-action-bar/hooks/useRecordActionBar.tsx @@ -13,9 +13,9 @@ import { } from '@/object-record/record-index/options/hooks/useExportTableData'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal'; -import { actionBarEntriesState } from '@/ui/navigation/action-bar/states/actionBarEntriesState'; -import { contextMenuEntriesState } from '@/ui/navigation/context-menu/states/contextMenuEntriesState'; -import { ContextMenuEntry } from '@/ui/navigation/context-menu/types/ContextMenuEntry'; + +import { actionMenuEntriesState } from '@/ui/navigation/action-menu/states/actionMenuEntriesState'; +import { ActionMenuEntry } from '@/ui/navigation/action-menu/types/ActionMenuEntry'; import { isDefined } from '~/utils/isDefined'; type useRecordActionBarProps = { @@ -31,8 +31,7 @@ export const useRecordActionBar = ({ callback, totalNumberOfRecordsSelected, }: useRecordActionBarProps) => { - const setContextMenuEntries = useSetRecoilState(contextMenuEntriesState); - const setActionBarEntriesState = useSetRecoilState(actionBarEntriesState); + const setActionMenuEntries = useSetRecoilState(actionMenuEntriesState); const [isDeleteRecordsModalOpen, setIsDeleteRecordsModalOpen] = useState(false); @@ -97,7 +96,7 @@ export const useRecordActionBar = ({ const canDelete = !isRemoteObject && numberOfSelectedRecords < DELETE_MAX_COUNT; - const menuActions: ContextMenuEntry[] = useMemo( + const menuActions: ActionMenuEntry[] = useMemo( () => [ { @@ -105,7 +104,7 @@ export const useRecordActionBar = ({ Icon: IconFileExport, accent: 'default', onClick: () => download(), - } satisfies ContextMenuEntry, + } satisfies ActionMenuEntry, canDelete ? ({ label: 'Delete', @@ -134,7 +133,7 @@ export const useRecordActionBar = ({ }`} /> ), - } satisfies ContextMenuEntry) + } satisfies ActionMenuEntry) : undefined, ].filter(isDefined), [ @@ -154,8 +153,8 @@ export const useRecordActionBar = ({ !!favorites?.find((favorite) => favorite.recordId === selectedRecordIds[0]); return { - setContextMenuEntries: useCallback(() => { - setContextMenuEntries([ + setActionMenuEntries: useCallback(() => { + setActionMenuEntries([ ...menuActions, ...(!isRemoteObject && isFavorite && hasOnlyOneRecordSelected ? [ @@ -182,31 +181,7 @@ export const useRecordActionBar = ({ hasOnlyOneRecordSelected, isFavorite, isRemoteObject, - setContextMenuEntries, + setActionMenuEntries, ]), - - setActionBarEntries: useCallback(() => { - setActionBarEntriesState([ - /* - { - label: 'Actions', - Icon: IconClick, - subActions: - - /* [ - { - label: 'Enrich', - Icon: IconPuzzle, - onClick: handleExecuteQuickActionOnClick, - }, - { - label: 'Send to mailjet', - Icon: IconMail, - }, - ], - */ - ...menuActions, - ]); - }, [menuActions, setActionBarEntriesState]), }; }; diff --git a/packages/twenty-front/src/modules/object-record/record-board/context-menu/components/RecordBoardContextMenu.tsx b/packages/twenty-front/src/modules/object-record/record-board/context-menu/components/RecordBoardContextMenu.tsx deleted file mode 100644 index fed35a6506d3..000000000000 --- a/packages/twenty-front/src/modules/object-record/record-board/context-menu/components/RecordBoardContextMenu.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { useRecoilValue } from 'recoil'; - -import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates'; -import { ContextMenu } from '@/ui/navigation/context-menu/components/ContextMenu'; - -type RecordBoardContextMenuProps = { - recordBoardId: string; -}; - -export const RecordBoardContextMenu = ({ - recordBoardId, -}: RecordBoardContextMenuProps) => { - const { selectedRecordIdsSelector } = useRecordBoardStates(recordBoardId); - - const selectedRecordIds = useRecoilValue(selectedRecordIdsSelector()); - - if (!selectedRecordIds.length) { - return null; - } - - return ; -}; 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 a14c85119d51..5bc9d3b62e06 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 @@ -1,7 +1,7 @@ import { useRecoilCallback, useSetRecoilState } from 'recoil'; import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates'; -import { contextMenuIsOpenState } from '@/ui/navigation/context-menu/states/contextMenuIsOpenState'; +import { contextMenuIsOpenState } from '@/ui/navigation/action-menu/states/contextMenuIsOpenState'; export const useRecordBoardSelection = (recordBoardId?: string) => { const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState); diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx index 4bfb9f2557fc..228d35be8c6c 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx @@ -17,8 +17,8 @@ import { ObjectRecord } from '@/object-record/types/ObjectRecord'; import { LightIconButton } from '@/ui/input/button/components/LightIconButton'; import { Checkbox, CheckboxVariant } from '@/ui/input/components/Checkbox'; import { TextInput } from '@/ui/input/components/TextInput'; -import { contextMenuIsOpenState } from '@/ui/navigation/context-menu/states/contextMenuIsOpenState'; -import { contextMenuPositionState } from '@/ui/navigation/context-menu/states/contextMenuPositionState'; +import { contextMenuIsOpenState } from '@/ui/navigation/action-menu/states/contextMenuIsOpenState'; +import { contextMenuPositionState } from '@/ui/navigation/action-menu/states/contextMenuPositionState'; import { AnimatedEaseInOut } from '@/ui/utilities/animation/components/AnimatedEaseInOut'; import { RecordBoardScrollWrapperContext } from '@/ui/utilities/scroll/contexts/ScrollWrapperContexts'; import styled from '@emotion/styled'; diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardContainer.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardContainer.tsx index 7658a4e9c1d8..b34fc8b7ac98 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardContainer.tsx @@ -5,7 +5,6 @@ import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord'; import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord'; import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord'; import { RecordBoard } from '@/object-record/record-board/components/RecordBoard'; -import { RecordBoardContextMenu } from '@/object-record/record-board/context-menu/components/RecordBoardContextMenu'; import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext'; import { recordIndexKanbanFieldMetadataIdState } from '@/object-record/record-index/states/recordIndexKanbanFieldMetadataIdState'; @@ -50,7 +49,6 @@ export const RecordIndexBoardContainer = ({ }} > - ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardDataLoaderEffect.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardDataLoaderEffect.tsx index fbbc80aee5de..49b18c0e4b8c 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardDataLoaderEffect.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardDataLoaderEffect.tsx @@ -124,7 +124,7 @@ export const RecordIndexBoardDataLoaderEffect = ({ const selectedRecordIds = useRecoilValue(selectedRecordIdsSelector()); - const { setActionBarEntries, setContextMenuEntries } = useRecordActionBar({ + const { setActionMenuEntries } = useRecordActionBar({ objectMetadataItem, selectedRecordIds, callback: resetRecordSelection, @@ -135,9 +135,8 @@ export const RecordIndexBoardDataLoaderEffect = ({ ); useEffect(() => { - setActionBarEntries?.(); - setContextMenuEntries?.(); - }, [setActionBarEntries, setContextMenuEntries]); + setActionMenuEntries?.(); + }, [setActionMenuEntries]); useEffect(() => { setContextStoreTargetedRecordIds(selectedRecordIds); diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx index 029a9a319778..891ec6bfbeb0 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx @@ -23,7 +23,9 @@ import { RecordIndexRootPropsContext } from '@/object-record/record-index/contex import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext'; import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable'; import { SpreadsheetImportProvider } from '@/spreadsheet-import/provider/components/SpreadsheetImportProvider'; -import { ActionBar } from '@/ui/navigation/action-bar/components/ActionBar'; + +import { ActionBar } from '@/ui/navigation/action-menu/components/ActionBar'; +import { ContextMenu } from '@/ui/navigation/action-menu/components/ContextMenu'; import { ViewBar } from '@/views/components/ViewBar'; import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext'; import { ViewField } from '@/views/types/ViewField'; @@ -193,6 +195,7 @@ export const RecordIndexContainer = () => { )} + diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexTableContainer.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexTableContainer.tsx index 0f9c228629c4..f1dec5e3e7e6 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexTableContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexTableContainer.tsx @@ -3,7 +3,6 @@ import { RecordUpdateHookParams } from '@/object-record/record-field/contexts/Fi import { RecordIndexRemoveSortingModal } from '@/object-record/record-index/components/RecordIndexRemoveSortingModal'; import { RecordIndexRootPropsContext } from '@/object-record/record-index/contexts/RecordIndexRootPropsContext'; import { RecordTableWithWrappers } from '@/object-record/record-table/components/RecordTableWithWrappers'; -import { RecordTableContextMenu } from '@/object-record/record-table/context-menu/components/RecordTableContextMenu'; import { useContext } from 'react'; type RecordIndexTableContainerProps = { @@ -37,7 +36,6 @@ export const RecordIndexTableContainer = ({ updateRecordMutation={updateEntity} /> - ); }; 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 63a2d367a8ca..40a884eecbff 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 @@ -74,7 +74,7 @@ export const RecordIndexTableContainerEffect = ({ (tableRowIds.length - selectedRowIds.length) // unselected row Ids : selectedRowIds.length; - const { setActionBarEntries, setContextMenuEntries } = useRecordActionBar({ + const { setActionMenuEntries } = useRecordActionBar({ objectMetadataItem, selectedRecordIds: selectedRowIds, callback: resetTableRowSelection, @@ -106,9 +106,8 @@ export const RecordIndexTableContainerEffect = ({ }, [setOnToggleColumnSort, handleToggleColumnSort]); useEffect(() => { - setActionBarEntries?.(); - setContextMenuEntries?.(); - }, [setActionBarEntries, setContextMenuEntries]); + setActionMenuEntries?.(); + }, [setActionMenuEntries]); useEffect(() => { setOnEntityCountChange( diff --git a/packages/twenty-front/src/modules/object-record/record-table/context-menu/components/RecordTableContextMenu.tsx b/packages/twenty-front/src/modules/object-record/record-table/context-menu/components/RecordTableContextMenu.tsx deleted file mode 100644 index d9f712ef82e4..000000000000 --- a/packages/twenty-front/src/modules/object-record/record-table/context-menu/components/RecordTableContextMenu.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { useRecoilValue } from 'recoil'; - -import { useRecordTableStates } from '@/object-record/record-table/hooks/internal/useRecordTableStates'; -import { ContextMenu } from '@/ui/navigation/context-menu/components/ContextMenu'; - -export const RecordTableContextMenu = ({ - recordTableId, -}: { - recordTableId: string; -}) => { - const { selectedRowIdsSelector } = useRecordTableStates(recordTableId); - - const selectedRowIds = useRecoilValue(selectedRowIdsSelector()); - - if (!selectedRowIds.length) { - return null; - } - - return ; -}; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellCheckbox.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellCheckbox.tsx index 645e2bc4ab6e..7fadf1b0c149 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellCheckbox.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellCheckbox.tsx @@ -7,7 +7,7 @@ import { useRecordTableStates } from '@/object-record/record-table/hooks/interna import { RecordTableTd } from '@/object-record/record-table/record-table-cell/components/RecordTableTd'; import { useSetCurrentRowSelected } from '@/object-record/record-table/record-table-row/hooks/useSetCurrentRowSelected'; import { Checkbox } from '@/ui/input/components/Checkbox'; -import { actionBarOpenState } from '@/ui/navigation/action-bar/states/actionBarIsOpenState'; +import { actionBarOpenState } from '@/ui/navigation/action-menu/states/actionBarIsOpenState'; const StyledContainer = styled.div` align-items: center; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerContextMenu.ts b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerContextMenu.ts index b9c04a8b7769..035e6b8ceddb 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerContextMenu.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerContextMenu.ts @@ -1,8 +1,8 @@ import { useRecoilCallback } from 'recoil'; import { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState'; -import { contextMenuIsOpenState } from '@/ui/navigation/context-menu/states/contextMenuIsOpenState'; -import { contextMenuPositionState } from '@/ui/navigation/context-menu/states/contextMenuPositionState'; +import { contextMenuIsOpenState } from '@/ui/navigation/action-menu/states/contextMenuIsOpenState'; +import { contextMenuPositionState } from '@/ui/navigation/action-menu/states/contextMenuPositionState'; import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId'; import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue'; import { extractComponentFamilyState } from '@/ui/utilities/state/component-state/utils/extractComponentFamilyState'; diff --git a/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockContainerEffect.tsx b/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockContainerEffect.tsx index f7fdf0218239..de08331b343a 100644 --- a/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockContainerEffect.tsx +++ b/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockContainerEffect.tsx @@ -75,16 +75,15 @@ export const SignInBackgroundMockContainerEffect = ({ setTableColumns, ]); - const { setActionBarEntries, setContextMenuEntries } = useRecordActionBar({ + const { setActionMenuEntries } = useRecordActionBar({ objectMetadataItem, selectedRecordIds: [], callback: resetTableRowSelection, }); useEffect(() => { - setActionBarEntries?.(); - setContextMenuEntries?.(); - }, [setActionBarEntries, setContextMenuEntries]); + setActionMenuEntries?.(); + }, [setActionMenuEntries]); useEffect(() => { setOnEntityCountChange( diff --git a/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockPage.tsx b/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockPage.tsx index c1a325563caf..2b17a655549d 100644 --- a/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockPage.tsx +++ b/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockPage.tsx @@ -2,7 +2,6 @@ import styled from '@emotion/styled'; import { IconBuildingSkyscraper } from 'twenty-ui'; import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext'; -import { RecordTableContextMenu } from '@/object-record/record-table/context-menu/components/RecordTableContextMenu'; import { SignInBackgroundMockContainer } from '@/sign-in-background-mock/components/SignInBackgroundMockContainer'; import { PageAddButton } from '@/ui/layout/page/PageAddButton'; import { PageBody } from '@/ui/layout/page/PageBody'; @@ -28,7 +27,6 @@ export const SignInBackgroundMockPage = () => { - diff --git a/packages/twenty-front/src/modules/ui/navigation/action-bar/states/actionBarEntriesState.ts b/packages/twenty-front/src/modules/ui/navigation/action-bar/states/actionBarEntriesState.ts deleted file mode 100644 index 35f8cab412b7..000000000000 --- a/packages/twenty-front/src/modules/ui/navigation/action-bar/states/actionBarEntriesState.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { createState } from 'twenty-ui'; - -import { ActionBarEntry } from '../types/ActionBarEntry'; - -export const actionBarEntriesState = createState({ - key: 'actionBarEntriesState', - defaultValue: [], -}); diff --git a/packages/twenty-front/src/modules/ui/navigation/action-bar/types/ActionBarEntry.ts b/packages/twenty-front/src/modules/ui/navigation/action-bar/types/ActionBarEntry.ts deleted file mode 100644 index a276736cfb1c..000000000000 --- a/packages/twenty-front/src/modules/ui/navigation/action-bar/types/ActionBarEntry.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { ContextMenuEntry } from '@/ui/navigation/context-menu/types/ContextMenuEntry'; - -export type ActionBarEntry = ContextMenuEntry & { - subActions?: ActionBarEntry[]; -}; diff --git a/packages/twenty-front/src/modules/ui/navigation/action-bar/components/ActionBar.tsx b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionBar.tsx similarity index 79% rename from packages/twenty-front/src/modules/ui/navigation/action-bar/components/ActionBar.tsx rename to packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionBar.tsx index 3eb9fc0d96fa..8f813c1214f5 100644 --- a/packages/twenty-front/src/modules/ui/navigation/action-bar/components/ActionBar.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionBar.tsx @@ -2,11 +2,9 @@ import styled from '@emotion/styled'; import { useEffect } from 'react'; import { useRecoilValue, useSetRecoilState } from 'recoil'; -import { actionBarEntriesState } from '@/ui/navigation/action-bar/states/actionBarEntriesState'; -import { contextMenuIsOpenState } from '@/ui/navigation/context-menu/states/contextMenuIsOpenState'; -import SharedNavigationModal from '@/ui/navigation/shared/components/NavigationModal'; - import { contextStoreTargetedRecordIdsState } from '@/context-store/states/contextStoreTargetedRecordIdsState'; +import { actionMenuEntriesState } from '@/ui/navigation/action-menu/states/actionMenuEntriesState'; +import { contextMenuIsOpenState } from '@/ui/navigation/action-menu/states/contextMenuIsOpenState'; import { ActionBarItem } from './ActionBarItem'; const StyledContainerActionBar = styled.div` @@ -51,7 +49,7 @@ export const ActionBar = () => { }, [contextStoreTargetedRecordIds, setContextMenuOpenState]); const contextMenuIsOpen = useRecoilValue(contextMenuIsOpenState); - const actionBarEntries = useRecoilValue(actionBarEntriesState); + const actionMenuEntries = useRecoilValue(actionMenuEntriesState); if (contextMenuIsOpen || !contextStoreTargetedRecordIds.length) { return null; @@ -63,14 +61,10 @@ export const ActionBar = () => { {contextStoreTargetedRecordIds?.length} selected: - {actionBarEntries.map((item, index) => ( + {actionMenuEntries.map((item, index) => ( ))} - ); }; diff --git a/packages/twenty-front/src/modules/ui/navigation/action-bar/components/ActionBarItem.tsx b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionBarItem.tsx similarity index 96% rename from packages/twenty-front/src/modules/ui/navigation/action-bar/components/ActionBarItem.tsx rename to packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionBarItem.tsx index dbb7623d25d4..dc8da5813521 100644 --- a/packages/twenty-front/src/modules/ui/navigation/action-bar/components/ActionBarItem.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionBarItem.tsx @@ -5,12 +5,12 @@ import { IconChevronDown } from 'twenty-ui'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; -import { ActionBarEntry } from '@/ui/navigation/action-bar/types/ActionBarEntry'; +import { ActionMenuEntry } from '@/ui/navigation/action-menu/types/ActionMenuEntry'; import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; import { MenuItemAccent } from '@/ui/navigation/menu-item/types/MenuItemAccent'; type ActionBarItemProps = { - item: ActionBarEntry; + item: ActionMenuEntry; }; const StyledButton = styled.div<{ accent: MenuItemAccent }>` diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenu.tsx b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenu.tsx new file mode 100644 index 000000000000..74b14bc7b020 --- /dev/null +++ b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenu.tsx @@ -0,0 +1,13 @@ +import { ActionBar } from '@/ui/navigation/action-menu/components/ActionBar'; +import { ContextMenu } from '@/ui/navigation/action-menu/components/ContextMenu'; +import { NavigationModal } from '@/ui/navigation/action-menu/components/NavigationModal'; + +export const ActionMenu = () => { + return ( + <> + + + + + ); +}; diff --git a/packages/twenty-front/src/modules/ui/navigation/context-menu/components/ContextMenu.tsx b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ContextMenu.tsx similarity index 65% rename from packages/twenty-front/src/modules/ui/navigation/context-menu/components/ContextMenu.tsx rename to packages/twenty-front/src/modules/ui/navigation/action-menu/components/ContextMenu.tsx index e27c6096cb07..6212f899fdad 100644 --- a/packages/twenty-front/src/modules/ui/navigation/context-menu/components/ContextMenu.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ContextMenu.tsx @@ -1,17 +1,14 @@ -import React, { useRef } from 'react'; import styled from '@emotion/styled'; import { useRecoilValue } from 'recoil'; import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; -import { actionBarEntriesState } from '@/ui/navigation/action-bar/states/actionBarEntriesState'; -import { contextMenuPositionState } from '@/ui/navigation/context-menu/states/contextMenuPositionState'; -import SharedNavigationModal from '@/ui/navigation/shared/components/NavigationModal'; -import { contextMenuEntriesState } from '../states/contextMenuEntriesState'; +import { actionMenuEntriesState } from '../states/actionMenuEntriesState'; import { contextMenuIsOpenState } from '../states/contextMenuIsOpenState'; import { PositionType } from '../types/PositionType'; +import { contextMenuPositionState } from '@/ui/navigation/action-menu/states/contextMenuPositionState'; import { ContextMenuItem } from './ContextMenuItem'; type StyledContainerProps = { @@ -40,16 +37,14 @@ const StyledContainerContextMenu = styled.div` export const ContextMenu = () => { const contextMenuPosition = useRecoilValue(contextMenuPositionState); const contextMenuIsOpen = useRecoilValue(contextMenuIsOpenState); - const contextMenuEntries = useRecoilValue(contextMenuEntriesState); - const wrapperRef = useRef(null); - const actionBarEntries = useRecoilValue(actionBarEntriesState); + const actionMenuEntries = useRecoilValue(actionMenuEntriesState); if (!contextMenuIsOpen) { return null; } - const width = contextMenuEntries.some( - (contextMenuEntry) => contextMenuEntry.label === 'Remove from favorites', + const width = actionMenuEntries.some( + (actionMenuEntry) => actionMenuEntry.label === 'Remove from favorites', ) ? 200 : undefined; @@ -58,21 +53,16 @@ export const ContextMenu = () => { <> - {contextMenuEntries.map((item, index) => { + {actionMenuEntries.map((item, index) => { return ; })} - ); }; diff --git a/packages/twenty-front/src/modules/ui/navigation/context-menu/components/ContextMenuItem.tsx b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ContextMenuItem.tsx similarity index 72% rename from packages/twenty-front/src/modules/ui/navigation/context-menu/components/ContextMenuItem.tsx rename to packages/twenty-front/src/modules/ui/navigation/action-menu/components/ContextMenuItem.tsx index 4ec9822a6750..d59400f579de 100644 --- a/packages/twenty-front/src/modules/ui/navigation/context-menu/components/ContextMenuItem.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ContextMenuItem.tsx @@ -1,8 +1,8 @@ -import { ContextMenuEntry } from '@/ui/navigation/context-menu/types/ContextMenuEntry'; +import { ActionMenuEntry } from '@/ui/navigation/action-menu/types/ActionMenuEntry'; import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; type ContextMenuItemProps = { - item: ContextMenuEntry; + item: ActionMenuEntry; }; export const ContextMenuItem = ({ item }: ContextMenuItemProps) => ( diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/NavigationModal.tsx b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/NavigationModal.tsx new file mode 100644 index 000000000000..efa25784b14d --- /dev/null +++ b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/NavigationModal.tsx @@ -0,0 +1,21 @@ +import { ActionMenuEntry } from '@/ui/navigation/action-menu/types/ActionMenuEntry'; + +type NavigationModalProps = { + actionMenuEntries: ActionMenuEntry[]; + customClassName: string; +}; + +export const NavigationModal = ({ + actionMenuEntries, + customClassName, +}: NavigationModalProps) => { + return ( +
+ {actionMenuEntries.map((actionMenuEntry, index) => + actionMenuEntry.ConfirmationModal ? ( +
{actionMenuEntry.ConfirmationModal}
+ ) : null, + )} +
+ ); +}; diff --git a/packages/twenty-front/src/modules/ui/navigation/action-bar/components/__stories__/ActionBar.stories.tsx b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/__stories__/ActionBar.stories.tsx similarity index 100% rename from packages/twenty-front/src/modules/ui/navigation/action-bar/components/__stories__/ActionBar.stories.tsx rename to packages/twenty-front/src/modules/ui/navigation/action-menu/components/__stories__/ActionBar.stories.tsx diff --git a/packages/twenty-front/src/modules/ui/navigation/context-menu/components/__stories__/ContextMenu.stories.tsx b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/__stories__/ContextMenu.stories.tsx similarity index 100% rename from packages/twenty-front/src/modules/ui/navigation/context-menu/components/__stories__/ContextMenu.stories.tsx rename to packages/twenty-front/src/modules/ui/navigation/action-menu/components/__stories__/ContextMenu.stories.tsx diff --git a/packages/twenty-front/src/modules/ui/navigation/shared/__stories__/NavigationModal.stories.tsx b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/__stories__/NavigationModal.stories.tsx similarity index 68% rename from packages/twenty-front/src/modules/ui/navigation/shared/__stories__/NavigationModal.stories.tsx rename to packages/twenty-front/src/modules/ui/navigation/action-menu/components/__stories__/NavigationModal.stories.tsx index becc1b72ab66..13b67280c0cc 100644 --- a/packages/twenty-front/src/modules/ui/navigation/shared/__stories__/NavigationModal.stories.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/__stories__/NavigationModal.stories.tsx @@ -2,13 +2,13 @@ import { Meta, StoryObj } from '@storybook/react'; import { IconTrash } from 'twenty-ui'; import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal'; -import SharedNavigationModal from '@/ui/navigation/shared/components/NavigationModal'; +import { NavigationModal } from '@/ui/navigation/action-menu/components/NavigationModal'; -const meta: Meta = { - title: 'UI/Navigation/Shared/SharedNavigationModal', - component: SharedNavigationModal, +const meta: Meta = { + title: 'UI/Navigation/Shared/NavigationModal', + component: NavigationModal, args: { - actionBarEntries: [ + actionMenuEntries: [ { ConfirmationModal: ( = { }; export default meta; -type Story = StoryObj; +type Story = StoryObj; export const Default: Story = {}; diff --git a/packages/twenty-front/src/modules/ui/navigation/action-bar/states/actionBarIsOpenState.ts b/packages/twenty-front/src/modules/ui/navigation/action-menu/states/actionBarIsOpenState.ts similarity index 100% rename from packages/twenty-front/src/modules/ui/navigation/action-bar/states/actionBarIsOpenState.ts rename to packages/twenty-front/src/modules/ui/navigation/action-menu/states/actionBarIsOpenState.ts diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/states/actionMenuEntriesState.ts b/packages/twenty-front/src/modules/ui/navigation/action-menu/states/actionMenuEntriesState.ts new file mode 100644 index 000000000000..9d3fc62d999e --- /dev/null +++ b/packages/twenty-front/src/modules/ui/navigation/action-menu/states/actionMenuEntriesState.ts @@ -0,0 +1,8 @@ +import { createState } from 'twenty-ui'; + +import { ActionMenuEntry } from '../types/ActionMenuEntry'; + +export const actionMenuEntriesState = createState({ + key: 'actionMenuEntriesState', + defaultValue: [], +}); diff --git a/packages/twenty-front/src/modules/ui/navigation/context-menu/states/contextMenuIsOpenState.ts b/packages/twenty-front/src/modules/ui/navigation/action-menu/states/contextMenuIsOpenState.ts similarity index 100% rename from packages/twenty-front/src/modules/ui/navigation/context-menu/states/contextMenuIsOpenState.ts rename to packages/twenty-front/src/modules/ui/navigation/action-menu/states/contextMenuIsOpenState.ts diff --git a/packages/twenty-front/src/modules/ui/navigation/context-menu/states/contextMenuPositionState.ts b/packages/twenty-front/src/modules/ui/navigation/action-menu/states/contextMenuPositionState.ts similarity index 70% rename from packages/twenty-front/src/modules/ui/navigation/context-menu/states/contextMenuPositionState.ts rename to packages/twenty-front/src/modules/ui/navigation/action-menu/states/contextMenuPositionState.ts index a47df13eb017..1312fa053f8f 100644 --- a/packages/twenty-front/src/modules/ui/navigation/context-menu/states/contextMenuPositionState.ts +++ b/packages/twenty-front/src/modules/ui/navigation/action-menu/states/contextMenuPositionState.ts @@ -1,7 +1,6 @@ +import { PositionType } from '@/ui/navigation/action-menu/types/PositionType'; import { createState } from 'twenty-ui'; -import { PositionType } from '@/ui/navigation/context-menu/types/PositionType'; - export const contextMenuPositionState = createState({ key: 'contextMenuPositionState', defaultValue: { diff --git a/packages/twenty-front/src/modules/ui/navigation/action-bar/types/ActionBarItemAccent.ts b/packages/twenty-front/src/modules/ui/navigation/action-menu/types/ActionBarItemAccent.ts similarity index 100% rename from packages/twenty-front/src/modules/ui/navigation/action-bar/types/ActionBarItemAccent.ts rename to packages/twenty-front/src/modules/ui/navigation/action-menu/types/ActionBarItemAccent.ts diff --git a/packages/twenty-front/src/modules/ui/navigation/context-menu/types/ContextMenuEntry.ts b/packages/twenty-front/src/modules/ui/navigation/action-menu/types/ActionMenuEntry.ts similarity index 83% rename from packages/twenty-front/src/modules/ui/navigation/context-menu/types/ContextMenuEntry.ts rename to packages/twenty-front/src/modules/ui/navigation/action-menu/types/ActionMenuEntry.ts index 416a41419f62..59f633548bd5 100644 --- a/packages/twenty-front/src/modules/ui/navigation/context-menu/types/ContextMenuEntry.ts +++ b/packages/twenty-front/src/modules/ui/navigation/action-menu/types/ActionMenuEntry.ts @@ -3,10 +3,11 @@ import { IconComponent } from 'twenty-ui'; import { MenuItemAccent } from '@/ui/navigation/menu-item/types/MenuItemAccent'; -export type ContextMenuEntry = { +export type ActionMenuEntry = { label: string; Icon: IconComponent; accent?: MenuItemAccent; onClick?: (event?: MouseEvent) => void; ConfirmationModal?: ReactNode; + subActions?: ActionMenuEntry[]; }; diff --git a/packages/twenty-front/src/modules/ui/navigation/context-menu/types/PositionType.ts b/packages/twenty-front/src/modules/ui/navigation/action-menu/types/PositionType.ts similarity index 100% rename from packages/twenty-front/src/modules/ui/navigation/context-menu/types/PositionType.ts rename to packages/twenty-front/src/modules/ui/navigation/action-menu/types/PositionType.ts diff --git a/packages/twenty-front/src/modules/ui/navigation/context-menu/states/contextMenuEntriesState.ts b/packages/twenty-front/src/modules/ui/navigation/context-menu/states/contextMenuEntriesState.ts deleted file mode 100644 index 1e22b562187e..000000000000 --- a/packages/twenty-front/src/modules/ui/navigation/context-menu/states/contextMenuEntriesState.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { createState } from 'twenty-ui'; - -import { ContextMenuEntry } from '../types/ContextMenuEntry'; - -export const contextMenuEntriesState = createState({ - key: 'contextMenuEntriesState', - defaultValue: [], -}); diff --git a/packages/twenty-front/src/modules/ui/navigation/context-menu/types/ContextMenuItemAccent.ts b/packages/twenty-front/src/modules/ui/navigation/context-menu/types/ContextMenuItemAccent.ts deleted file mode 100644 index ceae88f5beea..000000000000 --- a/packages/twenty-front/src/modules/ui/navigation/context-menu/types/ContextMenuItemAccent.ts +++ /dev/null @@ -1 +0,0 @@ -export type ContextMenuItemAccent = 'default' | 'danger'; diff --git a/packages/twenty-front/src/modules/ui/navigation/shared/components/NavigationModal.tsx b/packages/twenty-front/src/modules/ui/navigation/shared/components/NavigationModal.tsx deleted file mode 100644 index eeba07087165..000000000000 --- a/packages/twenty-front/src/modules/ui/navigation/shared/components/NavigationModal.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { ActionBarEntry } from '@/ui/navigation/action-bar/types/ActionBarEntry'; - -type SharedNavigationModalProps = { - actionBarEntries: ActionBarEntry[]; - customClassName: string; -}; - -const SharedNavigationModal = ({ - actionBarEntries, - customClassName, -}: SharedNavigationModalProps) => { - return ( -
- {actionBarEntries.map((actionBarEntry, index) => - actionBarEntry.ConfirmationModal ? ( -
{actionBarEntry.ConfirmationModal}
- ) : null, - )} -
- ); -}; - -export default SharedNavigationModal; From accf0dcfd95d093818b18e25b7a26a8ac5923366 Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Wed, 2 Oct 2024 17:21:25 +0200 Subject: [PATCH 12/52] refactoring ActionMenu components --- .../components/RecordIndexContainer.tsx | 6 +-- .../action-menu/components/ActionBar.tsx | 37 +++++------------- .../action-menu/components/ActionMenu.tsx | 39 +++++++++++++++++-- ...ContextMenu.tsx => ActionMenuDropdown.tsx} | 35 +++++++++-------- .../components/ContextMenuItem.tsx | 15 ------- .../components/NavigationModal.tsx | 4 +- .../__stories__/ContextMenu.stories.tsx | 8 ++-- .../__stories__/NavigationModal.stories.tsx | 1 - 8 files changed, 69 insertions(+), 76 deletions(-) rename packages/twenty-front/src/modules/ui/navigation/action-menu/components/{ContextMenu.tsx => ActionMenuDropdown.tsx} (69%) delete mode 100644 packages/twenty-front/src/modules/ui/navigation/action-menu/components/ContextMenuItem.tsx diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx index 891ec6bfbeb0..655acba61842 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx @@ -24,8 +24,7 @@ import { RecordFieldValueSelectorContextProvider } from '@/object-record/record- import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable'; import { SpreadsheetImportProvider } from '@/spreadsheet-import/provider/components/SpreadsheetImportProvider'; -import { ActionBar } from '@/ui/navigation/action-menu/components/ActionBar'; -import { ContextMenu } from '@/ui/navigation/action-menu/components/ContextMenu'; +import { ActionMenu } from '@/ui/navigation/action-menu/components/ActionMenu'; import { ViewBar } from '@/views/components/ViewBar'; import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext'; import { ViewField } from '@/views/types/ViewField'; @@ -194,8 +193,7 @@ export const RecordIndexContainer = () => { /> )} - - + diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionBar.tsx b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionBar.tsx index 8f813c1214f5..42830dbbacfb 100644 --- a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionBar.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionBar.tsx @@ -1,10 +1,6 @@ import styled from '@emotion/styled'; -import { useEffect } from 'react'; -import { useRecoilValue, useSetRecoilState } from 'recoil'; -import { contextStoreTargetedRecordIdsState } from '@/context-store/states/contextStoreTargetedRecordIdsState'; -import { actionMenuEntriesState } from '@/ui/navigation/action-menu/states/actionMenuEntriesState'; -import { contextMenuIsOpenState } from '@/ui/navigation/action-menu/states/contextMenuIsOpenState'; +import { ActionMenuEntry } from '@/ui/navigation/action-menu/types/ActionMenuEntry'; import { ActionBarItem } from './ActionBarItem'; const StyledContainerActionBar = styled.div` @@ -35,32 +31,17 @@ const StyledLabel = styled.div` padding-right: ${({ theme }) => theme.spacing(2)}; `; -export const ActionBar = () => { - const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState); - - const contextStoreTargetedRecordIds = useRecoilValue( - contextStoreTargetedRecordIdsState, - ); - - useEffect(() => { - if (contextStoreTargetedRecordIds.length > 1) { - setContextMenuOpenState(false); - } - }, [contextStoreTargetedRecordIds, setContextMenuOpenState]); - - const contextMenuIsOpen = useRecoilValue(contextMenuIsOpenState); - const actionMenuEntries = useRecoilValue(actionMenuEntriesState); - - if (contextMenuIsOpen || !contextStoreTargetedRecordIds.length) { - return null; - } - +export const ActionBar = ({ + selectedRecordIds, + actionMenuEntries, +}: { + selectedRecordIds: string[]; + actionMenuEntries: ActionMenuEntry[]; +}) => { return ( <> - - {contextStoreTargetedRecordIds?.length} selected: - + {selectedRecordIds?.length} selected: {actionMenuEntries.map((item, index) => ( ))} diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenu.tsx b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenu.tsx index 74b14bc7b020..e068450e7a90 100644 --- a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenu.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenu.tsx @@ -1,13 +1,44 @@ +import { contextStoreTargetedRecordIdsState } from '@/context-store/states/contextStoreTargetedRecordIdsState'; import { ActionBar } from '@/ui/navigation/action-menu/components/ActionBar'; -import { ContextMenu } from '@/ui/navigation/action-menu/components/ContextMenu'; +import { ActionMenuDropdown } from '@/ui/navigation/action-menu/components/ActionMenuDropdown'; import { NavigationModal } from '@/ui/navigation/action-menu/components/NavigationModal'; +import { actionMenuEntriesState } from '@/ui/navigation/action-menu/states/actionMenuEntriesState'; +import { contextMenuIsOpenState } from '@/ui/navigation/action-menu/states/contextMenuIsOpenState'; +import { useEffect } from 'react'; +import { useRecoilValue, useSetRecoilState } from 'recoil'; export const ActionMenu = () => { + const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState); + + const contextStoreTargetedRecordIds = useRecoilValue( + contextStoreTargetedRecordIdsState, + ); + + useEffect(() => { + if (contextStoreTargetedRecordIds.length > 1) { + setContextMenuOpenState(false); + } + }, [contextStoreTargetedRecordIds, setContextMenuOpenState]); + + const contextMenuIsOpen = useRecoilValue(contextMenuIsOpenState); + const actionMenuEntries = useRecoilValue(actionMenuEntriesState); + + if (!contextStoreTargetedRecordIds.length) { + return null; + } + return ( <> - - - + {!contextMenuIsOpen && ( + + )} + {contextMenuIsOpen && ( + + )} + ); }; diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ContextMenu.tsx b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenuDropdown.tsx similarity index 69% rename from packages/twenty-front/src/modules/ui/navigation/action-menu/components/ContextMenu.tsx rename to packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenuDropdown.tsx index 6212f899fdad..80d886e6a567 100644 --- a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ContextMenu.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenuDropdown.tsx @@ -4,12 +4,11 @@ import { useRecoilValue } from 'recoil'; import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; -import { actionMenuEntriesState } from '../states/actionMenuEntriesState'; -import { contextMenuIsOpenState } from '../states/contextMenuIsOpenState'; import { PositionType } from '../types/PositionType'; import { contextMenuPositionState } from '@/ui/navigation/action-menu/states/contextMenuPositionState'; -import { ContextMenuItem } from './ContextMenuItem'; +import { ActionMenuEntry } from '@/ui/navigation/action-menu/types/ActionMenuEntry'; +import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; type StyledContainerProps = { position: PositionType; @@ -34,15 +33,14 @@ const StyledContainerContextMenu = styled.div` z-index: 2; `; -export const ContextMenu = () => { +export const ActionMenuDropdown = ({ + actionMenuEntries, +}: { + actionMenuEntries: ActionMenuEntry[]; +}) => { const contextMenuPosition = useRecoilValue(contextMenuPositionState); - const contextMenuIsOpen = useRecoilValue(contextMenuIsOpenState); - const actionMenuEntries = useRecoilValue(actionMenuEntriesState); - - if (!contextMenuIsOpen) { - return null; - } + //TODO: remove this const width = actionMenuEntries.some( (actionMenuEntry) => actionMenuEntry.label === 'Remove from favorites', ) @@ -51,15 +49,18 @@ export const ContextMenu = () => { return ( <> - + - {actionMenuEntries.map((item, index) => { - return ; - })} + {actionMenuEntries.map((item, index) => ( + + ))} diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ContextMenuItem.tsx b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ContextMenuItem.tsx deleted file mode 100644 index d59400f579de..000000000000 --- a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ContextMenuItem.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { ActionMenuEntry } from '@/ui/navigation/action-menu/types/ActionMenuEntry'; -import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; - -type ContextMenuItemProps = { - item: ActionMenuEntry; -}; - -export const ContextMenuItem = ({ item }: ContextMenuItemProps) => ( - -); diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/NavigationModal.tsx b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/NavigationModal.tsx index efa25784b14d..d71d7913cd14 100644 --- a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/NavigationModal.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/NavigationModal.tsx @@ -2,15 +2,13 @@ import { ActionMenuEntry } from '@/ui/navigation/action-menu/types/ActionMenuEnt type NavigationModalProps = { actionMenuEntries: ActionMenuEntry[]; - customClassName: string; }; export const NavigationModal = ({ actionMenuEntries, - customClassName, }: NavigationModalProps) => { return ( -
+
{actionMenuEntries.map((actionMenuEntry, index) => actionMenuEntry.ConfirmationModal ? (
{actionMenuEntry.ConfirmationModal}
diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/__stories__/ContextMenu.stories.tsx b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/__stories__/ContextMenu.stories.tsx index 2b2f29e5c4ee..edcdc6a0ccae 100644 --- a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/__stories__/ContextMenu.stories.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/__stories__/ContextMenu.stories.tsx @@ -7,7 +7,7 @@ import { MemoryRouterDecorator } from '~/testing/decorators/MemoryRouterDecorato import { contextMenuIsOpenState } from '../../states/contextMenuIsOpenState'; import { contextMenuPositionState } from '../../states/contextMenuPositionState'; -import { ContextMenu } from '../ContextMenu'; +import { ActionMenuDropdown } from '../ActionMenuDropdown'; const FilledContextMenu = () => { const setContextMenuPosition = useSetRecoilState(contextMenuPositionState); @@ -17,10 +17,10 @@ const FilledContextMenu = () => { }); const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState); setContextMenuOpenState(true); - return ; + return ; }; -const meta: Meta = { +const meta: Meta = { title: 'UI/Navigation/ContextMenu/ContextMenu', component: FilledContextMenu, decorators: [ @@ -39,6 +39,6 @@ const meta: Meta = { }; export default meta; -type Story = StoryObj; +type Story = StoryObj; export const Default: Story = {}; diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/__stories__/NavigationModal.stories.tsx b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/__stories__/NavigationModal.stories.tsx index 13b67280c0cc..cb2cd7743891 100644 --- a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/__stories__/NavigationModal.stories.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/__stories__/NavigationModal.stories.tsx @@ -25,7 +25,6 @@ const meta: Meta = { onClick: () => {}, }, ], - customClassName: 'customClassName', }, }; From f582a5cbd9b245fbfb87ae4a7ae51841c80281c3 Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Wed, 2 Oct 2024 18:32:56 +0200 Subject: [PATCH 13/52] fix ActionMenuDropdown behavior --- .../modules/ui/navigation/action-menu/components/ActionMenu.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenu.tsx b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenu.tsx index e068450e7a90..f1c9fcf15b92 100644 --- a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenu.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenu.tsx @@ -15,7 +15,7 @@ export const ActionMenu = () => { ); useEffect(() => { - if (contextStoreTargetedRecordIds.length > 1) { + if (contextStoreTargetedRecordIds.length !== 1) { setContextMenuOpenState(false); } }, [contextStoreTargetedRecordIds, setContextMenuOpenState]); From a6b013713d5cdcc07b410a45edeb3845884bd817 Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Wed, 2 Oct 2024 18:48:18 +0200 Subject: [PATCH 14/52] renaming --- .../hooks/useRecordBoardSelection.ts | 10 +++++---- .../components/RecordBoardCard.tsx | 20 ++++++++++------- .../components/RecordTableContextProvider.tsx | 13 ++++++----- .../perf/RecordTableCell.perf.stories.tsx | 2 +- .../contexts/RecordTableContext.ts | 2 +- .../RecordTableCellBaseContainer.tsx | 8 +++---- .../hooks/useTriggerContextMenu.ts | 14 ++++++------ .../action-menu/components/ActionMenu.tsx | 18 +++++++++------ .../components/ActionMenuDropdown.tsx | 12 +++++----- .../__stories__/ContextMenu.stories.tsx | 22 +++++++++++-------- .../states/actionMenuDropdownIsOpenState.ts | 6 +++++ ....ts => actionMenuDropdownPositionState.ts} | 4 ++-- .../states/contextMenuIsOpenState.ts | 6 ----- .../hotkey/utils/isNonTextWritingKey.ts | 2 +- .../decorators/RecordTableDecorator.tsx | 2 +- 15 files changed, 80 insertions(+), 61 deletions(-) create mode 100644 packages/twenty-front/src/modules/ui/navigation/action-menu/states/actionMenuDropdownIsOpenState.ts rename packages/twenty-front/src/modules/ui/navigation/action-menu/states/{contextMenuPositionState.ts => actionMenuDropdownPositionState.ts} (59%) delete mode 100644 packages/twenty-front/src/modules/ui/navigation/action-menu/states/contextMenuIsOpenState.ts 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 5bc9d3b62e06..51d471bb201d 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 @@ -1,17 +1,19 @@ import { useRecoilCallback, useSetRecoilState } from 'recoil'; import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates'; -import { contextMenuIsOpenState } from '@/ui/navigation/action-menu/states/contextMenuIsOpenState'; +import { actionMenuDropdownIsOpenState } from '@/ui/navigation/action-menu/states/actionMenuDropdownIsOpenState'; export const useRecordBoardSelection = (recordBoardId?: string) => { - const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState); + const setActionMenuDropdownOpenState = useSetRecoilState( + actionMenuDropdownIsOpenState, + ); const { selectedRecordIdsSelector, isRecordBoardCardSelectedFamilyState } = useRecordBoardStates(recordBoardId); const resetRecordSelection = useRecoilCallback( ({ snapshot, set }) => () => { - setContextMenuOpenState(false); + setActionMenuDropdownOpenState(false); const recordIds = snapshot .getLoadable(selectedRecordIdsSelector()) .getValue(); @@ -23,7 +25,7 @@ export const useRecordBoardSelection = (recordBoardId?: string) => { [ selectedRecordIdsSelector, isRecordBoardCardSelectedFamilyState, - setContextMenuOpenState, + setActionMenuDropdownOpenState, ], ); diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx index 228d35be8c6c..320883cccb2c 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx @@ -17,8 +17,8 @@ import { ObjectRecord } from '@/object-record/types/ObjectRecord'; import { LightIconButton } from '@/ui/input/button/components/LightIconButton'; import { Checkbox, CheckboxVariant } from '@/ui/input/components/Checkbox'; import { TextInput } from '@/ui/input/components/TextInput'; -import { contextMenuIsOpenState } from '@/ui/navigation/action-menu/states/contextMenuIsOpenState'; -import { contextMenuPositionState } from '@/ui/navigation/action-menu/states/contextMenuPositionState'; +import { actionMenuDropdownIsOpenState } from '@/ui/navigation/action-menu/states/actionMenuDropdownIsOpenState'; +import { actionMenuDropdownPositionState } from '@/ui/navigation/action-menu/states/actionMenuDropdownPositionState'; import { AnimatedEaseInOut } from '@/ui/utilities/animation/components/AnimatedEaseInOut'; import { RecordBoardScrollWrapperContext } from '@/ui/utilities/scroll/contexts/ScrollWrapperContexts'; import styled from '@emotion/styled'; @@ -178,17 +178,21 @@ export const RecordBoardCard = ({ const record = useRecoilValue(recordStoreFamilyState(recordId)); - const setContextMenuPosition = useSetRecoilState(contextMenuPositionState); - const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState); + const setActionMenuDropdownPosition = useSetRecoilState( + actionMenuDropdownPositionState, + ); + const setActionMenuDropdownOpenState = useSetRecoilState( + actionMenuDropdownIsOpenState, + ); - const handleContextMenu = (event: React.MouseEvent) => { + const handleActionMenuDropdown = (event: React.MouseEvent) => { event.preventDefault(); setIsCurrentCardSelected(true); - setContextMenuPosition({ + setActionMenuDropdownPosition({ x: event.clientX, y: event.clientY, }); - setContextMenuOpenState(true); + setActionMenuDropdownOpenState(true); }; const PreventSelectOnClickContainer = ({ @@ -238,7 +242,7 @@ export const RecordBoardCard = ({ ); return ( - + {!isCreating && } { - triggerContextMenu(event, recordId); + const handleActionMenuDropdown = ( + event: React.MouseEvent, + recordId: string, + ) => { + triggerActionMenuDropdown(event, recordId); }; const { handleContainerMouseEnter } = useHandleContainerMouseEnter({ @@ -99,7 +102,7 @@ export const RecordTableContextProvider = ({ onMoveFocus: handleMoveFocus, onCloseTableCell: handleCloseTableCell, onMoveSoftFocusToCell: handleMoveSoftFocusToCell, - onContextMenu: handleContextMenu, + onActionMenuDropdown: handleActionMenuDropdown, onCellMouseEnter: handleContainerMouseEnter, visibleTableColumns, recordTableId, diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/__stories__/perf/RecordTableCell.perf.stories.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/__stories__/perf/RecordTableCell.perf.stories.tsx index 9b68416e8192..0cc7d83e7846 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/__stories__/perf/RecordTableCell.perf.stories.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/__stories__/perf/RecordTableCell.perf.stories.tsx @@ -70,7 +70,7 @@ const meta: Meta = { onMoveFocus: () => {}, onCloseTableCell: () => {}, onMoveSoftFocusToCell: () => {}, - onContextMenu: () => {}, + onActionMenuDropdown: () => {}, onCellMouseEnter: () => {}, visibleTableColumns: mockPerformance.visibleTableColumns as any, objectNameSingular: diff --git a/packages/twenty-front/src/modules/object-record/record-table/contexts/RecordTableContext.ts b/packages/twenty-front/src/modules/object-record/record-table/contexts/RecordTableContext.ts index cf8a8afed861..c1114e406a88 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/contexts/RecordTableContext.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/contexts/RecordTableContext.ts @@ -24,7 +24,7 @@ export type RecordTableContextProps = { onMoveFocus: (direction: MoveFocusDirection) => void; onCloseTableCell: () => void; onMoveSoftFocusToCell: (cellPosition: TableCellPosition) => void; - onContextMenu: (event: React.MouseEvent, recordId: string) => void; + onActionMenuDropdown: (event: React.MouseEvent, recordId: string) => void; onCellMouseEnter: (args: HandleContainerMouseEnterArgs) => void; visibleTableColumns: ColumnDefinition[]; recordTableId: string; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellBaseContainer.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellBaseContainer.tsx index 1e977ecaec4e..ab17a74fd255 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellBaseContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellBaseContainer.tsx @@ -71,10 +71,10 @@ export const RecordTableCellBaseContainer = ({ } }; - const { onContextMenu } = useContext(RecordTableContext); + const { onActionMenuDropdown } = useContext(RecordTableContext); - const handleContextMenu = (event: React.MouseEvent) => { - onContextMenu(event, recordId); + const handleActionMenuDropdown = (event: React.MouseEvent) => { + onActionMenuDropdown(event, recordId); }; const { hotkeyScope } = useContext(FieldContext); @@ -87,7 +87,7 @@ export const RecordTableCellBaseContainer = ({ onMouseLeave={handleContainerMouseLeave} onMouseMove={handleContainerMouseMove} onClick={handleContainerClick} - onContextMenu={handleContextMenu} + onContextMenu={handleActionMenuDropdown} backgroundColorTransparentSecondary={ theme.background.transparent.secondary } diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerContextMenu.ts b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerContextMenu.ts index 035e6b8ceddb..aa49e1491d9d 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerContextMenu.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerContextMenu.ts @@ -1,29 +1,29 @@ import { useRecoilCallback } from 'recoil'; import { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState'; -import { contextMenuIsOpenState } from '@/ui/navigation/action-menu/states/contextMenuIsOpenState'; -import { contextMenuPositionState } from '@/ui/navigation/action-menu/states/contextMenuPositionState'; +import { actionMenuDropdownIsOpenState } from '@/ui/navigation/action-menu/states/actionMenuDropdownIsOpenState'; +import { actionMenuDropdownPositionState } from '@/ui/navigation/action-menu/states/actionMenuDropdownPositionState'; import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId'; import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue'; import { extractComponentFamilyState } from '@/ui/utilities/state/component-state/utils/extractComponentFamilyState'; -export const useTriggerContextMenu = ({ +export const useTriggerActionMenuDropdown = ({ recordTableId, }: { recordTableId: string; }) => { - const triggerContextMenu = useRecoilCallback( + const triggerActionMenuDropdown = useRecoilCallback( ({ set, snapshot }) => (event: React.MouseEvent, recordId: string) => { event.preventDefault(); const tableScopeId = getScopeIdFromComponentId(recordTableId); - set(contextMenuPositionState, { + set(actionMenuDropdownPositionState, { x: event.clientX, y: event.clientY, }); - set(contextMenuIsOpenState, true); + set(actionMenuDropdownIsOpenState, true); const isRowSelectedFamilyState = extractComponentFamilyState( isRowSelectedComponentFamilyState, @@ -42,5 +42,5 @@ export const useTriggerContextMenu = ({ [recordTableId], ); - return { triggerContextMenu }; + return { triggerActionMenuDropdown }; }; diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenu.tsx b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenu.tsx index f1c9fcf15b92..ca57d53dd6c7 100644 --- a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenu.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenu.tsx @@ -2,13 +2,15 @@ import { contextStoreTargetedRecordIdsState } from '@/context-store/states/conte import { ActionBar } from '@/ui/navigation/action-menu/components/ActionBar'; import { ActionMenuDropdown } from '@/ui/navigation/action-menu/components/ActionMenuDropdown'; import { NavigationModal } from '@/ui/navigation/action-menu/components/NavigationModal'; +import { actionMenuDropdownIsOpenState } from '@/ui/navigation/action-menu/states/actionMenuDropdownIsOpenState'; import { actionMenuEntriesState } from '@/ui/navigation/action-menu/states/actionMenuEntriesState'; -import { contextMenuIsOpenState } from '@/ui/navigation/action-menu/states/contextMenuIsOpenState'; import { useEffect } from 'react'; import { useRecoilValue, useSetRecoilState } from 'recoil'; export const ActionMenu = () => { - const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState); + const setActionMenuDropdownOpenState = useSetRecoilState( + actionMenuDropdownIsOpenState, + ); const contextStoreTargetedRecordIds = useRecoilValue( contextStoreTargetedRecordIdsState, @@ -16,11 +18,13 @@ export const ActionMenu = () => { useEffect(() => { if (contextStoreTargetedRecordIds.length !== 1) { - setContextMenuOpenState(false); + setActionMenuDropdownOpenState(false); } - }, [contextStoreTargetedRecordIds, setContextMenuOpenState]); + }, [contextStoreTargetedRecordIds, setActionMenuDropdownOpenState]); - const contextMenuIsOpen = useRecoilValue(contextMenuIsOpenState); + const actionMenuDropdownIsOpen = useRecoilValue( + actionMenuDropdownIsOpenState, + ); const actionMenuEntries = useRecoilValue(actionMenuEntriesState); if (!contextStoreTargetedRecordIds.length) { @@ -29,13 +33,13 @@ export const ActionMenu = () => { return ( <> - {!contextMenuIsOpen && ( + {!actionMenuDropdownIsOpen && ( )} - {contextMenuIsOpen && ( + {actionMenuDropdownIsOpen && ( )} diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenuDropdown.tsx b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenuDropdown.tsx index 80d886e6a567..c0fd868aa9a5 100644 --- a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenuDropdown.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenuDropdown.tsx @@ -6,7 +6,7 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop import { PositionType } from '../types/PositionType'; -import { contextMenuPositionState } from '@/ui/navigation/action-menu/states/contextMenuPositionState'; +import { actionMenuDropdownPositionState } from '@/ui/navigation/action-menu/states/actionMenuDropdownPositionState'; import { ActionMenuEntry } from '@/ui/navigation/action-menu/types/ActionMenuEntry'; import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; @@ -14,7 +14,7 @@ type StyledContainerProps = { position: PositionType; }; -const StyledContainerContextMenu = styled.div` +const StyledContainerActionMenuDropdown = styled.div` align-items: flex-start; background: ${({ theme }) => theme.background.secondary}; border: 1px solid ${({ theme }) => theme.border.color.light}; @@ -38,7 +38,9 @@ export const ActionMenuDropdown = ({ }: { actionMenuEntries: ActionMenuEntry[]; }) => { - const contextMenuPosition = useRecoilValue(contextMenuPositionState); + const actionMenuDropdownPosition = useRecoilValue( + actionMenuDropdownPositionState, + ); //TODO: remove this const width = actionMenuEntries.some( @@ -49,7 +51,7 @@ export const ActionMenuDropdown = ({ return ( <> - + {actionMenuEntries.map((item, index) => ( @@ -63,7 +65,7 @@ export const ActionMenuDropdown = ({ ))} - + ); }; diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/__stories__/ContextMenu.stories.tsx b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/__stories__/ContextMenu.stories.tsx index edcdc6a0ccae..84fe6c76dce4 100644 --- a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/__stories__/ContextMenu.stories.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/action-menu/components/__stories__/ContextMenu.stories.tsx @@ -5,24 +5,28 @@ import { ComponentDecorator } from 'twenty-ui'; import { RecordTableScope } from '@/object-record/record-table/scopes/RecordTableScope'; import { MemoryRouterDecorator } from '~/testing/decorators/MemoryRouterDecorator'; -import { contextMenuIsOpenState } from '../../states/contextMenuIsOpenState'; -import { contextMenuPositionState } from '../../states/contextMenuPositionState'; +import { actionMenuDropdownIsOpenState } from '../../states/actionMenuDropdownIsOpenState'; +import { actionMenuDropdownPositionState } from '../../states/actionMenuDropdownPositionState'; import { ActionMenuDropdown } from '../ActionMenuDropdown'; -const FilledContextMenu = () => { - const setContextMenuPosition = useSetRecoilState(contextMenuPositionState); - setContextMenuPosition({ +const FilledActionMenuDropdown = () => { + const setActionMenuDropdownPosition = useSetRecoilState( + actionMenuDropdownPositionState, + ); + setActionMenuDropdownPosition({ x: 100, y: 10, }); - const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState); - setContextMenuOpenState(true); + const setActionMenuDropdownOpenState = useSetRecoilState( + actionMenuDropdownIsOpenState, + ); + setActionMenuDropdownOpenState(true); return ; }; const meta: Meta = { - title: 'UI/Navigation/ContextMenu/ContextMenu', - component: FilledContextMenu, + title: 'UI/Navigation/ActionMenuDropdown/ActionMenuDropdown', + component: FilledActionMenuDropdown, decorators: [ MemoryRouterDecorator, (Story) => ( diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/states/actionMenuDropdownIsOpenState.ts b/packages/twenty-front/src/modules/ui/navigation/action-menu/states/actionMenuDropdownIsOpenState.ts new file mode 100644 index 000000000000..47e16509864f --- /dev/null +++ b/packages/twenty-front/src/modules/ui/navigation/action-menu/states/actionMenuDropdownIsOpenState.ts @@ -0,0 +1,6 @@ +import { createState } from 'twenty-ui'; + +export const actionMenuDropdownIsOpenState = createState({ + key: 'actionMenuDropdownIsOpenState', + defaultValue: false, +}); diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/states/contextMenuPositionState.ts b/packages/twenty-front/src/modules/ui/navigation/action-menu/states/actionMenuDropdownPositionState.ts similarity index 59% rename from packages/twenty-front/src/modules/ui/navigation/action-menu/states/contextMenuPositionState.ts rename to packages/twenty-front/src/modules/ui/navigation/action-menu/states/actionMenuDropdownPositionState.ts index 1312fa053f8f..c62bb2b7f48c 100644 --- a/packages/twenty-front/src/modules/ui/navigation/action-menu/states/contextMenuPositionState.ts +++ b/packages/twenty-front/src/modules/ui/navigation/action-menu/states/actionMenuDropdownPositionState.ts @@ -1,8 +1,8 @@ import { PositionType } from '@/ui/navigation/action-menu/types/PositionType'; import { createState } from 'twenty-ui'; -export const contextMenuPositionState = createState({ - key: 'contextMenuPositionState', +export const actionMenuDropdownPositionState = createState({ + key: 'actionMenuDropdownPositionState', defaultValue: { x: null, y: null, diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/states/contextMenuIsOpenState.ts b/packages/twenty-front/src/modules/ui/navigation/action-menu/states/contextMenuIsOpenState.ts deleted file mode 100644 index d5aec39b905e..000000000000 --- a/packages/twenty-front/src/modules/ui/navigation/action-menu/states/contextMenuIsOpenState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { createState } from 'twenty-ui'; - -export const contextMenuIsOpenState = createState({ - key: 'contextMenuIsOpenState', - defaultValue: false, -}); diff --git a/packages/twenty-front/src/modules/ui/utilities/hotkey/utils/isNonTextWritingKey.ts b/packages/twenty-front/src/modules/ui/utilities/hotkey/utils/isNonTextWritingKey.ts index 8c1bd4be4b79..6c3a0f96ab81 100644 --- a/packages/twenty-front/src/modules/ui/utilities/hotkey/utils/isNonTextWritingKey.ts +++ b/packages/twenty-front/src/modules/ui/utilities/hotkey/utils/isNonTextWritingKey.ts @@ -35,7 +35,7 @@ export const isNonTextWritingKey = (key: string) => { 'Delete', 'End', 'PageDown', - 'ContextMenu', + 'ActionMenuDropdown', 'PrintScreen', 'BrowserBack', 'BrowserForward', diff --git a/packages/twenty-front/src/testing/decorators/RecordTableDecorator.tsx b/packages/twenty-front/src/testing/decorators/RecordTableDecorator.tsx index 11774aba44bf..6eba4d0e8f90 100644 --- a/packages/twenty-front/src/testing/decorators/RecordTableDecorator.tsx +++ b/packages/twenty-front/src/testing/decorators/RecordTableDecorator.tsx @@ -24,7 +24,7 @@ export const RecordTableDecorator: Decorator = (Story) => { onCellMouseEnter: () => {}, onCloseTableCell: () => {}, onOpenTableCell: () => {}, - onContextMenu: () => {}, + onActionMenuDropdown: () => {}, onMoveFocus: () => {}, onMoveSoftFocusToCell: () => {}, onUpsertRecord: () => {}, From 7eae28c85377430fd43220b6871fba4a1439db96 Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Thu, 3 Oct 2024 11:31:49 +0200 Subject: [PATCH 15/52] move components outside of ui folder --- .../action-menu/components/ActionBar.tsx | 2 +- .../action-menu/components/ActionBarItem.tsx | 2 +- .../action-menu/components/ActionMenu.tsx | 12 ++++++------ .../action-menu/components/ActionMenuDropdown.tsx | 4 ++-- .../components/ActionMenuNavigationModal.tsx} | 8 ++++---- .../components/__stories__/ActionBar.stories.tsx | 0 .../components/__stories__/ContextMenu.stories.tsx | 0 .../__stories__/NavigationModal.stories.tsx | 8 ++++---- .../components/RightDrawerActionMenu.tsx | 3 +++ .../action-menu/states/actionBarIsOpenState.ts | 0 .../states/actionMenuDropdownIsOpenState.ts | 0 .../states/actionMenuDropdownPositionState.ts | 2 +- .../action-menu/states/actionMenuEntriesState.ts | 0 .../action-menu/types/ActionBarItemAccent.ts | 0 .../action-menu/types/ActionMenuEntry.ts | 0 .../action-menu/types/PositionType.ts | 0 .../record-action-bar/hooks/useRecordActionBar.tsx | 4 ++-- .../record-board/hooks/useRecordBoardSelection.ts | 2 +- .../record-board-card/components/RecordBoardCard.tsx | 4 ++-- .../record-index/components/RecordIndexContainer.tsx | 2 +- .../components/RecordTableCellCheckbox.tsx | 2 +- .../record-table-cell/hooks/useTriggerContextMenu.ts | 4 ++-- 22 files changed, 31 insertions(+), 28 deletions(-) rename packages/twenty-front/src/modules/{ui/navigation => }/action-menu/components/ActionBar.tsx (94%) rename packages/twenty-front/src/modules/{ui/navigation => }/action-menu/components/ActionBarItem.tsx (97%) rename packages/twenty-front/src/modules/{ui/navigation => }/action-menu/components/ActionMenu.tsx (68%) rename packages/twenty-front/src/modules/{ui/navigation => }/action-menu/components/ActionMenuDropdown.tsx (90%) rename packages/twenty-front/src/modules/{ui/navigation/action-menu/components/NavigationModal.tsx => action-menu/components/ActionMenuNavigationModal.tsx} (62%) rename packages/twenty-front/src/modules/{ui/navigation => }/action-menu/components/__stories__/ActionBar.stories.tsx (100%) rename packages/twenty-front/src/modules/{ui/navigation => }/action-menu/components/__stories__/ContextMenu.stories.tsx (100%) rename packages/twenty-front/src/modules/{ui/navigation => }/action-menu/components/__stories__/NavigationModal.stories.tsx (74%) create mode 100644 packages/twenty-front/src/modules/action-menu/right-drawer/components/RightDrawerActionMenu.tsx rename packages/twenty-front/src/modules/{ui/navigation => }/action-menu/states/actionBarIsOpenState.ts (100%) rename packages/twenty-front/src/modules/{ui/navigation => }/action-menu/states/actionMenuDropdownIsOpenState.ts (100%) rename packages/twenty-front/src/modules/{ui/navigation => }/action-menu/states/actionMenuDropdownPositionState.ts (72%) rename packages/twenty-front/src/modules/{ui/navigation => }/action-menu/states/actionMenuEntriesState.ts (100%) rename packages/twenty-front/src/modules/{ui/navigation => }/action-menu/types/ActionBarItemAccent.ts (100%) rename packages/twenty-front/src/modules/{ui/navigation => }/action-menu/types/ActionMenuEntry.ts (100%) rename packages/twenty-front/src/modules/{ui/navigation => }/action-menu/types/PositionType.ts (100%) diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionBar.tsx b/packages/twenty-front/src/modules/action-menu/components/ActionBar.tsx similarity index 94% rename from packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionBar.tsx rename to packages/twenty-front/src/modules/action-menu/components/ActionBar.tsx index 42830dbbacfb..8d1b562d1302 100644 --- a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionBar.tsx +++ b/packages/twenty-front/src/modules/action-menu/components/ActionBar.tsx @@ -1,6 +1,6 @@ import styled from '@emotion/styled'; -import { ActionMenuEntry } from '@/ui/navigation/action-menu/types/ActionMenuEntry'; +import { ActionMenuEntry } from '@/action-menu/types/ActionMenuEntry'; import { ActionBarItem } from './ActionBarItem'; const StyledContainerActionBar = styled.div` diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionBarItem.tsx b/packages/twenty-front/src/modules/action-menu/components/ActionBarItem.tsx similarity index 97% rename from packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionBarItem.tsx rename to packages/twenty-front/src/modules/action-menu/components/ActionBarItem.tsx index dc8da5813521..812a14279d93 100644 --- a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionBarItem.tsx +++ b/packages/twenty-front/src/modules/action-menu/components/ActionBarItem.tsx @@ -2,10 +2,10 @@ import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; import { IconChevronDown } from 'twenty-ui'; +import { ActionMenuEntry } from '@/action-menu/types/ActionMenuEntry'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; -import { ActionMenuEntry } from '@/ui/navigation/action-menu/types/ActionMenuEntry'; import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; import { MenuItemAccent } from '@/ui/navigation/menu-item/types/MenuItemAccent'; diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenu.tsx b/packages/twenty-front/src/modules/action-menu/components/ActionMenu.tsx similarity index 68% rename from packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenu.tsx rename to packages/twenty-front/src/modules/action-menu/components/ActionMenu.tsx index ca57d53dd6c7..ee0c893bfe61 100644 --- a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenu.tsx +++ b/packages/twenty-front/src/modules/action-menu/components/ActionMenu.tsx @@ -1,9 +1,9 @@ +import { ActionBar } from '@/action-menu/components/ActionBar'; +import { ActionMenuDropdown } from '@/action-menu/components/ActionMenuDropdown'; +import { ActionMenuNavigationModal } from '@/action-menu/components/ActionMenuNavigationModal'; +import { actionMenuDropdownIsOpenState } from '@/action-menu/states/actionMenuDropdownIsOpenState'; +import { actionMenuEntriesState } from '@/action-menu/states/actionMenuEntriesState'; import { contextStoreTargetedRecordIdsState } from '@/context-store/states/contextStoreTargetedRecordIdsState'; -import { ActionBar } from '@/ui/navigation/action-menu/components/ActionBar'; -import { ActionMenuDropdown } from '@/ui/navigation/action-menu/components/ActionMenuDropdown'; -import { NavigationModal } from '@/ui/navigation/action-menu/components/NavigationModal'; -import { actionMenuDropdownIsOpenState } from '@/ui/navigation/action-menu/states/actionMenuDropdownIsOpenState'; -import { actionMenuEntriesState } from '@/ui/navigation/action-menu/states/actionMenuEntriesState'; import { useEffect } from 'react'; import { useRecoilValue, useSetRecoilState } from 'recoil'; @@ -42,7 +42,7 @@ export const ActionMenu = () => { {actionMenuDropdownIsOpen && ( )} - + ); }; diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenuDropdown.tsx b/packages/twenty-front/src/modules/action-menu/components/ActionMenuDropdown.tsx similarity index 90% rename from packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenuDropdown.tsx rename to packages/twenty-front/src/modules/action-menu/components/ActionMenuDropdown.tsx index c0fd868aa9a5..d3bdc07a1fbe 100644 --- a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/ActionMenuDropdown.tsx +++ b/packages/twenty-front/src/modules/action-menu/components/ActionMenuDropdown.tsx @@ -6,8 +6,8 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop import { PositionType } from '../types/PositionType'; -import { actionMenuDropdownPositionState } from '@/ui/navigation/action-menu/states/actionMenuDropdownPositionState'; -import { ActionMenuEntry } from '@/ui/navigation/action-menu/types/ActionMenuEntry'; +import { actionMenuDropdownPositionState } from '@/action-menu/states/actionMenuDropdownPositionState'; +import { ActionMenuEntry } from '@/action-menu/types/ActionMenuEntry'; import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; type StyledContainerProps = { diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/NavigationModal.tsx b/packages/twenty-front/src/modules/action-menu/components/ActionMenuNavigationModal.tsx similarity index 62% rename from packages/twenty-front/src/modules/ui/navigation/action-menu/components/NavigationModal.tsx rename to packages/twenty-front/src/modules/action-menu/components/ActionMenuNavigationModal.tsx index d71d7913cd14..f20d93616bf2 100644 --- a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/NavigationModal.tsx +++ b/packages/twenty-front/src/modules/action-menu/components/ActionMenuNavigationModal.tsx @@ -1,12 +1,12 @@ -import { ActionMenuEntry } from '@/ui/navigation/action-menu/types/ActionMenuEntry'; +import { ActionMenuEntry } from '@/action-menu/types/ActionMenuEntry'; -type NavigationModalProps = { +type ActionMenuNavigationModalProps = { actionMenuEntries: ActionMenuEntry[]; }; -export const NavigationModal = ({ +export const ActionMenuNavigationModal = ({ actionMenuEntries, -}: NavigationModalProps) => { +}: ActionMenuNavigationModalProps) => { return (
{actionMenuEntries.map((actionMenuEntry, index) => diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/__stories__/ActionBar.stories.tsx b/packages/twenty-front/src/modules/action-menu/components/__stories__/ActionBar.stories.tsx similarity index 100% rename from packages/twenty-front/src/modules/ui/navigation/action-menu/components/__stories__/ActionBar.stories.tsx rename to packages/twenty-front/src/modules/action-menu/components/__stories__/ActionBar.stories.tsx diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/__stories__/ContextMenu.stories.tsx b/packages/twenty-front/src/modules/action-menu/components/__stories__/ContextMenu.stories.tsx similarity index 100% rename from packages/twenty-front/src/modules/ui/navigation/action-menu/components/__stories__/ContextMenu.stories.tsx rename to packages/twenty-front/src/modules/action-menu/components/__stories__/ContextMenu.stories.tsx diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/__stories__/NavigationModal.stories.tsx b/packages/twenty-front/src/modules/action-menu/components/__stories__/NavigationModal.stories.tsx similarity index 74% rename from packages/twenty-front/src/modules/ui/navigation/action-menu/components/__stories__/NavigationModal.stories.tsx rename to packages/twenty-front/src/modules/action-menu/components/__stories__/NavigationModal.stories.tsx index cb2cd7743891..4435e005f963 100644 --- a/packages/twenty-front/src/modules/ui/navigation/action-menu/components/__stories__/NavigationModal.stories.tsx +++ b/packages/twenty-front/src/modules/action-menu/components/__stories__/NavigationModal.stories.tsx @@ -1,12 +1,12 @@ import { Meta, StoryObj } from '@storybook/react'; import { IconTrash } from 'twenty-ui'; +import { ActionMenuNavigationModal } from '@/action-menu/components/NavigationModal'; import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal'; -import { NavigationModal } from '@/ui/navigation/action-menu/components/NavigationModal'; -const meta: Meta = { +const meta: Meta = { title: 'UI/Navigation/Shared/NavigationModal', - component: NavigationModal, + component: ActionMenuNavigationModal, args: { actionMenuEntries: [ { @@ -29,6 +29,6 @@ const meta: Meta = { }; export default meta; -type Story = StoryObj; +type Story = StoryObj; export const Default: Story = {}; diff --git a/packages/twenty-front/src/modules/action-menu/right-drawer/components/RightDrawerActionMenu.tsx b/packages/twenty-front/src/modules/action-menu/right-drawer/components/RightDrawerActionMenu.tsx new file mode 100644 index 000000000000..81b81c1999f9 --- /dev/null +++ b/packages/twenty-front/src/modules/action-menu/right-drawer/components/RightDrawerActionMenu.tsx @@ -0,0 +1,3 @@ +export const RightDrawerActionMenu = () => { + return; +}; diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/states/actionBarIsOpenState.ts b/packages/twenty-front/src/modules/action-menu/states/actionBarIsOpenState.ts similarity index 100% rename from packages/twenty-front/src/modules/ui/navigation/action-menu/states/actionBarIsOpenState.ts rename to packages/twenty-front/src/modules/action-menu/states/actionBarIsOpenState.ts diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/states/actionMenuDropdownIsOpenState.ts b/packages/twenty-front/src/modules/action-menu/states/actionMenuDropdownIsOpenState.ts similarity index 100% rename from packages/twenty-front/src/modules/ui/navigation/action-menu/states/actionMenuDropdownIsOpenState.ts rename to packages/twenty-front/src/modules/action-menu/states/actionMenuDropdownIsOpenState.ts diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/states/actionMenuDropdownPositionState.ts b/packages/twenty-front/src/modules/action-menu/states/actionMenuDropdownPositionState.ts similarity index 72% rename from packages/twenty-front/src/modules/ui/navigation/action-menu/states/actionMenuDropdownPositionState.ts rename to packages/twenty-front/src/modules/action-menu/states/actionMenuDropdownPositionState.ts index c62bb2b7f48c..921214689b85 100644 --- a/packages/twenty-front/src/modules/ui/navigation/action-menu/states/actionMenuDropdownPositionState.ts +++ b/packages/twenty-front/src/modules/action-menu/states/actionMenuDropdownPositionState.ts @@ -1,4 +1,4 @@ -import { PositionType } from '@/ui/navigation/action-menu/types/PositionType'; +import { PositionType } from '@/action-menu/types/PositionType'; import { createState } from 'twenty-ui'; export const actionMenuDropdownPositionState = createState({ diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/states/actionMenuEntriesState.ts b/packages/twenty-front/src/modules/action-menu/states/actionMenuEntriesState.ts similarity index 100% rename from packages/twenty-front/src/modules/ui/navigation/action-menu/states/actionMenuEntriesState.ts rename to packages/twenty-front/src/modules/action-menu/states/actionMenuEntriesState.ts diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/types/ActionBarItemAccent.ts b/packages/twenty-front/src/modules/action-menu/types/ActionBarItemAccent.ts similarity index 100% rename from packages/twenty-front/src/modules/ui/navigation/action-menu/types/ActionBarItemAccent.ts rename to packages/twenty-front/src/modules/action-menu/types/ActionBarItemAccent.ts diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/types/ActionMenuEntry.ts b/packages/twenty-front/src/modules/action-menu/types/ActionMenuEntry.ts similarity index 100% rename from packages/twenty-front/src/modules/ui/navigation/action-menu/types/ActionMenuEntry.ts rename to packages/twenty-front/src/modules/action-menu/types/ActionMenuEntry.ts diff --git a/packages/twenty-front/src/modules/ui/navigation/action-menu/types/PositionType.ts b/packages/twenty-front/src/modules/action-menu/types/PositionType.ts similarity index 100% rename from packages/twenty-front/src/modules/ui/navigation/action-menu/types/PositionType.ts rename to packages/twenty-front/src/modules/action-menu/types/PositionType.ts diff --git a/packages/twenty-front/src/modules/object-record/record-action-bar/hooks/useRecordActionBar.tsx b/packages/twenty-front/src/modules/object-record/record-action-bar/hooks/useRecordActionBar.tsx index 57b241243869..48b26628fdae 100644 --- a/packages/twenty-front/src/modules/object-record/record-action-bar/hooks/useRecordActionBar.tsx +++ b/packages/twenty-front/src/modules/object-record/record-action-bar/hooks/useRecordActionBar.tsx @@ -14,8 +14,8 @@ import { import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal'; -import { actionMenuEntriesState } from '@/ui/navigation/action-menu/states/actionMenuEntriesState'; -import { ActionMenuEntry } from '@/ui/navigation/action-menu/types/ActionMenuEntry'; +import { actionMenuEntriesState } from '@/action-menu/states/actionMenuEntriesState'; +import { ActionMenuEntry } from '@/action-menu/types/ActionMenuEntry'; import { isDefined } from '~/utils/isDefined'; type useRecordActionBarProps = { 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 51d471bb201d..da5964403e25 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 @@ -1,7 +1,7 @@ import { useRecoilCallback, useSetRecoilState } from 'recoil'; +import { actionMenuDropdownIsOpenState } from '@/action-menu/states/actionMenuDropdownIsOpenState'; import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates'; -import { actionMenuDropdownIsOpenState } from '@/ui/navigation/action-menu/states/actionMenuDropdownIsOpenState'; export const useRecordBoardSelection = (recordBoardId?: string) => { const setActionMenuDropdownOpenState = useSetRecoilState( diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx index 39a29aca7800..f17c9495a530 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx @@ -1,3 +1,5 @@ +import { actionMenuDropdownIsOpenState } from '@/action-menu/states/actionMenuDropdownIsOpenState'; +import { actionMenuDropdownPositionState } from '@/action-menu/states/actionMenuDropdownPositionState'; import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext'; import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates'; import { RecordBoardCardContext } from '@/object-record/record-board/record-board-card/contexts/RecordBoardCardContext'; @@ -17,8 +19,6 @@ import { ObjectRecord } from '@/object-record/types/ObjectRecord'; import { LightIconButton } from '@/ui/input/button/components/LightIconButton'; import { Checkbox, CheckboxVariant } from '@/ui/input/components/Checkbox'; import { TextInput } from '@/ui/input/components/TextInput'; -import { actionMenuDropdownIsOpenState } from '@/ui/navigation/action-menu/states/actionMenuDropdownIsOpenState'; -import { actionMenuDropdownPositionState } from '@/ui/navigation/action-menu/states/actionMenuDropdownPositionState'; import { AnimatedEaseInOut } from '@/ui/utilities/animation/components/AnimatedEaseInOut'; import { RecordBoardScrollWrapperContext } from '@/ui/utilities/scroll/contexts/ScrollWrapperContexts'; import styled from '@emotion/styled'; diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx index 655acba61842..23bdb149360c 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx @@ -24,7 +24,7 @@ import { RecordFieldValueSelectorContextProvider } from '@/object-record/record- import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable'; import { SpreadsheetImportProvider } from '@/spreadsheet-import/provider/components/SpreadsheetImportProvider'; -import { ActionMenu } from '@/ui/navigation/action-menu/components/ActionMenu'; +import { ActionMenu } from '@/action-menu/components/ActionMenu'; import { ViewBar } from '@/views/components/ViewBar'; import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext'; import { ViewField } from '@/views/types/ViewField'; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellCheckbox.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellCheckbox.tsx index 7fadf1b0c149..a3ebc1a32c6a 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellCheckbox.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellCheckbox.tsx @@ -2,12 +2,12 @@ import styled from '@emotion/styled'; import { useCallback, useContext } from 'react'; import { useRecoilValue, useSetRecoilState } from 'recoil'; +import { actionBarOpenState } from '@/action-menu/states/actionBarIsOpenState'; import { RecordTableRowContext } from '@/object-record/record-table/contexts/RecordTableRowContext'; import { useRecordTableStates } from '@/object-record/record-table/hooks/internal/useRecordTableStates'; import { RecordTableTd } from '@/object-record/record-table/record-table-cell/components/RecordTableTd'; import { useSetCurrentRowSelected } from '@/object-record/record-table/record-table-row/hooks/useSetCurrentRowSelected'; import { Checkbox } from '@/ui/input/components/Checkbox'; -import { actionBarOpenState } from '@/ui/navigation/action-menu/states/actionBarIsOpenState'; const StyledContainer = styled.div` align-items: center; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerContextMenu.ts b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerContextMenu.ts index aa49e1491d9d..4ea1cf6796c8 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerContextMenu.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerContextMenu.ts @@ -1,8 +1,8 @@ import { useRecoilCallback } from 'recoil'; +import { actionMenuDropdownIsOpenState } from '@/action-menu/states/actionMenuDropdownIsOpenState'; +import { actionMenuDropdownPositionState } from '@/action-menu/states/actionMenuDropdownPositionState'; import { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState'; -import { actionMenuDropdownIsOpenState } from '@/ui/navigation/action-menu/states/actionMenuDropdownIsOpenState'; -import { actionMenuDropdownPositionState } from '@/ui/navigation/action-menu/states/actionMenuDropdownPositionState'; import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId'; import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue'; import { extractComponentFamilyState } from '@/ui/utilities/state/component-state/utils/extractComponentFamilyState'; From bcaf61e721e93a17346193cd7ed87bb7c16cb0d0 Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Thu, 3 Oct 2024 12:04:04 +0200 Subject: [PATCH 16/52] create bottom bar component --- .../action-menu/components/ActionBar.tsx | 15 ++++--- .../record-board/components/RecordBoard.tsx | 2 +- .../components/RecordTableInternalEffect.tsx | 2 +- .../bottom-bar/components/BottomBar.tsx | 40 +++++++++++++++++++ .../hooks/internal/useBottomBarStates.ts | 25 ++++++++++++ .../bottom-bar/scopes/BottomBarScope.tsx | 21 ++++++++++ .../BottomBarScopeInternalContext.ts | 7 ++++ .../states/isBottomBarOpenComponentState.ts | 6 +++ 8 files changed, 108 insertions(+), 10 deletions(-) create mode 100644 packages/twenty-front/src/modules/ui/layout/bottom-bar/components/BottomBar.tsx create mode 100644 packages/twenty-front/src/modules/ui/layout/bottom-bar/hooks/internal/useBottomBarStates.ts create mode 100644 packages/twenty-front/src/modules/ui/layout/bottom-bar/scopes/BottomBarScope.tsx create mode 100644 packages/twenty-front/src/modules/ui/layout/bottom-bar/scopes/scope-internal-context/BottomBarScopeInternalContext.ts create mode 100644 packages/twenty-front/src/modules/ui/layout/bottom-bar/states/isBottomBarOpenComponentState.ts diff --git a/packages/twenty-front/src/modules/action-menu/components/ActionBar.tsx b/packages/twenty-front/src/modules/action-menu/components/ActionBar.tsx index 8d1b562d1302..92fca19779f3 100644 --- a/packages/twenty-front/src/modules/action-menu/components/ActionBar.tsx +++ b/packages/twenty-front/src/modules/action-menu/components/ActionBar.tsx @@ -1,6 +1,7 @@ import styled from '@emotion/styled'; import { ActionMenuEntry } from '@/action-menu/types/ActionMenuEntry'; +import { BottomBar } from '@/ui/layout/bottom-bar/components/BottomBar'; import { ActionBarItem } from './ActionBarItem'; const StyledContainerActionBar = styled.div` @@ -39,13 +40,11 @@ export const ActionBar = ({ actionMenuEntries: ActionMenuEntry[]; }) => { return ( - <> - - {selectedRecordIds?.length} selected: - {actionMenuEntries.map((item, index) => ( - - ))} - - + + {selectedRecordIds?.length} selected: + {actionMenuEntries.map((item, index) => ( + + ))} + ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoard.tsx b/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoard.tsx index 2c3b0daf75cc..ff408eb407de 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoard.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoard.tsx @@ -69,7 +69,7 @@ export const RecordBoard = ({ recordBoardId }: RecordBoardProps) => { useListenClickOutsideByClassName({ classNames: ['record-board-card'], - excludeClassNames: ['action-bar', 'context-menu'], + excludeClassNames: ['bottom-bar', 'context-menu'], callback: resetRecordSelection, }); diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableInternalEffect.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableInternalEffect.tsx index 8b94a325f36a..0dff4b429dca 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableInternalEffect.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableInternalEffect.tsx @@ -46,7 +46,7 @@ export const RecordTableInternalEffect = ({ useListenClickOutsideByClassName({ classNames: ['entity-table-cell'], - excludeClassNames: ['action-bar', 'context-menu'], + excludeClassNames: ['bottom-bar', 'context-menu'], callback: () => { resetTableRowSelection(); }, diff --git a/packages/twenty-front/src/modules/ui/layout/bottom-bar/components/BottomBar.tsx b/packages/twenty-front/src/modules/ui/layout/bottom-bar/components/BottomBar.tsx new file mode 100644 index 000000000000..aa3c838afd15 --- /dev/null +++ b/packages/twenty-front/src/modules/ui/layout/bottom-bar/components/BottomBar.tsx @@ -0,0 +1,40 @@ +import styled from '@emotion/styled'; + +import { BottomBarScope } from '@/ui/layout/bottom-bar/scopes/BottomBarScope'; +import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId'; + +const StyledContainerActionBar = styled.div` + align-items: center; + background: ${({ theme }) => theme.background.secondary}; + border: 1px solid ${({ theme }) => theme.border.color.medium}; + border-radius: ${({ theme }) => theme.border.radius.md}; + bottom: 38px; + box-shadow: ${({ theme }) => theme.boxShadow.strong}; + display: flex; + height: 48px; + width: max-content; + left: 50%; + padding-left: ${({ theme }) => theme.spacing(2)}; + padding-right: ${({ theme }) => theme.spacing(2)}; + position: absolute; + top: auto; + + transform: translateX(-50%); + z-index: 1; +`; + +export const BottomBar = ({ + bottomBarId, + children, +}: { + bottomBarId: string; + children: React.ReactNode; +}) => { + return ( + + + {children} + + + ); +}; diff --git a/packages/twenty-front/src/modules/ui/layout/bottom-bar/hooks/internal/useBottomBarStates.ts b/packages/twenty-front/src/modules/ui/layout/bottom-bar/hooks/internal/useBottomBarStates.ts new file mode 100644 index 000000000000..6a351f60fdd0 --- /dev/null +++ b/packages/twenty-front/src/modules/ui/layout/bottom-bar/hooks/internal/useBottomBarStates.ts @@ -0,0 +1,25 @@ +import { BottomBarScopeInternalContext } from '@/ui/layout/bottom-bar/scopes/scope-internal-context/BottomBarScopeInternalContext'; +import { isBottomBarOpenComponentState } from '@/ui/layout/bottom-bar/states/isBottomBarOpenComponentState'; +import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId'; +import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState'; + +type UseBottomBarStatesProps = { + bottomBarScopeId?: string; +}; + +export const useBottomBarStates = ({ + bottomBarScopeId, +}: UseBottomBarStatesProps) => { + const scopeId = useAvailableScopeIdOrThrow( + BottomBarScopeInternalContext, + bottomBarScopeId, + ); + + return { + scopeId, + isBottomBarOpenState: extractComponentState( + isBottomBarOpenComponentState, + scopeId, + ), + }; +}; diff --git a/packages/twenty-front/src/modules/ui/layout/bottom-bar/scopes/BottomBarScope.tsx b/packages/twenty-front/src/modules/ui/layout/bottom-bar/scopes/BottomBarScope.tsx new file mode 100644 index 000000000000..a0ff278f3319 --- /dev/null +++ b/packages/twenty-front/src/modules/ui/layout/bottom-bar/scopes/BottomBarScope.tsx @@ -0,0 +1,21 @@ +import { ReactNode } from 'react'; + +import { BottomBarScopeInternalContext } from './scope-internal-context/BottomBarScopeInternalContext'; + +type BottomBarScopeProps = { + children: ReactNode; + bottomBarScopeId: string; +}; + +export const BottomBarScope = ({ + children, + bottomBarScopeId, +}: BottomBarScopeProps) => { + return ( + + {children} + + ); +}; diff --git a/packages/twenty-front/src/modules/ui/layout/bottom-bar/scopes/scope-internal-context/BottomBarScopeInternalContext.ts b/packages/twenty-front/src/modules/ui/layout/bottom-bar/scopes/scope-internal-context/BottomBarScopeInternalContext.ts new file mode 100644 index 000000000000..5f6644c73954 --- /dev/null +++ b/packages/twenty-front/src/modules/ui/layout/bottom-bar/scopes/scope-internal-context/BottomBarScopeInternalContext.ts @@ -0,0 +1,7 @@ +import { createScopeInternalContext } from '@/ui/utilities/recoil-scope/scopes-internal/utils/createScopeInternalContext'; +import { RecoilComponentStateKey } from '@/ui/utilities/state/component-state/types/RecoilComponentStateKey'; + +type BottomBarScopeInternalContextProps = RecoilComponentStateKey; + +export const BottomBarScopeInternalContext = + createScopeInternalContext(); diff --git a/packages/twenty-front/src/modules/ui/layout/bottom-bar/states/isBottomBarOpenComponentState.ts b/packages/twenty-front/src/modules/ui/layout/bottom-bar/states/isBottomBarOpenComponentState.ts new file mode 100644 index 000000000000..8e7a522560f1 --- /dev/null +++ b/packages/twenty-front/src/modules/ui/layout/bottom-bar/states/isBottomBarOpenComponentState.ts @@ -0,0 +1,6 @@ +import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; + +export const isBottomBarOpenComponentState = createComponentState({ + key: 'isBottomBarOpenComponentState', + defaultValue: false, +}); From deafb9185ca88e95f9a00aecf874346bd9070f01 Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Fri, 4 Oct 2024 11:59:49 +0200 Subject: [PATCH 17/52] refactor ActionMenu and BottomBar component --- .../action-menu/components/ActionBar.tsx | 30 ++++--- .../action-menu/components/ActionMenu.tsx | 48 ----------- .../components/ActionMenuDropdown.tsx | 54 ++++++------ .../components/ActionMenuNavigationModal.tsx | 11 +-- .../__stories__/NavigationModal.stories.tsx | 2 +- .../action-menu/types/ActionBarHotKeyScope.ts | 3 + .../types/ActionMenuDropdownHotKeyScope.ts | 3 + .../record-board/components/RecordBoard.tsx | 4 +- .../hooks/useRecordBoardSelection.ts | 12 +-- .../components/RecordBoardCard.tsx | 8 +- .../RecordIndexBoardDataLoaderEffect.tsx | 4 +- .../components/RecordIndexContainer.tsx | 8 +- .../components/RecordTableContextProvider.tsx | 2 +- .../components/RecordTableWithWrappers.tsx | 10 ++- ...enu.ts => useTriggerActionMenuDropdown.ts} | 9 +- .../bottom-bar/components/BottomBar.tsx | 30 +++++-- .../hooks/internal/useBottomBarStates.ts | 5 ++ .../layout/bottom-bar/hooks/useBottomBar.ts | 85 +++++++++++++++++++ ...eBottomBarInternalHotkeyScopeManagement.ts | 32 +++++++ .../states/bottomBarHotkeyComponentState.ts | 9 ++ 20 files changed, 253 insertions(+), 116 deletions(-) delete mode 100644 packages/twenty-front/src/modules/action-menu/components/ActionMenu.tsx create mode 100644 packages/twenty-front/src/modules/action-menu/types/ActionBarHotKeyScope.ts create mode 100644 packages/twenty-front/src/modules/action-menu/types/ActionMenuDropdownHotKeyScope.ts rename packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/{useTriggerContextMenu.ts => useTriggerActionMenuDropdown.ts} (85%) create mode 100644 packages/twenty-front/src/modules/ui/layout/bottom-bar/hooks/useBottomBar.ts create mode 100644 packages/twenty-front/src/modules/ui/layout/bottom-bar/hooks/useBottomBarInternalHotkeyScopeManagement.ts create mode 100644 packages/twenty-front/src/modules/ui/layout/bottom-bar/states/bottomBarHotkeyComponentState.ts diff --git a/packages/twenty-front/src/modules/action-menu/components/ActionBar.tsx b/packages/twenty-front/src/modules/action-menu/components/ActionBar.tsx index 92fca19779f3..7390c9544e4e 100644 --- a/packages/twenty-front/src/modules/action-menu/components/ActionBar.tsx +++ b/packages/twenty-front/src/modules/action-menu/components/ActionBar.tsx @@ -1,7 +1,10 @@ import styled from '@emotion/styled'; -import { ActionMenuEntry } from '@/action-menu/types/ActionMenuEntry'; +import { actionMenuEntriesState } from '@/action-menu/states/actionMenuEntriesState'; +import { ActionBarHotkeyScope } from '@/action-menu/types/ActionBarHotKeyScope'; +import { contextStoreTargetedRecordIdsState } from '@/context-store/states/contextStoreTargetedRecordIdsState'; import { BottomBar } from '@/ui/layout/bottom-bar/components/BottomBar'; +import { useRecoilValue } from 'recoil'; import { ActionBarItem } from './ActionBarItem'; const StyledContainerActionBar = styled.div` @@ -32,16 +35,23 @@ const StyledLabel = styled.div` padding-right: ${({ theme }) => theme.spacing(2)}; `; -export const ActionBar = ({ - selectedRecordIds, - actionMenuEntries, -}: { - selectedRecordIds: string[]; - actionMenuEntries: ActionMenuEntry[]; -}) => { +export const ActionBar = () => { + const contextStoreTargetedRecordIds = useRecoilValue( + contextStoreTargetedRecordIdsState, + ); + + const actionMenuEntries = useRecoilValue(actionMenuEntriesState); + return ( - - {selectedRecordIds?.length} selected: + + + {contextStoreTargetedRecordIds.length} selected: + {actionMenuEntries.map((item, index) => ( ))} diff --git a/packages/twenty-front/src/modules/action-menu/components/ActionMenu.tsx b/packages/twenty-front/src/modules/action-menu/components/ActionMenu.tsx deleted file mode 100644 index ee0c893bfe61..000000000000 --- a/packages/twenty-front/src/modules/action-menu/components/ActionMenu.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { ActionBar } from '@/action-menu/components/ActionBar'; -import { ActionMenuDropdown } from '@/action-menu/components/ActionMenuDropdown'; -import { ActionMenuNavigationModal } from '@/action-menu/components/ActionMenuNavigationModal'; -import { actionMenuDropdownIsOpenState } from '@/action-menu/states/actionMenuDropdownIsOpenState'; -import { actionMenuEntriesState } from '@/action-menu/states/actionMenuEntriesState'; -import { contextStoreTargetedRecordIdsState } from '@/context-store/states/contextStoreTargetedRecordIdsState'; -import { useEffect } from 'react'; -import { useRecoilValue, useSetRecoilState } from 'recoil'; - -export const ActionMenu = () => { - const setActionMenuDropdownOpenState = useSetRecoilState( - actionMenuDropdownIsOpenState, - ); - - const contextStoreTargetedRecordIds = useRecoilValue( - contextStoreTargetedRecordIdsState, - ); - - useEffect(() => { - if (contextStoreTargetedRecordIds.length !== 1) { - setActionMenuDropdownOpenState(false); - } - }, [contextStoreTargetedRecordIds, setActionMenuDropdownOpenState]); - - const actionMenuDropdownIsOpen = useRecoilValue( - actionMenuDropdownIsOpenState, - ); - const actionMenuEntries = useRecoilValue(actionMenuEntriesState); - - if (!contextStoreTargetedRecordIds.length) { - return null; - } - - return ( - <> - {!actionMenuDropdownIsOpen && ( - - )} - {actionMenuDropdownIsOpen && ( - - )} - - - ); -}; diff --git a/packages/twenty-front/src/modules/action-menu/components/ActionMenuDropdown.tsx b/packages/twenty-front/src/modules/action-menu/components/ActionMenuDropdown.tsx index d3bdc07a1fbe..2c5811aa702a 100644 --- a/packages/twenty-front/src/modules/action-menu/components/ActionMenuDropdown.tsx +++ b/packages/twenty-front/src/modules/action-menu/components/ActionMenuDropdown.tsx @@ -1,13 +1,12 @@ import styled from '@emotion/styled'; import { useRecoilValue } from 'recoil'; -import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu'; -import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; - import { PositionType } from '../types/PositionType'; import { actionMenuDropdownPositionState } from '@/action-menu/states/actionMenuDropdownPositionState'; -import { ActionMenuEntry } from '@/action-menu/types/ActionMenuEntry'; +import { actionMenuEntriesState } from '@/action-menu/states/actionMenuEntriesState'; +import { ActionMenuDropdownHotkeyScope } from '@/action-menu/types/ActionMenuDropdownHotKeyScope'; +import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; type StyledContainerProps = { @@ -33,11 +32,9 @@ const StyledContainerActionMenuDropdown = styled.div` z-index: 2; `; -export const ActionMenuDropdown = ({ - actionMenuEntries, -}: { - actionMenuEntries: ActionMenuEntry[]; -}) => { +export const ActionMenuDropdown = () => { + const actionMenuEntries = useRecoilValue(actionMenuEntriesState); + const actionMenuDropdownPosition = useRecoilValue( actionMenuDropdownPositionState, ); @@ -50,22 +47,27 @@ export const ActionMenuDropdown = ({ : undefined; return ( - <> - - - - {actionMenuEntries.map((item, index) => ( - - ))} - - - - + + ( + + ))} + /> + ); }; diff --git a/packages/twenty-front/src/modules/action-menu/components/ActionMenuNavigationModal.tsx b/packages/twenty-front/src/modules/action-menu/components/ActionMenuNavigationModal.tsx index f20d93616bf2..61e7c3046d4a 100644 --- a/packages/twenty-front/src/modules/action-menu/components/ActionMenuNavigationModal.tsx +++ b/packages/twenty-front/src/modules/action-menu/components/ActionMenuNavigationModal.tsx @@ -1,12 +1,9 @@ -import { ActionMenuEntry } from '@/action-menu/types/ActionMenuEntry'; +import { actionMenuEntriesState } from '@/action-menu/states/actionMenuEntriesState'; +import { useRecoilValue } from 'recoil'; -type ActionMenuNavigationModalProps = { - actionMenuEntries: ActionMenuEntry[]; -}; +export const ActionMenuNavigationModal = () => { + const actionMenuEntries = useRecoilValue(actionMenuEntriesState); -export const ActionMenuNavigationModal = ({ - actionMenuEntries, -}: ActionMenuNavigationModalProps) => { return (
{actionMenuEntries.map((actionMenuEntry, index) => diff --git a/packages/twenty-front/src/modules/action-menu/components/__stories__/NavigationModal.stories.tsx b/packages/twenty-front/src/modules/action-menu/components/__stories__/NavigationModal.stories.tsx index 4435e005f963..8a30195c6122 100644 --- a/packages/twenty-front/src/modules/action-menu/components/__stories__/NavigationModal.stories.tsx +++ b/packages/twenty-front/src/modules/action-menu/components/__stories__/NavigationModal.stories.tsx @@ -1,7 +1,7 @@ import { Meta, StoryObj } from '@storybook/react'; import { IconTrash } from 'twenty-ui'; -import { ActionMenuNavigationModal } from '@/action-menu/components/NavigationModal'; +import { ActionMenuNavigationModal } from '@/action-menu/components/ActionMenuNavigationModal'; import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal'; const meta: Meta = { diff --git a/packages/twenty-front/src/modules/action-menu/types/ActionBarHotKeyScope.ts b/packages/twenty-front/src/modules/action-menu/types/ActionBarHotKeyScope.ts new file mode 100644 index 000000000000..fcadbee366f0 --- /dev/null +++ b/packages/twenty-front/src/modules/action-menu/types/ActionBarHotKeyScope.ts @@ -0,0 +1,3 @@ +export enum ActionBarHotkeyScope { + ActionBar = 'action-bar', +} diff --git a/packages/twenty-front/src/modules/action-menu/types/ActionMenuDropdownHotKeyScope.ts b/packages/twenty-front/src/modules/action-menu/types/ActionMenuDropdownHotKeyScope.ts new file mode 100644 index 000000000000..9c0e2df42edf --- /dev/null +++ b/packages/twenty-front/src/modules/action-menu/types/ActionMenuDropdownHotKeyScope.ts @@ -0,0 +1,3 @@ +export enum ActionMenuDropdownHotkeyScope { + ActionMenuDropdown = 'action-menu-dropdown', +} diff --git a/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoard.tsx b/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoard.tsx index ff408eb407de..331f6cbf8492 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoard.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoard.tsx @@ -70,7 +70,9 @@ export const RecordBoard = ({ recordBoardId }: RecordBoardProps) => { useListenClickOutsideByClassName({ classNames: ['record-board-card'], excludeClassNames: ['bottom-bar', 'context-menu'], - callback: resetRecordSelection, + callback: () => { + resetRecordSelection(); + }, }); useScopedHotkeys([Key.Escape], resetRecordSelection, TableHotkeyScope.Table); 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 da5964403e25..2d29b55a7672 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 @@ -1,11 +1,11 @@ -import { useRecoilCallback, useSetRecoilState } from 'recoil'; +import { useRecoilCallback } from 'recoil'; -import { actionMenuDropdownIsOpenState } from '@/action-menu/states/actionMenuDropdownIsOpenState'; import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates'; +import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; export const useRecordBoardSelection = (recordBoardId?: string) => { - const setActionMenuDropdownOpenState = useSetRecoilState( - actionMenuDropdownIsOpenState, + const { closeDropdown: closeActionMenuDropdown } = useDropdown( + 'action-menu-dropdown', ); const { selectedRecordIdsSelector, isRecordBoardCardSelectedFamilyState } = useRecordBoardStates(recordBoardId); @@ -13,7 +13,7 @@ export const useRecordBoardSelection = (recordBoardId?: string) => { const resetRecordSelection = useRecoilCallback( ({ snapshot, set }) => () => { - setActionMenuDropdownOpenState(false); + closeActionMenuDropdown(); const recordIds = snapshot .getLoadable(selectedRecordIdsSelector()) .getValue(); @@ -23,9 +23,9 @@ export const useRecordBoardSelection = (recordBoardId?: string) => { } }, [ + closeActionMenuDropdown, selectedRecordIdsSelector, isRecordBoardCardSelectedFamilyState, - setActionMenuDropdownOpenState, ], ); diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx index f17c9495a530..e6c0d23d0bd1 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx @@ -1,4 +1,3 @@ -import { actionMenuDropdownIsOpenState } from '@/action-menu/states/actionMenuDropdownIsOpenState'; import { actionMenuDropdownPositionState } from '@/action-menu/states/actionMenuDropdownPositionState'; import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext'; import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates'; @@ -19,6 +18,7 @@ import { ObjectRecord } from '@/object-record/types/ObjectRecord'; import { LightIconButton } from '@/ui/input/button/components/LightIconButton'; import { Checkbox, CheckboxVariant } from '@/ui/input/components/Checkbox'; import { TextInput } from '@/ui/input/components/TextInput'; +import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { AnimatedEaseInOut } from '@/ui/utilities/animation/components/AnimatedEaseInOut'; import { RecordBoardScrollWrapperContext } from '@/ui/utilities/scroll/contexts/ScrollWrapperContexts'; import styled from '@emotion/styled'; @@ -181,8 +181,8 @@ export const RecordBoardCard = ({ const setActionMenuDropdownPosition = useSetRecoilState( actionMenuDropdownPositionState, ); - const setActionMenuDropdownOpenState = useSetRecoilState( - actionMenuDropdownIsOpenState, + const { openDropdown: openActionMenuDropdown } = useDropdown( + 'action-menu-dropdown', ); const handleActionMenuDropdown = (event: React.MouseEvent) => { @@ -192,7 +192,7 @@ export const RecordBoardCard = ({ x: event.clientX, y: event.clientY, }); - setActionMenuDropdownOpenState(true); + openActionMenuDropdown(); }; const PreventSelectOnClickContainer = ({ diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardDataLoaderEffect.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardDataLoaderEffect.tsx index 49b18c0e4b8c..ea4657559930 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardDataLoaderEffect.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardDataLoaderEffect.tsx @@ -127,7 +127,9 @@ export const RecordIndexBoardDataLoaderEffect = ({ const { setActionMenuEntries } = useRecordActionBar({ objectMetadataItem, selectedRecordIds, - callback: resetRecordSelection, + callback: () => { + resetRecordSelection(); + }, }); const setContextStoreTargetedRecordIds = useSetRecoilState( diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx index 23bdb149360c..2166beb352e5 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx @@ -24,7 +24,9 @@ import { RecordFieldValueSelectorContextProvider } from '@/object-record/record- import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable'; import { SpreadsheetImportProvider } from '@/spreadsheet-import/provider/components/SpreadsheetImportProvider'; -import { ActionMenu } from '@/action-menu/components/ActionMenu'; +import { ActionBar } from '@/action-menu/components/ActionBar'; +import { ActionMenuDropdown } from '@/action-menu/components/ActionMenuDropdown'; +import { ActionMenuNavigationModal } from '@/action-menu/components/ActionMenuNavigationModal'; import { ViewBar } from '@/views/components/ViewBar'; import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext'; import { ViewField } from '@/views/types/ViewField'; @@ -193,7 +195,9 @@ export const RecordIndexContainer = () => { /> )} - + + + diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableContextProvider.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableContextProvider.tsx index a725cf229ce7..b1038c973717 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableContextProvider.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableContextProvider.tsx @@ -12,7 +12,7 @@ import { OpenTableCellArgs, useOpenRecordTableCellV2, } from '@/object-record/record-table/record-table-cell/hooks/useOpenRecordTableCellV2'; -import { useTriggerActionMenuDropdown } from '@/object-record/record-table/record-table-cell/hooks/useTriggerContextMenu'; +import { useTriggerActionMenuDropdown } from '@/object-record/record-table/record-table-cell/hooks/useTriggerActionMenuDropdown'; import { useUpsertRecord } from '@/object-record/record-table/record-table-cell/hooks/useUpsertRecord'; import { MoveFocusDirection } from '@/object-record/record-table/types/MoveFocusDirection'; import { TableCellPosition } from '@/object-record/record-table/types/TableCellPosition'; diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx index 268608e183cc..565293645d0f 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx @@ -15,6 +15,7 @@ import { mapColumnDefinitionsToViewFields } from '@/views/utils/mapColumnDefinit import { RecordUpdateContext } from '../contexts/EntityUpdateMutationHookContext'; import { useRecordTable } from '../hooks/useRecordTable'; +import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { RecordTableInternalEffect } from './RecordTableInternalEffect'; const StyledTableWithHeader = styled.div` @@ -66,6 +67,10 @@ export const RecordTableWithWrappers = ({ [saveViewFields], ); + const { closeDropdown: closeActionMenuDropdown } = useDropdown( + 'action-menu-dropdown', + ); + return ( @@ -81,7 +86,10 @@ export const RecordTableWithWrappers = ({ /> { + closeActionMenuDropdown(); + resetTableRowSelection(); + }} onDragSelectionChange={setRowSelected} /> diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerContextMenu.ts b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerActionMenuDropdown.ts similarity index 85% rename from packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerContextMenu.ts rename to packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerActionMenuDropdown.ts index 4ea1cf6796c8..c422f11d9560 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerContextMenu.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerActionMenuDropdown.ts @@ -1,8 +1,8 @@ import { useRecoilCallback } from 'recoil'; -import { actionMenuDropdownIsOpenState } from '@/action-menu/states/actionMenuDropdownIsOpenState'; import { actionMenuDropdownPositionState } from '@/action-menu/states/actionMenuDropdownPositionState'; import { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState'; +import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId'; import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue'; import { extractComponentFamilyState } from '@/ui/utilities/state/component-state/utils/extractComponentFamilyState'; @@ -12,6 +12,9 @@ export const useTriggerActionMenuDropdown = ({ }: { recordTableId: string; }) => { + const { openDropdown: openActionMenuDropdown } = useDropdown( + 'action-menu-dropdown', + ); const triggerActionMenuDropdown = useRecoilCallback( ({ set, snapshot }) => (event: React.MouseEvent, recordId: string) => { @@ -23,7 +26,7 @@ export const useTriggerActionMenuDropdown = ({ x: event.clientX, y: event.clientY, }); - set(actionMenuDropdownIsOpenState, true); + openActionMenuDropdown(); const isRowSelectedFamilyState = extractComponentFamilyState( isRowSelectedComponentFamilyState, @@ -39,7 +42,7 @@ export const useTriggerActionMenuDropdown = ({ set(isRowSelectedFamilyState(recordId), true); } }, - [recordTableId], + [openActionMenuDropdown, recordTableId], ); return { triggerActionMenuDropdown }; diff --git a/packages/twenty-front/src/modules/ui/layout/bottom-bar/components/BottomBar.tsx b/packages/twenty-front/src/modules/ui/layout/bottom-bar/components/BottomBar.tsx index aa3c838afd15..4662e604564e 100644 --- a/packages/twenty-front/src/modules/ui/layout/bottom-bar/components/BottomBar.tsx +++ b/packages/twenty-front/src/modules/ui/layout/bottom-bar/components/BottomBar.tsx @@ -1,6 +1,9 @@ import styled from '@emotion/styled'; +import { useBottomBarStates } from '@/ui/layout/bottom-bar/hooks/internal/useBottomBarStates'; +import { useBottomBarInternalHotkeyScopeManagement } from '@/ui/layout/bottom-bar/hooks/useBottomBarInternalHotkeyScopeManagement'; import { BottomBarScope } from '@/ui/layout/bottom-bar/scopes/BottomBarScope'; +import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope'; import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId'; const StyledContainerActionBar = styled.div` @@ -23,15 +26,32 @@ const StyledContainerActionBar = styled.div` z-index: 1; `; +type BottomBarProps = { + bottomBarId: string; + bottomBarHotkeyScopeFromParent: HotkeyScope; + children: React.ReactNode; +}; + export const BottomBar = ({ bottomBarId, + bottomBarHotkeyScopeFromParent, children, -}: { - bottomBarId: string; - children: React.ReactNode; -}) => { +}: BottomBarProps) => { + const scopeId = getScopeIdFromComponentId(bottomBarId); + const { isBottomBarOpenState } = useBottomBarStates({ + bottomBarScopeId: scopeId, + }); + useBottomBarInternalHotkeyScopeManagement({ + bottomBarScopeId: scopeId, + bottomBarHotkeyScopeFromParent, + }); + + if (!isBottomBarOpenState) { + return null; + } + return ( - + {children} diff --git a/packages/twenty-front/src/modules/ui/layout/bottom-bar/hooks/internal/useBottomBarStates.ts b/packages/twenty-front/src/modules/ui/layout/bottom-bar/hooks/internal/useBottomBarStates.ts index 6a351f60fdd0..4a0f3ed726dd 100644 --- a/packages/twenty-front/src/modules/ui/layout/bottom-bar/hooks/internal/useBottomBarStates.ts +++ b/packages/twenty-front/src/modules/ui/layout/bottom-bar/hooks/internal/useBottomBarStates.ts @@ -1,4 +1,5 @@ import { BottomBarScopeInternalContext } from '@/ui/layout/bottom-bar/scopes/scope-internal-context/BottomBarScopeInternalContext'; +import { bottomBarHotkeyComponentState } from '@/ui/layout/bottom-bar/states/bottomBarHotkeyComponentState'; import { isBottomBarOpenComponentState } from '@/ui/layout/bottom-bar/states/isBottomBarOpenComponentState'; import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId'; import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState'; @@ -17,6 +18,10 @@ export const useBottomBarStates = ({ return { scopeId, + bottomBarHotkeyScopeState: extractComponentState( + bottomBarHotkeyComponentState, + scopeId, + ), isBottomBarOpenState: extractComponentState( isBottomBarOpenComponentState, scopeId, diff --git a/packages/twenty-front/src/modules/ui/layout/bottom-bar/hooks/useBottomBar.ts b/packages/twenty-front/src/modules/ui/layout/bottom-bar/hooks/useBottomBar.ts new file mode 100644 index 000000000000..87279fab79ca --- /dev/null +++ b/packages/twenty-front/src/modules/ui/layout/bottom-bar/hooks/useBottomBar.ts @@ -0,0 +1,85 @@ +import { useRecoilCallback } from 'recoil'; + +import { bottomBarHotkeyComponentState } from '@/ui/layout/bottom-bar/states/bottomBarHotkeyComponentState'; +import { isBottomBarOpenComponentState } from '@/ui/layout/bottom-bar/states/isBottomBarOpenComponentState'; +import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope'; +import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope'; +import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId'; +import { isDefined } from '~/utils/isDefined'; + +export const useBottomBar = () => { + const { + setHotkeyScopeAndMemorizePreviousScope, + goBackToPreviousHotkeyScope, + } = usePreviousHotkeyScope(); + + const closeBottomBar = useRecoilCallback( + ({ set }) => + (specificComponentId: string) => { + const scopeId = getScopeIdFromComponentId(specificComponentId); + + goBackToPreviousHotkeyScope(); + set( + isBottomBarOpenComponentState({ + scopeId, + }), + false, + ); + }, + [goBackToPreviousHotkeyScope], + ); + + const openBottomBar = useRecoilCallback( + ({ set, snapshot }) => + (specificComponentId: string, customHotkeyScope?: HotkeyScope) => { + const scopeId = getScopeIdFromComponentId(specificComponentId); + + const bottomBarHotkeyScope = snapshot + .getLoadable(bottomBarHotkeyComponentState({ scopeId })) + .getValue(); + + set( + isBottomBarOpenComponentState({ + scopeId, + }), + true, + ); + + if (isDefined(customHotkeyScope)) { + setHotkeyScopeAndMemorizePreviousScope( + customHotkeyScope.scope, + customHotkeyScope.customScopes, + ); + } else if (isDefined(bottomBarHotkeyScope)) { + setHotkeyScopeAndMemorizePreviousScope( + bottomBarHotkeyScope.scope, + bottomBarHotkeyScope.customScopes, + ); + } + }, + [setHotkeyScopeAndMemorizePreviousScope], + ); + + const toggleBottomBar = useRecoilCallback( + ({ snapshot }) => + (specificComponentId: string) => { + const scopeId = getScopeIdFromComponentId(specificComponentId); + const isBottomBarOpen = snapshot + .getLoadable(isBottomBarOpenComponentState({ scopeId })) + .getValue(); + + if (isBottomBarOpen) { + closeBottomBar(specificComponentId); + } else { + openBottomBar(specificComponentId); + } + }, + [closeBottomBar, openBottomBar], + ); + + return { + closeBottomBar, + openBottomBar, + toggleBottomBar, + }; +}; diff --git a/packages/twenty-front/src/modules/ui/layout/bottom-bar/hooks/useBottomBarInternalHotkeyScopeManagement.ts b/packages/twenty-front/src/modules/ui/layout/bottom-bar/hooks/useBottomBarInternalHotkeyScopeManagement.ts new file mode 100644 index 000000000000..275f391e9023 --- /dev/null +++ b/packages/twenty-front/src/modules/ui/layout/bottom-bar/hooks/useBottomBarInternalHotkeyScopeManagement.ts @@ -0,0 +1,32 @@ +import { useEffect } from 'react'; +import { useRecoilState } from 'recoil'; + +import { useBottomBarStates } from '@/ui/layout/bottom-bar/hooks/internal/useBottomBarStates'; +import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope'; +import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; + +export const useBottomBarInternalHotkeyScopeManagement = ({ + bottomBarScopeId, + bottomBarHotkeyScopeFromParent, +}: { + bottomBarScopeId: string; + bottomBarHotkeyScopeFromParent?: HotkeyScope; +}) => { + const { bottomBarHotkeyScopeState } = useBottomBarStates({ + bottomBarScopeId, + }); + + const [bottomBarHotkeyScope, setBottomBarHotkeyScope] = useRecoilState( + bottomBarHotkeyScopeState, + ); + + useEffect(() => { + if (!isDeeplyEqual(bottomBarHotkeyScopeFromParent, bottomBarHotkeyScope)) { + setBottomBarHotkeyScope(bottomBarHotkeyScopeFromParent); + } + }, [ + bottomBarHotkeyScope, + bottomBarHotkeyScopeFromParent, + setBottomBarHotkeyScope, + ]); +}; diff --git a/packages/twenty-front/src/modules/ui/layout/bottom-bar/states/bottomBarHotkeyComponentState.ts b/packages/twenty-front/src/modules/ui/layout/bottom-bar/states/bottomBarHotkeyComponentState.ts new file mode 100644 index 000000000000..5ea1aa0da1bc --- /dev/null +++ b/packages/twenty-front/src/modules/ui/layout/bottom-bar/states/bottomBarHotkeyComponentState.ts @@ -0,0 +1,9 @@ +import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope'; +import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState'; + +export const bottomBarHotkeyComponentState = createComponentState< + HotkeyScope | null | undefined +>({ + key: 'bottomBarHotkeyComponentState', + defaultValue: null, +}); From 96091ceef67ef04a96c5a70e63216fbde7f6d6b2 Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Fri, 4 Oct 2024 14:31:57 +0200 Subject: [PATCH 18/52] scope component states --- .../action-menu/components/ActionBar.tsx | 28 ++++--------------- .../components/ActionMenuDropdown.tsx | 13 +++++++-- .../hooks/useRecordBoardSelection.ts | 2 +- .../components/RecordBoardCard.tsx | 7 ++++- .../components/RecordIndexContainer.tsx | 10 +++++-- .../components/RecordTableWithWrappers.tsx | 2 +- .../hooks/useTriggerActionMenuDropdown.ts | 2 +- .../bottom-bar/components/BottomBar.tsx | 4 ++- 8 files changed, 37 insertions(+), 31 deletions(-) diff --git a/packages/twenty-front/src/modules/action-menu/components/ActionBar.tsx b/packages/twenty-front/src/modules/action-menu/components/ActionBar.tsx index 7390c9544e4e..f68fb048af62 100644 --- a/packages/twenty-front/src/modules/action-menu/components/ActionBar.tsx +++ b/packages/twenty-front/src/modules/action-menu/components/ActionBar.tsx @@ -7,26 +7,6 @@ import { BottomBar } from '@/ui/layout/bottom-bar/components/BottomBar'; import { useRecoilValue } from 'recoil'; import { ActionBarItem } from './ActionBarItem'; -const StyledContainerActionBar = styled.div` - align-items: center; - background: ${({ theme }) => theme.background.secondary}; - border: 1px solid ${({ theme }) => theme.border.color.medium}; - border-radius: ${({ theme }) => theme.border.radius.md}; - bottom: 38px; - box-shadow: ${({ theme }) => theme.boxShadow.strong}; - display: flex; - height: 48px; - width: max-content; - left: 50%; - padding-left: ${({ theme }) => theme.spacing(2)}; - padding-right: ${({ theme }) => theme.spacing(2)}; - position: absolute; - top: auto; - - transform: translateX(-50%); - z-index: 1; -`; - const StyledLabel = styled.div` color: ${({ theme }) => theme.font.color.tertiary}; font-size: ${({ theme }) => theme.font.size.md}; @@ -35,7 +15,11 @@ const StyledLabel = styled.div` padding-right: ${({ theme }) => theme.spacing(2)}; `; -export const ActionBar = () => { +type ActionBarProps = { + actionBarId: string; +}; + +export const ActionBar = ({ actionBarId }: ActionBarProps) => { const contextStoreTargetedRecordIds = useRecoilValue( contextStoreTargetedRecordIdsState, ); @@ -44,7 +28,7 @@ export const ActionBar = () => { return ( ` z-index: 2; `; -export const ActionMenuDropdown = () => { +export type ActionMenuDropdownProps = { + actionMenuDropdownId: string; + onOpen: () => void; +}; + +export const ActionMenuDropdown = ({ + actionMenuDropdownId, + onOpen, +}: ActionMenuDropdownProps) => { const actionMenuEntries = useRecoilValue(actionMenuEntriesState); const actionMenuDropdownPosition = useRecoilValue( @@ -52,7 +60,7 @@ export const ActionMenuDropdown = () => { className="context-menu" > { text={item.label} /> ))} + onOpen={onOpen} /> ); 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 2d29b55a7672..04d38aaea6fb 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 @@ -5,7 +5,7 @@ import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; export const useRecordBoardSelection = (recordBoardId?: string) => { const { closeDropdown: closeActionMenuDropdown } = useDropdown( - 'action-menu-dropdown', + `action-menu-dropdown-${recordBoardId}`, ); const { selectedRecordIdsSelector, isRecordBoardCardSelectedFamilyState } = useRecordBoardStates(recordBoardId); diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx index e6c0d23d0bd1..126c641c9d65 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx @@ -2,6 +2,7 @@ import { actionMenuDropdownPositionState } from '@/action-menu/states/actionMenu import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext'; import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates'; import { RecordBoardCardContext } from '@/object-record/record-board/record-board-card/contexts/RecordBoardCardContext'; +import { RecordBoardScopeInternalContext } from '@/object-record/record-board/scopes/scope-internal-context/RecordBoardScopeInternalContext'; import { FieldContext, RecordUpdateHook, @@ -20,6 +21,7 @@ import { Checkbox, CheckboxVariant } from '@/ui/input/components/Checkbox'; import { TextInput } from '@/ui/input/components/TextInput'; import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { AnimatedEaseInOut } from '@/ui/utilities/animation/components/AnimatedEaseInOut'; +import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId'; import { RecordBoardScrollWrapperContext } from '@/ui/utilities/scroll/contexts/ScrollWrapperContexts'; import styled from '@emotion/styled'; import { ReactNode, useContext, useState } from 'react'; @@ -181,8 +183,11 @@ export const RecordBoardCard = ({ const setActionMenuDropdownPosition = useSetRecoilState( actionMenuDropdownPositionState, ); + const recordBoardId = useAvailableScopeIdOrThrow( + RecordBoardScopeInternalContext, + ); const { openDropdown: openActionMenuDropdown } = useDropdown( - 'action-menu-dropdown', + `action-menu-dropdown-${recordBoardId}`, ); const handleActionMenuDropdown = (event: React.MouseEvent) => { diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx index 2166beb352e5..ad0a736eea4b 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx @@ -27,6 +27,7 @@ import { SpreadsheetImportProvider } from '@/spreadsheet-import/provider/compone import { ActionBar } from '@/action-menu/components/ActionBar'; import { ActionMenuDropdown } from '@/action-menu/components/ActionMenuDropdown'; import { ActionMenuNavigationModal } from '@/action-menu/components/ActionMenuNavigationModal'; +import { useBottomBar } from '@/ui/layout/bottom-bar/hooks/useBottomBar'; import { ViewBar } from '@/views/components/ViewBar'; import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext'; import { ViewField } from '@/views/types/ViewField'; @@ -109,6 +110,8 @@ export const RecordIndexContainer = () => { [columnDefinitions, setTableColumns], ); + const { closeBottomBar } = useBottomBar(); + return ( @@ -195,8 +198,11 @@ export const RecordIndexContainer = () => { /> )} - - + + closeBottomBar(`action-bar-${recordIndexId}`)} + /> diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx index 565293645d0f..44c9f1366f34 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx @@ -68,7 +68,7 @@ export const RecordTableWithWrappers = ({ ); const { closeDropdown: closeActionMenuDropdown } = useDropdown( - 'action-menu-dropdown', + `action-menu-dropdown-${recordTableId}`, ); return ( diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerActionMenuDropdown.ts b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerActionMenuDropdown.ts index c422f11d9560..16a8a51c78c8 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerActionMenuDropdown.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerActionMenuDropdown.ts @@ -13,7 +13,7 @@ export const useTriggerActionMenuDropdown = ({ recordTableId: string; }) => { const { openDropdown: openActionMenuDropdown } = useDropdown( - 'action-menu-dropdown', + `action-menu-dropdown-${recordTableId}`, ); const triggerActionMenuDropdown = useRecoilCallback( ({ set, snapshot }) => diff --git a/packages/twenty-front/src/modules/ui/layout/bottom-bar/components/BottomBar.tsx b/packages/twenty-front/src/modules/ui/layout/bottom-bar/components/BottomBar.tsx index 4662e604564e..609f0ee372ac 100644 --- a/packages/twenty-front/src/modules/ui/layout/bottom-bar/components/BottomBar.tsx +++ b/packages/twenty-front/src/modules/ui/layout/bottom-bar/components/BottomBar.tsx @@ -5,6 +5,7 @@ import { useBottomBarInternalHotkeyScopeManagement } from '@/ui/layout/bottom-ba import { BottomBarScope } from '@/ui/layout/bottom-bar/scopes/BottomBarScope'; import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope'; import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId'; +import { useRecoilValue } from 'recoil'; const StyledContainerActionBar = styled.div` align-items: center; @@ -41,12 +42,13 @@ export const BottomBar = ({ const { isBottomBarOpenState } = useBottomBarStates({ bottomBarScopeId: scopeId, }); + const isBottomBarOpen = useRecoilValue(isBottomBarOpenState); useBottomBarInternalHotkeyScopeManagement({ bottomBarScopeId: scopeId, bottomBarHotkeyScopeFromParent, }); - if (!isBottomBarOpenState) { + if (!isBottomBarOpen) { return null; } From 347284ca4de3cf6b577b82957ee349e734851e69 Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Fri, 4 Oct 2024 16:08:37 +0200 Subject: [PATCH 19/52] create useActionMenu hook --- .../action-menu/components/ActionBar.tsx | 6 +-- .../components/ActionMenuDropdown.tsx | 9 ++-- .../__stories__/ActionBar.stories.tsx | 38 --------------- .../__stories__/ContextMenu.stories.tsx | 48 ------------------- .../__stories__/NavigationModal.stories.tsx | 34 ------------- .../action-menu/hooks/useActionMenu.ts | 38 +++++++++++++++ .../states/actionBarIsOpenState.ts | 6 --- .../states/actionMenuDropdownIsOpenState.ts | 6 --- .../action-menu/types/ActionMenuDisplay.ts | 5 ++ .../hooks/useRecordBoardSelection.ts | 8 ++-- .../components/RecordBoardCard.tsx | 6 +-- .../components/RecordIndexContainer.tsx | 10 +--- .../components/RecordTableWithWrappers.tsx | 6 --- .../components/RecordTableCellCheckbox.tsx | 7 +-- .../hooks/useTriggerActionMenuDropdown.ts | 6 +-- 15 files changed, 60 insertions(+), 173 deletions(-) delete mode 100644 packages/twenty-front/src/modules/action-menu/components/__stories__/ActionBar.stories.tsx delete mode 100644 packages/twenty-front/src/modules/action-menu/components/__stories__/ContextMenu.stories.tsx delete mode 100644 packages/twenty-front/src/modules/action-menu/components/__stories__/NavigationModal.stories.tsx create mode 100644 packages/twenty-front/src/modules/action-menu/hooks/useActionMenu.ts delete mode 100644 packages/twenty-front/src/modules/action-menu/states/actionBarIsOpenState.ts delete mode 100644 packages/twenty-front/src/modules/action-menu/states/actionMenuDropdownIsOpenState.ts create mode 100644 packages/twenty-front/src/modules/action-menu/types/ActionMenuDisplay.ts diff --git a/packages/twenty-front/src/modules/action-menu/components/ActionBar.tsx b/packages/twenty-front/src/modules/action-menu/components/ActionBar.tsx index f68fb048af62..13e3c347068d 100644 --- a/packages/twenty-front/src/modules/action-menu/components/ActionBar.tsx +++ b/packages/twenty-front/src/modules/action-menu/components/ActionBar.tsx @@ -16,10 +16,10 @@ const StyledLabel = styled.div` `; type ActionBarProps = { - actionBarId: string; + actionMenuId: string; }; -export const ActionBar = ({ actionBarId }: ActionBarProps) => { +export const ActionBar = ({ actionMenuId }: ActionBarProps) => { const contextStoreTargetedRecordIds = useRecoilValue( contextStoreTargetedRecordIdsState, ); @@ -28,7 +28,7 @@ export const ActionBar = ({ actionBarId }: ActionBarProps) => { return ( ` `; export type ActionMenuDropdownProps = { - actionMenuDropdownId: string; - onOpen: () => void; + actionMenuId: string; }; export const ActionMenuDropdown = ({ - actionMenuDropdownId, - onOpen, + actionMenuId, }: ActionMenuDropdownProps) => { const actionMenuEntries = useRecoilValue(actionMenuEntriesState); @@ -60,7 +58,7 @@ export const ActionMenuDropdown = ({ className="context-menu" > ))} - onOpen={onOpen} /> ); diff --git a/packages/twenty-front/src/modules/action-menu/components/__stories__/ActionBar.stories.tsx b/packages/twenty-front/src/modules/action-menu/components/__stories__/ActionBar.stories.tsx deleted file mode 100644 index 9610eb43b311..000000000000 --- a/packages/twenty-front/src/modules/action-menu/components/__stories__/ActionBar.stories.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { useSetRecoilState } from 'recoil'; -import { ComponentDecorator } from 'twenty-ui'; - -import { RecordTableScope } from '@/object-record/record-table/scopes/RecordTableScope'; -import { MemoryRouterDecorator } from '~/testing/decorators/MemoryRouterDecorator'; - -import { actionBarOpenState } from '../../states/actionBarIsOpenState'; -import { ActionBar } from '../ActionBar'; - -const FilledActionBar = () => { - const setActionBarOpenState = useSetRecoilState(actionBarOpenState); - setActionBarOpenState(true); - return ; -}; - -const meta: Meta = { - title: 'UI/Navigation/ActionBar/ActionBar', - component: FilledActionBar, - decorators: [ - MemoryRouterDecorator, - (Story) => ( - {}} - > - - - ), - ComponentDecorator, - ], - args: { selectedIds: ['TestId'] }, -}; - -export default meta; -type Story = StoryObj; - -export const Default: Story = {}; diff --git a/packages/twenty-front/src/modules/action-menu/components/__stories__/ContextMenu.stories.tsx b/packages/twenty-front/src/modules/action-menu/components/__stories__/ContextMenu.stories.tsx deleted file mode 100644 index 84fe6c76dce4..000000000000 --- a/packages/twenty-front/src/modules/action-menu/components/__stories__/ContextMenu.stories.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { useSetRecoilState } from 'recoil'; -import { ComponentDecorator } from 'twenty-ui'; - -import { RecordTableScope } from '@/object-record/record-table/scopes/RecordTableScope'; -import { MemoryRouterDecorator } from '~/testing/decorators/MemoryRouterDecorator'; - -import { actionMenuDropdownIsOpenState } from '../../states/actionMenuDropdownIsOpenState'; -import { actionMenuDropdownPositionState } from '../../states/actionMenuDropdownPositionState'; -import { ActionMenuDropdown } from '../ActionMenuDropdown'; - -const FilledActionMenuDropdown = () => { - const setActionMenuDropdownPosition = useSetRecoilState( - actionMenuDropdownPositionState, - ); - setActionMenuDropdownPosition({ - x: 100, - y: 10, - }); - const setActionMenuDropdownOpenState = useSetRecoilState( - actionMenuDropdownIsOpenState, - ); - setActionMenuDropdownOpenState(true); - return ; -}; - -const meta: Meta = { - title: 'UI/Navigation/ActionMenuDropdown/ActionMenuDropdown', - component: FilledActionMenuDropdown, - decorators: [ - MemoryRouterDecorator, - (Story) => ( - {}} - > - - - ), - ComponentDecorator, - ], - args: { selectedIds: ['TestId'] }, -}; - -export default meta; -type Story = StoryObj; - -export const Default: Story = {}; diff --git a/packages/twenty-front/src/modules/action-menu/components/__stories__/NavigationModal.stories.tsx b/packages/twenty-front/src/modules/action-menu/components/__stories__/NavigationModal.stories.tsx deleted file mode 100644 index 8a30195c6122..000000000000 --- a/packages/twenty-front/src/modules/action-menu/components/__stories__/NavigationModal.stories.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { IconTrash } from 'twenty-ui'; - -import { ActionMenuNavigationModal } from '@/action-menu/components/ActionMenuNavigationModal'; -import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal'; - -const meta: Meta = { - title: 'UI/Navigation/Shared/NavigationModal', - component: ActionMenuNavigationModal, - args: { - actionMenuEntries: [ - { - ConfirmationModal: ( - {}} - setIsOpen={() => {}} - isOpen={false} - subtitle="Subtitle" - /> - ), - Icon: IconTrash, - label: 'Label', - onClick: () => {}, - }, - ], - }, -}; - -export default meta; -type Story = StoryObj; - -export const Default: Story = {}; diff --git a/packages/twenty-front/src/modules/action-menu/hooks/useActionMenu.ts b/packages/twenty-front/src/modules/action-menu/hooks/useActionMenu.ts new file mode 100644 index 000000000000..7555806b3be8 --- /dev/null +++ b/packages/twenty-front/src/modules/action-menu/hooks/useActionMenu.ts @@ -0,0 +1,38 @@ +import { useBottomBar } from '@/ui/layout/bottom-bar/hooks/useBottomBar'; +import { useDropdownV2 } from '@/ui/layout/dropdown/hooks/useDropdownV2'; + +export const useActionMenu = (actionMenuId: string) => { + const { openDropdown, closeDropdown } = useDropdownV2(); + const { openBottomBar, closeBottomBar } = useBottomBar(); + + const openActionMenuDropdown = () => { + closeBottomBar(`action-bar-${actionMenuId}`); + openDropdown(`action-menu-dropdown-${actionMenuId}`); + }; + + const openActionBar = () => { + closeDropdown(`action-menu-dropdown-${actionMenuId}`); + openBottomBar(`action-bar-${actionMenuId}`); + }; + + const closeActionMenuDropdown = () => { + closeDropdown(`action-menu-dropdown-${actionMenuId}`); + }; + + const closeActionBar = () => { + closeBottomBar(`action-bar-${actionMenuId}`); + }; + + const closeActionMenu = () => { + closeActionMenuDropdown(); + closeActionBar(); + }; + + return { + openActionMenuDropdown, + openActionBar, + closeActionMenu, + closeActionBar, + closeActionMenuDropdown, + }; +}; diff --git a/packages/twenty-front/src/modules/action-menu/states/actionBarIsOpenState.ts b/packages/twenty-front/src/modules/action-menu/states/actionBarIsOpenState.ts deleted file mode 100644 index 0ef918e6652e..000000000000 --- a/packages/twenty-front/src/modules/action-menu/states/actionBarIsOpenState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { createState } from 'twenty-ui'; - -export const actionBarOpenState = createState({ - key: 'actionBarOpenState', - defaultValue: false, -}); diff --git a/packages/twenty-front/src/modules/action-menu/states/actionMenuDropdownIsOpenState.ts b/packages/twenty-front/src/modules/action-menu/states/actionMenuDropdownIsOpenState.ts deleted file mode 100644 index 47e16509864f..000000000000 --- a/packages/twenty-front/src/modules/action-menu/states/actionMenuDropdownIsOpenState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { createState } from 'twenty-ui'; - -export const actionMenuDropdownIsOpenState = createState({ - key: 'actionMenuDropdownIsOpenState', - defaultValue: false, -}); diff --git a/packages/twenty-front/src/modules/action-menu/types/ActionMenuDisplay.ts b/packages/twenty-front/src/modules/action-menu/types/ActionMenuDisplay.ts new file mode 100644 index 000000000000..1b2b9f94abeb --- /dev/null +++ b/packages/twenty-front/src/modules/action-menu/types/ActionMenuDisplay.ts @@ -0,0 +1,5 @@ +export enum ActionMenuDisplay { + NONE = 'NONE', + DROPDOWN = 'DROPDOWN', + ACTION_BAR = 'ACTION_BAR', +} 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 04d38aaea6fb..3e2704c35686 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 @@ -1,12 +1,10 @@ import { useRecoilCallback } from 'recoil'; +import { useActionMenu } from '@/action-menu/hooks/useActionMenu'; import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates'; -import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; -export const useRecordBoardSelection = (recordBoardId?: string) => { - const { closeDropdown: closeActionMenuDropdown } = useDropdown( - `action-menu-dropdown-${recordBoardId}`, - ); +export const useRecordBoardSelection = (recordBoardId: string) => { + const { closeActionMenuDropdown } = useActionMenu(recordBoardId); const { selectedRecordIdsSelector, isRecordBoardCardSelectedFamilyState } = useRecordBoardStates(recordBoardId); diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx index 126c641c9d65..18a40bbfa8c0 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx @@ -1,3 +1,4 @@ +import { useActionMenu } from '@/action-menu/hooks/useActionMenu'; import { actionMenuDropdownPositionState } from '@/action-menu/states/actionMenuDropdownPositionState'; import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext'; import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates'; @@ -19,7 +20,6 @@ import { ObjectRecord } from '@/object-record/types/ObjectRecord'; import { LightIconButton } from '@/ui/input/button/components/LightIconButton'; import { Checkbox, CheckboxVariant } from '@/ui/input/components/Checkbox'; import { TextInput } from '@/ui/input/components/TextInput'; -import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { AnimatedEaseInOut } from '@/ui/utilities/animation/components/AnimatedEaseInOut'; import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId'; import { RecordBoardScrollWrapperContext } from '@/ui/utilities/scroll/contexts/ScrollWrapperContexts'; @@ -186,9 +186,7 @@ export const RecordBoardCard = ({ const recordBoardId = useAvailableScopeIdOrThrow( RecordBoardScopeInternalContext, ); - const { openDropdown: openActionMenuDropdown } = useDropdown( - `action-menu-dropdown-${recordBoardId}`, - ); + const { openActionMenuDropdown } = useActionMenu(recordBoardId); const handleActionMenuDropdown = (event: React.MouseEvent) => { event.preventDefault(); diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx index ad0a736eea4b..62b405990976 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx @@ -27,7 +27,6 @@ import { SpreadsheetImportProvider } from '@/spreadsheet-import/provider/compone import { ActionBar } from '@/action-menu/components/ActionBar'; import { ActionMenuDropdown } from '@/action-menu/components/ActionMenuDropdown'; import { ActionMenuNavigationModal } from '@/action-menu/components/ActionMenuNavigationModal'; -import { useBottomBar } from '@/ui/layout/bottom-bar/hooks/useBottomBar'; import { ViewBar } from '@/views/components/ViewBar'; import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext'; import { ViewField } from '@/views/types/ViewField'; @@ -110,8 +109,6 @@ export const RecordIndexContainer = () => { [columnDefinitions, setTableColumns], ); - const { closeBottomBar } = useBottomBar(); - return ( @@ -198,11 +195,8 @@ export const RecordIndexContainer = () => { /> )} - - closeBottomBar(`action-bar-${recordIndexId}`)} - /> + + diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx index 44c9f1366f34..b7a46e64829d 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx @@ -15,7 +15,6 @@ import { mapColumnDefinitionsToViewFields } from '@/views/utils/mapColumnDefinit import { RecordUpdateContext } from '../contexts/EntityUpdateMutationHookContext'; import { useRecordTable } from '../hooks/useRecordTable'; -import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { RecordTableInternalEffect } from './RecordTableInternalEffect'; const StyledTableWithHeader = styled.div` @@ -67,10 +66,6 @@ export const RecordTableWithWrappers = ({ [saveViewFields], ); - const { closeDropdown: closeActionMenuDropdown } = useDropdown( - `action-menu-dropdown-${recordTableId}`, - ); - return ( @@ -87,7 +82,6 @@ export const RecordTableWithWrappers = ({ { - closeActionMenuDropdown(); resetTableRowSelection(); }} onDragSelectionChange={setRowSelected} diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellCheckbox.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellCheckbox.tsx index a3ebc1a32c6a..459211537244 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellCheckbox.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellCheckbox.tsx @@ -1,8 +1,7 @@ import styled from '@emotion/styled'; import { useCallback, useContext } from 'react'; -import { useRecoilValue, useSetRecoilState } from 'recoil'; +import { useRecoilValue } from 'recoil'; -import { actionBarOpenState } from '@/action-menu/states/actionBarIsOpenState'; import { RecordTableRowContext } from '@/object-record/record-table/contexts/RecordTableRowContext'; import { useRecordTableStates } from '@/object-record/record-table/hooks/internal/useRecordTableStates'; import { RecordTableTd } from '@/object-record/record-table/record-table-cell/components/RecordTableTd'; @@ -24,14 +23,12 @@ export const RecordTableCellCheckbox = () => { const { recordId } = useContext(RecordTableRowContext); const { isRowSelectedFamilyState } = useRecordTableStates(); - const setActionBarOpenState = useSetRecoilState(actionBarOpenState); const { setCurrentRowSelected } = useSetCurrentRowSelected(); const currentRowSelected = useRecoilValue(isRowSelectedFamilyState(recordId)); const handleClick = useCallback(() => { setCurrentRowSelected(!currentRowSelected); - setActionBarOpenState(true); - }, [currentRowSelected, setActionBarOpenState, setCurrentRowSelected]); + }, [currentRowSelected, setCurrentRowSelected]); return ( diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerActionMenuDropdown.ts b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerActionMenuDropdown.ts index 16a8a51c78c8..d7d0b9a40bf0 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerActionMenuDropdown.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerActionMenuDropdown.ts @@ -1,8 +1,8 @@ import { useRecoilCallback } from 'recoil'; +import { useActionMenu } from '@/action-menu/hooks/useActionMenu'; import { actionMenuDropdownPositionState } from '@/action-menu/states/actionMenuDropdownPositionState'; import { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState'; -import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId'; import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue'; import { extractComponentFamilyState } from '@/ui/utilities/state/component-state/utils/extractComponentFamilyState'; @@ -12,9 +12,7 @@ export const useTriggerActionMenuDropdown = ({ }: { recordTableId: string; }) => { - const { openDropdown: openActionMenuDropdown } = useDropdown( - `action-menu-dropdown-${recordTableId}`, - ); + const { openActionMenuDropdown } = useActionMenu(recordTableId); const triggerActionMenuDropdown = useRecoilCallback( ({ set, snapshot }) => (event: React.MouseEvent, recordId: string) => { From b851f29ddf3c7ffc8cbf624dd05f35a48e661007 Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Fri, 4 Oct 2024 17:30:45 +0200 Subject: [PATCH 20/52] add ActionMenuEffect --- .../components/ActionMenuEffect.tsx | 26 +++++++++++++++++++ .../components/RecordIndexContainer.tsx | 2 ++ 2 files changed, 28 insertions(+) create mode 100644 packages/twenty-front/src/modules/action-menu/components/ActionMenuEffect.tsx diff --git a/packages/twenty-front/src/modules/action-menu/components/ActionMenuEffect.tsx b/packages/twenty-front/src/modules/action-menu/components/ActionMenuEffect.tsx new file mode 100644 index 000000000000..2d41f33bbd65 --- /dev/null +++ b/packages/twenty-front/src/modules/action-menu/components/ActionMenuEffect.tsx @@ -0,0 +1,26 @@ +import { useActionMenu } from '@/action-menu/hooks/useActionMenu'; +import { contextStoreTargetedRecordIdsState } from '@/context-store/states/contextStoreTargetedRecordIdsState'; +import { useEffect } from 'react'; +import { useRecoilValue } from 'recoil'; + +type ActionMenuEffectProps = { + actionMenuId: string; +}; + +export const ActionMenuEffect = ({ actionMenuId }: ActionMenuEffectProps) => { + const contextStoreTargetedRecordIds = useRecoilValue( + contextStoreTargetedRecordIdsState, + ); + + const { openActionBar, closeActionMenu } = useActionMenu(actionMenuId); + + useEffect(() => { + if (contextStoreTargetedRecordIds.length > 0) { + openActionBar(); + } else { + closeActionMenu(); + } + }, [contextStoreTargetedRecordIds, openActionBar, closeActionMenu]); + + return null; +}; diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx index 62b405990976..97539e2dc399 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx @@ -26,6 +26,7 @@ import { SpreadsheetImportProvider } from '@/spreadsheet-import/provider/compone import { ActionBar } from '@/action-menu/components/ActionBar'; import { ActionMenuDropdown } from '@/action-menu/components/ActionMenuDropdown'; +import { ActionMenuEffect } from '@/action-menu/components/ActionMenuEffect'; import { ActionMenuNavigationModal } from '@/action-menu/components/ActionMenuNavigationModal'; import { ViewBar } from '@/views/components/ViewBar'; import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext'; @@ -195,6 +196,7 @@ export const RecordIndexContainer = () => { /> )} + From e542d0c9818df08c364b7ca05404ed2160adad24 Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Mon, 7 Oct 2024 11:47:01 +0200 Subject: [PATCH 21/52] set state in useRecoilCallback --- .../components/ActionMenuEffect.tsx | 27 +++++++++++++++---- .../action-menu/hooks/useActionMenu.ts | 6 ----- .../hooks/useTriggerActionMenuDropdown.ts | 21 ++++++++++++--- 3 files changed, 39 insertions(+), 15 deletions(-) diff --git a/packages/twenty-front/src/modules/action-menu/components/ActionMenuEffect.tsx b/packages/twenty-front/src/modules/action-menu/components/ActionMenuEffect.tsx index 2d41f33bbd65..7942acfb3e35 100644 --- a/packages/twenty-front/src/modules/action-menu/components/ActionMenuEffect.tsx +++ b/packages/twenty-front/src/modules/action-menu/components/ActionMenuEffect.tsx @@ -1,5 +1,7 @@ import { useActionMenu } from '@/action-menu/hooks/useActionMenu'; import { contextStoreTargetedRecordIdsState } from '@/context-store/states/contextStoreTargetedRecordIdsState'; +import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState'; +import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState'; import { useEffect } from 'react'; import { useRecoilValue } from 'recoil'; @@ -12,15 +14,30 @@ export const ActionMenuEffect = ({ actionMenuId }: ActionMenuEffectProps) => { contextStoreTargetedRecordIdsState, ); - const { openActionBar, closeActionMenu } = useActionMenu(actionMenuId); + const { openActionBar, closeActionMenuDropdown, closeActionBar } = + useActionMenu(actionMenuId); + + const isDropdownOpen = useRecoilValue( + extractComponentState( + isDropdownOpenComponentState, + `action-menu-dropdown-${actionMenuId}`, + ), + ); useEffect(() => { - if (contextStoreTargetedRecordIds.length > 0) { + if (contextStoreTargetedRecordIds.length > 0 && !isDropdownOpen) { openActionBar(); - } else { - closeActionMenu(); } - }, [contextStoreTargetedRecordIds, openActionBar, closeActionMenu]); + if (contextStoreTargetedRecordIds.length === 0) { + closeActionBar(); + } + }, [ + contextStoreTargetedRecordIds, + openActionBar, + closeActionMenuDropdown, + closeActionBar, + isDropdownOpen, + ]); return null; }; diff --git a/packages/twenty-front/src/modules/action-menu/hooks/useActionMenu.ts b/packages/twenty-front/src/modules/action-menu/hooks/useActionMenu.ts index 7555806b3be8..881cadd694e1 100644 --- a/packages/twenty-front/src/modules/action-menu/hooks/useActionMenu.ts +++ b/packages/twenty-front/src/modules/action-menu/hooks/useActionMenu.ts @@ -23,15 +23,9 @@ export const useActionMenu = (actionMenuId: string) => { closeBottomBar(`action-bar-${actionMenuId}`); }; - const closeActionMenu = () => { - closeActionMenuDropdown(); - closeActionBar(); - }; - return { openActionMenuDropdown, openActionBar, - closeActionMenu, closeActionBar, closeActionMenuDropdown, }; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerActionMenuDropdown.ts b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerActionMenuDropdown.ts index d7d0b9a40bf0..c3bcfa85ec4b 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerActionMenuDropdown.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerActionMenuDropdown.ts @@ -1,18 +1,19 @@ import { useRecoilCallback } from 'recoil'; -import { useActionMenu } from '@/action-menu/hooks/useActionMenu'; import { actionMenuDropdownPositionState } from '@/action-menu/states/actionMenuDropdownPositionState'; import { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState'; +import { isBottomBarOpenComponentState } from '@/ui/layout/bottom-bar/states/isBottomBarOpenComponentState'; +import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState'; import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId'; import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue'; import { extractComponentFamilyState } from '@/ui/utilities/state/component-state/utils/extractComponentFamilyState'; +import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState'; export const useTriggerActionMenuDropdown = ({ recordTableId, }: { recordTableId: string; }) => { - const { openActionMenuDropdown } = useActionMenu(recordTableId); const triggerActionMenuDropdown = useRecoilCallback( ({ set, snapshot }) => (event: React.MouseEvent, recordId: string) => { @@ -24,7 +25,6 @@ export const useTriggerActionMenuDropdown = ({ x: event.clientX, y: event.clientY, }); - openActionMenuDropdown(); const isRowSelectedFamilyState = extractComponentFamilyState( isRowSelectedComponentFamilyState, @@ -39,8 +39,21 @@ export const useTriggerActionMenuDropdown = ({ if (isRowSelected !== true) { set(isRowSelectedFamilyState(recordId), true); } + + const isActionMenuDropdownOpenState = extractComponentState( + isDropdownOpenComponentState, + `action-menu-dropdown-${recordTableId}`, + ); + + const isActionBarOpenState = extractComponentState( + isBottomBarOpenComponentState, + `action-bar-${recordTableId}`, + ); + + set(isActionBarOpenState, false); + set(isActionMenuDropdownOpenState, true); }, - [openActionMenuDropdown, recordTableId], + [recordTableId], ); return { triggerActionMenuDropdown }; From a2d85c55ce707f9d728672e29b829bb1d53b1a85 Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Mon, 7 Oct 2024 11:54:19 +0200 Subject: [PATCH 22/52] set ActionMenuDropdown open state inside recoil callback when resetting selection --- .../hooks/useRecordBoardSelection.ts | 14 ++++++++++---- .../hooks/internal/useResetTableRowSelection.ts | 16 +++++++++++++++- 2 files changed, 25 insertions(+), 5 deletions(-) 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 3e2704c35686..8b2d11837ae1 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 @@ -1,17 +1,23 @@ import { useRecoilCallback } from 'recoil'; -import { useActionMenu } from '@/action-menu/hooks/useActionMenu'; import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates'; +import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState'; +import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState'; export const useRecordBoardSelection = (recordBoardId: string) => { - const { closeActionMenuDropdown } = useActionMenu(recordBoardId); const { selectedRecordIdsSelector, isRecordBoardCardSelectedFamilyState } = useRecordBoardStates(recordBoardId); const resetRecordSelection = useRecoilCallback( ({ snapshot, set }) => () => { - closeActionMenuDropdown(); + const isActionMenuDropdownOpenState = extractComponentState( + isDropdownOpenComponentState, + `action-menu-dropdown-${recordBoardId}`, + ); + + set(isActionMenuDropdownOpenState, false); + const recordIds = snapshot .getLoadable(selectedRecordIdsSelector()) .getValue(); @@ -21,7 +27,7 @@ export const useRecordBoardSelection = (recordBoardId: string) => { } }, [ - closeActionMenuDropdown, + recordBoardId, selectedRecordIdsSelector, isRecordBoardCardSelectedFamilyState, ], 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 1b6263739111..58779a443da2 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 @@ -1,7 +1,9 @@ import { useRecoilCallback } from 'recoil'; import { useRecordTableStates } from '@/object-record/record-table/hooks/internal/useRecordTableStates'; +import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState'; import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue'; +import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState'; export const useResetTableRowSelection = (recordTableId?: string) => { const { @@ -20,7 +22,19 @@ export const useResetTableRowSelection = (recordTableId?: string) => { } set(hasUserSelectedAllRowsState, false); + + const isActionMenuDropdownOpenState = extractComponentState( + isDropdownOpenComponentState, + `action-menu-dropdown-${recordTableId}`, + ); + + set(isActionMenuDropdownOpenState, false); }, - [tableRowIdsState, isRowSelectedFamilyState, hasUserSelectedAllRowsState], + [ + tableRowIdsState, + hasUserSelectedAllRowsState, + recordTableId, + isRowSelectedFamilyState, + ], ); }; From fc6b859d6e71c3063faea426916b97b47058b9cc Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Mon, 7 Oct 2024 13:29:54 +0200 Subject: [PATCH 23/52] remove empty component --- .../right-drawer/components/RightDrawerActionMenu.tsx | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 packages/twenty-front/src/modules/action-menu/right-drawer/components/RightDrawerActionMenu.tsx diff --git a/packages/twenty-front/src/modules/action-menu/right-drawer/components/RightDrawerActionMenu.tsx b/packages/twenty-front/src/modules/action-menu/right-drawer/components/RightDrawerActionMenu.tsx deleted file mode 100644 index 81b81c1999f9..000000000000 --- a/packages/twenty-front/src/modules/action-menu/right-drawer/components/RightDrawerActionMenu.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export const RightDrawerActionMenu = () => { - return; -}; From 1baffb6895488ade5099dc21da423e005307c3be Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Mon, 7 Oct 2024 13:34:54 +0200 Subject: [PATCH 24/52] remove unused dependency from dependency array --- .../src/modules/action-menu/components/ActionMenuEffect.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/twenty-front/src/modules/action-menu/components/ActionMenuEffect.tsx b/packages/twenty-front/src/modules/action-menu/components/ActionMenuEffect.tsx index 7942acfb3e35..ae885251fa3b 100644 --- a/packages/twenty-front/src/modules/action-menu/components/ActionMenuEffect.tsx +++ b/packages/twenty-front/src/modules/action-menu/components/ActionMenuEffect.tsx @@ -34,7 +34,6 @@ export const ActionMenuEffect = ({ actionMenuId }: ActionMenuEffectProps) => { }, [ contextStoreTargetedRecordIds, openActionBar, - closeActionMenuDropdown, closeActionBar, isDropdownOpen, ]); From 588d1aa69bb8dad5b49356d629536b66ecd0405e Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Mon, 7 Oct 2024 13:35:21 +0200 Subject: [PATCH 25/52] remove unused dependency from dependency array --- .../src/modules/action-menu/components/ActionMenuEffect.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/twenty-front/src/modules/action-menu/components/ActionMenuEffect.tsx b/packages/twenty-front/src/modules/action-menu/components/ActionMenuEffect.tsx index ae885251fa3b..a8413d20f8c1 100644 --- a/packages/twenty-front/src/modules/action-menu/components/ActionMenuEffect.tsx +++ b/packages/twenty-front/src/modules/action-menu/components/ActionMenuEffect.tsx @@ -14,8 +14,7 @@ export const ActionMenuEffect = ({ actionMenuId }: ActionMenuEffectProps) => { contextStoreTargetedRecordIdsState, ); - const { openActionBar, closeActionMenuDropdown, closeActionBar } = - useActionMenu(actionMenuId); + const { openActionBar, closeActionBar } = useActionMenu(actionMenuId); const isDropdownOpen = useRecoilValue( extractComponentState( From f18d74fe911267ed8f6790cbbf574b6733e0b4ef Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Mon, 7 Oct 2024 14:02:26 +0200 Subject: [PATCH 26/52] create bottom bar stories --- .../__stories__/BottomBar.stories.tsx | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 packages/twenty-front/src/modules/ui/layout/bottom-bar/components/__stories__/BottomBar.stories.tsx diff --git a/packages/twenty-front/src/modules/ui/layout/bottom-bar/components/__stories__/BottomBar.stories.tsx b/packages/twenty-front/src/modules/ui/layout/bottom-bar/components/__stories__/BottomBar.stories.tsx new file mode 100644 index 000000000000..022f3ba6635b --- /dev/null +++ b/packages/twenty-front/src/modules/ui/layout/bottom-bar/components/__stories__/BottomBar.stories.tsx @@ -0,0 +1,64 @@ +import { Meta, StoryObj } from '@storybook/react'; +import { IconPlus } from 'twenty-ui'; + +import { Button } from '@/ui/input/button/components/Button'; +import { BottomBar } from '@/ui/layout/bottom-bar/components/BottomBar'; +import { isBottomBarOpenComponentState } from '@/ui/layout/bottom-bar/states/isBottomBarOpenComponentState'; +import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState'; +import styled from '@emotion/styled'; +import { RecoilRoot } from 'recoil'; + +const StyledContainer = styled.div` + display: flex; + gap: 10px; +`; + +const meta: Meta = { + title: 'UI/Layout/BottomBar/BottomBar', + component: BottomBar, + args: { + bottomBarId: 'test', + bottomBarHotkeyScopeFromParent: { scope: 'test' }, + children: ( + +