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 = {};