Disable the fields of all CRUD workflow actions on readonly mode (#9939)
Fixes https://discord.com/channels/1130383047699738754/1333822806504247467 In this PR: - Make the workflow step title input readonly when the visualizer is in readonly mode - Make all the fields of the Update Record and Delete Record readonly when the visualizer is in readonly mode - Create stories for the Create Record, Updated Record and Delete Record actions; I'm checking for the default mode and several variants of the disabled mode - Set up mocks for the workflows and use them in msw handlers Follow up: - We use `readonly` and `disabled` alternatively; these are two different states when talking about a HTML `<input />` element. I think we should settle on a single word. - Refactor the `<WorkflowSingleRecordPicker />` component to behave as other selects | Current component | Should look like | |--------|--------| |  |  |
This commit is contained in:
committed by
GitHub
parent
4e32fd1c98
commit
d946cdcba4
+8
-7
@@ -49,12 +49,14 @@ export const WorkflowStepHeader = ({
|
||||
iconColor,
|
||||
initialTitle,
|
||||
headerType,
|
||||
disabled,
|
||||
}: {
|
||||
onTitleChange: (newTitle: string) => void;
|
||||
Icon: IconComponent;
|
||||
iconColor: string;
|
||||
initialTitle: string;
|
||||
headerType: string;
|
||||
disabled?: boolean;
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const [title, setTitle] = useState(initialTitle);
|
||||
@@ -67,17 +69,16 @@ export const WorkflowStepHeader = ({
|
||||
return (
|
||||
<StyledHeader>
|
||||
<StyledHeaderIconContainer>
|
||||
{
|
||||
<Icon
|
||||
color={iconColor}
|
||||
stroke={theme.icon.stroke.sm}
|
||||
size={theme.icon.size.lg}
|
||||
/>
|
||||
}
|
||||
<Icon
|
||||
color={iconColor}
|
||||
stroke={theme.icon.stroke.sm}
|
||||
size={theme.icon.size.lg}
|
||||
/>
|
||||
</StyledHeaderIconContainer>
|
||||
<StyledHeaderInfo>
|
||||
<StyledHeaderTitle>
|
||||
<TextInput
|
||||
disabled={disabled}
|
||||
value={title}
|
||||
copyButton={false}
|
||||
hotkeyScope="workflow-step-title"
|
||||
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { expect, fn, userEvent, waitFor, within } from '@storybook/test';
|
||||
import { ComponentDecorator, IconPlus, THEME_LIGHT } from 'twenty-ui';
|
||||
import { WorkflowStepHeader } from '../WorkflowStepHeader';
|
||||
|
||||
const meta: Meta<typeof WorkflowStepHeader> = {
|
||||
title: 'Modules/Workflow/WorkflowStepHeader',
|
||||
component: WorkflowStepHeader,
|
||||
args: {
|
||||
onTitleChange: fn(),
|
||||
},
|
||||
argTypes: {},
|
||||
decorators: [ComponentDecorator],
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof WorkflowStepHeader>;
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
headerType: 'Action',
|
||||
iconColor: THEME_LIGHT.font.color.tertiary,
|
||||
initialTitle: 'Create Record',
|
||||
Icon: IconPlus,
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
expect(await canvas.findByDisplayValue('Create Record')).toBeVisible();
|
||||
expect(await canvas.findByText('Action')).toBeVisible();
|
||||
},
|
||||
};
|
||||
|
||||
export const EditableTitle: Story = {
|
||||
args: {
|
||||
headerType: 'Action',
|
||||
iconColor: THEME_LIGHT.font.color.tertiary,
|
||||
initialTitle: 'Create Record',
|
||||
Icon: IconPlus,
|
||||
onTitleChange: fn(),
|
||||
},
|
||||
play: async ({ canvasElement, args }) => {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
const titleInput = await canvas.findByDisplayValue('Create Record');
|
||||
|
||||
const NEW_TITLE = 'New Title';
|
||||
|
||||
await userEvent.clear(titleInput);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(args.onTitleChange).toHaveBeenCalledWith('');
|
||||
});
|
||||
|
||||
await userEvent.type(titleInput, NEW_TITLE);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(args.onTitleChange).toHaveBeenCalledWith(NEW_TITLE);
|
||||
});
|
||||
|
||||
expect(args.onTitleChange).toHaveBeenCalledTimes(2);
|
||||
expect(titleInput).toHaveValue(NEW_TITLE);
|
||||
},
|
||||
};
|
||||
|
||||
export const Disabled: Story = {
|
||||
args: {
|
||||
headerType: 'Action',
|
||||
iconColor: THEME_LIGHT.font.color.tertiary,
|
||||
initialTitle: 'Create Record',
|
||||
Icon: IconPlus,
|
||||
disabled: true,
|
||||
onTitleChange: fn(),
|
||||
},
|
||||
play: async ({ canvasElement, args }) => {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
const titleInput = await canvas.findByDisplayValue('Create Record');
|
||||
expect(titleInput).toBeDisabled();
|
||||
|
||||
const NEW_TITLE = 'New Title';
|
||||
|
||||
await userEvent.type(titleInput, NEW_TITLE);
|
||||
|
||||
expect(args.onTitleChange).not.toHaveBeenCalled();
|
||||
expect(titleInput).toHaveValue('Create Record');
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user