From 2f5dc265458e3a68626b3d6fcc8724e3b9f200a4 Mon Sep 17 00:00:00 2001 From: nitin <142569587+ehconitin@users.noreply.github.com> Date: Mon, 18 Nov 2024 14:52:33 +0530 Subject: [PATCH] Settings Option Card component (#8456) fixes - #8195 --------- Co-authored-by: Charles Bochet --- .../display/typography/components/H2Title.tsx | 6 +- ...SettingsAccountsCalendarChannelDetails.tsx | 9 +- .../SettingsAccountsMessageChannelDetails.tsx | 12 +- .../components/AdvancedSettingsWrapper.tsx | 68 +++++ .../settings/components/SettingsCounter.tsx | 103 ++++++++ .../SettingsNavigationDrawerItems.tsx | 4 +- .../components/SettingsOptionCardContent.tsx | 95 ------- .../SettingsOptionCardContentBase.tsx | 37 +++ .../SettingsOptionCardContentCounter.tsx | 57 ++++ .../SettingsOptionCardContentSelect.tsx | 75 ++++++ .../SettingsOptionCardContentToggle.tsx | 89 +++++++ .../SettingsOptionIconCustomizer.tsx | 33 +++ .../SettingsDataModelFieldBooleanForm.tsx | 80 +++--- .../SettingsDataModelFieldToggle.tsx | 91 ------- .../SettingsDataModelFieldCurrencyForm.tsx | 22 +- .../SettingsDataModelFieldDateForm.tsx | 41 ++- ...ttingsDataModelFieldNumberDecimalInput.tsx | 167 ------------ .../SettingsDataModelFieldNumberForm.tsx | 108 ++++---- .../SettingsDataModelFieldSelectForm.tsx | 31 +-- ...tingsDataModelFieldSelectFormOptionRow.tsx | 56 ++-- .../SettingsDataModelObjectAboutForm.tsx | 248 ++++++++---------- .../SyncObjectLabelAndNameToggle.tsx | 80 ------ .../settings/hooks/useExpandedAnimation.ts | 63 +++++ .../hooks/useExpandedHeightAnimation.ts | 52 ---- .../SettingsSecurityOptionsList.tsx | 7 +- .../modules/ui/input/components/Select.tsx | 14 +- .../ui/input/components/SelectControl.tsx | 11 +- .../components/__stories__/Select.stories.tsx | 4 +- .../src/pages/settings/SettingsWorkspace.tsx | 2 +- .../settings/security/SettingsSecurity.tsx | 69 +++-- .../icon/components/IllustrationIconArray.tsx | 4 +- .../IllustrationIconCalendarEvent.tsx | 4 +- .../IllustrationIconCalendarTime.tsx | 4 +- .../components/IllustrationIconCurrency.tsx | 4 +- .../icon/components/IllustrationIconJson.tsx | 4 +- ...nIconLink.tsx => IllustrationIconLink.tsx} | 4 +- .../icon/components/IllustrationIconMail.tsx | 4 +- .../components/IllustrationIconManyToMany.tsx | 4 +- .../icon/components/IllustrationIconMap.tsx | 4 +- .../components/IllustrationIconNumbers.tsx | 4 +- .../components/IllustrationIconOneToMany.tsx | 4 +- .../components/IllustrationIconOneToOne.tsx | 4 +- .../icon/components/IllustrationIconPhone.tsx | 4 +- .../components/IllustrationIconSetting.tsx | 4 +- .../icon/components/IllustrationIconStar.tsx | 4 +- .../icon/components/IllustrationIconTag.tsx | 4 +- .../icon/components/IllustrationIconTags.tsx | 4 +- .../icon/components/IllustrationIconText.tsx | 4 +- .../components/IllustrationIconToggle.tsx | 4 +- .../icon/components/IllustrationIconUid.tsx | 4 +- .../icon/components/IllustrationIconUser.tsx | 4 +- .../display/icon/components/TablerIcons.ts | 3 + packages/twenty-ui/src/display/index.ts | 2 +- .../display/typography/components/H2Title.tsx | 6 +- .../theme/constants/IllustrationIconDark.ts | 11 +- .../theme/constants/IllustrationIconLight.ts | 11 +- 56 files changed, 931 insertions(+), 920 deletions(-) create mode 100644 packages/twenty-front/src/modules/settings/components/AdvancedSettingsWrapper.tsx create mode 100644 packages/twenty-front/src/modules/settings/components/SettingsCounter.tsx delete mode 100644 packages/twenty-front/src/modules/settings/components/SettingsOptionCardContent.tsx create mode 100644 packages/twenty-front/src/modules/settings/components/SettingsOptions/SettingsOptionCardContentBase.tsx create mode 100644 packages/twenty-front/src/modules/settings/components/SettingsOptions/SettingsOptionCardContentCounter.tsx create mode 100644 packages/twenty-front/src/modules/settings/components/SettingsOptions/SettingsOptionCardContentSelect.tsx create mode 100644 packages/twenty-front/src/modules/settings/components/SettingsOptions/SettingsOptionCardContentToggle.tsx create mode 100644 packages/twenty-front/src/modules/settings/components/SettingsOptions/SettingsOptionIconCustomizer.tsx delete mode 100644 packages/twenty-front/src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldToggle.tsx delete mode 100644 packages/twenty-front/src/modules/settings/data-model/fields/forms/number/components/SettingsDataModelFieldNumberDecimalInput.tsx delete mode 100644 packages/twenty-front/src/modules/settings/data-model/objects/forms/components/SyncObjectLabelAndNameToggle.tsx create mode 100644 packages/twenty-front/src/modules/settings/hooks/useExpandedAnimation.ts delete mode 100644 packages/twenty-front/src/modules/settings/hooks/useExpandedHeightAnimation.ts rename packages/twenty-ui/src/display/icon/components/{llustrationIconLink.tsx => IllustrationIconLink.tsx} (93%) diff --git a/packages/twenty-chrome-extension/src/options/modules/ui/display/typography/components/H2Title.tsx b/packages/twenty-chrome-extension/src/options/modules/ui/display/typography/components/H2Title.tsx index 2a3cfbf34..3d1dd2706 100644 --- a/packages/twenty-chrome-extension/src/options/modules/ui/display/typography/components/H2Title.tsx +++ b/packages/twenty-chrome-extension/src/options/modules/ui/display/typography/components/H2Title.tsx @@ -3,7 +3,7 @@ import styled from '@emotion/styled'; type H2TitleProps = { title: string; description?: string; - addornment?: React.ReactNode; + adornment?: React.ReactNode; }; const StyledContainer = styled.div` @@ -33,11 +33,11 @@ const StyledDescription = styled.h3` margin-top: ${({ theme }) => theme.spacing(3)}; `; -export const H2Title = ({ title, description, addornment }: H2TitleProps) => ( +export const H2Title = ({ title, description, adornment }: H2TitleProps) => ( {title} - {addornment} + {adornment} {description && {description}} diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarChannelDetails.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarChannelDetails.tsx index d017bf42d..13039837c 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarChannelDetails.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarChannelDetails.tsx @@ -2,10 +2,10 @@ import { CalendarChannel } from '@/accounts/types/CalendarChannel'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord'; import { SettingsAccountsEventVisibilitySettingsCard } from '@/settings/accounts/components/SettingsAccountsCalendarVisibilitySettingsCard'; -import { SettingsOptionCardContent } from '@/settings/components/SettingsOptionCardContent'; +import { SettingsOptionCardContentToggle } from '@/settings/components/SettingsOptions/SettingsOptionCardContentToggle'; import styled from '@emotion/styled'; import { Section } from '@react-email/components'; -import { Card, H2Title } from 'twenty-ui'; +import { Card, H2Title, IconUserPlus } from 'twenty-ui'; import { CalendarChannelVisibility } from '~/generated-metadata/graphql'; const StyledDetailsContainer = styled.div` @@ -63,8 +63,9 @@ export const SettingsAccountsCalendarChannelDetails = ({ title="Contact auto-creation" description="Automatically create contacts for people you've participated in an event with." /> - - +
- - + - theme.spacing(-6)}; + position: absolute; + top: 0; +`; + +const StyledContent = styled.div` + width: 100%; +`; +const StyledIconTool = styled(IconTool)` + margin-right: ${({ theme }) => theme.spacing(0.5)}; +`; + +type AdvancedSettingsWrapperProps = { + children: React.ReactNode; + dimension?: 'width' | 'height'; + hideIcon?: boolean; +}; + +export const AdvancedSettingsWrapper = ({ + children, + dimension = 'height', + hideIcon = false, +}: AdvancedSettingsWrapperProps) => { + const isAdvancedModeEnabled = useRecoilValue(isAdvancedModeEnabledState); + const { contentRef, motionAnimationVariants } = useExpandedAnimation( + isAdvancedModeEnabled, + dimension, + ); + + return ( + + {isAdvancedModeEnabled && ( + + + {!hideIcon && ( + + + + )} + {children} + + + )} + + ); +}; diff --git a/packages/twenty-front/src/modules/settings/components/SettingsCounter.tsx b/packages/twenty-front/src/modules/settings/components/SettingsCounter.tsx new file mode 100644 index 000000000..c9c7ce309 --- /dev/null +++ b/packages/twenty-front/src/modules/settings/components/SettingsCounter.tsx @@ -0,0 +1,103 @@ +import { TextInput } from '@/ui/input/components/TextInput'; +import styled from '@emotion/styled'; +import { Button, IconMinus, IconPlus } from 'twenty-ui'; +import { castAsNumberOrNull } from '~/utils/cast-as-number-or-null'; + +type SettingsCounterProps = { + value: number; + onChange: (value: number) => void; + minValue?: number; + maxValue?: number; + disabled?: boolean; +}; + +const StyledCounterContainer = styled.div` + align-items: center; + display: flex; + gap: ${({ theme }) => theme.spacing(1)}; + margin-left: auto; + width: ${({ theme }) => theme.spacing(30)}; +`; + +const StyledTextInput = styled(TextInput)` + width: ${({ theme }) => theme.spacing(16)}; + input { + width: ${({ theme }) => theme.spacing(16)}; + height: ${({ theme }) => theme.spacing(6)}; + text-align: center; + font-weight: ${({ theme }) => theme.font.weight.medium}; + } +`; + +const StyledControlButton = styled(Button)` + height: ${({ theme }) => theme.spacing(6)}; + width: ${({ theme }) => theme.spacing(6)}; + padding: 0; + justify-content: center; + svg { + height: ${({ theme }) => theme.spacing(4)}; + width: ${({ theme }) => theme.spacing(4)}; + } +`; + +export const SettingsCounter = ({ + value, + onChange, + minValue = 0, + maxValue = 100, + disabled = false, +}: SettingsCounterProps) => { + const handleIncrementCounter = () => { + if (value < maxValue) { + onChange(value + 1); + } + }; + + const handleDecrementCounter = () => { + if (value > minValue) { + onChange(value - 1); + } + }; + + const handleTextInputChange = (value: string) => { + const castedNumber = castAsNumberOrNull(value); + if (castedNumber === null) { + onChange(minValue); + return; + } + + if (castedNumber < minValue) { + return; + } + + if (castedNumber > maxValue) { + onChange(maxValue); + return; + } + onChange(castedNumber); + }; + + return ( + + + + + + ); +}; diff --git a/packages/twenty-front/src/modules/settings/components/SettingsNavigationDrawerItems.tsx b/packages/twenty-front/src/modules/settings/components/SettingsNavigationDrawerItems.tsx index f762df6e8..c7d8569cf 100644 --- a/packages/twenty-front/src/modules/settings/components/SettingsNavigationDrawerItems.tsx +++ b/packages/twenty-front/src/modules/settings/components/SettingsNavigationDrawerItems.tsx @@ -23,7 +23,7 @@ import { import { useAuth } from '@/auth/hooks/useAuth'; import { billingState } from '@/client-config/states/billingState'; import { SettingsNavigationDrawerItem } from '@/settings/components/SettingsNavigationDrawerItem'; -import { useExpandedHeightAnimation } from '@/settings/hooks/useExpandedHeightAnimation'; +import { useExpandedAnimation } from '@/settings/hooks/useExpandedAnimation'; import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath'; import { SettingsPath } from '@/types/SettingsPath'; import { @@ -69,7 +69,7 @@ const StyledIconTool = styled(IconTool)` export const SettingsNavigationDrawerItems = () => { const isAdvancedModeEnabled = useRecoilValue(isAdvancedModeEnabledState); - const { contentRef, motionAnimationVariants } = useExpandedHeightAnimation( + const { contentRef, motionAnimationVariants } = useExpandedAnimation( isAdvancedModeEnabled, ); const { signOut } = useAuth(); diff --git a/packages/twenty-front/src/modules/settings/components/SettingsOptionCardContent.tsx b/packages/twenty-front/src/modules/settings/components/SettingsOptionCardContent.tsx deleted file mode 100644 index 3628119fb..000000000 --- a/packages/twenty-front/src/modules/settings/components/SettingsOptionCardContent.tsx +++ /dev/null @@ -1,95 +0,0 @@ -import { useTheme } from '@emotion/react'; -import styled from '@emotion/styled'; - -import { useId } from 'react'; -import { CardContent, IconComponent, Toggle } from 'twenty-ui'; - -type SettingsOptionCardContentProps = { - Icon?: IconComponent; - title: React.ReactNode; - description: string; - divider?: boolean; - checked: boolean; - onChange: (checked: boolean) => void; -}; - -const StyledCardContent = styled(CardContent)` - align-items: center; - display: flex; - gap: ${({ theme }) => theme.spacing(4)}; - cursor: pointer; - position: relative; - - &:hover { - background: ${({ theme }) => theme.background.transparent.lighter}; - } -`; - -const StyledTitle = styled.div` - color: ${({ theme }) => theme.font.color.primary}; - font-weight: ${({ theme }) => theme.font.weight.medium}; - margin-bottom: ${({ theme }) => theme.spacing(2)}; -`; - -const StyledDescription = styled.div` - color: ${({ theme }) => theme.font.color.tertiary}; - font-size: ${({ theme }) => theme.font.size.sm}; -`; - -const StyledIcon = styled.div` - align-items: center; - border: 2px solid ${({ theme }) => theme.border.color.light}; - border-radius: ${({ theme }) => theme.border.radius.sm}; - background-color: ${({ theme }) => theme.background.primary}; - display: flex; - height: ${({ theme }) => theme.spacing(8)}; - justify-content: center; - width: ${({ theme }) => theme.spacing(8)}; - min-width: ${({ theme }) => theme.icon.size.md}; -`; - -const StyledToggle = styled(Toggle)` - margin-left: auto; -`; - -const StyledCover = styled.span` - cursor: pointer; - inset: 0; - position: absolute; -`; - -export const SettingsOptionCardContent = ({ - Icon, - title, - description, - divider, - checked, - onChange, -}: SettingsOptionCardContentProps) => { - const theme = useTheme(); - - const toggleId = useId(); - - return ( - - {Icon && ( - - - - )} - -
- - - - {description} -
- - -
- ); -}; diff --git a/packages/twenty-front/src/modules/settings/components/SettingsOptions/SettingsOptionCardContentBase.tsx b/packages/twenty-front/src/modules/settings/components/SettingsOptions/SettingsOptionCardContentBase.tsx new file mode 100644 index 000000000..c89ac354a --- /dev/null +++ b/packages/twenty-front/src/modules/settings/components/SettingsOptions/SettingsOptionCardContentBase.tsx @@ -0,0 +1,37 @@ +import styled from '@emotion/styled'; +import { CardContent } from 'twenty-ui'; + +type StyledCardContentProps = { + disabled?: boolean; + divider?: boolean; +}; + +export const StyledSettingsOptionCardContent = styled( + CardContent, +)` + align-items: center; + display: flex; + gap: ${({ theme }) => theme.spacing(4)}; +`; +export const StyledSettingsOptionCardIcon = styled.div` + align-items: center; + border: 2px solid ${({ theme }) => theme.border.color.light}; + border-radius: ${({ theme }) => theme.border.radius.sm}; + background-color: ${({ theme }) => theme.background.primary}; + display: flex; + height: ${({ theme }) => theme.spacing(8)}; + justify-content: center; + width: ${({ theme }) => theme.spacing(8)}; + min-width: ${({ theme }) => theme.icon.size.md}; +`; + +export const StyledSettingsOptionCardTitle = styled.div` + color: ${({ theme }) => theme.font.color.primary}; + font-weight: ${({ theme }) => theme.font.weight.medium}; + margin-bottom: ${({ theme }) => theme.spacing(1)}; +`; + +export const StyledSettingsOptionCardDescription = styled.div` + color: ${({ theme }) => theme.font.color.tertiary}; + font-size: ${({ theme }) => theme.font.size.sm}; +`; diff --git a/packages/twenty-front/src/modules/settings/components/SettingsOptions/SettingsOptionCardContentCounter.tsx b/packages/twenty-front/src/modules/settings/components/SettingsOptions/SettingsOptionCardContentCounter.tsx new file mode 100644 index 000000000..e0d63e22b --- /dev/null +++ b/packages/twenty-front/src/modules/settings/components/SettingsOptions/SettingsOptionCardContentCounter.tsx @@ -0,0 +1,57 @@ +import { SettingsCounter } from '@/settings/components/SettingsCounter'; +import { + StyledSettingsOptionCardContent, + StyledSettingsOptionCardDescription, + StyledSettingsOptionCardIcon, + StyledSettingsOptionCardTitle, +} from '@/settings/components/SettingsOptions/SettingsOptionCardContentBase'; +import { SettingsOptionIconCustomizer } from '@/settings/components/SettingsOptions/SettingsOptionIconCustomizer'; +import { IconComponent } from 'twenty-ui'; + +type SettingsOptionCardContentCounterProps = { + Icon?: IconComponent; + title: React.ReactNode; + description?: string; + divider?: boolean; + disabled?: boolean; + value: number; + onChange: (value: number) => void; + minValue?: number; + maxValue?: number; +}; + +export const SettingsOptionCardContentCounter = ({ + Icon, + title, + description, + divider, + disabled = false, + value, + onChange, + minValue, + maxValue, +}: SettingsOptionCardContentCounterProps) => { + return ( + + {Icon && ( + + + + )} +
+ {title} + {description && ( + + {description} + + )} +
+ +
+ ); +}; diff --git a/packages/twenty-front/src/modules/settings/components/SettingsOptions/SettingsOptionCardContentSelect.tsx b/packages/twenty-front/src/modules/settings/components/SettingsOptions/SettingsOptionCardContentSelect.tsx new file mode 100644 index 000000000..f84c54ec4 --- /dev/null +++ b/packages/twenty-front/src/modules/settings/components/SettingsOptions/SettingsOptionCardContentSelect.tsx @@ -0,0 +1,75 @@ +import { + StyledSettingsOptionCardContent, + StyledSettingsOptionCardDescription, + StyledSettingsOptionCardIcon, + StyledSettingsOptionCardTitle, +} from '@/settings/components/SettingsOptions/SettingsOptionCardContentBase'; +import { SettingsOptionIconCustomizer } from '@/settings/components/SettingsOptions/SettingsOptionIconCustomizer'; +import { Select } from '@/ui/input/components/Select'; +import styled from '@emotion/styled'; +import { IconComponent } from 'twenty-ui'; + +const StyledSettingsOptionCardSelect = styled(Select)` + margin-left: auto; + width: 120px; +`; + +type SelectValue = string | number | boolean | null; + +type SettingsOptionCardContentSelectProps = { + Icon?: IconComponent; + title: React.ReactNode; + description?: string; + divider?: boolean; + disabled?: boolean; + value: Value; + onChange: (value: SelectValue) => void; + options: { + value: Value; + label: string; + Icon?: IconComponent; + }[]; + selectClassName?: string; + dropdownId: string; + fullWidth?: boolean; +}; + +export const SettingsOptionCardContentSelect = ({ + Icon, + title, + description, + divider, + disabled = false, + value, + onChange, + options, + selectClassName, + dropdownId, + fullWidth, +}: SettingsOptionCardContentSelectProps) => { + return ( + + {Icon && ( + + + + )} +
+ {title} + + {description} + +
+ +
+ ); +}; diff --git a/packages/twenty-front/src/modules/settings/components/SettingsOptions/SettingsOptionCardContentToggle.tsx b/packages/twenty-front/src/modules/settings/components/SettingsOptions/SettingsOptionCardContentToggle.tsx new file mode 100644 index 000000000..53f3df5f4 --- /dev/null +++ b/packages/twenty-front/src/modules/settings/components/SettingsOptions/SettingsOptionCardContentToggle.tsx @@ -0,0 +1,89 @@ +import { + StyledSettingsOptionCardContent, + StyledSettingsOptionCardDescription, + StyledSettingsOptionCardIcon, + StyledSettingsOptionCardTitle, +} from '@/settings/components/SettingsOptions/SettingsOptionCardContentBase'; +import { SettingsOptionIconCustomizer } from '@/settings/components/SettingsOptions/SettingsOptionIconCustomizer'; +import { useTheme } from '@emotion/react'; +import styled from '@emotion/styled'; +import { useId } from 'react'; +import { IconComponent, Toggle } from 'twenty-ui'; + +const StyledSettingsOptionCardToggleContent = styled( + StyledSettingsOptionCardContent, +)` + cursor: ${({ disabled }) => (disabled ? 'default' : 'pointer')}; + position: relative; + pointer-events: ${({ disabled }) => (disabled ? 'none' : 'auto')}; + + &:hover { + background: ${({ theme }) => theme.background.transparent.lighter}; + } +`; + +const StyledSettingsOptionCardToggleButton = styled(Toggle)` + margin-left: auto; +`; + +const StyledSettingsOptionCardToggleCover = styled.span` + cursor: pointer; + inset: 0; + position: absolute; +`; + +type SettingsOptionCardContentToggleProps = { + Icon?: IconComponent; + title: React.ReactNode; + description?: string; + divider?: boolean; + disabled?: boolean; + advancedMode?: boolean; + checked: boolean; + onChange: (checked: boolean) => void; +}; + +export const SettingsOptionCardContentToggle = ({ + Icon, + title, + description, + divider, + disabled = false, + advancedMode = false, + checked, + onChange, +}: SettingsOptionCardContentToggleProps) => { + const theme = useTheme(); + const toggleId = useId(); + + return ( + + {Icon && ( + + + + )} +
+ + + + + {description} + +
+ +
+ ); +}; diff --git a/packages/twenty-front/src/modules/settings/components/SettingsOptions/SettingsOptionIconCustomizer.tsx b/packages/twenty-front/src/modules/settings/components/SettingsOptions/SettingsOptionIconCustomizer.tsx new file mode 100644 index 000000000..1f576bb88 --- /dev/null +++ b/packages/twenty-front/src/modules/settings/components/SettingsOptions/SettingsOptionIconCustomizer.tsx @@ -0,0 +1,33 @@ +import { useTheme } from '@emotion/react'; +import styled from '@emotion/styled'; +import { IconComponent } from 'twenty-ui'; + +type SettingsOptionIconCustomizerProps = { + Icon: IconComponent; + zoom?: number; + rotate?: number; +}; + +const StyledIconCustomizer = styled.div<{ zoom: number; rotate: number }>` + display: inline-flex; + align-items: center; + justify-content: center; + transform: scale(${({ zoom }) => zoom}) rotate(${({ rotate }) => rotate}deg); +`; + +export const SettingsOptionIconCustomizer = ({ + Icon, + zoom = 1, + rotate = -4, +}: SettingsOptionIconCustomizerProps) => { + const theme = useTheme(); + return ( + + + + ); +}; diff --git a/packages/twenty-front/src/modules/settings/data-model/fields/forms/boolean/components/SettingsDataModelFieldBooleanForm.tsx b/packages/twenty-front/src/modules/settings/data-model/fields/forms/boolean/components/SettingsDataModelFieldBooleanForm.tsx index 106fbac9a..4e50078d7 100644 --- a/packages/twenty-front/src/modules/settings/data-model/fields/forms/boolean/components/SettingsDataModelFieldBooleanForm.tsx +++ b/packages/twenty-front/src/modules/settings/data-model/fields/forms/boolean/components/SettingsDataModelFieldBooleanForm.tsx @@ -1,11 +1,10 @@ -import styled from '@emotion/styled'; import { Controller, useFormContext } from 'react-hook-form'; -import { IconCheck, IconX, CardContent } from 'twenty-ui'; +import { IconCheck, IconX } from 'twenty-ui'; import { z } from 'zod'; import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; +import { SettingsOptionCardContentSelect } from '@/settings/components/SettingsOptions/SettingsOptionCardContentSelect'; import { useBooleanSettingsFormInitialValues } from '@/settings/data-model/fields/forms/boolean/hooks/useBooleanSettingsFormInitialValues'; -import { Select } from '@/ui/input/components/Select'; import { isDefined } from '~/utils/isDefined'; export const settingsDataModelFieldBooleanFormSchema = z.object({ @@ -21,18 +20,6 @@ type SettingsDataModelFieldBooleanFormProps = { fieldMetadataItem: Pick; }; -const StyledContainer = styled(CardContent)` - padding-bottom: ${({ theme }) => theme.spacing(3.5)}; -`; - -const StyledLabel = styled.span` - color: ${({ theme }) => theme.font.color.light}; - display: block; - font-size: ${({ theme }) => theme.font.size.xs}; - font-weight: ${({ theme }) => theme.font.weight.semiBold}; - margin-bottom: 6px; -`; - export const SettingsDataModelFieldBooleanForm = ({ className, fieldMetadataItem, @@ -45,37 +32,36 @@ export const SettingsDataModelFieldBooleanForm = ({ }); return ( - - Default Value - ( - )} /> - + ); }; diff --git a/packages/twenty-front/src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm.tsx b/packages/twenty-front/src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm.tsx index c90fba312..c3f109289 100644 --- a/packages/twenty-front/src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm.tsx +++ b/packages/twenty-front/src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm.tsx @@ -2,10 +2,9 @@ import { Controller, useFormContext } from 'react-hook-form'; import { z } from 'zod'; import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; -import { StyledFormCardTitle } from '@/settings/data-model/fields/components/StyledFormCardTitle'; -import { SettingsDataModelFieldToggle } from '@/settings/data-model/fields/forms/components/SettingsDataModelFieldToggle'; +import { SettingsOptionCardContentToggle } from '@/settings/components/SettingsOptions/SettingsOptionCardContentToggle'; import { useDateSettingsFormInitialValues } from '@/settings/data-model/fields/forms/date/hooks/useDateSettingsFormInitialValues'; -import { IconClockShare, CardContent } from 'twenty-ui'; +import { IconSlash } from 'twenty-ui'; export const settingsDataModelFieldDateFormSchema = z.object({ settings: z @@ -36,27 +35,19 @@ export const SettingsDataModelFieldDateForm = ({ }); return ( - - ( - <> - Options - - - )} - /> - + ( + + )} + /> ); }; diff --git a/packages/twenty-front/src/modules/settings/data-model/fields/forms/number/components/SettingsDataModelFieldNumberDecimalInput.tsx b/packages/twenty-front/src/modules/settings/data-model/fields/forms/number/components/SettingsDataModelFieldNumberDecimalInput.tsx deleted file mode 100644 index ce67a9bda..000000000 --- a/packages/twenty-front/src/modules/settings/data-model/fields/forms/number/components/SettingsDataModelFieldNumberDecimalInput.tsx +++ /dev/null @@ -1,167 +0,0 @@ -import styled from '@emotion/styled'; - -import { TextInput } from '@/ui/input/components/TextInput'; -import { Button, IconInfoCircle, IconMinus, IconPlus } from 'twenty-ui'; -import { castAsNumberOrNull } from '~/utils/cast-as-number-or-null'; - -type SettingsDataModelFieldNumberDecimalsInputProps = { - value: number; - onChange: (value: number) => void; - disabled?: boolean; -}; - -const StyledCounterContainer = styled.div` - align-items: center; - background: ${({ theme }) => theme.background.noisy}; - border: 1px solid ${({ theme }) => theme.border.color.medium}; - border-radius: 4px; - display: flex; - flex-direction: column; - flex: 1; - gap: ${({ theme }) => theme.spacing(1)}; - justify-content: center; -`; - -const StyledExampleText = styled.div` - color: ${({ theme }) => theme.font.color.primary}; - width: 100%; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - font-weight: ${({ theme }) => theme.font.weight.regular}; -`; - -const StyledCounterControlsIcons = styled.div` - align-items: center; - display: flex; - gap: ${({ theme }) => theme.spacing(2)}; -`; - -const StyledCounterInnerContainer = styled.div` - align-items: center; - align-self: stretch; - display: flex; - gap: ${({ theme }) => theme.spacing(1)}; - padding: ${({ theme }) => theme.spacing(2)}; - height: 24px; -`; - -const StyledTextInput = styled(TextInput)` - width: ${({ theme }) => theme.spacing(16)}; - input { - width: ${({ theme }) => theme.spacing(16)}; - height: ${({ theme }) => theme.spacing(6)}; - text-align: center; - font-weight: ${({ theme }) => theme.font.weight.medium}; - background: ${({ theme }) => theme.background.noisy}; - } - input ~ div { - padding-right: ${({ theme }) => theme.spacing(0)}; - border-radius: ${({ theme }) => theme.spacing(1)}; - background: ${({ theme }) => theme.background.noisy}; - } -`; - -const StyledTitle = 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)}; -`; - -const StyledControlButton = styled(Button)` - height: ${({ theme }) => theme.spacing(6)}; - width: ${({ theme }) => theme.spacing(6)}; - padding: 0; - justify-content: center; - svg { - height: ${({ theme }) => theme.spacing(4)}; - width: ${({ theme }) => theme.spacing(4)}; - } -`; - -const StyledInfoButton = styled(Button)` - height: ${({ theme }) => theme.spacing(6)}; - width: ${({ theme }) => theme.spacing(6)}; - padding: 0; - justify-content: center; - svg { - color: ${({ theme }) => theme.font.color.extraLight}; - height: ${({ theme }) => theme.spacing(4)}; - width: ${({ theme }) => theme.spacing(4)}; - } -`; - -const MIN_VALUE = 0; -const MAX_VALUE = 100; -export const SettingsDataModelFieldNumberDecimalsInput = ({ - value, - onChange, - disabled, -}: SettingsDataModelFieldNumberDecimalsInputProps) => { - const exampleValue = (1000).toFixed(value); - - const handleIncrementCounter = () => { - if (value < MAX_VALUE) { - const newValue = value + 1; - onChange(newValue); - } - }; - - const handleDecrementCounter = () => { - if (value > MIN_VALUE) { - const newValue = value - 1; - onChange(newValue); - } - }; - - const handleTextInputChange = (value: string) => { - const castedNumber = castAsNumberOrNull(value); - if (castedNumber === null) { - onChange(MIN_VALUE); - return; - } - - if (castedNumber < MIN_VALUE) { - return; - } - - if (castedNumber > MAX_VALUE) { - onChange(MAX_VALUE); - return; - } - onChange(castedNumber); - }; - return ( - <> - Number of decimals - - - Example: {exampleValue} - - - - handleTextInputChange(value)} - disabled={disabled} - /> - - - - - - ); -}; diff --git a/packages/twenty-front/src/modules/settings/data-model/fields/forms/number/components/SettingsDataModelFieldNumberForm.tsx b/packages/twenty-front/src/modules/settings/data-model/fields/forms/number/components/SettingsDataModelFieldNumberForm.tsx index 139be3993..271da1e0c 100644 --- a/packages/twenty-front/src/modules/settings/data-model/fields/forms/number/components/SettingsDataModelFieldNumberForm.tsx +++ b/packages/twenty-front/src/modules/settings/data-model/fields/forms/number/components/SettingsDataModelFieldNumberForm.tsx @@ -3,10 +3,9 @@ import { z } from 'zod'; import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; import { numberFieldDefaultValueSchema } from '@/object-record/record-field/validation-schemas/numberFieldDefaultValueSchema'; -import { SettingsDataModelFieldNumberDecimalsInput } from '@/settings/data-model/fields/forms/number/components/SettingsDataModelFieldNumberDecimalInput'; -import { Select } from '@/ui/input/components/Select'; -import styled from '@emotion/styled'; -import { CardContent, IconNumber9, IconPercentage } from 'twenty-ui'; +import { SettingsOptionCardContentCounter } from '@/settings/components/SettingsOptions/SettingsOptionCardContentCounter'; +import { SettingsOptionCardContentSelect } from '@/settings/components/SettingsOptions/SettingsOptionCardContentSelect'; +import { IconDecimal, IconEye, IconNumber9, IconPercentage } from 'twenty-ui'; import { DEFAULT_DECIMAL_VALUE } from '~/utils/format/number'; export const settingsDataModelFieldNumberFormSchema = z.object({ @@ -17,13 +16,6 @@ export type SettingsDataModelFieldNumberFormValues = z.infer< typeof settingsDataModelFieldNumberFormSchema >; -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 SettingsDataModelFieldNumberFormProps = { disabled?: boolean; fieldMetadataItem: Pick< @@ -39,52 +31,54 @@ export const SettingsDataModelFieldNumberForm = ({ const { control } = useFormContext(); return ( - - { - const count = value?.decimals ?? 0; - const type = value?.type ?? 'number'; + { + const count = value?.decimals ?? 0; + const type = value?.type ?? 'number'; - return ( - <> - Type -