diff --git a/packages/twenty-front/src/modules/auth/sign-in-up/components/SignInUpForm.tsx b/packages/twenty-front/src/modules/auth/sign-in-up/components/SignInUpForm.tsx index 228fde192827..54474bc1a30f 100644 --- a/packages/twenty-front/src/modules/auth/sign-in-up/components/SignInUpForm.tsx +++ b/packages/twenty-front/src/modules/auth/sign-in-up/components/SignInUpForm.tsx @@ -1,5 +1,14 @@ import { FooterNote } from '@/auth/sign-in-up/components/FooterNote'; -import { HorizontalSeparator } from '@/auth/sign-in-up/components/HorizontalSeparator'; +import { + HorizontalSeparator, + ActionLink, + IconGoogle, + IconKey, + IconMicrosoft, + Loader, + MainButton, + StyledText, +} from 'twenty-ui'; import { useHandleResetPassword } from '@/auth/sign-in-up/hooks/useHandleResetPassword'; import { SignInUpMode, useSignInUp } from '@/auth/sign-in-up/hooks/useSignInUp'; import { @@ -20,15 +29,6 @@ import { useMemo, useState } from 'react'; import { Controller } from 'react-hook-form'; import { useRecoilState, useRecoilValue } from 'recoil'; import { Key } from 'ts-key-enum'; -import { - ActionLink, - IconGoogle, - IconKey, - IconMicrosoft, - Loader, - MainButton, - StyledText, -} from 'twenty-ui'; import { isDefined } from '~/utils/isDefined'; const StyledContentContainer = styled.div` diff --git a/packages/twenty-front/src/modules/settings/security/components/SettingsSSOSAMLForm.tsx b/packages/twenty-front/src/modules/settings/security/components/SettingsSSOSAMLForm.tsx index f42e3d8954fd..2f39960f000b 100644 --- a/packages/twenty-front/src/modules/settings/security/components/SettingsSSOSAMLForm.tsx +++ b/packages/twenty-front/src/modules/settings/security/components/SettingsSSOSAMLForm.tsx @@ -1,15 +1,7 @@ /* @license Enterprise */ -import { HorizontalSeparator } from '@/auth/sign-in-up/components/HorizontalSeparator'; -import { parseSAMLMetadataFromXMLFile } from '@/settings/security/utils/parseSAMLMetadataFromXMLFile'; -import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar'; -import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; -import { TextInput } from '@/ui/input/components/TextInput'; -import { useTheme } from '@emotion/react'; -import styled from '@emotion/styled'; -import { ChangeEvent, useRef } from 'react'; -import { useFormContext } from 'react-hook-form'; import { + HorizontalSeparator, Button, H2Title, IconCheck, @@ -18,6 +10,14 @@ import { IconUpload, Section, } from 'twenty-ui'; +import { parseSAMLMetadataFromXMLFile } from '@/settings/security/utils/parseSAMLMetadataFromXMLFile'; +import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar'; +import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; +import { TextInput } from '@/ui/input/components/TextInput'; +import { useTheme } from '@emotion/react'; +import styled from '@emotion/styled'; +import { ChangeEvent, useRef } from 'react'; +import { useFormContext } from 'react-hook-form'; import { REACT_APP_SERVER_BASE_URL } from '~/config'; import { isDefined } from '~/utils/isDefined'; diff --git a/packages/twenty-front/src/modules/workflow/components/WorkflowEditActionFormServerlessFunction.tsx b/packages/twenty-front/src/modules/workflow/components/WorkflowEditActionFormServerlessFunction.tsx index c1e67d2a9f1e..95bbcd3f9341 100644 --- a/packages/twenty-front/src/modules/workflow/components/WorkflowEditActionFormServerlessFunction.tsx +++ b/packages/twenty-front/src/modules/workflow/components/WorkflowEditActionFormServerlessFunction.tsx @@ -1,6 +1,5 @@ import { ReactNode } from 'react'; import styled from '@emotion/styled'; - import { useGetManyServerlessFunctions } from '@/settings/serverless-functions/hooks/useGetManyServerlessFunctions'; import { setNestedValue } from '@/workflow/utils/setNestedValue'; import { Select, SelectOption } from '@/ui/input/components/Select'; @@ -8,7 +7,7 @@ import { WorkflowEditGenericFormBase } from '@/workflow/components/WorkflowEditG import VariableTagInput from '@/workflow/search-variables/components/VariableTagInput'; import { WorkflowCodeStep } from '@/workflow/types/Workflow'; import { useTheme } from '@emotion/react'; -import { IconCode, isDefined } from 'twenty-ui'; +import { IconCode, isDefined, HorizontalSeparator } from 'twenty-ui'; import { useDebouncedCallback } from 'use-debounce'; import { getDefaultFunctionInputFromInputSchema } from '@/workflow/utils/getDefaultFunctionInputFromInputSchema'; import { FunctionInput } from '@/workflow/types/FunctionInput'; @@ -23,16 +22,19 @@ const StyledLabel = styled.div` color: ${({ theme }) => theme.font.color.light}; font-size: ${({ theme }) => theme.font.size.md}; font-weight: ${({ theme }) => theme.font.weight.semiBold}; - margin-top: ${({ theme }) => theme.spacing(3)}; + margin-top: ${({ 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; - gap: ${({ theme }) => theme.spacing(4)}; - padding-left: ${({ theme }) => theme.spacing(4)}; `; type WorkflowEditActionFormServerlessFunctionProps = @@ -139,17 +141,40 @@ export const WorkflowEditActionFormServerlessFunction = ( const renderFields = ( functionInput: FunctionInput, path: string[] = [], - ): ReactNode | undefined => { + isRoot = true, + ): ReactNode[] => { + const displaySeparator = (functionInput: FunctionInput) => { + const keys = Object.keys(functionInput); + if (keys.length > 1) { + return true; + } + if (keys.length === 1) { + const subKeys = Object.keys(functionInput[keys[0]]); + return subKeys.length > 0; + } + return false; + }; + return Object.entries(functionInput).map(([inputKey, inputValue]) => { const currentPath = [...path, inputKey]; const pathKey = currentPath.join('.'); if (inputValue !== null && typeof inputValue === 'object') { + if (isRoot) { + return ( + <> + {displaySeparator(functionInput) && ( + + )} + {renderFields(inputValue, currentPath, false)} + + ); + } return ( {inputKey} - {renderFields(inputValue, currentPath)} + {renderFields(inputValue, currentPath, false)} ); @@ -184,7 +209,7 @@ export const WorkflowEditActionFormServerlessFunction = ( disabled={props.readonly} onChange={handleFunctionChange} /> - {functionInput && renderFields(functionInput)} + {renderFields(functionInput)} ); }; diff --git a/packages/twenty-front/src/modules/workflow/search-variables/components/VariableTagInput.tsx b/packages/twenty-front/src/modules/workflow/search-variables/components/VariableTagInput.tsx index eeb1e9386586..fe16f975b631 100644 --- a/packages/twenty-front/src/modules/workflow/search-variables/components/VariableTagInput.tsx +++ b/packages/twenty-front/src/modules/workflow/search-variables/components/VariableTagInput.tsx @@ -21,7 +21,7 @@ const StyledContainer = styled.div` const StyledLabel = styled.div` color: ${({ theme }) => theme.font.color.light}; - font-size: ${({ theme }) => theme.font.size.xs}; + font-size: ${({ theme }) => theme.font.size.md}; font-weight: ${({ theme }) => theme.font.weight.semiBold}; margin-bottom: ${({ theme }) => theme.spacing(1)}; `; diff --git a/packages/twenty-front/src/pages/auth/SSOWorkspaceSelection.tsx b/packages/twenty-front/src/pages/auth/SSOWorkspaceSelection.tsx index 1767b134262e..617728095e7b 100644 --- a/packages/twenty-front/src/pages/auth/SSOWorkspaceSelection.tsx +++ b/packages/twenty-front/src/pages/auth/SSOWorkspaceSelection.tsx @@ -1,14 +1,13 @@ /* @license Enterprise */ import { FooterNote } from '@/auth/sign-in-up/components/FooterNote'; -import { HorizontalSeparator } from '@/auth/sign-in-up/components/HorizontalSeparator'; +import { HorizontalSeparator, MainButton } from 'twenty-ui'; import { useSSO } from '@/auth/sign-in-up/hooks/useSSO'; import { availableSSOIdentityProvidersState } from '@/auth/states/availableWorkspacesForSSO'; import { guessSSOIdentityProviderIconByUrl } from '@/settings/security/utils/guessSSOIdentityProviderIconByUrl'; import { DEFAULT_WORKSPACE_NAME } from '@/ui/navigation/navigation-drawer/constants/DefaultWorkspaceName'; import styled from '@emotion/styled'; import { useRecoilValue } from 'recoil'; -import { MainButton } from 'twenty-ui'; const StyledContentContainer = styled.div` margin-bottom: ${({ theme }) => theme.spacing(8)}; diff --git a/packages/twenty-ui/src/display/index.ts b/packages/twenty-ui/src/display/index.ts index b0f67a365fdf..45144332b2bf 100644 --- a/packages/twenty-ui/src/display/index.ts +++ b/packages/twenty-ui/src/display/index.ts @@ -50,6 +50,7 @@ export * from './info/components/Info'; export * from './status/components/Status'; export * from './tag/components/Tag'; export * from './text/components/SeparatorLineText'; +export * from './text/components/HorizontalSeparator'; export * from './tooltip/AppTooltip'; export * from './tooltip/OverflowingTextWithTooltip'; export * from './typography/components/H1Title'; diff --git a/packages/twenty-front/src/modules/auth/sign-in-up/components/HorizontalSeparator.tsx b/packages/twenty-ui/src/display/text/components/HorizontalSeparator.tsx similarity index 66% rename from packages/twenty-front/src/modules/auth/sign-in-up/components/HorizontalSeparator.tsx rename to packages/twenty-ui/src/display/text/components/HorizontalSeparator.tsx index d8d68bfbb71c..1e705663e709 100644 --- a/packages/twenty-front/src/modules/auth/sign-in-up/components/HorizontalSeparator.tsx +++ b/packages/twenty-ui/src/display/text/components/HorizontalSeparator.tsx @@ -4,20 +4,21 @@ import styled from '@emotion/styled'; type HorizontalSeparatorProps = { visible?: boolean; text?: string; + noMargin?: boolean; }; const StyledSeparator = styled.div` background-color: ${({ theme }) => theme.border.color.medium}; height: ${({ visible }) => (visible ? '1px' : 0)}; - margin-bottom: ${({ theme }) => theme.spacing(3)}; - margin-top: ${({ theme }) => theme.spacing(3)}; + margin-bottom: ${({ theme, noMargin }) => (noMargin ? 0 : theme.spacing(3))}; + margin-top: ${({ theme, noMargin }) => (noMargin ? 0 : theme.spacing(3))}; width: 100%; `; -const StyledSeparatorContainer = styled.div` +const StyledSeparatorContainer = styled.div<{ noMargin: boolean }>` align-items: center; display: flex; - margin-bottom: ${({ theme }) => theme.spacing(3)}; - margin-top: ${({ theme }) => theme.spacing(3)}; + margin-bottom: ${({ theme, noMargin }) => (noMargin ? 0 : theme.spacing(3))}; + margin-top: ${({ theme, noMargin }) => (noMargin ? 0 : theme.spacing(3))}; width: 100%; `; @@ -36,16 +37,17 @@ const StyledText = styled.span` export const HorizontalSeparator = ({ visible = true, text = '', + noMargin = false, }: HorizontalSeparatorProps): JSX.Element => ( <> {text ? ( - + {text && {text}} ) : ( - + )} ); diff --git a/packages/twenty-ui/src/display/text/components/__stories__/HorizontalSeparator.stories.tsx b/packages/twenty-ui/src/display/text/components/__stories__/HorizontalSeparator.stories.tsx new file mode 100644 index 000000000000..641fd7779b6b --- /dev/null +++ b/packages/twenty-ui/src/display/text/components/__stories__/HorizontalSeparator.stories.tsx @@ -0,0 +1,15 @@ +import { Meta, StoryObj } from '@storybook/react'; +import { ComponentDecorator } from '@ui/testing'; + +import { HorizontalSeparator } from '../HorizontalSeparator'; + +const meta: Meta = { + title: 'UI/Display/Text/HorizontalSeparator', + component: HorizontalSeparator, + decorators: [ComponentDecorator], +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = {};