Wrap Long text fields (textarea) (#8557)

Here we add the option for Text inputs to be wrapped, and to select on
how many lines text should be displayed.

Fix #7552

---------

Co-authored-by: guillim <guillaume@twenty.com>
This commit is contained in:
Guillim
2024-11-18 17:36:19 +01:00
committed by GitHub
parent 83b5eb69b0
commit 2f3c41620c
14 changed files with 235 additions and 27 deletions

View File

@ -7,6 +7,8 @@ import { SettingsDataModelPreviewFormCard } from '@/settings/data-model/componen
import { SETTINGS_FIELD_TYPE_CONFIGS } from '@/settings/data-model/constants/SettingsFieldTypeConfigs';
import { settingsDataModelFieldBooleanFormSchema } from '@/settings/data-model/fields/forms/boolean/components/SettingsDataModelFieldBooleanForm';
import { SettingsDataModelFieldBooleanSettingsFormCard } from '@/settings/data-model/fields/forms/boolean/components/SettingsDataModelFieldBooleanSettingsFormCard';
import { settingsDataModelFieldtextFormSchema } from '@/settings/data-model/fields/forms/components/text/SettingsDataModelFieldTextForm';
import { SettingsDataModelFieldTextSettingsFormCard } from '@/settings/data-model/fields/forms/components/text/SettingsDataModelFieldTextSettingsFormCard';
import { settingsDataModelFieldCurrencyFormSchema } from '@/settings/data-model/fields/forms/currency/components/SettingsDataModelFieldCurrencyForm';
import { SettingsDataModelFieldCurrencySettingsFormCard } from '@/settings/data-model/fields/forms/currency/components/SettingsDataModelFieldCurrencySettingsFormCard';
import { settingsDataModelFieldDateFormSchema } from '@/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm';
@ -58,6 +60,10 @@ const numberFieldFormSchema = z
.object({ type: z.literal(FieldMetadataType.Number) })
.merge(settingsDataModelFieldNumberFormSchema);
const textFieldFormSchema = z
.object({ type: z.literal(FieldMetadataType.Text) })
.merge(settingsDataModelFieldtextFormSchema);
const otherFieldsFormSchema = z.object({
type: z.enum(
Object.keys(
@ -70,6 +76,7 @@ const otherFieldsFormSchema = z.object({
FieldMetadataType.Date,
FieldMetadataType.DateTime,
FieldMetadataType.Number,
FieldMetadataType.Text,
]),
) as [FieldMetadataType, ...FieldMetadataType[]],
),
@ -86,6 +93,7 @@ export const settingsDataModelFieldSettingsFormSchema = z.discriminatedUnion(
selectFieldFormSchema,
multiSelectFieldFormSchema,
numberFieldFormSchema,
textFieldFormSchema,
otherFieldsFormSchema,
],
);
@ -183,6 +191,15 @@ export const SettingsDataModelFieldSettingsFormCard = ({
);
}
if (fieldMetadataItem.type === FieldMetadataType.Text) {
return (
<SettingsDataModelFieldTextSettingsFormCard
fieldMetadataItem={fieldMetadataItem}
objectMetadataItem={objectMetadataItem}
/>
);
}
if (
fieldMetadataItem.type === FieldMetadataType.Select ||
fieldMetadataItem.type === FieldMetadataType.MultiSelect

View File

@ -0,0 +1,91 @@
import { Controller, useFormContext } from 'react-hook-form';
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { Select } from '@/ui/input/components/Select';
import styled from '@emotion/styled';
import { CardContent } from 'twenty-ui';
import { z } from 'zod';
const StyledFormCardTitle = styled.div`
color: ${({ theme }) => theme.font.color.light};
font-size: ${({ theme }) => theme.font.size.xs};
font-weight: ${({ theme }) => theme.font.weight.semiBold};
margin-bottom: ${({ theme }) => theme.spacing(1)};
`;
type SettingsDataModelFieldTextFormProps = {
disabled?: boolean;
fieldMetadataItem: Pick<
FieldMetadataItem,
'icon' | 'label' | 'type' | 'defaultValue' | 'settings'
>;
};
export const textFieldDefaultValueSchema = z.object({
displayedMaxRows: z.number().nullable(),
});
export const settingsDataModelFieldtextFormSchema = z.object({
settings: textFieldDefaultValueSchema,
});
export type SettingsDataModelFieldTextFormValues = z.infer<
typeof settingsDataModelFieldtextFormSchema
>;
export const SettingsDataModelFieldTextForm = ({
disabled,
fieldMetadataItem,
}: SettingsDataModelFieldTextFormProps) => {
const { control } = useFormContext<SettingsDataModelFieldTextFormValues>();
return (
<CardContent>
<Controller
name="settings"
defaultValue={{
displayedMaxRows: fieldMetadataItem?.settings?.displayedMaxRows || 0,
}}
control={control}
render={({ field: { onChange, value } }) => {
const displayedMaxRows = value?.displayedMaxRows ?? 0;
return (
<>
<StyledFormCardTitle>Wrap on record pages</StyledFormCardTitle>
<Select
disabled={disabled}
dropdownId="selectTextWrap"
options={[
{
label: 'Deactivated',
value: 0,
},
{
label: 'First 2 lines',
value: 2,
},
{
label: 'First 5 lines',
value: 5,
},
{
label: 'First 10 lines',
value: 10,
},
{
label: 'All lines',
value: 99,
},
]}
value={displayedMaxRows}
onChange={(value) => onChange({ displayedMaxRows: value })}
withSearchInput={false}
dropdownWidthAuto={true}
/>
</>
);
}}
/>
</CardContent>
);
};

View File

@ -0,0 +1,45 @@
import styled from '@emotion/styled';
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { SettingsDataModelPreviewFormCard } from '@/settings/data-model/components/SettingsDataModelPreviewFormCard';
import { SettingsDataModelFieldTextForm } from '@/settings/data-model/fields/forms/components/text/SettingsDataModelFieldTextForm';
import {
SettingsDataModelFieldPreviewCard,
SettingsDataModelFieldPreviewCardProps,
} from '@/settings/data-model/fields/preview/components/SettingsDataModelFieldPreviewCard';
type SettingsDataModelFieldTextSettingsFormCardProps = {
disabled?: boolean;
fieldMetadataItem: Pick<
FieldMetadataItem,
'icon' | 'label' | 'type' | 'defaultValue'
>;
} & Pick<SettingsDataModelFieldPreviewCardProps, 'objectMetadataItem'>;
const StyledFieldPreviewCard = styled(SettingsDataModelFieldPreviewCard)`
flex: 1 1 100%;
`;
export const SettingsDataModelFieldTextSettingsFormCard = ({
disabled,
fieldMetadataItem,
objectMetadataItem,
}: SettingsDataModelFieldTextSettingsFormCardProps) => {
return (
<SettingsDataModelPreviewFormCard
preview={
<StyledFieldPreviewCard
fieldMetadataItem={fieldMetadataItem}
objectMetadataItem={objectMetadataItem}
/>
}
form={
<SettingsDataModelFieldTextForm
disabled={disabled}
fieldMetadataItem={fieldMetadataItem}
/>
}
/>
);
};

View File

@ -30,18 +30,21 @@ export type SettingsDataModelFieldPreviewProps = {
};
const StyledFieldPreview = styled.div<{ shrink?: boolean }>`
align-items: center;
align-items: flex-start;
background-color: ${({ theme }) => theme.background.primary};
border: 1px solid ${({ theme }) => theme.border.color.medium};
border-radius: ${({ theme }) => theme.border.radius.sm};
display: flex;
gap: ${({ theme }) => theme.spacing(2)};
height: ${({ theme }) => theme.spacing(8)};
height: fit-content;
line-height: 24px;
overflow: hidden;
padding: 0
${({ shrink, theme }) => (shrink ? theme.spacing(1) : theme.spacing(2))};
white-space: nowrap;
margin-top: ${({ theme }) => theme.spacing(2)};
padding-top: ${({ theme }) => theme.spacing(2)};
padding-bottom: ${({ theme }) => theme.spacing(2)};
`;
const StyledFieldLabel = styled.div`