Create stories for action display components (#11547)
Create stories for: - ActionButton - ActionComponent - ActionDisplay - ActionDropdownItem - ActionListItem
This commit is contained in:
@ -0,0 +1,66 @@
|
||||
import { NoSelectionRecordActionKeys } from '@/action-menu/actions/record-actions/no-selection/types/NoSelectionRecordActionsKeys';
|
||||
import { SingleRecordActionKeys } from '@/action-menu/actions/record-actions/single-record/types/SingleRecordActionsKey';
|
||||
import { createMockActionMenuActions } from '@/action-menu/mock/action-menu-actions.mock';
|
||||
import { getActionLabel } from '@/action-menu/utils/getActionLabel';
|
||||
import { expect } from '@storybook/jest';
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { fn, userEvent, within } from '@storybook/test';
|
||||
import { ComponentDecorator, RouterDecorator } from 'twenty-ui/testing';
|
||||
import { ActionButton } from '../ActionButton';
|
||||
|
||||
const meta: Meta<typeof ActionButton> = {
|
||||
title: 'Modules/ActionMenu/Actions/Display/ActionButton',
|
||||
component: ActionButton,
|
||||
decorators: [ComponentDecorator, RouterDecorator],
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof ActionButton>;
|
||||
|
||||
const deleteMock = fn();
|
||||
const addToFavoritesMock = fn();
|
||||
|
||||
const mockActions = createMockActionMenuActions({
|
||||
deleteMock,
|
||||
addToFavoritesMock,
|
||||
});
|
||||
|
||||
const addToFavoritesAction = mockActions.find(
|
||||
(action) => action.key === SingleRecordActionKeys.ADD_TO_FAVORITES,
|
||||
);
|
||||
|
||||
const goToPeopleAction = mockActions.find(
|
||||
(action) => action.key === NoSelectionRecordActionKeys.GO_TO_PEOPLE,
|
||||
);
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
action: addToFavoritesAction,
|
||||
onClick: addToFavoritesMock,
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
await userEvent.click(
|
||||
await canvas.findByText(
|
||||
getActionLabel(addToFavoritesAction?.shortLabel ?? ''),
|
||||
),
|
||||
);
|
||||
expect(addToFavoritesMock).toHaveBeenCalled();
|
||||
},
|
||||
};
|
||||
|
||||
export const WithLink: Story = {
|
||||
args: {
|
||||
action: goToPeopleAction,
|
||||
to: '/objects/people',
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
const menuItem = await canvas.findByText(
|
||||
getActionLabel(goToPeopleAction?.shortLabel ?? ''),
|
||||
);
|
||||
expect(menuItem).toBeVisible();
|
||||
expect(canvas.getByRole('link')).toHaveAttribute('href', '/objects/people');
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,67 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { expect, within } from '@storybook/test';
|
||||
|
||||
import { ActionComponent } from '@/action-menu/actions/display/components/ActionComponent';
|
||||
import { SingleRecordActionKeys } from '@/action-menu/actions/record-actions/single-record/types/SingleRecordActionsKey';
|
||||
import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext';
|
||||
import { createMockActionMenuActions } from '@/action-menu/mock/action-menu-actions.mock';
|
||||
import { ActionMenuComponentInstanceContext } from '@/action-menu/states/contexts/ActionMenuComponentInstanceContext';
|
||||
import { getActionLabel } from '@/action-menu/utils/getActionLabel';
|
||||
import { ComponentDecorator } from 'twenty-ui/testing';
|
||||
|
||||
const mockActions = createMockActionMenuActions({});
|
||||
|
||||
const addToFavoritesAction = mockActions.find(
|
||||
(action) => action.key === SingleRecordActionKeys.ADD_TO_FAVORITES,
|
||||
);
|
||||
|
||||
if (!addToFavoritesAction) {
|
||||
throw new Error('Add to favorites action not found');
|
||||
}
|
||||
|
||||
const meta: Meta<typeof ActionComponent> = {
|
||||
title: 'Modules/ActionMenu/Actions/Display/ActionComponent',
|
||||
component: ActionComponent,
|
||||
decorators: [
|
||||
ComponentDecorator,
|
||||
(Story) => (
|
||||
<ActionMenuComponentInstanceContext.Provider
|
||||
value={{ instanceId: 'story' }}
|
||||
>
|
||||
<ActionMenuContext.Provider
|
||||
value={{
|
||||
isInRightDrawer: false,
|
||||
actionMenuType: 'index-page-action-menu',
|
||||
displayType: 'button',
|
||||
actions: [addToFavoritesAction],
|
||||
}}
|
||||
>
|
||||
<Story />
|
||||
</ActionMenuContext.Provider>
|
||||
</ActionMenuComponentInstanceContext.Provider>
|
||||
),
|
||||
],
|
||||
args: {
|
||||
action: addToFavoritesAction,
|
||||
},
|
||||
parameters: {
|
||||
container: {
|
||||
width: 'auto',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof ActionComponent>;
|
||||
|
||||
export const Default: Story = {
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
expect(
|
||||
await canvas.findByText(
|
||||
getActionLabel(addToFavoritesAction?.shortLabel ?? ''),
|
||||
),
|
||||
).toBeVisible();
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,139 @@
|
||||
import { SingleRecordActionKeys } from '@/action-menu/actions/record-actions/single-record/types/SingleRecordActionsKey';
|
||||
import { ActionConfigContext } from '@/action-menu/contexts/ActionConfigContext';
|
||||
import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext';
|
||||
import { createMockActionMenuActions } from '@/action-menu/mock/action-menu-actions.mock';
|
||||
import { getActionLabel } from '@/action-menu/utils/getActionLabel';
|
||||
import { SelectableListComponentInstanceContext } from '@/ui/layout/selectable-list/states/contexts/SelectableListComponentInstanceContext';
|
||||
import { expect } from '@storybook/jest';
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { fn, userEvent, within } from '@storybook/test';
|
||||
import { ComponentDecorator, RouterDecorator } from 'twenty-ui/testing';
|
||||
import { ActionDisplay } from '../ActionDisplay';
|
||||
|
||||
type Story = StoryObj<typeof ActionDisplay>;
|
||||
|
||||
const deleteMock = fn();
|
||||
const addToFavoritesMock = fn();
|
||||
|
||||
const mockActions = createMockActionMenuActions({
|
||||
deleteMock,
|
||||
addToFavoritesMock,
|
||||
});
|
||||
|
||||
const addToFavoritesAction = mockActions.find(
|
||||
(action) => action.key === SingleRecordActionKeys.ADD_TO_FAVORITES,
|
||||
);
|
||||
|
||||
if (!addToFavoritesAction) {
|
||||
throw new Error('addToFavoritesAction not found');
|
||||
}
|
||||
|
||||
const meta: Meta<typeof ActionDisplay> = {
|
||||
title: 'Modules/ActionMenu/Actions/Display/ActionDisplay',
|
||||
component: ActionDisplay,
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<ActionConfigContext.Provider value={addToFavoritesAction}>
|
||||
<Story />
|
||||
</ActionConfigContext.Provider>
|
||||
),
|
||||
ComponentDecorator,
|
||||
RouterDecorator,
|
||||
],
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
export const AsButton: Story = {
|
||||
args: {
|
||||
onClick: addToFavoritesMock,
|
||||
},
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<ActionMenuContext.Provider
|
||||
value={{
|
||||
isInRightDrawer: false,
|
||||
actionMenuType: 'command-menu',
|
||||
displayType: 'button',
|
||||
actions: [],
|
||||
}}
|
||||
>
|
||||
<Story />
|
||||
</ActionMenuContext.Provider>
|
||||
),
|
||||
],
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
await userEvent.click(
|
||||
await canvas.findByText(
|
||||
getActionLabel(addToFavoritesAction?.shortLabel ?? ''),
|
||||
),
|
||||
);
|
||||
expect(addToFavoritesMock).toHaveBeenCalled();
|
||||
},
|
||||
};
|
||||
|
||||
export const AsListItem: Story = {
|
||||
args: {
|
||||
onClick: addToFavoritesMock,
|
||||
},
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<SelectableListComponentInstanceContext.Provider
|
||||
value={{ instanceId: 'story' }}
|
||||
>
|
||||
<Story />
|
||||
</SelectableListComponentInstanceContext.Provider>
|
||||
),
|
||||
(Story) => (
|
||||
<ActionMenuContext.Provider
|
||||
value={{
|
||||
isInRightDrawer: false,
|
||||
actionMenuType: 'command-menu',
|
||||
displayType: 'listItem',
|
||||
actions: [],
|
||||
}}
|
||||
>
|
||||
<Story />
|
||||
</ActionMenuContext.Provider>
|
||||
),
|
||||
],
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
await userEvent.click(
|
||||
await canvas.findByText(
|
||||
getActionLabel(addToFavoritesAction?.label ?? ''),
|
||||
),
|
||||
);
|
||||
expect(addToFavoritesMock).toHaveBeenCalled();
|
||||
},
|
||||
};
|
||||
|
||||
export const AsDropdownItem: Story = {
|
||||
args: {
|
||||
onClick: addToFavoritesMock,
|
||||
},
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<ActionMenuContext.Provider
|
||||
value={{
|
||||
isInRightDrawer: false,
|
||||
actionMenuType: 'command-menu',
|
||||
displayType: 'dropdownItem',
|
||||
actions: [],
|
||||
}}
|
||||
>
|
||||
<Story />
|
||||
</ActionMenuContext.Provider>
|
||||
),
|
||||
],
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
await userEvent.click(
|
||||
await canvas.findByText(
|
||||
getActionLabel(addToFavoritesAction?.label ?? ''),
|
||||
),
|
||||
);
|
||||
expect(addToFavoritesMock).toHaveBeenCalled();
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,65 @@
|
||||
import { NoSelectionRecordActionKeys } from '@/action-menu/actions/record-actions/no-selection/types/NoSelectionRecordActionsKeys';
|
||||
import { SingleRecordActionKeys } from '@/action-menu/actions/record-actions/single-record/types/SingleRecordActionsKey';
|
||||
import { createMockActionMenuActions } from '@/action-menu/mock/action-menu-actions.mock';
|
||||
import { getActionLabel } from '@/action-menu/utils/getActionLabel';
|
||||
import { expect } from '@storybook/jest';
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { fn, userEvent, within } from '@storybook/test';
|
||||
import { ComponentDecorator, RouterDecorator } from 'twenty-ui/testing';
|
||||
import { ActionDropdownItem } from '../ActionDropdownItem';
|
||||
|
||||
const meta: Meta<typeof ActionDropdownItem> = {
|
||||
title: 'Modules/ActionMenu/Actions/Display/ActionDropdownItem',
|
||||
component: ActionDropdownItem,
|
||||
decorators: [ComponentDecorator, RouterDecorator],
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof ActionDropdownItem>;
|
||||
|
||||
const deleteMock = fn();
|
||||
const addToFavoritesMock = fn();
|
||||
|
||||
const mockActions = createMockActionMenuActions({
|
||||
deleteMock,
|
||||
addToFavoritesMock,
|
||||
});
|
||||
|
||||
const addToFavoritesAction = mockActions.find(
|
||||
(action) => action.key === SingleRecordActionKeys.ADD_TO_FAVORITES,
|
||||
);
|
||||
|
||||
const goToPeopleAction = mockActions.find(
|
||||
(action) => action.key === NoSelectionRecordActionKeys.GO_TO_PEOPLE,
|
||||
);
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
action: addToFavoritesAction,
|
||||
onClick: addToFavoritesMock,
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
await userEvent.click(
|
||||
await canvas.findByText(
|
||||
getActionLabel(addToFavoritesAction?.label ?? ''),
|
||||
),
|
||||
);
|
||||
expect(addToFavoritesMock).toHaveBeenCalled();
|
||||
},
|
||||
};
|
||||
|
||||
export const WithLink: Story = {
|
||||
args: {
|
||||
action: goToPeopleAction,
|
||||
to: '/objects/people',
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
const dropdownItem = await canvas.findByText(
|
||||
getActionLabel(goToPeopleAction?.label ?? ''),
|
||||
);
|
||||
expect(dropdownItem).toBeVisible();
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,76 @@
|
||||
import { NoSelectionRecordActionKeys } from '@/action-menu/actions/record-actions/no-selection/types/NoSelectionRecordActionsKeys';
|
||||
import { SingleRecordActionKeys } from '@/action-menu/actions/record-actions/single-record/types/SingleRecordActionsKey';
|
||||
import { createMockActionMenuActions } from '@/action-menu/mock/action-menu-actions.mock';
|
||||
import { getActionLabel } from '@/action-menu/utils/getActionLabel';
|
||||
import { SelectableListComponentInstanceContext } from '@/ui/layout/selectable-list/states/contexts/SelectableListComponentInstanceContext';
|
||||
import { expect } from '@storybook/jest';
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { fn, userEvent, within } from '@storybook/test';
|
||||
import { ComponentDecorator, RouterDecorator } from 'twenty-ui/testing';
|
||||
import { ActionListItem } from '../ActionListItem';
|
||||
|
||||
type Story = StoryObj<typeof ActionListItem>;
|
||||
|
||||
const deleteMock = fn();
|
||||
const addToFavoritesMock = fn();
|
||||
|
||||
const mockActions = createMockActionMenuActions({
|
||||
deleteMock,
|
||||
addToFavoritesMock,
|
||||
});
|
||||
|
||||
const addToFavoritesAction = mockActions.find(
|
||||
(action) => action.key === SingleRecordActionKeys.ADD_TO_FAVORITES,
|
||||
);
|
||||
|
||||
const goToPeopleAction = mockActions.find(
|
||||
(action) => action.key === NoSelectionRecordActionKeys.GO_TO_PEOPLE,
|
||||
);
|
||||
|
||||
const meta: Meta<typeof ActionListItem> = {
|
||||
title: 'Modules/ActionMenu/Actions/Display/ActionListItem',
|
||||
component: ActionListItem,
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<SelectableListComponentInstanceContext.Provider
|
||||
value={{ instanceId: 'story' }}
|
||||
>
|
||||
<Story />
|
||||
</SelectableListComponentInstanceContext.Provider>
|
||||
),
|
||||
ComponentDecorator,
|
||||
RouterDecorator,
|
||||
],
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
action: addToFavoritesAction,
|
||||
onClick: addToFavoritesMock,
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
await userEvent.click(
|
||||
await canvas.findByText(
|
||||
getActionLabel(addToFavoritesAction?.label ?? ''),
|
||||
),
|
||||
);
|
||||
expect(addToFavoritesMock).toHaveBeenCalled();
|
||||
},
|
||||
};
|
||||
|
||||
export const WithLink: Story = {
|
||||
args: {
|
||||
action: goToPeopleAction,
|
||||
to: '/objects/people',
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
const listItem = await canvas.findByText(
|
||||
getActionLabel(goToPeopleAction?.label ?? ''),
|
||||
);
|
||||
expect(listItem).toBeVisible();
|
||||
},
|
||||
};
|
||||
@ -1,20 +1,30 @@
|
||||
import { Action } from '@/action-menu/actions/components/Action';
|
||||
import { ActionLink } from '@/action-menu/actions/components/ActionLink';
|
||||
import { NoSelectionRecordActionKeys } from '@/action-menu/actions/record-actions/no-selection/types/NoSelectionRecordActionsKeys';
|
||||
import { SingleRecordActionKeys } from '@/action-menu/actions/record-actions/single-record/types/SingleRecordActionsKey';
|
||||
import { ActionConfig } from '@/action-menu/actions/types/ActionConfig';
|
||||
import { ActionScope } from '@/action-menu/actions/types/ActionScope';
|
||||
import { ActionType } from '@/action-menu/actions/types/ActionType';
|
||||
import { ActionViewType } from '@/action-menu/actions/types/ActionViewType';
|
||||
import { CoreObjectNamePlural } from '@/object-metadata/types/CoreObjectNamePlural';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { AppPath } from '@/types/AppPath';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { IconFileExport, IconHeart, IconTrash } from 'twenty-ui/display';
|
||||
import {
|
||||
IconFileExport,
|
||||
IconHeart,
|
||||
IconTrash,
|
||||
IconUser,
|
||||
} from 'twenty-ui/display';
|
||||
|
||||
export const createMockActionMenuActions = ({
|
||||
deleteMock,
|
||||
addToFavoritesMock,
|
||||
exportMock,
|
||||
deleteMock = () => {},
|
||||
addToFavoritesMock = () => {},
|
||||
exportMock = () => {},
|
||||
}: {
|
||||
deleteMock: () => void;
|
||||
addToFavoritesMock: () => void;
|
||||
exportMock: () => void;
|
||||
deleteMock?: () => void;
|
||||
addToFavoritesMock?: () => void;
|
||||
exportMock?: () => void;
|
||||
}): ActionConfig[] => [
|
||||
{
|
||||
type: ActionType.Standard,
|
||||
@ -66,4 +76,30 @@ export const createMockActionMenuActions = ({
|
||||
],
|
||||
component: <Action onClick={deleteMock} />,
|
||||
},
|
||||
{
|
||||
type: ActionType.Navigation,
|
||||
scope: ActionScope.Global,
|
||||
key: NoSelectionRecordActionKeys.GO_TO_PEOPLE,
|
||||
label: msg`Go to People`,
|
||||
shortLabel: msg`People`,
|
||||
position: 19,
|
||||
Icon: IconUser,
|
||||
isPinned: false,
|
||||
availableOn: [
|
||||
ActionViewType.INDEX_PAGE_NO_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
|
||||
ActionViewType.INDEX_PAGE_BULK_SELECTION,
|
||||
ActionViewType.SHOW_PAGE,
|
||||
],
|
||||
shouldBeRegistered: ({ objectMetadataItem, viewType }) =>
|
||||
objectMetadataItem?.nameSingular !== CoreObjectNameSingular.Person ||
|
||||
viewType === ActionViewType.SHOW_PAGE,
|
||||
component: (
|
||||
<ActionLink
|
||||
to={AppPath.RecordIndexPage}
|
||||
params={{ objectNamePlural: CoreObjectNamePlural.Person }}
|
||||
/>
|
||||
),
|
||||
hotKeys: ['G', 'P'],
|
||||
},
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user