Fix readonly date still editable (#19334)

Fixes #19319

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Rohit Sekh
2026-04-06 12:12:25 +05:30
committed by GitHub
parent bad488494f
commit 3747af4b5a
3 changed files with 117 additions and 1 deletions
@@ -270,6 +270,7 @@ export const FormDateFieldInput = ({
<DatePickerInput
date={plainDateValue}
onChange={handleInputChange}
readonly={readonly}
/>
</StyledDateInputTextContainer>
{draftValue.mode === 'edit' && !readonly ? (
@@ -0,0 +1,109 @@
import { FormDateFieldInput } from '@/object-record/record-field/ui/form-types/components/FormDateFieldInput';
import { type Meta, type StoryObj } from '@storybook/react-vite';
import { expect, fn, userEvent, waitFor, within } from 'storybook/test';
import { WorkflowStepDecorator } from '~/testing/decorators/WorkflowStepDecorator';
import { MOCKED_STEP_ID } from '~/testing/mock-data/workflow';
const meta: Meta<typeof FormDateFieldInput> = {
title: 'UI/Data/Field/Form/Input/FormDateFieldInput',
component: FormDateFieldInput,
args: {},
argTypes: {},
decorators: [WorkflowStepDecorator],
};
export default meta;
type Story = StoryObj<typeof FormDateFieldInput>;
export const Default: Story = {
args: {
label: 'Date',
defaultValue: undefined,
onChange: fn(),
},
};
export const WithDefaultValue: Story = {
args: {
label: 'Date',
defaultValue: '2024-06-15',
onChange: fn(),
},
};
export const Disabled: Story = {
args: {
label: 'Date',
defaultValue: '2024-06-15',
readonly: true,
VariablePicker: () => <div>VariablePicker</div>,
onChange: fn(),
},
play: async ({ canvasElement, args }) => {
const canvas = within(canvasElement);
const input = await waitFor(() => {
const inputElement = canvasElement.querySelector('input');
expect(inputElement).not.toBeNull();
return inputElement!;
});
expect(input).toBeDisabled();
const variablePicker = canvas.queryByText('VariablePicker');
expect(variablePicker).not.toBeInTheDocument();
expect(args.onChange).not.toHaveBeenCalled();
},
};
export const DisabledWithVariable: Story = {
args: {
label: 'Date',
defaultValue: `{{${MOCKED_STEP_ID}.name}}`,
readonly: true,
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const variable = await canvas.findByText('Name');
expect(variable).toBeVisible();
const deleteVariableButton = canvas.queryByRole('button');
expect(deleteVariableButton).not.toBeInTheDocument();
},
};
export const WithVariable: Story = {
args: {
label: 'Date',
defaultValue: undefined,
VariablePicker: ({ onVariableSelect }) => {
return (
<button
onClick={() => {
onVariableSelect(`{{${MOCKED_STEP_ID}.name}}`);
}}
>
Add variable
</button>
);
},
onChange: fn(),
},
play: async ({ canvasElement, args }) => {
const canvas = within(canvasElement);
const addVariableButton = await canvas.findByRole('button', {
name: 'Add variable',
});
await userEvent.click(addVariableButton);
const variable = await canvas.findByText('Name');
expect(variable).toBeVisible();
expect(args.onChange).toHaveBeenCalledWith(`{{${MOCKED_STEP_ID}.name}}`);
},
};
@@ -42,9 +42,14 @@ const StyledInput = styled.input<{ hasError?: boolean }>`
type DatePickerInputProps = {
onChange?: (date: string | null) => void;
date: string | null;
readonly?: boolean;
};
export const DatePickerInput = ({ date, onChange }: DatePickerInputProps) => {
export const DatePickerInput = ({
date,
onChange,
readonly = false,
}: DatePickerInputProps) => {
const { dateFormat } = useDateTimeFormat();
const [internalDate, setInternalDate] = useState(date);
@@ -105,6 +110,7 @@ export const DatePickerInput = ({ date, onChange }: DatePickerInputProps) => {
<StyledInputContainer>
<StyledInput
type="text"
disabled={readonly}
ref={ref as any}
value={value}
onChange={() => {}} // Prevent React warning