Add links composite field (#9059)

- only primary links for now
- need for a global strat for validation. This will come later
This commit is contained in:
Thomas Trompette 2024-12-13 16:53:21 +01:00 committed by GitHub
parent 7e67b1c5a6
commit 32e7eb79b9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 103 additions and 4 deletions

View File

@ -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) ? (
<FormAddressFieldInput
label={field.label}
defaultValue={defaultValue as FieldAddressValue}
defaultValue={defaultValue as FieldAddressValue | undefined}
onPersist={onPersist}
VariablePicker={VariablePicker}
/>
) : isFieldLinks(field) ? (
<FormLinksFieldInput
label={field.label}
defaultValue={defaultValue as FieldLinksValue | undefined}
onPersist={onPersist}
VariablePicker={VariablePicker}
/>

View File

@ -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;

View File

@ -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 (
<FormFieldInputContainer>
{label ? <InputLabel>{label}</InputLabel> : null}
<FormNestedFieldInputContainer>
<FormTextFieldInput
label="Primary Link Label"
defaultValue={defaultValue?.primaryLinkLabel}
onPersist={handleChange('primaryLinkLabel')}
placeholder={'Primary Link Label'}
readonly={readonly}
VariablePicker={VariablePicker}
/>
<FormTextFieldInput
label="Primary Link URL"
defaultValue={defaultValue?.primaryLinkUrl}
onPersist={handleChange('primaryLinkUrl')}
placeholder={'Primary Link URL'}
readonly={readonly}
VariablePicker={VariablePicker}
/>
</FormNestedFieldInputContainer>
</FormFieldInputContainer>
);
};

View File

@ -0,0 +1,31 @@
import { Meta, StoryObj } from '@storybook/react';
import { within } from '@storybook/test';
import { FormLinksFieldInput } from '../FormLinksFieldInput';
const meta: Meta<typeof FormLinksFieldInput> = {
title: 'UI/Data/Field/Form/Input/FormLinksFieldInput',
component: FormLinksFieldInput,
args: {},
argTypes: {},
};
export default meta;
type Story = StoryObj<typeof FormLinksFieldInput>;
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');
},
};