Add full name composite field (#9008)
- Add composite field - Add test - Fix search variable dropdown scroll <img width="548" alt="Capture d’écran 2024-12-10 à 16 52 43" src="https://github.com/user-attachments/assets/c337f0c3-8a70-401a-abd0-7206489ba73e">
This commit is contained in:
@ -1,11 +1,16 @@
|
|||||||
import { FormBooleanFieldInput } from '@/object-record/record-field/form-types/components/FormBooleanFieldInput';
|
import { FormBooleanFieldInput } from '@/object-record/record-field/form-types/components/FormBooleanFieldInput';
|
||||||
|
import { FormFullNameFieldInput } from '@/object-record/record-field/form-types/components/FormFullNameFieldInput';
|
||||||
import { FormNumberFieldInput } from '@/object-record/record-field/form-types/components/FormNumberFieldInput';
|
import { FormNumberFieldInput } from '@/object-record/record-field/form-types/components/FormNumberFieldInput';
|
||||||
import { FormSelectFieldInput } from '@/object-record/record-field/form-types/components/FormSelectFieldInput';
|
import { FormSelectFieldInput } from '@/object-record/record-field/form-types/components/FormSelectFieldInput';
|
||||||
import { FormTextFieldInput } from '@/object-record/record-field/form-types/components/FormTextFieldInput';
|
import { FormTextFieldInput } from '@/object-record/record-field/form-types/components/FormTextFieldInput';
|
||||||
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
||||||
import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition';
|
import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition';
|
||||||
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
import {
|
||||||
|
FieldFullNameValue,
|
||||||
|
FieldMetadata,
|
||||||
|
} from '@/object-record/record-field/types/FieldMetadata';
|
||||||
import { isFieldBoolean } from '@/object-record/record-field/types/guards/isFieldBoolean';
|
import { isFieldBoolean } from '@/object-record/record-field/types/guards/isFieldBoolean';
|
||||||
|
import { isFieldFullName } from '@/object-record/record-field/types/guards/isFieldFullName';
|
||||||
import { isFieldNumber } from '@/object-record/record-field/types/guards/isFieldNumber';
|
import { isFieldNumber } from '@/object-record/record-field/types/guards/isFieldNumber';
|
||||||
import { isFieldSelect } from '@/object-record/record-field/types/guards/isFieldSelect';
|
import { isFieldSelect } from '@/object-record/record-field/types/guards/isFieldSelect';
|
||||||
import { isFieldText } from '@/object-record/record-field/types/guards/isFieldText';
|
import { isFieldText } from '@/object-record/record-field/types/guards/isFieldText';
|
||||||
@ -55,5 +60,12 @@ export const FormFieldInput = ({
|
|||||||
field={field}
|
field={field}
|
||||||
VariablePicker={VariablePicker}
|
VariablePicker={VariablePicker}
|
||||||
/>
|
/>
|
||||||
|
) : isFieldFullName(field) ? (
|
||||||
|
<FormFullNameFieldInput
|
||||||
|
label={field.label}
|
||||||
|
defaultValue={defaultValue as FieldFullNameValue | undefined}
|
||||||
|
onPersist={onPersist}
|
||||||
|
VariablePicker={VariablePicker}
|
||||||
|
/>
|
||||||
) : null;
|
) : null;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -0,0 +1,66 @@
|
|||||||
|
import { FormTextFieldInput } from '@/object-record/record-field/form-types/components/FormTextFieldInput';
|
||||||
|
import { StyledFormCompositeFieldInputContainer } from '@/object-record/record-field/form-types/components/StyledFormCompositeFieldInputContainer';
|
||||||
|
import { StyledFormFieldInputContainer } from '@/object-record/record-field/form-types/components/StyledFormFieldInputContainer';
|
||||||
|
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
|
||||||
|
import { FIRST_NAME_PLACEHOLDER_WITH_SPECIAL_CHARACTER_TO_AVOID_PASSWORD_MANAGERS } from '@/object-record/record-field/meta-types/input/constants/FirstNamePlaceholder';
|
||||||
|
import { LAST_NAME_PLACEHOLDER_WITH_SPECIAL_CHARACTER_TO_AVOID_PASSWORD_MANAGERS } from '@/object-record/record-field/meta-types/input/constants/LastNamePlaceholder';
|
||||||
|
import { FieldFullNameValue } from '@/object-record/record-field/types/FieldMetadata';
|
||||||
|
import { InputLabel } from '@/ui/input/components/InputLabel';
|
||||||
|
|
||||||
|
type FormFullNameFieldInputProps = {
|
||||||
|
label?: string;
|
||||||
|
defaultValue: FieldFullNameValue | undefined;
|
||||||
|
onPersist: (value: FieldFullNameValue) => void;
|
||||||
|
VariablePicker?: VariablePickerComponent;
|
||||||
|
readonly?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const FormFullNameFieldInput = ({
|
||||||
|
label,
|
||||||
|
defaultValue,
|
||||||
|
onPersist,
|
||||||
|
readonly,
|
||||||
|
VariablePicker,
|
||||||
|
}: FormFullNameFieldInputProps) => {
|
||||||
|
const handleFirstNameChange = (newText: string) => {
|
||||||
|
onPersist({
|
||||||
|
lastName: defaultValue?.lastName ?? '',
|
||||||
|
firstName: newText,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleLastNameChange = (newText: string) => {
|
||||||
|
onPersist({
|
||||||
|
firstName: defaultValue?.firstName ?? '',
|
||||||
|
lastName: newText,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledFormFieldInputContainer>
|
||||||
|
{label ? <InputLabel>{label}</InputLabel> : null}
|
||||||
|
<StyledFormCompositeFieldInputContainer>
|
||||||
|
<FormTextFieldInput
|
||||||
|
label="First Name"
|
||||||
|
defaultValue={defaultValue?.firstName}
|
||||||
|
onPersist={handleFirstNameChange}
|
||||||
|
placeholder={
|
||||||
|
FIRST_NAME_PLACEHOLDER_WITH_SPECIAL_CHARACTER_TO_AVOID_PASSWORD_MANAGERS
|
||||||
|
}
|
||||||
|
readonly={readonly}
|
||||||
|
VariablePicker={VariablePicker}
|
||||||
|
/>
|
||||||
|
<FormTextFieldInput
|
||||||
|
label="Last Name"
|
||||||
|
defaultValue={defaultValue?.lastName}
|
||||||
|
onPersist={handleLastNameChange}
|
||||||
|
placeholder={
|
||||||
|
LAST_NAME_PLACEHOLDER_WITH_SPECIAL_CHARACTER_TO_AVOID_PASSWORD_MANAGERS
|
||||||
|
}
|
||||||
|
readonly={readonly}
|
||||||
|
VariablePicker={VariablePicker}
|
||||||
|
/>
|
||||||
|
</StyledFormCompositeFieldInputContainer>
|
||||||
|
</StyledFormFieldInputContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
export const StyledFormCompositeFieldInputContainer = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: ${({ theme }) => theme.background.secondary};
|
||||||
|
border: 1px solid ${({ theme }) => theme.border.color.medium};
|
||||||
|
border-radius: ${({ theme }) => theme.border.radius.sm};
|
||||||
|
gap: ${({ theme }) => theme.spacing(2)};
|
||||||
|
padding: ${({ theme }) => theme.spacing(2)};
|
||||||
|
`;
|
||||||
@ -3,4 +3,5 @@ import styled from '@emotion/styled';
|
|||||||
export const StyledFormFieldInputContainer = styled.div`
|
export const StyledFormFieldInputContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
`;
|
`;
|
||||||
|
|||||||
@ -0,0 +1,31 @@
|
|||||||
|
import { Meta, StoryObj } from '@storybook/react';
|
||||||
|
import { within } from '@storybook/test';
|
||||||
|
import { FormFullNameFieldInput } from '../FormFullNameFieldInput';
|
||||||
|
|
||||||
|
const meta: Meta<typeof FormFullNameFieldInput> = {
|
||||||
|
title: 'UI/Data/Field/Form/Input/FormFullNameFieldInput',
|
||||||
|
component: FormFullNameFieldInput,
|
||||||
|
args: {},
|
||||||
|
argTypes: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
|
||||||
|
type Story = StoryObj<typeof FormFullNameFieldInput>;
|
||||||
|
|
||||||
|
export const Default: Story = {
|
||||||
|
args: {
|
||||||
|
label: 'Name',
|
||||||
|
defaultValue: {
|
||||||
|
firstName: 'John',
|
||||||
|
lastName: 'Doe',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
play: async ({ canvasElement }) => {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
await canvas.findByText('Name');
|
||||||
|
await canvas.findByText('First Name');
|
||||||
|
await canvas.findByText('Last Name');
|
||||||
|
},
|
||||||
|
};
|
||||||
@ -3,18 +3,14 @@ import { FieldDoubleText } from '@/object-record/record-field/types/FieldDoubleT
|
|||||||
import { DoubleTextInput } from '@/ui/field/input/components/DoubleTextInput';
|
import { DoubleTextInput } from '@/ui/field/input/components/DoubleTextInput';
|
||||||
import { FieldInputOverlay } from '@/ui/field/input/components/FieldInputOverlay';
|
import { FieldInputOverlay } from '@/ui/field/input/components/FieldInputOverlay';
|
||||||
|
|
||||||
|
import { FIRST_NAME_PLACEHOLDER_WITH_SPECIAL_CHARACTER_TO_AVOID_PASSWORD_MANAGERS } from '@/object-record/record-field/meta-types/input/constants/FirstNamePlaceholder';
|
||||||
|
import { LAST_NAME_PLACEHOLDER_WITH_SPECIAL_CHARACTER_TO_AVOID_PASSWORD_MANAGERS } from '@/object-record/record-field/meta-types/input/constants/LastNamePlaceholder';
|
||||||
import { isDoubleTextFieldEmpty } from '@/object-record/record-field/meta-types/input/utils/isDoubleTextFieldEmpty';
|
import { isDoubleTextFieldEmpty } from '@/object-record/record-field/meta-types/input/utils/isDoubleTextFieldEmpty';
|
||||||
import {
|
import {
|
||||||
FieldInputClickOutsideEvent,
|
FieldInputClickOutsideEvent,
|
||||||
FieldInputEvent,
|
FieldInputEvent,
|
||||||
} from './DateTimeFieldInput';
|
} from './DateTimeFieldInput';
|
||||||
|
|
||||||
const FIRST_NAME_PLACEHOLDER_WITH_SPECIAL_CHARACTER_TO_AVOID_PASSWORD_MANAGERS =
|
|
||||||
'First name';
|
|
||||||
|
|
||||||
const LAST_NAME_PLACEHOLDER_WITH_SPECIAL_CHARACTER_TO_AVOID_PASSWORD_MANAGERS =
|
|
||||||
'Last name';
|
|
||||||
|
|
||||||
type FullNameFieldInputProps = {
|
type FullNameFieldInputProps = {
|
||||||
onClickOutside?: FieldInputClickOutsideEvent;
|
onClickOutside?: FieldInputClickOutsideEvent;
|
||||||
onEnter?: FieldInputEvent;
|
onEnter?: FieldInputEvent;
|
||||||
|
|||||||
@ -0,0 +1,2 @@
|
|||||||
|
export const FIRST_NAME_PLACEHOLDER_WITH_SPECIAL_CHARACTER_TO_AVOID_PASSWORD_MANAGERS =
|
||||||
|
'First name';
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
export const LAST_NAME_PLACEHOLDER_WITH_SPECIAL_CHARACTER_TO_AVOID_PASSWORD_MANAGERS =
|
||||||
|
'Last name';
|
||||||
@ -1,4 +1,5 @@
|
|||||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||||
|
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||||
import { StyledDropdownButtonContainer } from '@/ui/layout/dropdown/components/StyledDropdownButtonContainer';
|
import { StyledDropdownButtonContainer } from '@/ui/layout/dropdown/components/StyledDropdownButtonContainer';
|
||||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||||
import { SearchVariablesDropdownFieldItems } from '@/workflow/search-variables/components/SearchVariablesDropdownFieldItems';
|
import { SearchVariablesDropdownFieldItems } from '@/workflow/search-variables/components/SearchVariablesDropdownFieldItems';
|
||||||
@ -26,7 +27,7 @@ const StyledDropdownVariableButtonContainer = styled(
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledDropdownComponetsContainer = styled.div`
|
const StyledDropdownComponentsContainer = styled(DropdownMenuItemsContainer)`
|
||||||
background-color: ${({ theme }) => theme.background.transparent.light};
|
background-color: ${({ theme }) => theme.background.transparent.light};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -136,9 +137,9 @@ const SearchVariablesDropdown = ({
|
|||||||
</StyledDropdownVariableButtonContainer>
|
</StyledDropdownVariableButtonContainer>
|
||||||
}
|
}
|
||||||
dropdownComponents={
|
dropdownComponents={
|
||||||
<StyledDropdownComponetsContainer>
|
<StyledDropdownComponentsContainer>
|
||||||
{renderSearchVariablesDropdownComponents()}
|
{renderSearchVariablesDropdownComponents()}
|
||||||
</StyledDropdownComponetsContainer>
|
</StyledDropdownComponentsContainer>
|
||||||
}
|
}
|
||||||
dropdownPlacement="bottom-end"
|
dropdownPlacement="bottom-end"
|
||||||
dropdownOffset={{ x: 0, y: 4 }}
|
dropdownOffset={{ x: 0, y: 4 }}
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader';
|
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader';
|
||||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
|
||||||
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
||||||
import {
|
import {
|
||||||
BaseOutputSchema,
|
BaseOutputSchema,
|
||||||
@ -100,8 +99,14 @@ export const SearchVariablesDropdownFieldItems = ({
|
|||||||
: options;
|
: options;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownMenuItemsContainer>
|
<>
|
||||||
<DropdownMenuHeader StartIcon={IconChevronLeft} onClick={goBack}>
|
<DropdownMenuHeader
|
||||||
|
StartIcon={IconChevronLeft}
|
||||||
|
onClick={goBack}
|
||||||
|
style={{
|
||||||
|
position: 'fixed',
|
||||||
|
}}
|
||||||
|
>
|
||||||
<OverflowingTextWithTooltip text={headerLabel} />
|
<OverflowingTextWithTooltip text={headerLabel} />
|
||||||
</DropdownMenuHeader>
|
</DropdownMenuHeader>
|
||||||
<HorizontalSeparator
|
<HorizontalSeparator
|
||||||
@ -128,6 +133,6 @@ export const SearchVariablesDropdownFieldItems = ({
|
|||||||
LeftIcon={value.icon ? getIcon(value.icon) : undefined}
|
LeftIcon={value.icon ? getIcon(value.icon) : undefined}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</DropdownMenuItemsContainer>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader';
|
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader';
|
||||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
|
||||||
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
||||||
import {
|
import {
|
||||||
OutputSchema,
|
OutputSchema,
|
||||||
@ -112,7 +111,7 @@ export const SearchVariablesDropdownObjectItems = ({
|
|||||||
: options;
|
: options;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownMenuItemsContainer>
|
<>
|
||||||
<DropdownMenuHeader StartIcon={IconChevronLeft} onClick={goBack}>
|
<DropdownMenuHeader StartIcon={IconChevronLeft} onClick={goBack}>
|
||||||
<OverflowingTextWithTooltip text={headerLabel} />
|
<OverflowingTextWithTooltip text={headerLabel} />
|
||||||
</DropdownMenuHeader>
|
</DropdownMenuHeader>
|
||||||
@ -154,6 +153,6 @@ export const SearchVariablesDropdownObjectItems = ({
|
|||||||
LeftIcon={value.icon ? getIcon(value.icon) : undefined}
|
LeftIcon={value.icon ? getIcon(value.icon) : undefined}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</DropdownMenuItemsContainer>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader';
|
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader';
|
||||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
|
||||||
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
||||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||||
import { StepOutputSchema } from '@/workflow/search-variables/types/StepOutputSchema';
|
import { StepOutputSchema } from '@/workflow/search-variables/types/StepOutputSchema';
|
||||||
@ -36,7 +35,7 @@ export const SearchVariablesDropdownWorkflowStepItems = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownMenuItemsContainer>
|
<>
|
||||||
<DropdownMenuHeader StartIcon={IconX} onClick={closeDropdown}>
|
<DropdownMenuHeader StartIcon={IconX} onClick={closeDropdown}>
|
||||||
<OverflowingTextWithTooltip text={'Select Step'} />
|
<OverflowingTextWithTooltip text={'Select Step'} />
|
||||||
</DropdownMenuHeader>
|
</DropdownMenuHeader>
|
||||||
@ -74,6 +73,6 @@ export const SearchVariablesDropdownWorkflowStepItems = ({
|
|||||||
hasSubMenu={false}
|
hasSubMenu={false}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</DropdownMenuItemsContainer>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { FormTextFieldInput } from '@/object-record/record-field/form-types/components/FormTextFieldInput';
|
import { FormTextFieldInput } from '@/object-record/record-field/form-types/components/FormTextFieldInput';
|
||||||
|
import { StyledFormCompositeFieldInputContainer } from '@/object-record/record-field/form-types/components/StyledFormCompositeFieldInputContainer';
|
||||||
import { useGetAvailablePackages } from '@/settings/serverless-functions/hooks/useGetAvailablePackages';
|
import { useGetAvailablePackages } from '@/settings/serverless-functions/hooks/useGetAvailablePackages';
|
||||||
import { useServerlessFunctionUpdateFormState } from '@/settings/serverless-functions/hooks/useServerlessFunctionUpdateFormState';
|
import { useServerlessFunctionUpdateFormState } from '@/settings/serverless-functions/hooks/useServerlessFunctionUpdateFormState';
|
||||||
import { useUpdateOneServerlessFunction } from '@/settings/serverless-functions/hooks/useUpdateOneServerlessFunction';
|
import { useUpdateOneServerlessFunction } from '@/settings/serverless-functions/hooks/useUpdateOneServerlessFunction';
|
||||||
@ -44,17 +45,6 @@ const StyledLabel = styled.div`
|
|||||||
margin-bottom: ${({ theme }) => theme.spacing(2)};
|
margin-bottom: ${({ theme }) => theme.spacing(2)};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledInputContainer = styled.div`
|
|
||||||
background: ${({ theme }) => theme.background.secondary};
|
|
||||||
border: 1px solid ${({ theme }) => theme.border.color.medium};
|
|
||||||
border-radius: ${({ theme }) => theme.border.radius.md};
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: ${({ theme }) => theme.spacing(2)};
|
|
||||||
padding: ${({ theme }) => theme.spacing(2)};
|
|
||||||
position: relative;
|
|
||||||
`;
|
|
||||||
|
|
||||||
type WorkflowEditActionFormServerlessFunctionProps = {
|
type WorkflowEditActionFormServerlessFunctionProps = {
|
||||||
action: WorkflowCodeAction;
|
action: WorkflowCodeAction;
|
||||||
actionOptions:
|
actionOptions:
|
||||||
@ -223,9 +213,9 @@ export const WorkflowEditActionFormServerlessFunction = ({
|
|||||||
return (
|
return (
|
||||||
<StyledContainer key={pathKey}>
|
<StyledContainer key={pathKey}>
|
||||||
<StyledLabel>{inputKey}</StyledLabel>
|
<StyledLabel>{inputKey}</StyledLabel>
|
||||||
<StyledInputContainer>
|
<StyledFormCompositeFieldInputContainer>
|
||||||
{renderFields(inputValue, currentPath, false)}
|
{renderFields(inputValue, currentPath, false)}
|
||||||
</StyledInputContainer>
|
</StyledFormCompositeFieldInputContainer>
|
||||||
</StyledContainer>
|
</StyledContainer>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user