Refactor command menu items deprecated code (#19508)
- Removes the intermediate `CommandMenuItemConfig` / `CommandConfigContext` / `CommandMenuItemDisplay` abstraction layers, replacing them with a single `CommandMenuItemRenderer` that renders directly from the command menu items from the backend - Eliminates the server-items/ subdirectory by moving its contents (hooks/, contexts/, states/, display/, edit/) up into the parent command-menu-item/ module, removing an unnecessary nesting level.
This commit is contained in:
+3
-3
@@ -1,8 +1,8 @@
|
||||
import { PinnedCommandMenuItemButtons } from '@/command-menu-item/server-items/display/components/PinnedCommandMenuItemButtons';
|
||||
import { PinnedCommandMenuItemButtons } from '@/command-menu-item/display/components/PinnedCommandMenuItemButtons';
|
||||
import { RecordIndexCommandMenuDropdown } from '@/command-menu-item/components/RecordIndexCommandMenuDropdown';
|
||||
import { CommandMenuContextProvider } from '@/command-menu-item/contexts/CommandMenuContextProvider';
|
||||
import { CommandMenuItemEditButton } from '@/command-menu-item/server-items/edit/components/CommandMenuItemEditButton';
|
||||
import { PinnedCommandMenuItemButtonsEditMode } from '@/command-menu-item/server-items/edit/components/PinnedCommandMenuItemButtonsEditMode';
|
||||
import { CommandMenuItemEditButton } from '@/command-menu-item/edit/components/CommandMenuItemEditButton';
|
||||
import { PinnedCommandMenuItemButtonsEditMode } from '@/command-menu-item/edit/components/PinnedCommandMenuItemButtonsEditMode';
|
||||
import { MAIN_CONTEXT_STORE_INSTANCE_ID } from '@/context-store/constants/MainContextStoreInstanceId';
|
||||
import { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemIdComponentState';
|
||||
import { isLayoutCustomizationModeEnabledState } from '@/layout-customization/states/isLayoutCustomizationModeEnabledState';
|
||||
|
||||
+10
-11
@@ -1,11 +1,9 @@
|
||||
import { CommandMenuItemComponent } from '@/command-menu-item/display/components/CommandMenuItemComponent';
|
||||
import { CommandMenuItemScope } from '@/command-menu-item/types/CommandMenuItemScope';
|
||||
import { CommandMenuItemType } from '@/command-menu-item/types/CommandMenuItemType';
|
||||
import { COMMAND_MENU_DROPDOWN_CLICK_OUTSIDE_ID } from '@/command-menu-item/constants/CommandMenuDropdownClickOutsideId';
|
||||
import { CommandMenuContext } from '@/command-menu-item/contexts/CommandMenuContext';
|
||||
import { CommandMenuComponentInstanceContext } from '@/command-menu/states/contexts/CommandMenuComponentInstanceContext';
|
||||
import { CommandMenuItemRenderer } from '@/command-menu-item/display/components/CommandMenuItemRenderer';
|
||||
import { recordIndexCommandMenuDropdownPositionComponentState } from '@/command-menu-item/states/recordIndexCommandMenuDropdownPositionComponentState';
|
||||
import { getCommandMenuDropdownIdFromCommandMenuId } from '@/command-menu-item/utils/getCommandMenuDropdownIdFromCommandMenuId';
|
||||
import { CommandMenuComponentInstanceContext } from '@/command-menu/states/contexts/CommandMenuComponentInstanceContext';
|
||||
import { useSidePanelMenu } from '@/side-panel/hooks/useSidePanelMenu';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||
@@ -21,6 +19,7 @@ import { useLingui } from '@lingui/react/macro';
|
||||
import { useContext } from 'react';
|
||||
import { IconLayoutSidebarRightExpand } from 'twenty-ui/display';
|
||||
import { MenuItem } from 'twenty-ui/navigation';
|
||||
import { CommandMenuItemAvailabilityType } from '~/generated-metadata/graphql';
|
||||
|
||||
const StyledDropdownMenuContainer = styled.div`
|
||||
align-items: center;
|
||||
@@ -36,10 +35,10 @@ export const RecordIndexCommandMenuDropdown = () => {
|
||||
const { t } = useLingui();
|
||||
const { commandMenuItems } = useContext(CommandMenuContext);
|
||||
|
||||
const recordIndexActions = commandMenuItems.filter(
|
||||
(action) =>
|
||||
action.type === CommandMenuItemType.Standard &&
|
||||
action.scope === CommandMenuItemScope.RecordSelection,
|
||||
const recordIndexCommandMenuItems = commandMenuItems.filter(
|
||||
(item) =>
|
||||
item.availabilityType ===
|
||||
CommandMenuItemAvailabilityType.RECORD_SELECTION,
|
||||
);
|
||||
|
||||
const commandMenuId = useAvailableComponentInstanceIdOrThrow(
|
||||
@@ -57,7 +56,7 @@ export const RecordIndexCommandMenuDropdown = () => {
|
||||
const { openSidePanelMenu } = useSidePanelMenu();
|
||||
|
||||
const selectedItemIdArray = [
|
||||
...recordIndexActions.map((action) => action.key),
|
||||
...recordIndexCommandMenuItems.map((item) => item.id),
|
||||
'more-actions',
|
||||
];
|
||||
|
||||
@@ -87,8 +86,8 @@ export const RecordIndexCommandMenuDropdown = () => {
|
||||
selectableItemIdArray={selectedItemIdArray}
|
||||
selectableListInstanceId={dropdownId}
|
||||
>
|
||||
{recordIndexActions.map((action) => (
|
||||
<CommandMenuItemComponent action={action} key={action.key} />
|
||||
{recordIndexCommandMenuItems.map((item) => (
|
||||
<CommandMenuItemRenderer item={item} key={item.id} />
|
||||
))}
|
||||
<SelectableListItem
|
||||
itemId="more-actions"
|
||||
|
||||
+34
-23
@@ -1,16 +1,16 @@
|
||||
import { CommandMenuItemComponent } from '@/command-menu-item/display/components/CommandMenuItemComponent';
|
||||
import { CommandMenuItemScope } from '@/command-menu-item/types/CommandMenuItemScope';
|
||||
import { CommandMenuContext } from '@/command-menu-item/contexts/CommandMenuContext';
|
||||
import { CommandMenuComponentInstanceContext } from '@/command-menu/states/contexts/CommandMenuComponentInstanceContext';
|
||||
import { CommandMenuItemRenderer } from '@/command-menu-item/display/components/CommandMenuItemRenderer';
|
||||
import { getSidePanelCommandMenuDropdownIdFromCommandMenuId } from '@/command-menu-item/utils/getSidePanelCommandMenuDropdownIdFromCommandMenuId';
|
||||
import { CommandMenuComponentInstanceContext } from '@/command-menu/states/contexts/CommandMenuComponentInstanceContext';
|
||||
import { OptionsDropdownMenu } from '@/ui/layout/dropdown/components/OptionsDropdownMenu';
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { sidePanelWidgetFooterActionsState } from '@/ui/layout/side-panel/states/sidePanelWidgetFooterActionsState';
|
||||
import { sidePanelWidgetFooterCommandMenuItemsState } from '@/ui/layout/side-panel/states/sidePanelWidgetFooterCommandMenuItemsState';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { useContext } from 'react';
|
||||
import { useContext, useMemo } from 'react';
|
||||
import { HorizontalSeparator } from 'twenty-ui/display';
|
||||
import { MenuItem } from 'twenty-ui/navigation';
|
||||
import { CommandMenuItemAvailabilityType } from '~/generated-metadata/graphql';
|
||||
|
||||
export const RecordPageSidePanelCommandMenuDropdown = () => {
|
||||
const { commandMenuItems } = useContext(CommandMenuContext);
|
||||
@@ -24,21 +24,30 @@ export const RecordPageSidePanelCommandMenuDropdown = () => {
|
||||
|
||||
const { closeDropdown } = useCloseDropdown();
|
||||
|
||||
const sidePanelWidgetFooterActions = useAtomStateValue(
|
||||
sidePanelWidgetFooterActionsState,
|
||||
const sidePanelWidgetFooterCommandMenuItems = useAtomStateValue(
|
||||
sidePanelWidgetFooterCommandMenuItemsState,
|
||||
);
|
||||
|
||||
const dropdownWidgetActions = sidePanelWidgetFooterActions.filter(
|
||||
(action) => action.isPinned === false,
|
||||
);
|
||||
const dropdownWidgetCommandMenuItems =
|
||||
sidePanelWidgetFooterCommandMenuItems.filter(
|
||||
(commandMenuItem) => commandMenuItem.isPinned === false,
|
||||
);
|
||||
|
||||
const recordSelectionActions = commandMenuItems.filter(
|
||||
(action) => action.scope === CommandMenuItemScope.RecordSelection,
|
||||
const recordSelectionCommandMenuItems = useMemo(
|
||||
() =>
|
||||
commandMenuItems.filter(
|
||||
(item) =>
|
||||
item.availabilityType ===
|
||||
CommandMenuItemAvailabilityType.RECORD_SELECTION,
|
||||
),
|
||||
[commandMenuItems],
|
||||
);
|
||||
|
||||
const selectableItemIdArray = [
|
||||
...dropdownWidgetActions.map((action) => action.key),
|
||||
...recordSelectionActions.map((action) => action.key),
|
||||
...dropdownWidgetCommandMenuItems.map(
|
||||
(commandMenuItem) => commandMenuItem.id,
|
||||
),
|
||||
...recordSelectionCommandMenuItems.map((item) => item.id),
|
||||
];
|
||||
|
||||
return (
|
||||
@@ -47,21 +56,23 @@ export const RecordPageSidePanelCommandMenuDropdown = () => {
|
||||
selectableListId={commandMenuId}
|
||||
selectableItemIdArray={selectableItemIdArray}
|
||||
>
|
||||
{dropdownWidgetActions.map((action) => (
|
||||
{dropdownWidgetCommandMenuItems.map((commandMenuItem) => (
|
||||
<MenuItem
|
||||
key={action.key}
|
||||
text={action.label}
|
||||
LeftIcon={action.Icon}
|
||||
key={commandMenuItem.id}
|
||||
text={commandMenuItem.label}
|
||||
LeftIcon={commandMenuItem.Icon}
|
||||
onClick={() => {
|
||||
closeDropdown(dropdownId);
|
||||
action.onClick();
|
||||
commandMenuItem.onClick();
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
{dropdownWidgetActions.length > 0 &&
|
||||
recordSelectionActions.length > 0 && <HorizontalSeparator noMargin />}
|
||||
{recordSelectionActions.map((action) => (
|
||||
<CommandMenuItemComponent action={action} key={action.key} />
|
||||
{dropdownWidgetCommandMenuItems.length > 0 &&
|
||||
recordSelectionCommandMenuItems.length > 0 && (
|
||||
<HorizontalSeparator noMargin />
|
||||
)}
|
||||
{recordSelectionCommandMenuItems.map((item) => (
|
||||
<CommandMenuItemRenderer item={item} key={item.id} />
|
||||
))}
|
||||
</OptionsDropdownMenu>
|
||||
);
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
import { CommandMenuContextProvider } from '@/command-menu-item/contexts/CommandMenuContextProvider';
|
||||
import { PinnedCommandMenuItemButtons } from '@/command-menu-item/server-items/display/components/PinnedCommandMenuItemButtons';
|
||||
import { CommandMenuItemEditButton } from '@/command-menu-item/server-items/edit/components/CommandMenuItemEditButton';
|
||||
import { PinnedCommandMenuItemButtons } from '@/command-menu-item/display/components/PinnedCommandMenuItemButtons';
|
||||
import { CommandMenuItemEditButton } from '@/command-menu-item/edit/components/CommandMenuItemEditButton';
|
||||
import { MAIN_CONTEXT_STORE_INSTANCE_ID } from '@/context-store/constants/MainContextStoreInstanceId';
|
||||
import { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemIdComponentState';
|
||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||
|
||||
+13
-25
@@ -1,22 +1,20 @@
|
||||
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
||||
import { Provider as JotaiProvider } from 'jotai';
|
||||
import * as test from 'storybook/test';
|
||||
import { expect, userEvent, waitFor, within } from 'storybook/test';
|
||||
import { expect, within } from 'storybook/test';
|
||||
|
||||
import { RecordIndexCommandMenuDropdown } from '@/command-menu-item/components/RecordIndexCommandMenuDropdown';
|
||||
import { CommandMenuContext } from '@/command-menu-item/contexts/CommandMenuContext';
|
||||
import { createMockCommandMenuItems } from '@/command-menu-item/mock/command-menu-items.mock';
|
||||
import { CommandMenuComponentInstanceContext } from '@/command-menu/states/contexts/CommandMenuComponentInstanceContext';
|
||||
import { recordIndexCommandMenuDropdownPositionComponentState } from '@/command-menu-item/states/recordIndexCommandMenuDropdownPositionComponentState';
|
||||
import { CommandMenuComponentInstanceContext } from '@/command-menu/states/contexts/CommandMenuComponentInstanceContext';
|
||||
|
||||
import { EMPTY_COMMAND_MENU_CONTEXT_API } from '@/command-menu-item/constants/EmptyCommandMenuContextApi';
|
||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { RouterDecorator } from 'twenty-ui/testing';
|
||||
import { ContextStoreDecorator } from '~/testing/decorators/ContextStoreDecorator';
|
||||
|
||||
const deleteMock = test.fn();
|
||||
const addToFavoritesMock = test.fn();
|
||||
const exportMock = test.fn();
|
||||
import { ObjectMetadataItemsDecorator } from '~/testing/decorators/ObjectMetadataItemsDecorator';
|
||||
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
|
||||
|
||||
const meta: Meta<typeof RecordIndexCommandMenuDropdown> = {
|
||||
title: 'Modules/CommandMenu/RecordIndexCommandMenuDropdown',
|
||||
@@ -43,14 +41,10 @@ const meta: Meta<typeof RecordIndexCommandMenuDropdown> = {
|
||||
>
|
||||
<CommandMenuContext.Provider
|
||||
value={{
|
||||
isInSidePanel: true,
|
||||
displayType: 'dropdownItem',
|
||||
containerType: 'index-page-dropdown',
|
||||
commandMenuItems: createMockCommandMenuItems({
|
||||
deleteMock,
|
||||
addToFavoritesMock,
|
||||
exportMock,
|
||||
}),
|
||||
commandMenuItems: createMockCommandMenuItems(),
|
||||
commandMenuContextApi: EMPTY_COMMAND_MENU_CONTEXT_API,
|
||||
}}
|
||||
>
|
||||
<Story />
|
||||
@@ -60,6 +54,8 @@ const meta: Meta<typeof RecordIndexCommandMenuDropdown> = {
|
||||
);
|
||||
},
|
||||
ContextStoreDecorator,
|
||||
ObjectMetadataItemsDecorator,
|
||||
SnackBarDecorator,
|
||||
RouterDecorator,
|
||||
],
|
||||
};
|
||||
@@ -82,21 +78,13 @@ export const WithInteractions: Story = {
|
||||
const canvas = within(canvasElement.ownerDocument.body);
|
||||
|
||||
const deleteButton = await canvas.findByText('Delete');
|
||||
await userEvent.click(deleteButton);
|
||||
|
||||
const addToFavoritesButton = await canvas.findByText('Add to favorites');
|
||||
await userEvent.click(addToFavoritesButton);
|
||||
|
||||
const exportButton = await canvas.findByText('Export');
|
||||
await userEvent.click(exportButton);
|
||||
|
||||
const moreActionsButton = await canvas.findByText('More actions');
|
||||
|
||||
await waitFor(() => {
|
||||
expect(deleteMock).toHaveBeenCalled();
|
||||
expect(addToFavoritesMock).toHaveBeenCalled();
|
||||
expect(exportMock).toHaveBeenCalled();
|
||||
expect(moreActionsButton).toBeInTheDocument();
|
||||
});
|
||||
expect(deleteButton).toBeInTheDocument();
|
||||
expect(addToFavoritesButton).toBeInTheDocument();
|
||||
expect(exportButton).toBeInTheDocument();
|
||||
expect(moreActionsButton).toBeInTheDocument();
|
||||
},
|
||||
};
|
||||
|
||||
+8
-18
@@ -1,7 +1,6 @@
|
||||
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
||||
import { Provider as JotaiProvider } from 'jotai';
|
||||
import * as test from 'storybook/test';
|
||||
import { expect, userEvent, waitFor, within } from 'storybook/test';
|
||||
import { userEvent, within } from 'storybook/test';
|
||||
|
||||
import { RecordPageSidePanelCommandMenuDropdown } from '@/command-menu-item/components/RecordPageSidePanelCommandMenuDropdown';
|
||||
import { CommandMenuContext } from '@/command-menu-item/contexts/CommandMenuContext';
|
||||
@@ -9,15 +8,13 @@ import { createMockCommandMenuItems } from '@/command-menu-item/mock/command-men
|
||||
import { CommandMenuComponentInstanceContext } from '@/command-menu/states/contexts/CommandMenuComponentInstanceContext';
|
||||
import { MAIN_CONTEXT_STORE_INSTANCE_ID } from '@/context-store/constants/MainContextStoreInstanceId';
|
||||
import { ContextStoreComponentInstanceContext } from '@/context-store/states/contexts/ContextStoreComponentInstanceContext';
|
||||
import { ComponentDecorator, RouterDecorator } from 'twenty-ui/testing';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { EMPTY_COMMAND_MENU_CONTEXT_API } from '@/command-menu-item/constants/EmptyCommandMenuContextApi';
|
||||
import { ComponentDecorator, RouterDecorator } from 'twenty-ui/testing';
|
||||
import { ContextStoreDecorator } from '~/testing/decorators/ContextStoreDecorator';
|
||||
import { ObjectMetadataItemsDecorator } from '~/testing/decorators/ObjectMetadataItemsDecorator';
|
||||
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
|
||||
import { JestContextStoreSetter } from '~/testing/jest/JestContextStoreSetter';
|
||||
const deleteMock = test.fn();
|
||||
const addToFavoritesMock = test.fn();
|
||||
const exportMock = test.fn();
|
||||
|
||||
const meta: Meta<typeof RecordPageSidePanelCommandMenuDropdown> = {
|
||||
title: 'Modules/CommandMenu/RecordPageSidePanelCommandMenuDropdown',
|
||||
@@ -40,14 +37,13 @@ const meta: Meta<typeof RecordPageSidePanelCommandMenuDropdown> = {
|
||||
>
|
||||
<CommandMenuContext.Provider
|
||||
value={{
|
||||
isInSidePanel: true,
|
||||
displayType: 'dropdownItem',
|
||||
containerType: 'command-menu-show-page-dropdown',
|
||||
commandMenuItems: createMockCommandMenuItems({
|
||||
deleteMock,
|
||||
addToFavoritesMock,
|
||||
exportMock,
|
||||
}),
|
||||
commandMenuItems: createMockCommandMenuItems(),
|
||||
commandMenuContextApi: {
|
||||
...EMPTY_COMMAND_MENU_CONTEXT_API,
|
||||
isInSidePanel: true,
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Story />
|
||||
@@ -102,11 +98,5 @@ export const WithButtonClicks: Story = {
|
||||
|
||||
const exportButton = await canvas.findByText('Export');
|
||||
await userEvent.click(exportButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(deleteMock).toHaveBeenCalled();
|
||||
expect(addToFavoritesMock).toHaveBeenCalled();
|
||||
expect(exportMock).toHaveBeenCalled();
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user