7339 implement contextual actions inside the commandmenu (#8000)
Closes #7339 https://github.com/user-attachments/assets/b623caa4-c1b3-448e-8880-4a8301802ba8
This commit is contained in:
@ -71,7 +71,7 @@ export const RecordBoard = () => {
|
||||
|
||||
useListenClickOutsideByClassName({
|
||||
classNames: ['record-board-card'],
|
||||
excludeClassNames: ['bottom-bar', 'action-menu-dropdown'],
|
||||
excludeClassNames: ['bottom-bar', 'action-menu-dropdown', 'command-menu'],
|
||||
callback: resetRecordSelection,
|
||||
});
|
||||
|
||||
|
||||
@ -206,6 +206,7 @@ export const RecordIndexContainer = () => {
|
||||
viewBarId={recordIndexId}
|
||||
/>
|
||||
</SpreadsheetImportProvider>
|
||||
|
||||
{recordIndexViewType === ViewType.Table && (
|
||||
<>
|
||||
<RecordIndexTableContainer
|
||||
@ -232,7 +233,7 @@ export const RecordIndexContainer = () => {
|
||||
/>
|
||||
</StyledContainerWithPadding>
|
||||
)}
|
||||
<RecordIndexActionMenu actionMenuId={recordIndexId} />
|
||||
<RecordIndexActionMenu />
|
||||
</RecordFieldValueSelectorContextProvider>
|
||||
</StyledContainer>
|
||||
);
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { ActionMenuComponentInstanceContext } from '@/action-menu/states/contexts/ActionMenuComponentInstanceContext';
|
||||
import { ContextStoreComponentInstanceContext } from '@/context-store/states/contexts/ContextStoreComponentInstanceContext';
|
||||
import { isNewViewableRecordLoadingState } from '@/object-record/record-right-drawer/states/isNewViewableRecordLoading';
|
||||
import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState';
|
||||
import { viewableRecordNameSingularState } from '@/object-record/record-right-drawer/states/viewableRecordNameSingularState';
|
||||
@ -38,19 +40,29 @@ export const RightDrawerRecord = () => {
|
||||
);
|
||||
|
||||
return (
|
||||
<StyledRightDrawerRecord>
|
||||
<RecordFieldValueSelectorContextProvider>
|
||||
{!isNewViewableRecordLoading && (
|
||||
<RecordValueSetterEffect recordId={objectRecordId} />
|
||||
)}
|
||||
<RecordShowContainer
|
||||
objectNameSingular={objectNameSingular}
|
||||
objectRecordId={objectRecordId}
|
||||
loading={false}
|
||||
isInRightDrawer={true}
|
||||
isNewRightDrawerItemLoading={isNewViewableRecordLoading}
|
||||
/>
|
||||
</RecordFieldValueSelectorContextProvider>
|
||||
</StyledRightDrawerRecord>
|
||||
<ContextStoreComponentInstanceContext.Provider
|
||||
value={{
|
||||
instanceId: `record-show-${objectRecordId}`,
|
||||
}}
|
||||
>
|
||||
<ActionMenuComponentInstanceContext.Provider
|
||||
value={{ instanceId: `record-show-${objectRecordId}` }}
|
||||
>
|
||||
<StyledRightDrawerRecord>
|
||||
<RecordFieldValueSelectorContextProvider>
|
||||
{!isNewViewableRecordLoading && (
|
||||
<RecordValueSetterEffect recordId={objectRecordId} />
|
||||
)}
|
||||
<RecordShowContainer
|
||||
objectNameSingular={objectNameSingular}
|
||||
objectRecordId={objectRecordId}
|
||||
loading={false}
|
||||
isInRightDrawer={true}
|
||||
isNewRightDrawerItemLoading={isNewViewableRecordLoading}
|
||||
/>
|
||||
</RecordFieldValueSelectorContextProvider>
|
||||
</StyledRightDrawerRecord>
|
||||
</ActionMenuComponentInstanceContext.Provider>
|
||||
</ContextStoreComponentInstanceContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { ShowPageContainer } from '@/ui/layout/page/components/ShowPageContainer';
|
||||
|
||||
import { SetMainContextStoreComponentInstanceIdEffect } from '@/context-store/components/SetMainContextStoreComponentInstanceIdEffect';
|
||||
import { ContextStoreComponentInstanceContext } from '@/context-store/states/contexts/ContextStoreComponentInstanceContext';
|
||||
import { MainContextStoreComponentInstanceIdSetterEffect } from '@/context-store/components/MainContextStoreComponentInstanceIdSetterEffect';
|
||||
import { InformationBannerDeletedRecord } from '@/information-banner/components/deleted-record/InformationBannerDeletedRecord';
|
||||
import { RecordShowContainerContextStoreEffect } from '@/object-record/record-show/components/RecordShowContainerContextStoreEffect';
|
||||
|
||||
import { RecordShowContainerContextStoreObjectMetadataIdEffect } from '@/object-record/record-show/components/RecordShowContainerContextStoreObjectMetadataIdEffect';
|
||||
import { RecordShowContainerContextStoreTargetedRecordsEffect } from '@/object-record/record-show/components/RecordShowContainerContextStoreTargetedRecordsEffect';
|
||||
import { useRecordShowContainerData } from '@/object-record/record-show/hooks/useRecordShowContainerData';
|
||||
import { useRecordShowContainerTabs } from '@/object-record/record-show/hooks/useRecordShowContainerTabs';
|
||||
import { ShowPageSubContainer } from '@/ui/layout/show-page/components/ShowPageSubContainer';
|
||||
@ -41,16 +42,15 @@ export const RecordShowContainer = ({
|
||||
);
|
||||
|
||||
return (
|
||||
<ContextStoreComponentInstanceContext.Provider
|
||||
value={{
|
||||
instanceId: 'record-show',
|
||||
}}
|
||||
>
|
||||
<RecordShowContainerContextStoreEffect
|
||||
<>
|
||||
<RecordShowContainerContextStoreObjectMetadataIdEffect
|
||||
recordId={objectRecordId}
|
||||
objectNameSingular={objectNameSingular}
|
||||
/>
|
||||
{!isInRightDrawer && <SetMainContextStoreComponentInstanceIdEffect />}
|
||||
<RecordShowContainerContextStoreTargetedRecordsEffect
|
||||
recordId={objectRecordId}
|
||||
/>
|
||||
{!isInRightDrawer && <MainContextStoreComponentInstanceIdSetterEffect />}
|
||||
{recordFromStore && recordFromStore.deletedAt && (
|
||||
<InformationBannerDeletedRecord
|
||||
recordId={objectRecordId}
|
||||
@ -69,6 +69,6 @@ export const RecordShowContainer = ({
|
||||
isNewRightDrawerItemLoading={isNewRightDrawerItemLoading}
|
||||
/>
|
||||
</ShowPageContainer>
|
||||
</ContextStoreComponentInstanceContext.Provider>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
import { contextStoreCurrentObjectMetadataIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataIdComponentState';
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
export const RecordShowContainerContextStoreObjectMetadataIdEffect = ({
|
||||
recordId,
|
||||
objectNameSingular,
|
||||
}: {
|
||||
recordId: string;
|
||||
objectNameSingular: string;
|
||||
}) => {
|
||||
const setContextStoreCurrentObjectMetadataId = useSetRecoilComponentStateV2(
|
||||
contextStoreCurrentObjectMetadataIdComponentState,
|
||||
);
|
||||
|
||||
const { objectMetadataItem } = useObjectMetadataItem({
|
||||
objectNameSingular: objectNameSingular,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setContextStoreCurrentObjectMetadataId(objectMetadataItem?.id);
|
||||
|
||||
return () => {
|
||||
setContextStoreCurrentObjectMetadataId(null);
|
||||
};
|
||||
}, [recordId, setContextStoreCurrentObjectMetadataId, objectMetadataItem.id]);
|
||||
|
||||
return null;
|
||||
};
|
||||
@ -1,29 +1,17 @@
|
||||
import { contextStoreCurrentObjectMetadataIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataIdComponentState';
|
||||
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
export const RecordShowContainerContextStoreEffect = ({
|
||||
export const RecordShowContainerContextStoreTargetedRecordsEffect = ({
|
||||
recordId,
|
||||
objectNameSingular,
|
||||
}: {
|
||||
recordId: string;
|
||||
objectNameSingular: string;
|
||||
}) => {
|
||||
const setContextStoreTargetedRecordsRule = useSetRecoilComponentStateV2(
|
||||
contextStoreTargetedRecordsRuleComponentState,
|
||||
);
|
||||
|
||||
const setContextStoreCurrentObjectMetadataId = useSetRecoilComponentStateV2(
|
||||
contextStoreCurrentObjectMetadataIdComponentState,
|
||||
);
|
||||
|
||||
const { objectMetadataItem } = useObjectMetadataItem({
|
||||
objectNameSingular: objectNameSingular,
|
||||
});
|
||||
|
||||
const setContextStoreNumberOfSelectedRecords = useSetRecoilComponentStateV2(
|
||||
contextStoreNumberOfSelectedRecordsComponentState,
|
||||
);
|
||||
@ -33,7 +21,6 @@ export const RecordShowContainerContextStoreEffect = ({
|
||||
mode: 'selection',
|
||||
selectedRecordIds: [recordId],
|
||||
});
|
||||
setContextStoreCurrentObjectMetadataId(objectMetadataItem?.id);
|
||||
setContextStoreNumberOfSelectedRecords(1);
|
||||
|
||||
return () => {
|
||||
@ -41,14 +28,11 @@ export const RecordShowContainerContextStoreEffect = ({
|
||||
mode: 'selection',
|
||||
selectedRecordIds: [],
|
||||
});
|
||||
setContextStoreCurrentObjectMetadataId(null);
|
||||
setContextStoreNumberOfSelectedRecords(0);
|
||||
};
|
||||
}, [
|
||||
recordId,
|
||||
setContextStoreTargetedRecordsRule,
|
||||
setContextStoreCurrentObjectMetadataId,
|
||||
objectMetadataItem?.id,
|
||||
setContextStoreNumberOfSelectedRecords,
|
||||
]);
|
||||
|
||||
@ -27,7 +27,7 @@ export const RecordTableInternalEffect = ({
|
||||
|
||||
useListenClickOutsideByClassName({
|
||||
classNames: ['entity-table-cell'],
|
||||
excludeClassNames: ['bottom-bar', 'action-menu-dropdown'],
|
||||
excludeClassNames: ['bottom-bar', 'action-menu-dropdown', 'command-menu'],
|
||||
callback: () => {
|
||||
leaveTableFocus();
|
||||
},
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
import { ActionMenuComponentInstanceContext } from '@/action-menu/states/contexts/ActionMenuComponentInstanceContext';
|
||||
import { recordIndexActionMenuDropdownPositionComponentState } from '@/action-menu/states/recordIndexActionMenuDropdownPositionComponentState';
|
||||
import { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState';
|
||||
import { isBottomBarOpenedComponentState } from '@/ui/layout/bottom-bar/states/isBottomBarOpenedComponentState';
|
||||
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 { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { extractComponentFamilyState } from '@/ui/utilities/state/component-state/utils/extractComponentFamilyState';
|
||||
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
|
||||
|
||||
@ -14,6 +16,10 @@ export const useTriggerActionMenuDropdown = ({
|
||||
}: {
|
||||
recordTableId: string;
|
||||
}) => {
|
||||
const actionMenuInstanceId = useAvailableComponentInstanceIdOrThrow(
|
||||
ActionMenuComponentInstanceContext,
|
||||
);
|
||||
|
||||
const triggerActionMenuDropdown = useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
(event: React.MouseEvent, recordId: string) => {
|
||||
@ -24,7 +30,7 @@ export const useTriggerActionMenuDropdown = ({
|
||||
set(
|
||||
extractComponentState(
|
||||
recordIndexActionMenuDropdownPositionComponentState,
|
||||
`action-menu-dropdown-${recordTableId}`,
|
||||
`action-menu-dropdown-${actionMenuInstanceId}`,
|
||||
),
|
||||
{
|
||||
x: event.clientX,
|
||||
@ -48,19 +54,19 @@ export const useTriggerActionMenuDropdown = ({
|
||||
|
||||
const isActionMenuDropdownOpenState = extractComponentState(
|
||||
isDropdownOpenComponentState,
|
||||
`action-menu-dropdown-${recordTableId}`,
|
||||
`action-menu-dropdown-${actionMenuInstanceId}`,
|
||||
);
|
||||
|
||||
const isActionBarOpenState = isBottomBarOpenedComponentState.atomFamily(
|
||||
{
|
||||
instanceId: `action-bar-${recordTableId}`,
|
||||
instanceId: `action-bar-${actionMenuInstanceId}`,
|
||||
},
|
||||
);
|
||||
|
||||
set(isActionBarOpenState, false);
|
||||
set(isActionMenuDropdownOpenState, true);
|
||||
},
|
||||
[recordTableId],
|
||||
[actionMenuInstanceId, recordTableId],
|
||||
);
|
||||
|
||||
return { triggerActionMenuDropdown };
|
||||
|
||||
Reference in New Issue
Block a user