Reset limit to 1 when object is changed (#15354)

Closes #15345 

The issue was that when the `onChange` was called on the Select
component in `WorkflowEditActionFindRecords.tsx`, the limit was being
reset to 1, but it wasn't rendering immediately. The sidebar had to be
closed and reopened.

I have added a `useEffect` as a hack to re-render the
`FormNumberFieldInput` when it's `defaultValue` is changed. I understand
that using `useEffect` is not a good choice. Please suggest a better fix
if any and I will implement it.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Balaji Krishnamurthy
2025-10-28 19:36:15 +05:30
committed by GitHub
parent 2f3912aa98
commit 98b4e8431b
2 changed files with 55 additions and 34 deletions
@@ -33,6 +33,16 @@ type FormNumberFieldInputProps = {
onError?: (error: string | undefined) => void;
};
type FormNumberFieldInputValue =
| {
type: 'static';
value: string;
}
| {
type: 'variable';
value: string;
};
export const FormNumberFieldInput = ({
label,
placeholder,
@@ -50,26 +60,17 @@ export const FormNumberFieldInput = ({
undefined,
);
const [draftValue, setDraftValue] = useState<
| {
type: 'static';
value: string;
const draftValue: FormNumberFieldInputValue = isStandaloneVariableString(
defaultValue,
)
? {
type: 'variable',
value: defaultValue,
}
| {
type: 'variable';
value: string;
}
>(
isStandaloneVariableString(defaultValue)
? {
type: 'variable',
value: defaultValue,
}
: {
type: 'static',
value: isDefined(defaultValue) ? String(defaultValue) : '',
},
);
: {
type: 'static',
value: isDefined(defaultValue) ? String(defaultValue) : '',
};
const persistNumber = (newValue: string) => {
if (!canBeCastAsNumberOrNull(newValue)) {
@@ -87,29 +88,14 @@ export const FormNumberFieldInput = ({
};
const handleChange = (newText: string) => {
setDraftValue({
type: 'static',
value: newText,
});
persistNumber(newText.trim());
};
const handleUnlinkVariable = () => {
setDraftValue({
type: 'static',
value: '',
});
onChange(null);
};
const handleVariableTagInsert = (variableName: string) => {
setDraftValue({
type: 'variable',
value: variableName,
});
onChange(variableName);
};
@@ -1,5 +1,6 @@
import { type Meta, type StoryObj } from '@storybook/react';
import { expect, fn, userEvent, waitFor, within } from '@storybook/test';
import { useState } from 'react';
import { type FieldPhonesValue } from '@/object-record/record-field/ui/types/FieldMetadata';
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
@@ -25,6 +26,31 @@ const defaultPhoneValue: FieldPhonesValue = {
primaryPhoneCallingCode: '33',
};
const FormPhoneFieldInputWithState = ({
defaultValue,
label,
onChange,
readonly,
VariablePicker,
}: React.ComponentProps<typeof FormPhoneFieldInput>) => {
const [value, setValue] = useState<FieldPhonesValue | undefined>(
defaultValue,
);
return (
<FormPhoneFieldInput
label={label}
defaultValue={value}
onChange={(newValue) => {
setValue(newValue);
onChange?.(newValue);
}}
readonly={readonly}
VariablePicker={VariablePicker}
/>
);
};
export const Default: Story = {
args: {
label: 'Phone',
@@ -78,6 +104,15 @@ export const SelectingVariables: Story = {
},
onChange: fn(),
},
render: (args) => (
<FormPhoneFieldInputWithState
label={args.label}
defaultValue={args.defaultValue}
onChange={args.onChange}
readonly={args.readonly}
VariablePicker={args.VariablePicker}
/>
),
play: async ({ canvasElement, args }) => {
const canvas = within(canvasElement);