Add readonly mode to form fields - 2nd part (#9582)
In this PR, I implemented or confirmed that the read-only mode works for the following fields: - [x] FormUuidFieldInput - [x] FormRawJsonFieldInput - [x] FormPhoneFieldInput - [x] FormEmailsFieldInput - [x] FormLinksFieldInput - [x] FormAddressFieldInput - [x] FormFullNameFieldInput
This commit is contained in:
committed by
GitHub
parent
21a6dff2c9
commit
5eeee6a7ed
@ -57,7 +57,9 @@ export const FormCountryCodeSelectInput = ({
|
|||||||
onPersist={onChange}
|
onPersist={onChange}
|
||||||
options={options}
|
options={options}
|
||||||
defaultValue={selectedCountryCode}
|
defaultValue={selectedCountryCode}
|
||||||
|
readonly={readonly}
|
||||||
VariablePicker={VariablePicker}
|
VariablePicker={VariablePicker}
|
||||||
|
preventDisplayPadding
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -57,7 +57,9 @@ export const FormCountrySelectInput = ({
|
|||||||
onPersist={onChange}
|
onPersist={onChange}
|
||||||
options={options}
|
options={options}
|
||||||
defaultValue={selectedCountryName}
|
defaultValue={selectedCountryName}
|
||||||
|
readonly={readonly}
|
||||||
VariablePicker={VariablePicker}
|
VariablePicker={VariablePicker}
|
||||||
|
preventDisplayPadding
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -62,6 +62,7 @@ export const FormCurrencyFieldInput = ({
|
|||||||
clearLabel={'Currency Code'}
|
clearLabel={'Currency Code'}
|
||||||
VariablePicker={VariablePicker}
|
VariablePicker={VariablePicker}
|
||||||
readonly={readonly}
|
readonly={readonly}
|
||||||
|
preventDisplayPadding
|
||||||
/>
|
/>
|
||||||
<FormNumberFieldInput
|
<FormNumberFieldInput
|
||||||
label="Amount Micros"
|
label="Amount Micros"
|
||||||
|
|||||||
@ -57,6 +57,7 @@ export const FormPhoneFieldInput = ({
|
|||||||
VariablePicker={VariablePicker}
|
VariablePicker={VariablePicker}
|
||||||
placeholder="Enter phone number"
|
placeholder="Enter phone number"
|
||||||
hint="Without calling code"
|
hint="Without calling code"
|
||||||
|
readonly={readonly}
|
||||||
/>
|
/>
|
||||||
</FormNestedFieldInputContainer>
|
</FormNestedFieldInputContainer>
|
||||||
</FormFieldInputContainer>
|
</FormFieldInputContainer>
|
||||||
|
|||||||
@ -66,19 +66,19 @@ export const FormRawJsonFieldInput = ({
|
|||||||
|
|
||||||
<FormFieldInputRowContainer multiline>
|
<FormFieldInputRowContainer multiline>
|
||||||
<FormFieldInputInputContainer
|
<FormFieldInputInputContainer
|
||||||
hasRightElement={isDefined(VariablePicker)}
|
hasRightElement={isDefined(VariablePicker) && !readonly}
|
||||||
multiline
|
multiline
|
||||||
>
|
>
|
||||||
<TextVariableEditor editor={editor} multiline readonly={readonly} />
|
<TextVariableEditor editor={editor} multiline readonly={readonly} />
|
||||||
</FormFieldInputInputContainer>
|
</FormFieldInputInputContainer>
|
||||||
|
|
||||||
{VariablePicker ? (
|
{VariablePicker && !readonly && (
|
||||||
<VariablePicker
|
<VariablePicker
|
||||||
inputId={inputId}
|
inputId={inputId}
|
||||||
multiline
|
multiline
|
||||||
onVariableSelect={handleVariableTagInsert}
|
onVariableSelect={handleVariableTagInsert}
|
||||||
/>
|
/>
|
||||||
) : null}
|
)}
|
||||||
</FormFieldInputRowContainer>
|
</FormFieldInputRowContainer>
|
||||||
</FormFieldInputContainer>
|
</FormFieldInputContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -28,6 +28,7 @@ type FormSelectFieldInputProps = {
|
|||||||
options: SelectOption[];
|
options: SelectOption[];
|
||||||
clearLabel?: string;
|
clearLabel?: string;
|
||||||
readonly?: boolean;
|
readonly?: boolean;
|
||||||
|
preventDisplayPadding?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const StyledDisplayModeReadonlyContainer = styled.div`
|
const StyledDisplayModeReadonlyContainer = styled.div`
|
||||||
@ -65,6 +66,7 @@ export const FormSelectFieldInput = ({
|
|||||||
options,
|
options,
|
||||||
clearLabel,
|
clearLabel,
|
||||||
readonly,
|
readonly,
|
||||||
|
preventDisplayPadding,
|
||||||
}: FormSelectFieldInputProps) => {
|
}: FormSelectFieldInputProps) => {
|
||||||
const inputId = useId();
|
const inputId = useId();
|
||||||
|
|
||||||
@ -219,7 +221,7 @@ export const FormSelectFieldInput = ({
|
|||||||
|
|
||||||
<FormFieldInputRowContainer>
|
<FormFieldInputRowContainer>
|
||||||
<FormFieldInputInputContainer
|
<FormFieldInputInputContainer
|
||||||
hasRightElement={isDefined(VariablePicker)}
|
hasRightElement={isDefined(VariablePicker) && !readonly}
|
||||||
>
|
>
|
||||||
{draftValue.type === 'static' ? (
|
{draftValue.type === 'static' ? (
|
||||||
readonly ? (
|
readonly ? (
|
||||||
@ -229,6 +231,7 @@ export const FormSelectFieldInput = ({
|
|||||||
color={selectedOption.color ?? 'transparent'}
|
color={selectedOption.color ?? 'transparent'}
|
||||||
label={selectedOption.label}
|
label={selectedOption.label}
|
||||||
Icon={selectedOption.icon ?? undefined}
|
Icon={selectedOption.icon ?? undefined}
|
||||||
|
preventPadding={preventDisplayPadding}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<IconChevronDown
|
<IconChevronDown
|
||||||
@ -248,6 +251,7 @@ export const FormSelectFieldInput = ({
|
|||||||
color={selectedOption.color ?? 'transparent'}
|
color={selectedOption.color ?? 'transparent'}
|
||||||
label={selectedOption.label}
|
label={selectedOption.label}
|
||||||
Icon={selectedOption.icon ?? undefined}
|
Icon={selectedOption.icon ?? undefined}
|
||||||
|
preventPadding={preventDisplayPadding}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<IconChevronDown
|
<IconChevronDown
|
||||||
|
|||||||
@ -28,6 +28,7 @@ export const FormUuidFieldInput = ({
|
|||||||
defaultValue,
|
defaultValue,
|
||||||
placeholder,
|
placeholder,
|
||||||
onPersist,
|
onPersist,
|
||||||
|
readonly,
|
||||||
VariablePicker,
|
VariablePicker,
|
||||||
}: FormUuidFieldInputProps) => {
|
}: FormUuidFieldInputProps) => {
|
||||||
const inputId = useId();
|
const inputId = useId();
|
||||||
@ -94,7 +95,7 @@ export const FormUuidFieldInput = ({
|
|||||||
|
|
||||||
<FormFieldInputRowContainer>
|
<FormFieldInputRowContainer>
|
||||||
<FormFieldInputInputContainer
|
<FormFieldInputInputContainer
|
||||||
hasRightElement={isDefined(VariablePicker)}
|
hasRightElement={isDefined(VariablePicker) && !readonly}
|
||||||
>
|
>
|
||||||
{draftValue.type === 'static' ? (
|
{draftValue.type === 'static' ? (
|
||||||
<StyledInput
|
<StyledInput
|
||||||
@ -103,17 +104,18 @@ export const FormUuidFieldInput = ({
|
|||||||
value={draftValue.value}
|
value={draftValue.value}
|
||||||
copyButton={false}
|
copyButton={false}
|
||||||
hotkeyScope="record-create"
|
hotkeyScope="record-create"
|
||||||
|
disabled={readonly}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<VariableChip
|
<VariableChip
|
||||||
rawVariableName={draftValue.value}
|
rawVariableName={draftValue.value}
|
||||||
onRemove={handleUnlinkVariable}
|
onRemove={readonly ? undefined : handleUnlinkVariable}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</FormFieldInputInputContainer>
|
</FormFieldInputInputContainer>
|
||||||
|
|
||||||
{VariablePicker ? (
|
{VariablePicker && !readonly ? (
|
||||||
<VariablePicker
|
<VariablePicker
|
||||||
inputId={inputId}
|
inputId={inputId}
|
||||||
onVariableSelect={handleVariableTagInsert}
|
onVariableSelect={handleVariableTagInsert}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { Meta, StoryObj } from '@storybook/react';
|
import { Meta, StoryObj } from '@storybook/react';
|
||||||
import { within } from '@storybook/test';
|
import { expect, fn, userEvent, within } from '@storybook/test';
|
||||||
import { FormAddressFieldInput } from '../FormAddressFieldInput';
|
import { FormAddressFieldInput } from '../FormAddressFieldInput';
|
||||||
|
|
||||||
const meta: Meta<typeof FormAddressFieldInput> = {
|
const meta: Meta<typeof FormAddressFieldInput> = {
|
||||||
@ -21,7 +21,7 @@ export const Default: Story = {
|
|||||||
addressStreet2: 'Apt 123',
|
addressStreet2: 'Apt 123',
|
||||||
addressCity: 'Springfield',
|
addressCity: 'Springfield',
|
||||||
addressState: 'IL',
|
addressState: 'IL',
|
||||||
addressCountry: 'US',
|
addressCountry: 'United States',
|
||||||
addressPostcode: '12345',
|
addressPostcode: '12345',
|
||||||
addressLat: 39.781721,
|
addressLat: 39.781721,
|
||||||
addressLng: -89.650148,
|
addressLng: -89.650148,
|
||||||
@ -35,3 +35,85 @@ export const Default: Story = {
|
|||||||
await canvas.findByText('Post Code');
|
await canvas.findByText('Post Code');
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const WithVariables: Story = {
|
||||||
|
args: {
|
||||||
|
label: 'Address',
|
||||||
|
defaultValue: {
|
||||||
|
addressStreet1: '{{a.street1}}',
|
||||||
|
addressStreet2: '{{a.street2}}',
|
||||||
|
addressCity: '{{a.city}}',
|
||||||
|
addressState: '{{a.state}}',
|
||||||
|
addressCountry: '{{a.country}}',
|
||||||
|
addressPostcode: '{{a.postcode}}',
|
||||||
|
addressLat: 39.781721,
|
||||||
|
addressLng: -89.650148,
|
||||||
|
},
|
||||||
|
VariablePicker: () => <div>VariablePicker</div>,
|
||||||
|
},
|
||||||
|
play: async ({ canvasElement }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
const street1Variable = await canvas.findByText('street1');
|
||||||
|
const street2Variable = await canvas.findByText('street2');
|
||||||
|
const cityVariable = await canvas.findByText('city');
|
||||||
|
const stateVariable = await canvas.findByText('state');
|
||||||
|
const countryVariable = await canvas.findByText('country');
|
||||||
|
const postcodeVariable = await canvas.findByText('postcode');
|
||||||
|
|
||||||
|
expect(street1Variable).toBeVisible();
|
||||||
|
expect(street2Variable).toBeVisible();
|
||||||
|
expect(cityVariable).toBeVisible();
|
||||||
|
expect(stateVariable).toBeVisible();
|
||||||
|
expect(countryVariable).toBeVisible();
|
||||||
|
expect(postcodeVariable).toBeVisible();
|
||||||
|
|
||||||
|
const variablePickers = await canvas.findAllByText('VariablePicker');
|
||||||
|
expect(variablePickers).toHaveLength(6);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Disabled: Story = {
|
||||||
|
args: {
|
||||||
|
label: 'Address',
|
||||||
|
readonly: true,
|
||||||
|
defaultValue: {
|
||||||
|
addressStreet1: '123 Main St',
|
||||||
|
addressStreet2: 'Apt 123',
|
||||||
|
addressCity: 'Springfield',
|
||||||
|
addressState: 'IL',
|
||||||
|
addressCountry: 'United States',
|
||||||
|
addressPostcode: '12345',
|
||||||
|
addressLat: 39.781721,
|
||||||
|
addressLng: -89.650148,
|
||||||
|
},
|
||||||
|
onPersist: fn(),
|
||||||
|
VariablePicker: () => <div>VariablePicker</div>,
|
||||||
|
},
|
||||||
|
play: async ({ canvasElement, args }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
const street1Input = await canvas.findByText('123 Main St');
|
||||||
|
const street2Input = await canvas.findByText('Apt 123');
|
||||||
|
const cityInput = await canvas.findByText('Springfield');
|
||||||
|
const stateInput = await canvas.findByText('IL');
|
||||||
|
const postcodeInput = await canvas.findByText('12345');
|
||||||
|
const countrySelect = await canvas.findByText('United States');
|
||||||
|
|
||||||
|
await userEvent.type(street1Input, 'XXX');
|
||||||
|
await userEvent.type(street2Input, 'YYY');
|
||||||
|
await userEvent.type(cityInput, 'ZZZ');
|
||||||
|
await userEvent.type(stateInput, 'ZZ');
|
||||||
|
await userEvent.type(postcodeInput, '1234');
|
||||||
|
|
||||||
|
await userEvent.click(countrySelect);
|
||||||
|
|
||||||
|
const searchInputInModal = canvas.queryByPlaceholderText('Search');
|
||||||
|
expect(searchInputInModal).not.toBeInTheDocument();
|
||||||
|
|
||||||
|
expect(args.onPersist).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
const variablePickers = canvas.queryAllByText('VariablePicker');
|
||||||
|
expect(variablePickers).toHaveLength(0);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { Meta, StoryObj } from '@storybook/react';
|
import { Meta, StoryObj } from '@storybook/react';
|
||||||
import { within } from '@storybook/test';
|
import { expect, fn, userEvent, within } from '@storybook/test';
|
||||||
import { FormEmailsFieldInput } from '../FormEmailsFieldInput';
|
import { FormEmailsFieldInput } from '../FormEmailsFieldInput';
|
||||||
|
|
||||||
const meta: Meta<typeof FormEmailsFieldInput> = {
|
const meta: Meta<typeof FormEmailsFieldInput> = {
|
||||||
@ -29,3 +29,54 @@ export const Default: Story = {
|
|||||||
await canvas.findByText('tim@twenty.com');
|
await canvas.findByText('tim@twenty.com');
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const WithVariable: Story = {
|
||||||
|
args: {
|
||||||
|
label: 'Emails',
|
||||||
|
defaultValue: {
|
||||||
|
primaryEmail: '{{a.b.c}}',
|
||||||
|
additionalEmails: [],
|
||||||
|
},
|
||||||
|
VariablePicker: () => <div>VariablePicker</div>,
|
||||||
|
},
|
||||||
|
play: async ({ canvasElement }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
const primaryEmailVariable = await canvas.findByText('c');
|
||||||
|
expect(primaryEmailVariable).toBeVisible();
|
||||||
|
|
||||||
|
const variablePicker = await canvas.findByText('VariablePicker');
|
||||||
|
expect(variablePicker).toBeVisible();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Disabled: Story = {
|
||||||
|
args: {
|
||||||
|
label: 'Emails',
|
||||||
|
defaultValue: {
|
||||||
|
primaryEmail: 'tim@twenty.com',
|
||||||
|
additionalEmails: [],
|
||||||
|
},
|
||||||
|
onPersist: fn(),
|
||||||
|
VariablePicker: () => <div>VariablePicker</div>,
|
||||||
|
readonly: true,
|
||||||
|
},
|
||||||
|
play: async ({ canvasElement, args }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
const editor = canvasElement.querySelector('.ProseMirror > p');
|
||||||
|
expect(editor).toBeVisible();
|
||||||
|
|
||||||
|
const defaultValue = await canvas.findByText('tim@twenty.com');
|
||||||
|
expect(defaultValue).toBeVisible();
|
||||||
|
|
||||||
|
await userEvent.type(editor, 'hello@gmail.com');
|
||||||
|
|
||||||
|
expect(args.onPersist).not.toHaveBeenCalled();
|
||||||
|
expect(canvas.queryByText('hello@gmail.com')).not.toBeInTheDocument();
|
||||||
|
expect(defaultValue).toBeVisible();
|
||||||
|
|
||||||
|
const variablePicker = canvas.queryByText('VariablePicker');
|
||||||
|
expect(variablePicker).not.toBeInTheDocument();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { Meta, StoryObj } from '@storybook/react';
|
import { Meta, StoryObj } from '@storybook/react';
|
||||||
import { within } from '@storybook/test';
|
import { expect, fn, userEvent, within } from '@storybook/test';
|
||||||
import { FormFullNameFieldInput } from '../FormFullNameFieldInput';
|
import { FormFullNameFieldInput } from '../FormFullNameFieldInput';
|
||||||
|
|
||||||
const meta: Meta<typeof FormFullNameFieldInput> = {
|
const meta: Meta<typeof FormFullNameFieldInput> = {
|
||||||
@ -29,3 +29,53 @@ export const Default: Story = {
|
|||||||
await canvas.findByText('Last Name');
|
await canvas.findByText('Last Name');
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const WithVariable: Story = {
|
||||||
|
args: {
|
||||||
|
label: 'Name',
|
||||||
|
defaultValue: {
|
||||||
|
firstName: '{{a.firstName}}',
|
||||||
|
lastName: '{{a.lastName}}',
|
||||||
|
},
|
||||||
|
VariablePicker: () => <div>VariablePicker</div>,
|
||||||
|
},
|
||||||
|
play: async ({ canvasElement }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
const firstNameVariable = await canvas.findByText('firstName');
|
||||||
|
expect(firstNameVariable).toBeVisible();
|
||||||
|
|
||||||
|
const lastNameVariable = await canvas.findByText('lastName');
|
||||||
|
expect(lastNameVariable).toBeVisible();
|
||||||
|
|
||||||
|
const variablePickers = await canvas.findAllByText('VariablePicker');
|
||||||
|
expect(variablePickers).toHaveLength(2);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Disabled: Story = {
|
||||||
|
args: {
|
||||||
|
label: 'Name',
|
||||||
|
readonly: true,
|
||||||
|
defaultValue: {
|
||||||
|
firstName: 'John',
|
||||||
|
lastName: 'Doe',
|
||||||
|
},
|
||||||
|
VariablePicker: () => <div>VariablePicker</div>,
|
||||||
|
onPersist: fn(),
|
||||||
|
},
|
||||||
|
play: async ({ canvasElement, args }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
const firstNameVariable = await canvas.findByText('John');
|
||||||
|
const lastNameVariable = await canvas.findByText('Doe');
|
||||||
|
|
||||||
|
await userEvent.type(firstNameVariable, 'Jane');
|
||||||
|
await userEvent.type(lastNameVariable, 'Smith');
|
||||||
|
|
||||||
|
expect(args.onPersist).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
const variablePickers = canvas.queryAllByText('VariablePicker');
|
||||||
|
expect(variablePickers).toHaveLength(0);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
|
import { expect } from '@storybook/jest';
|
||||||
import { Meta, StoryObj } from '@storybook/react';
|
import { Meta, StoryObj } from '@storybook/react';
|
||||||
import { within } from '@storybook/test';
|
import { fn, userEvent, within } from '@storybook/test';
|
||||||
import { FormLinksFieldInput } from '../FormLinksFieldInput';
|
import { FormLinksFieldInput } from '../FormLinksFieldInput';
|
||||||
|
|
||||||
const meta: Meta<typeof FormLinksFieldInput> = {
|
const meta: Meta<typeof FormLinksFieldInput> = {
|
||||||
@ -29,3 +30,57 @@ export const Default: Story = {
|
|||||||
await canvas.findByText('Google');
|
await canvas.findByText('Google');
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const WithVariables: Story = {
|
||||||
|
args: {
|
||||||
|
label: 'Domain Name',
|
||||||
|
defaultValue: {
|
||||||
|
primaryLinkLabel: '{{a.label}}',
|
||||||
|
primaryLinkUrl: '{{a.url}}',
|
||||||
|
},
|
||||||
|
VariablePicker: () => <div>VariablePicker</div>,
|
||||||
|
},
|
||||||
|
play: async ({ canvasElement }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
const primaryLinkLabelVariable = await canvas.findByText('label');
|
||||||
|
expect(primaryLinkLabelVariable).toBeVisible();
|
||||||
|
|
||||||
|
const primaryLinkUrlVariable = await canvas.findByText('url');
|
||||||
|
expect(primaryLinkUrlVariable).toBeVisible();
|
||||||
|
|
||||||
|
const variablePickers = await canvas.findAllByText('VariablePicker');
|
||||||
|
expect(variablePickers).toHaveLength(2);
|
||||||
|
|
||||||
|
for (const variablePicker of variablePickers) {
|
||||||
|
expect(variablePicker).toBeVisible();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Disabled: Story = {
|
||||||
|
args: {
|
||||||
|
label: 'Number field...',
|
||||||
|
readonly: true,
|
||||||
|
onPersist: fn(),
|
||||||
|
VariablePicker: () => <div>VariablePicker</div>,
|
||||||
|
defaultValue: {
|
||||||
|
primaryLinkLabel: 'Google',
|
||||||
|
primaryLinkUrl: 'https://www.google.com',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
play: async ({ canvasElement, args }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
const labelInput = await canvas.findByText('Google');
|
||||||
|
const linkInput = await canvas.findByText('https://www.google.com');
|
||||||
|
|
||||||
|
await userEvent.type(labelInput, 'Yahoo');
|
||||||
|
await userEvent.type(linkInput, 'https://www.yahoo.com');
|
||||||
|
|
||||||
|
expect(args.onPersist).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
const variablePickers = canvas.queryAllByText('VariablePicker');
|
||||||
|
expect(variablePickers).toHaveLength(0);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { Meta, StoryObj } from '@storybook/react';
|
import { Meta, StoryObj } from '@storybook/react';
|
||||||
import { within } from '@storybook/test';
|
import { expect, userEvent, within } from '@storybook/test';
|
||||||
|
|
||||||
import { FieldPhonesValue } from '@/object-record/record-field/types/FieldMetadata';
|
import { FieldPhonesValue } from '@/object-record/record-field/types/FieldMetadata';
|
||||||
import { FormPhoneFieldInput } from '../FormPhoneFieldInput';
|
import { FormPhoneFieldInput } from '../FormPhoneFieldInput';
|
||||||
@ -32,3 +32,57 @@ export const Default: Story = {
|
|||||||
await canvas.findByText('Phone');
|
await canvas.findByText('Phone');
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const WithVariables: Story = {
|
||||||
|
args: {
|
||||||
|
label: 'Enter phone...',
|
||||||
|
defaultValue: {
|
||||||
|
primaryPhoneCountryCode: '{{a.countryCode}}',
|
||||||
|
primaryPhoneNumber: '{{a.phoneNumber}}',
|
||||||
|
},
|
||||||
|
VariablePicker: () => <div>VariablePicker</div>,
|
||||||
|
},
|
||||||
|
play: async ({ canvasElement }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
const countryCodeVariable = await canvas.findByText('countryCode');
|
||||||
|
expect(countryCodeVariable).toBeVisible();
|
||||||
|
|
||||||
|
const phoneNumberVariable = await canvas.findByText('phoneNumber');
|
||||||
|
expect(phoneNumberVariable).toBeVisible();
|
||||||
|
|
||||||
|
const variablePickers = await canvas.findAllByText('VariablePicker');
|
||||||
|
|
||||||
|
expect(variablePickers).toHaveLength(2);
|
||||||
|
|
||||||
|
for (const variablePicker of variablePickers) {
|
||||||
|
expect(variablePicker).toBeVisible();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Disabled: Story = {
|
||||||
|
args: {
|
||||||
|
label: 'Enter phone...',
|
||||||
|
readonly: true,
|
||||||
|
VariablePicker: () => <div>VariablePicker</div>,
|
||||||
|
},
|
||||||
|
play: async ({ canvasElement }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
const countryInput = await canvas.findByText('No country');
|
||||||
|
expect(countryInput).toBeVisible();
|
||||||
|
|
||||||
|
await userEvent.click(countryInput);
|
||||||
|
|
||||||
|
const searchInputInModal = canvas.queryByPlaceholderText('Search');
|
||||||
|
expect(searchInputInModal).not.toBeInTheDocument();
|
||||||
|
|
||||||
|
const phoneNumberInput =
|
||||||
|
await canvas.findByPlaceholderText('Enter phone number');
|
||||||
|
expect(phoneNumberInput).toBeDisabled();
|
||||||
|
|
||||||
|
const variablePickers = canvas.queryAllByText('VariablePicker');
|
||||||
|
expect(variablePickers).toHaveLength(0);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|||||||
@ -32,8 +32,21 @@ export const Readonly: Story = {
|
|||||||
placeholder: 'Enter valid json',
|
placeholder: 'Enter valid json',
|
||||||
readonly: true,
|
readonly: true,
|
||||||
onPersist: fn(),
|
onPersist: fn(),
|
||||||
|
VariablePicker: ({ onVariableSelect }) => {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
onVariableSelect('{{test}}');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Add variable
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
play: async ({ canvasElement, args }) => {
|
play: async ({ canvasElement, args }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
const editor = canvasElement.querySelector('.ProseMirror > p');
|
const editor = canvasElement.querySelector('.ProseMirror > p');
|
||||||
expect(editor).toBeVisible();
|
expect(editor).toBeVisible();
|
||||||
|
|
||||||
@ -46,6 +59,9 @@ export const Readonly: Story = {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(args.onPersist).not.toHaveBeenCalled();
|
expect(args.onPersist).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
const addVariableButton = canvas.queryByText('Add variable');
|
||||||
|
expect(addVariableButton).not.toBeInTheDocument();
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -212,3 +212,33 @@ export const ReplaceStaticValueWithVariable: Story = {
|
|||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const Disabled: Story = {
|
||||||
|
args: {
|
||||||
|
label: 'UUID field',
|
||||||
|
placeholder: 'Enter UUID',
|
||||||
|
readonly: true,
|
||||||
|
VariablePicker: ({ onVariableSelect }) => {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
onVariableSelect('{{test}}');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Add variable
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
play: async ({ canvasElement }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
const input = await canvas.findByPlaceholderText('Enter UUID');
|
||||||
|
|
||||||
|
expect(input).toBeDisabled();
|
||||||
|
|
||||||
|
const variablePicker = canvas.queryByText('Add variable');
|
||||||
|
|
||||||
|
expect(variablePicker).not.toBeInTheDocument();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|||||||
@ -4,8 +4,22 @@ type SelectDisplayProps = {
|
|||||||
color: ThemeColor | 'transparent';
|
color: ThemeColor | 'transparent';
|
||||||
label: string;
|
label: string;
|
||||||
Icon?: IconComponent;
|
Icon?: IconComponent;
|
||||||
|
preventPadding?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SelectDisplay = ({ color, label, Icon }: SelectDisplayProps) => {
|
export const SelectDisplay = ({
|
||||||
return <Tag preventShrink color={color} text={label} Icon={Icon} />;
|
color,
|
||||||
|
label,
|
||||||
|
Icon,
|
||||||
|
preventPadding,
|
||||||
|
}: SelectDisplayProps) => {
|
||||||
|
return (
|
||||||
|
<Tag
|
||||||
|
preventShrink
|
||||||
|
color={color}
|
||||||
|
text={label}
|
||||||
|
Icon={Icon}
|
||||||
|
preventPadding={preventPadding}
|
||||||
|
/>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user