7499 refactor right drawer to have contextual actions (#7954)

Closes #7499
- Modifies context store states to be component states
- Introduces the concept of `mainContextStore` which will dictate the
available actions inside the command K
- Adds contextual actions inside the right drawer
- Creates a new type of modal variant
This commit is contained in:
Raphaël Bosi
2024-10-22 18:35:45 +02:00
committed by GitHub
parent 6c93587efb
commit 6843a642b5
56 changed files with 718 additions and 418 deletions

View File

@ -1,6 +1,7 @@
import { useActionMenuEntries } from '@/action-menu/hooks/useActionMenuEntries';
import { contextStoreNumberOfSelectedRecordsState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsState';
import { contextStoreTargetedRecordsRuleState } from '@/context-store/states/contextStoreTargetedRecordsRuleState';
import { ActionMenuType } from '@/action-menu/types/ActionMenuType';
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
import { computeContextStoreFilters } from '@/context-store/utils/computeContextStoreFilters';
import { useFavorites } from '@/favorites/hooks/useFavorites';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
@ -9,16 +10,19 @@ import { useDeleteManyRecords } from '@/object-record/hooks/useDeleteManyRecords
import { useFetchAllRecordIds } from '@/object-record/hooks/useFetchAllRecordIds';
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { useCallback, useEffect, useState } from 'react';
import { useRecoilValue } from 'recoil';
import { IconTrash, isDefined } from 'twenty-ui';
export const DeleteRecordsActionEffect = ({
position,
objectMetadataItem,
actionMenuType,
}: {
position: number;
objectMetadataItem: ObjectMetadataItem;
actionMenuType: ActionMenuType;
}) => {
const { addActionMenuEntry, removeActionMenuEntry } = useActionMenuEntries();
@ -35,12 +39,12 @@ export const DeleteRecordsActionEffect = ({
const { favorites, deleteFavorite } = useFavorites();
const contextStoreNumberOfSelectedRecords = useRecoilValue(
contextStoreNumberOfSelectedRecordsState,
const contextStoreNumberOfSelectedRecords = useRecoilComponentValueV2(
contextStoreNumberOfSelectedRecordsComponentState,
);
const contextStoreTargetedRecordsRule = useRecoilValue(
contextStoreTargetedRecordsRuleState,
const contextStoreTargetedRecordsRule = useRecoilComponentValueV2(
contextStoreTargetedRecordsRuleComponentState,
);
const graphqlFilter = computeContextStoreFilters(
@ -53,6 +57,8 @@ export const DeleteRecordsActionEffect = ({
filter: graphqlFilter,
});
const { closeRightDrawer } = useRightDrawer();
const handleDeleteClick = useCallback(async () => {
const recordIdsToDelete = await fetchAllRecordIds();
@ -112,10 +118,19 @@ export const DeleteRecordsActionEffect = ({
}? ${
contextStoreNumberOfSelectedRecords === 1 ? 'It' : 'They'
} can be recovered from the Options menu.`}
onConfirmClick={() => handleDeleteClick()}
onConfirmClick={() => {
handleDeleteClick();
if (actionMenuType === 'recordShow') {
closeRightDrawer();
}
}}
deleteButtonText={`Delete ${
contextStoreNumberOfSelectedRecords > 1 ? 'Records' : 'Record'
}`}
modalVariant={
actionMenuType === 'recordShow' ? 'tertiary' : 'primary'
}
/>
),
});
@ -127,8 +142,10 @@ export const DeleteRecordsActionEffect = ({
removeActionMenuEntry('delete');
};
}, [
actionMenuType,
addActionMenuEntry,
canDelete,
closeRightDrawer,
contextStoreNumberOfSelectedRecords,
handleDeleteClick,
isDeleteRecordsModalOpen,

View File

@ -1,8 +1,9 @@
import { useActionMenuEntries } from '@/action-menu/hooks/useActionMenuEntries';
import { contextStoreTargetedRecordsRuleState } from '@/context-store/states/contextStoreTargetedRecordsRuleState';
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
import { useFavorites } from '@/favorites/hooks/useFavorites';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { useEffect } from 'react';
import { useRecoilValue } from 'recoil';
import { IconHeart, IconHeartOff, isDefined } from 'twenty-ui';
@ -16,8 +17,8 @@ export const ManageFavoritesActionEffect = ({
}) => {
const { addActionMenuEntry, removeActionMenuEntry } = useActionMenuEntries();
const contextStoreTargetedRecordsRule = useRecoilValue(
contextStoreTargetedRecordsRuleState,
const contextStoreTargetedRecordsRule = useRecoilComponentValueV2(
contextStoreTargetedRecordsRuleComponentState,
);
const { favorites, createFavorite, deleteFavorite } = useFavorites();

View File

@ -1,13 +1,16 @@
import { DeleteRecordsActionEffect } from '@/action-menu/actions/record-actions/components/DeleteRecordsActionEffect';
import { ExportRecordsActionEffect } from '@/action-menu/actions/record-actions/components/ExportRecordsActionEffect';
import { ActionMenuType } from '@/action-menu/types/ActionMenuType';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
const actionEffects = [ExportRecordsActionEffect, DeleteRecordsActionEffect];
export const MultipleRecordsActionMenuEntriesSetter = ({
objectMetadataItem,
actionMenuType,
}: {
objectMetadataItem: ObjectMetadataItem;
actionMenuType: ActionMenuType;
}) => {
return (
<>
@ -16,6 +19,7 @@ export const MultipleRecordsActionMenuEntriesSetter = ({
key={index}
position={index}
objectMetadataItem={objectMetadataItem}
actionMenuType={actionMenuType}
/>
))}
</>

View File

@ -1,17 +1,22 @@
import { MultipleRecordsActionMenuEntriesSetter } from '@/action-menu/actions/record-actions/components/MultipleRecordsActionMenuEntriesSetter';
import { SingleRecordActionMenuEntriesSetter } from '@/action-menu/actions/record-actions/components/SingleRecordActionMenuEntriesSetter';
import { contextStoreCurrentObjectMetadataIdState } from '@/context-store/states/contextStoreCurrentObjectMetadataIdState';
import { contextStoreNumberOfSelectedRecordsState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsState';
import { ActionMenuType } from '@/action-menu/types/ActionMenuType';
import { contextStoreCurrentObjectMetadataIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataIdComponentState';
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMetadataItemById';
import { useRecoilValue } from 'recoil';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
export const RecordActionMenuEntriesSetter = () => {
const contextStoreNumberOfSelectedRecords = useRecoilValue(
contextStoreNumberOfSelectedRecordsState,
export const RecordActionMenuEntriesSetter = ({
actionMenuType,
}: {
actionMenuType: ActionMenuType;
}) => {
const contextStoreNumberOfSelectedRecords = useRecoilComponentValueV2(
contextStoreNumberOfSelectedRecordsComponentState,
);
const contextStoreCurrentObjectMetadataId = useRecoilValue(
contextStoreCurrentObjectMetadataIdState,
const contextStoreCurrentObjectMetadataId = useRecoilComponentValueV2(
contextStoreCurrentObjectMetadataIdComponentState,
);
const { objectMetadataItem } = useObjectMetadataItemById({
@ -32,6 +37,7 @@ export const RecordActionMenuEntriesSetter = () => {
return (
<SingleRecordActionMenuEntriesSetter
objectMetadataItem={objectMetadataItem}
actionMenuType={actionMenuType}
/>
);
}
@ -39,6 +45,7 @@ export const RecordActionMenuEntriesSetter = () => {
return (
<MultipleRecordsActionMenuEntriesSetter
objectMetadataItem={objectMetadataItem}
actionMenuType={actionMenuType}
/>
);
};

View File

@ -1,12 +1,15 @@
import { DeleteRecordsActionEffect } from '@/action-menu/actions/record-actions/components/DeleteRecordsActionEffect';
import { ExportRecordsActionEffect } from '@/action-menu/actions/record-actions/components/ExportRecordsActionEffect';
import { ManageFavoritesActionEffect } from '@/action-menu/actions/record-actions/components/ManageFavoritesActionEffect';
import { ActionMenuType } from '@/action-menu/types/ActionMenuType';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
export const SingleRecordActionMenuEntriesSetter = ({
objectMetadataItem,
actionMenuType,
}: {
objectMetadataItem: ObjectMetadataItem;
actionMenuType: ActionMenuType;
}) => {
const actionEffects = [
ManageFavoritesActionEffect,
@ -20,6 +23,7 @@ export const SingleRecordActionMenuEntriesSetter = ({
key={index}
position={index}
objectMetadataItem={objectMetadataItem}
actionMenuType={actionMenuType}
/>
))}
</>