diff --git a/packages/twenty-front/src/modules/object-record/record-field/components/FormFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/components/FormFieldInput.tsx index a547d2d67..67cf91492 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/components/FormFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/components/FormFieldInput.tsx @@ -1,6 +1,7 @@ import { FormAddressFieldInput } from '@/object-record/record-field/form-types/components/FormAddressFieldInput'; import { FormBooleanFieldInput } from '@/object-record/record-field/form-types/components/FormBooleanFieldInput'; import { FormFullNameFieldInput } from '@/object-record/record-field/form-types/components/FormFullNameFieldInput'; +import { FormLinksFieldInput } from '@/object-record/record-field/form-types/components/FormLinksFieldInput'; import { FormNumberFieldInput } from '@/object-record/record-field/form-types/components/FormNumberFieldInput'; import { FormSelectFieldInput } from '@/object-record/record-field/form-types/components/FormSelectFieldInput'; import { FormTextFieldInput } from '@/object-record/record-field/form-types/components/FormTextFieldInput'; @@ -9,11 +10,13 @@ import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinit import { FieldAddressValue, FieldFullNameValue, + FieldLinksValue, FieldMetadata, } from '@/object-record/record-field/types/FieldMetadata'; import { isFieldAddress } from '@/object-record/record-field/types/guards/isFieldAddress'; import { isFieldBoolean } from '@/object-record/record-field/types/guards/isFieldBoolean'; import { isFieldFullName } from '@/object-record/record-field/types/guards/isFieldFullName'; +import { isFieldLinks } from '@/object-record/record-field/types/guards/isFieldLinks'; import { isFieldNumber } from '@/object-record/record-field/types/guards/isFieldNumber'; import { isFieldSelect } from '@/object-record/record-field/types/guards/isFieldSelect'; import { isFieldText } from '@/object-record/record-field/types/guards/isFieldText'; @@ -74,7 +77,14 @@ export const FormFieldInput = ({ ) : isFieldAddress(field) ? ( + ) : isFieldLinks(field) ? ( + diff --git a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormAddressFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormAddressFieldInput.tsx index 143ee62fb..6feb38319 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormAddressFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormAddressFieldInput.tsx @@ -1,7 +1,7 @@ import { FormCountrySelectInput } from '@/object-record/record-field/form-types/components/FormCountrySelectInput'; -import { FormTextFieldInput } from '@/object-record/record-field/form-types/components/FormTextFieldInput'; -import { FormNestedFieldInputContainer } from '@/object-record/record-field/form-types/components/FormNestedFieldInputContainer'; import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer'; +import { FormNestedFieldInputContainer } from '@/object-record/record-field/form-types/components/FormNestedFieldInputContainer'; +import { FormTextFieldInput } from '@/object-record/record-field/form-types/components/FormTextFieldInput'; import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent'; import { FieldAddressDraftValue } from '@/object-record/record-field/types/FieldInputDraftValue'; import { FieldAddressValue } from '@/object-record/record-field/types/FieldMetadata'; @@ -9,7 +9,7 @@ import { InputLabel } from '@/ui/input/components/InputLabel'; type FormAddressFieldInputProps = { label?: string; - defaultValue: FieldAddressDraftValue | null; + defaultValue?: FieldAddressDraftValue | null; onPersist: (value: FieldAddressValue) => void; VariablePicker?: VariablePickerComponent; readonly?: boolean; diff --git a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormLinksFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormLinksFieldInput.tsx new file mode 100644 index 000000000..1f8b61702 --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormLinksFieldInput.tsx @@ -0,0 +1,58 @@ +import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer'; +import { FormNestedFieldInputContainer } from '@/object-record/record-field/form-types/components/FormNestedFieldInputContainer'; +import { FormTextFieldInput } from '@/object-record/record-field/form-types/components/FormTextFieldInput'; +import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent'; +import { FieldLinksDraftValue } from '@/object-record/record-field/types/FieldInputDraftValue'; +import { FieldLinksValue } from '@/object-record/record-field/types/FieldMetadata'; +import { InputLabel } from '@/ui/input/components/InputLabel'; + +type FormLinksFieldInputProps = { + label?: string; + defaultValue?: FieldLinksValue; + onPersist: (value: FieldLinksValue) => void; + VariablePicker?: VariablePickerComponent; + readonly?: boolean; +}; + +export const FormLinksFieldInput = ({ + label, + defaultValue, + onPersist, + readonly, + VariablePicker, +}: FormLinksFieldInputProps) => { + const handleChange = + (field: keyof FieldLinksDraftValue) => (updatedLinksPart: string) => { + const updatedLinks = { + primaryLinkLabel: defaultValue?.primaryLinkLabel ?? '', + primaryLinkUrl: defaultValue?.primaryLinkUrl ?? '', + [field]: updatedLinksPart, + }; + // We need to validate the links and display an error message if the links are not valid + onPersist(updatedLinks); + }; + + return ( + + {label ? {label} : null} + + + + + + ); +}; diff --git a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/__stories__/FormLinksFieldInput.stories.tsx b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/__stories__/FormLinksFieldInput.stories.tsx new file mode 100644 index 000000000..8dccf506c --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/__stories__/FormLinksFieldInput.stories.tsx @@ -0,0 +1,31 @@ +import { Meta, StoryObj } from '@storybook/react'; +import { within } from '@storybook/test'; +import { FormLinksFieldInput } from '../FormLinksFieldInput'; + +const meta: Meta = { + title: 'UI/Data/Field/Form/Input/FormLinksFieldInput', + component: FormLinksFieldInput, + args: {}, + argTypes: {}, +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: { + label: 'Domain Name', + defaultValue: { + primaryLinkLabel: 'Google', + primaryLinkUrl: 'https://www.google.com', + }, + }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + + await canvas.findByText('Domain Name'); + await canvas.findByText('Primary Link Label'); + await canvas.findByText('Google'); + }, +};