feat: add New Field Step 2 form (#2138)
Closes #2001 Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -0,0 +1,64 @@
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import { H2Title } from '@/ui/display/typography/components/H2Title';
|
||||
import { IconPicker } from '@/ui/input/components/IconPicker';
|
||||
import { TextArea } from '@/ui/input/components/TextArea';
|
||||
import { TextInput } from '@/ui/input/components/TextInput';
|
||||
import { Section } from '@/ui/layout/section/components/Section';
|
||||
|
||||
type SettingsObjectFieldFormSectionProps = {
|
||||
disabled?: boolean;
|
||||
name?: string;
|
||||
description?: string;
|
||||
iconKey?: string;
|
||||
onChange?: (
|
||||
formValues: Partial<{
|
||||
iconKey: string;
|
||||
name: string;
|
||||
description: string;
|
||||
}>,
|
||||
) => void;
|
||||
};
|
||||
|
||||
const StyledInputsContainer = styled.div`
|
||||
display: flex;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
margin-bottom: ${({ theme }) => theme.spacing(2)};
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
export const SettingsObjectFieldFormSection = ({
|
||||
disabled,
|
||||
name = '',
|
||||
description = '',
|
||||
iconKey = 'IconUsers',
|
||||
onChange,
|
||||
}: SettingsObjectFieldFormSectionProps) => (
|
||||
<Section>
|
||||
<H2Title
|
||||
title="Name and description"
|
||||
description="The name and description of this field"
|
||||
/>
|
||||
<StyledInputsContainer>
|
||||
<IconPicker
|
||||
selectedIconKey={iconKey}
|
||||
onChange={(value) => onChange?.({ iconKey: value.iconKey })}
|
||||
variant="primary"
|
||||
/>
|
||||
<TextInput
|
||||
placeholder="Employees"
|
||||
value={name}
|
||||
onChange={(value) => onChange?.({ name: value })}
|
||||
disabled={disabled}
|
||||
fullWidth
|
||||
/>
|
||||
</StyledInputsContainer>
|
||||
<TextArea
|
||||
placeholder="Write a description"
|
||||
minRows={4}
|
||||
value={description}
|
||||
onChange={(value) => onChange?.({ description: value })}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</Section>
|
||||
);
|
||||
@ -0,0 +1,32 @@
|
||||
import { H2Title } from '@/ui/display/typography/components/H2Title';
|
||||
import { Select } from '@/ui/input/components/Select';
|
||||
import { Section } from '@/ui/layout/section/components/Section';
|
||||
|
||||
import { dataTypes } from '../constants/dataTypes';
|
||||
import { ObjectFieldDataType } from '../types/ObjectFieldDataType';
|
||||
|
||||
type SettingsObjectFieldTypeSelectSectionProps = {
|
||||
type: ObjectFieldDataType;
|
||||
onChange: (value: ObjectFieldDataType) => void;
|
||||
};
|
||||
|
||||
export const SettingsObjectFieldTypeSelectSection = ({
|
||||
type,
|
||||
onChange,
|
||||
}: SettingsObjectFieldTypeSelectSectionProps) => (
|
||||
<Section>
|
||||
<H2Title
|
||||
title="Type and values"
|
||||
description="The field's type and values."
|
||||
/>
|
||||
<Select
|
||||
dropdownScopeId="object-field-type-select"
|
||||
value={type}
|
||||
onChange={onChange}
|
||||
options={Object.entries(dataTypes).map(([key, dataType]) => ({
|
||||
value: key as ObjectFieldDataType,
|
||||
...dataType,
|
||||
}))}
|
||||
/>
|
||||
</Section>
|
||||
);
|
||||
@ -26,10 +26,6 @@ const StyledInputsContainer = styled.div`
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const StyledTextInput = styled(TextInput)`
|
||||
flex: 1 0 auto;
|
||||
`;
|
||||
|
||||
export const SettingsObjectFormSection = ({
|
||||
disabled,
|
||||
singularName = '',
|
||||
@ -43,19 +39,21 @@ export const SettingsObjectFormSection = ({
|
||||
description="Name in both singular (e.g., 'Invoice') and plural (e.g., 'Invoices') forms."
|
||||
/>
|
||||
<StyledInputsContainer>
|
||||
<StyledTextInput
|
||||
<TextInput
|
||||
label="Singular"
|
||||
placeholder="Investor"
|
||||
value={singularName}
|
||||
onChange={(value) => onChange?.({ singularName: value })}
|
||||
disabled={disabled}
|
||||
fullWidth
|
||||
/>
|
||||
<StyledTextInput
|
||||
<TextInput
|
||||
label="Plural"
|
||||
placeholder="Investors"
|
||||
value={pluralName}
|
||||
onChange={(value) => onChange?.({ pluralName: value })}
|
||||
disabled={disabled}
|
||||
fullWidth
|
||||
/>
|
||||
</StyledInputsContainer>
|
||||
<TextArea
|
||||
|
||||
@ -0,0 +1,24 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
|
||||
import { SettingsObjectFieldFormSection } from '../SettingsObjectFieldFormSection';
|
||||
|
||||
const meta: Meta<typeof SettingsObjectFieldFormSection> = {
|
||||
title: 'Modules/Settings/DataModel/SettingsObjectFieldFormSection',
|
||||
component: SettingsObjectFieldFormSection,
|
||||
decorators: [ComponentDecorator],
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof SettingsObjectFieldFormSection>;
|
||||
|
||||
export const Default: Story = {};
|
||||
|
||||
export const WithDefaultValues: Story = {
|
||||
args: {
|
||||
iconKey: 'IconLink',
|
||||
name: 'URL',
|
||||
description: 'Lorem ipsum',
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,28 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { userEvent, within } from '@storybook/testing-library';
|
||||
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
|
||||
import { SettingsObjectFieldTypeSelectSection } from '../SettingsObjectFieldTypeSelectSection';
|
||||
|
||||
const meta: Meta<typeof SettingsObjectFieldTypeSelectSection> = {
|
||||
title: 'Modules/Settings/DataModel/SettingsObjectFieldTypeSelectSection',
|
||||
component: SettingsObjectFieldTypeSelectSection,
|
||||
decorators: [ComponentDecorator],
|
||||
args: { type: 'number' },
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof SettingsObjectFieldTypeSelectSection>;
|
||||
|
||||
export const Default: Story = {};
|
||||
|
||||
export const WithOpenSelect: Story = {
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
const selectLabel = canvas.getByText('Number');
|
||||
|
||||
await userEvent.click(selectLabel);
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user