martmull
2024-11-13 14:32:40 +01:00
committed by GitHub
parent d2af97276d
commit ba79a1d324
8 changed files with 79 additions and 37 deletions

View File

@@ -1,5 +1,14 @@
import { FooterNote } from '@/auth/sign-in-up/components/FooterNote'; 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 { useHandleResetPassword } from '@/auth/sign-in-up/hooks/useHandleResetPassword';
import { SignInUpMode, useSignInUp } from '@/auth/sign-in-up/hooks/useSignInUp'; import { SignInUpMode, useSignInUp } from '@/auth/sign-in-up/hooks/useSignInUp';
import { import {
@@ -20,15 +29,6 @@ import { useMemo, useState } from 'react';
import { Controller } from 'react-hook-form'; import { Controller } from 'react-hook-form';
import { useRecoilState, useRecoilValue } from 'recoil'; import { useRecoilState, useRecoilValue } from 'recoil';
import { Key } from 'ts-key-enum'; import { Key } from 'ts-key-enum';
import {
ActionLink,
IconGoogle,
IconKey,
IconMicrosoft,
Loader,
MainButton,
StyledText,
} from 'twenty-ui';
import { isDefined } from '~/utils/isDefined'; import { isDefined } from '~/utils/isDefined';
const StyledContentContainer = styled.div` const StyledContentContainer = styled.div`

View File

@@ -1,15 +1,7 @@
/* @license Enterprise */ /* @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 { import {
HorizontalSeparator,
Button, Button,
H2Title, H2Title,
IconCheck, IconCheck,
@@ -18,6 +10,14 @@ import {
IconUpload, IconUpload,
Section, Section,
} from 'twenty-ui'; } 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 { REACT_APP_SERVER_BASE_URL } from '~/config';
import { isDefined } from '~/utils/isDefined'; import { isDefined } from '~/utils/isDefined';

View File

@@ -1,6 +1,5 @@
import { ReactNode } from 'react'; import { ReactNode } from 'react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { useGetManyServerlessFunctions } from '@/settings/serverless-functions/hooks/useGetManyServerlessFunctions'; import { useGetManyServerlessFunctions } from '@/settings/serverless-functions/hooks/useGetManyServerlessFunctions';
import { setNestedValue } from '@/workflow/utils/setNestedValue'; import { setNestedValue } from '@/workflow/utils/setNestedValue';
import { Select, SelectOption } from '@/ui/input/components/Select'; 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 VariableTagInput from '@/workflow/search-variables/components/VariableTagInput';
import { WorkflowCodeStep } from '@/workflow/types/Workflow'; import { WorkflowCodeStep } from '@/workflow/types/Workflow';
import { useTheme } from '@emotion/react'; import { useTheme } from '@emotion/react';
import { IconCode, isDefined } from 'twenty-ui'; import { IconCode, isDefined, HorizontalSeparator } from 'twenty-ui';
import { useDebouncedCallback } from 'use-debounce'; import { useDebouncedCallback } from 'use-debounce';
import { getDefaultFunctionInputFromInputSchema } from '@/workflow/utils/getDefaultFunctionInputFromInputSchema'; import { getDefaultFunctionInputFromInputSchema } from '@/workflow/utils/getDefaultFunctionInputFromInputSchema';
import { FunctionInput } from '@/workflow/types/FunctionInput'; import { FunctionInput } from '@/workflow/types/FunctionInput';
@@ -23,16 +22,19 @@ const StyledLabel = styled.div`
color: ${({ theme }) => theme.font.color.light}; color: ${({ theme }) => theme.font.color.light};
font-size: ${({ theme }) => theme.font.size.md}; font-size: ${({ theme }) => theme.font.size.md};
font-weight: ${({ theme }) => theme.font.weight.semiBold}; 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)}; margin-bottom: ${({ theme }) => theme.spacing(2)};
`; `;
const StyledInputContainer = styled.div` 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; display: flex;
flex-direction: column; flex-direction: column;
gap: ${({ theme }) => theme.spacing(2)};
padding: ${({ theme }) => theme.spacing(2)};
position: relative; position: relative;
gap: ${({ theme }) => theme.spacing(4)};
padding-left: ${({ theme }) => theme.spacing(4)};
`; `;
type WorkflowEditActionFormServerlessFunctionProps = type WorkflowEditActionFormServerlessFunctionProps =
@@ -139,17 +141,40 @@ export const WorkflowEditActionFormServerlessFunction = (
const renderFields = ( const renderFields = (
functionInput: FunctionInput, functionInput: FunctionInput,
path: string[] = [], 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]) => { return Object.entries(functionInput).map(([inputKey, inputValue]) => {
const currentPath = [...path, inputKey]; const currentPath = [...path, inputKey];
const pathKey = currentPath.join('.'); const pathKey = currentPath.join('.');
if (inputValue !== null && typeof inputValue === 'object') { if (inputValue !== null && typeof inputValue === 'object') {
if (isRoot) {
return (
<>
{displaySeparator(functionInput) && (
<HorizontalSeparator noMargin />
)}
{renderFields(inputValue, currentPath, false)}
</>
);
}
return ( return (
<StyledContainer key={pathKey}> <StyledContainer key={pathKey}>
<StyledLabel>{inputKey}</StyledLabel> <StyledLabel>{inputKey}</StyledLabel>
<StyledInputContainer> <StyledInputContainer>
{renderFields(inputValue, currentPath)} {renderFields(inputValue, currentPath, false)}
</StyledInputContainer> </StyledInputContainer>
</StyledContainer> </StyledContainer>
); );
@@ -184,7 +209,7 @@ export const WorkflowEditActionFormServerlessFunction = (
disabled={props.readonly} disabled={props.readonly}
onChange={handleFunctionChange} onChange={handleFunctionChange}
/> />
{functionInput && renderFields(functionInput)} {renderFields(functionInput)}
</WorkflowEditGenericFormBase> </WorkflowEditGenericFormBase>
); );
}; };

View File

@@ -21,7 +21,7 @@ const StyledContainer = styled.div`
const StyledLabel = styled.div` const StyledLabel = styled.div`
color: ${({ theme }) => theme.font.color.light}; 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}; font-weight: ${({ theme }) => theme.font.weight.semiBold};
margin-bottom: ${({ theme }) => theme.spacing(1)}; margin-bottom: ${({ theme }) => theme.spacing(1)};
`; `;

View File

@@ -1,14 +1,13 @@
/* @license Enterprise */ /* @license Enterprise */
import { FooterNote } from '@/auth/sign-in-up/components/FooterNote'; 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 { useSSO } from '@/auth/sign-in-up/hooks/useSSO';
import { availableSSOIdentityProvidersState } from '@/auth/states/availableWorkspacesForSSO'; import { availableSSOIdentityProvidersState } from '@/auth/states/availableWorkspacesForSSO';
import { guessSSOIdentityProviderIconByUrl } from '@/settings/security/utils/guessSSOIdentityProviderIconByUrl'; import { guessSSOIdentityProviderIconByUrl } from '@/settings/security/utils/guessSSOIdentityProviderIconByUrl';
import { DEFAULT_WORKSPACE_NAME } from '@/ui/navigation/navigation-drawer/constants/DefaultWorkspaceName'; import { DEFAULT_WORKSPACE_NAME } from '@/ui/navigation/navigation-drawer/constants/DefaultWorkspaceName';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { MainButton } from 'twenty-ui';
const StyledContentContainer = styled.div` const StyledContentContainer = styled.div`
margin-bottom: ${({ theme }) => theme.spacing(8)}; margin-bottom: ${({ theme }) => theme.spacing(8)};

View File

@@ -50,6 +50,7 @@ export * from './info/components/Info';
export * from './status/components/Status'; export * from './status/components/Status';
export * from './tag/components/Tag'; export * from './tag/components/Tag';
export * from './text/components/SeparatorLineText'; export * from './text/components/SeparatorLineText';
export * from './text/components/HorizontalSeparator';
export * from './tooltip/AppTooltip'; export * from './tooltip/AppTooltip';
export * from './tooltip/OverflowingTextWithTooltip'; export * from './tooltip/OverflowingTextWithTooltip';
export * from './typography/components/H1Title'; export * from './typography/components/H1Title';

View File

@@ -4,20 +4,21 @@ import styled from '@emotion/styled';
type HorizontalSeparatorProps = { type HorizontalSeparatorProps = {
visible?: boolean; visible?: boolean;
text?: string; text?: string;
noMargin?: boolean;
}; };
const StyledSeparator = styled.div<HorizontalSeparatorProps>` const StyledSeparator = styled.div<HorizontalSeparatorProps>`
background-color: ${({ theme }) => theme.border.color.medium}; background-color: ${({ theme }) => theme.border.color.medium};
height: ${({ visible }) => (visible ? '1px' : 0)}; height: ${({ visible }) => (visible ? '1px' : 0)};
margin-bottom: ${({ theme }) => theme.spacing(3)}; margin-bottom: ${({ theme, noMargin }) => (noMargin ? 0 : theme.spacing(3))};
margin-top: ${({ theme }) => theme.spacing(3)}; margin-top: ${({ theme, noMargin }) => (noMargin ? 0 : theme.spacing(3))};
width: 100%; width: 100%;
`; `;
const StyledSeparatorContainer = styled.div` const StyledSeparatorContainer = styled.div<{ noMargin: boolean }>`
align-items: center; align-items: center;
display: flex; display: flex;
margin-bottom: ${({ theme }) => theme.spacing(3)}; margin-bottom: ${({ theme, noMargin }) => (noMargin ? 0 : theme.spacing(3))};
margin-top: ${({ theme }) => theme.spacing(3)}; margin-top: ${({ theme, noMargin }) => (noMargin ? 0 : theme.spacing(3))};
width: 100%; width: 100%;
`; `;
@@ -36,16 +37,17 @@ const StyledText = styled.span`
export const HorizontalSeparator = ({ export const HorizontalSeparator = ({
visible = true, visible = true,
text = '', text = '',
noMargin = false,
}: HorizontalSeparatorProps): JSX.Element => ( }: HorizontalSeparatorProps): JSX.Element => (
<> <>
{text ? ( {text ? (
<StyledSeparatorContainer> <StyledSeparatorContainer noMargin={noMargin}>
<StyledLine visible={visible} /> <StyledLine visible={visible} />
{text && <StyledText>{text}</StyledText>} {text && <StyledText>{text}</StyledText>}
<StyledLine visible={visible} /> <StyledLine visible={visible} />
</StyledSeparatorContainer> </StyledSeparatorContainer>
) : ( ) : (
<StyledSeparator visible={visible} /> <StyledSeparator visible={visible} noMargin={noMargin} />
)} )}
</> </>
); );

View File

@@ -0,0 +1,15 @@
import { Meta, StoryObj } from '@storybook/react';
import { ComponentDecorator } from '@ui/testing';
import { HorizontalSeparator } from '../HorizontalSeparator';
const meta: Meta<typeof HorizontalSeparator> = {
title: 'UI/Display/Text/HorizontalSeparator',
component: HorizontalSeparator,
decorators: [ComponentDecorator],
};
export default meta;
type Story = StoryObj<typeof HorizontalSeparator>;
export const Default: Story = {};