mirror of
https://github.com/twentyhq/twenty.git
synced 2024-12-22 19:41:53 +03:00
fix icon shrink and use avatar for logo and icons (#9117)
- Fixed icon shrinking on tabs. The introduction of EllipsisDisplay takes 100% of the width, thus shrinking the icons. - Removed scroll wrapper tablist. This was removed in #9016 but reintroduced in #9089. This reintroduction made the dark border below the active tab disappear. - Used Avatar for icon and logo rendering following the changes made in #9093
This commit is contained in:
parent
a2423fad5e
commit
5e03f4dfb1
@ -1,10 +1,10 @@
|
||||
import { EllipsisDisplay } from '@/ui/field/display/components/EllipsisDisplay';
|
||||
import isPropValid from '@emotion/is-prop-valid';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { ReactElement } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { IconComponent, Pill } from 'twenty-ui';
|
||||
import { EllipsisDisplay } from '@/ui/field/display/components/EllipsisDisplay';
|
||||
import { Avatar, IconComponent, Pill } from 'twenty-ui';
|
||||
|
||||
type TabProps = {
|
||||
id: string;
|
||||
@ -54,7 +54,7 @@ const StyledHover = styled.span`
|
||||
padding-left: ${({ theme }) => theme.spacing(2)};
|
||||
padding-right: ${({ theme }) => theme.spacing(2)};
|
||||
font-weight: ${({ theme }) => theme.font.weight.medium};
|
||||
|
||||
width: 100%;
|
||||
&:hover {
|
||||
background: ${({ theme }) => theme.background.tertiary};
|
||||
border-radius: ${({ theme }) => theme.border.radius.sm};
|
||||
@ -63,9 +63,9 @@ const StyledHover = styled.span`
|
||||
background: ${({ theme }) => theme.background.quaternary};
|
||||
}
|
||||
`;
|
||||
const StyledLogo = styled.img`
|
||||
height: 14px;
|
||||
width: 14px;
|
||||
|
||||
const StyledIconContainer = styled.div`
|
||||
flex-shrink: 0;
|
||||
`;
|
||||
|
||||
export const Tab = ({
|
||||
@ -81,6 +81,10 @@ export const Tab = ({
|
||||
logo,
|
||||
}: TabProps) => {
|
||||
const theme = useTheme();
|
||||
const iconColor = active
|
||||
? theme.font.color.primary
|
||||
: theme.font.color.secondary;
|
||||
|
||||
return (
|
||||
<StyledTab
|
||||
onClick={onClick}
|
||||
@ -92,8 +96,24 @@ export const Tab = ({
|
||||
to={to}
|
||||
>
|
||||
<StyledHover>
|
||||
{logo && <StyledLogo src={logo} alt={`${title} logo`} />}
|
||||
{Icon && <Icon size={theme.icon.size.md} />}
|
||||
<StyledIconContainer>
|
||||
{logo && (
|
||||
<Avatar
|
||||
avatarUrl={logo}
|
||||
size="md"
|
||||
placeholder={title}
|
||||
iconColor={iconColor}
|
||||
/>
|
||||
)}
|
||||
{Icon && (
|
||||
<Avatar
|
||||
Icon={Icon}
|
||||
size="md"
|
||||
placeholder={title}
|
||||
iconColor={iconColor}
|
||||
/>
|
||||
)}
|
||||
</StyledIconContainer>
|
||||
<EllipsisDisplay>{title}</EllipsisDisplay>
|
||||
{pill && typeof pill === 'string' ? <Pill label={pill} /> : pill}
|
||||
</StyledHover>
|
||||
|
@ -1,14 +1,12 @@
|
||||
import styled from '@emotion/styled';
|
||||
import * as React from 'react';
|
||||
import { IconComponent } from 'twenty-ui';
|
||||
|
||||
import { TabListFromUrlOptionalEffect } from '@/ui/layout/tab/components/TabListFromUrlOptionalEffect';
|
||||
import { useTabList } from '@/ui/layout/tab/hooks/useTabList';
|
||||
import { TabListScope } from '@/ui/layout/tab/scopes/TabListScope';
|
||||
|
||||
import { TabListFromUrlOptionalEffect } from '@/ui/layout/tab/components/TabListFromUrlOptionalEffect';
|
||||
import { LayoutCard } from '@/ui/layout/tab/types/LayoutCard';
|
||||
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
||||
import styled from '@emotion/styled';
|
||||
import * as React from 'react';
|
||||
import { useEffect } from 'react';
|
||||
import { IconComponent } from 'twenty-ui';
|
||||
import { Tab } from './Tab';
|
||||
|
||||
export type SingleTabProps = {
|
||||
@ -26,33 +24,25 @@ type TabListProps = {
|
||||
tabListInstanceId: string;
|
||||
tabs: SingleTabProps[];
|
||||
loading?: boolean;
|
||||
className?: string;
|
||||
behaveAsLinks?: boolean;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
const StyledTabsContainer = styled.div`
|
||||
const StyledContainer = styled.div`
|
||||
border-bottom: ${({ theme }) => `1px solid ${theme.border.color.light}`};
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
height: 40px;
|
||||
user-select: none;
|
||||
margin-bottom: -1px;
|
||||
overflow-y: scroll;
|
||||
::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
border-bottom: ${({ theme }) => `1px solid ${theme.border.color.light}`};
|
||||
`;
|
||||
|
||||
export const TabList = ({
|
||||
tabs,
|
||||
tabListInstanceId,
|
||||
loading,
|
||||
className,
|
||||
behaveAsLinks = true,
|
||||
className,
|
||||
}: TabListProps) => {
|
||||
const visibleTabs = tabs.filter((tab) => !tab.hide);
|
||||
|
||||
@ -69,39 +59,37 @@ export const TabList = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledContainer className={className}>
|
||||
<TabListScope tabListScopeId={tabListInstanceId}>
|
||||
<TabListFromUrlOptionalEffect
|
||||
componentInstanceId={tabListInstanceId}
|
||||
tabListIds={tabs.map((tab) => tab.id)}
|
||||
/>
|
||||
<ScrollWrapper
|
||||
defaultEnableYScroll={false}
|
||||
contextProviderName="tabList"
|
||||
componentInstanceId={`scroll-wrapper-tab-list-${tabListInstanceId}`}
|
||||
>
|
||||
<StyledTabsContainer>
|
||||
{visibleTabs.map((tab) => (
|
||||
<Tab
|
||||
id={tab.id}
|
||||
key={tab.id}
|
||||
title={tab.title}
|
||||
Icon={tab.Icon}
|
||||
logo={tab.logo}
|
||||
active={tab.id === activeTabId}
|
||||
disabled={tab.disabled ?? loading}
|
||||
pill={tab.pill}
|
||||
to={behaveAsLinks ? `#${tab.id}` : undefined}
|
||||
onClick={() => {
|
||||
if (!behaveAsLinks) {
|
||||
setActiveTabId(tab.id);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</StyledTabsContainer>
|
||||
</ScrollWrapper>
|
||||
</TabListScope>
|
||||
</StyledContainer>
|
||||
<TabListScope tabListScopeId={tabListInstanceId}>
|
||||
<TabListFromUrlOptionalEffect
|
||||
componentInstanceId={tabListInstanceId}
|
||||
tabListIds={tabs.map((tab) => tab.id)}
|
||||
/>
|
||||
<ScrollWrapper
|
||||
defaultEnableYScroll={false}
|
||||
contextProviderName="tabList"
|
||||
componentInstanceId={`scroll-wrapper-tab-list-${tabListInstanceId}`}
|
||||
>
|
||||
<StyledContainer className={className}>
|
||||
{visibleTabs.map((tab) => (
|
||||
<Tab
|
||||
id={tab.id}
|
||||
key={tab.id}
|
||||
title={tab.title}
|
||||
Icon={tab.Icon}
|
||||
logo={tab.logo}
|
||||
active={tab.id === activeTabId}
|
||||
disabled={tab.disabled ?? loading}
|
||||
pill={tab.pill}
|
||||
to={behaveAsLinks ? `#${tab.id}` : undefined}
|
||||
onClick={() => {
|
||||
if (!behaveAsLinks) {
|
||||
setActiveTabId(tab.id);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</StyledContainer>
|
||||
</ScrollWrapper>
|
||||
</TabListScope>
|
||||
);
|
||||
};
|
||||
|
@ -8,6 +8,22 @@ import { workflowIdState } from '@/workflow/states/workflowIdState';
|
||||
import { WorkflowCodeAction } from '@/workflow/types/Workflow';
|
||||
import { setNestedValue } from '@/workflow/utils/setNestedValue';
|
||||
|
||||
import { CmdEnterActionButton } from '@/action-menu/components/CmdEnterActionButton';
|
||||
import { ServerlessFunctionExecutionResult } from '@/serverless-functions/components/ServerlessFunctionExecutionResult';
|
||||
import { INDEX_FILE_PATH } from '@/serverless-functions/constants/IndexFilePath';
|
||||
import { useTestServerlessFunction } from '@/serverless-functions/hooks/useTestServerlessFunction';
|
||||
import { getFunctionInputFromSourceCode } from '@/serverless-functions/utils/getFunctionInputFromSourceCode';
|
||||
import { getFunctionOutputSchema } from '@/serverless-functions/utils/getFunctionOutputSchema';
|
||||
import { mergeDefaultFunctionInputAndFunctionInput } from '@/serverless-functions/utils/mergeDefaultFunctionInputAndFunctionInput';
|
||||
import { InputLabel } from '@/ui/input/components/InputLabel';
|
||||
import { RightDrawerFooter } from '@/ui/layout/right-drawer/components/RightDrawerFooter';
|
||||
import { TabList } from '@/ui/layout/tab/components/TabList';
|
||||
import { useTabList } from '@/ui/layout/tab/hooks/useTabList';
|
||||
import { WorkflowStepBody } from '@/workflow/components/WorkflowStepBody';
|
||||
import { WorkflowVariablePicker } from '@/workflow/components/WorkflowVariablePicker';
|
||||
import { serverlessFunctionTestDataFamilyState } from '@/workflow/states/serverlessFunctionTestDataFamilyState';
|
||||
import { WorkflowEditActionFormServerlessFunctionFields } from '@/workflow/workflow-actions/components/WorkflowEditActionFormServerlessFunctionFields';
|
||||
import { WORKFLOW_SERVERLESS_FUNCTION_TAB_LIST_COMPONENT_ID } from '@/workflow/workflow-actions/constants/WorkflowServerlessFunctionTabListComponentId';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { Monaco } from '@monaco-editor/react';
|
||||
@ -17,22 +33,6 @@ import { useEffect, useState } from 'react';
|
||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { CodeEditor, IconCode, IconPlayerPlay, isDefined } from 'twenty-ui';
|
||||
import { useDebouncedCallback } from 'use-debounce';
|
||||
import { WorkflowStepBody } from '@/workflow/components/WorkflowStepBody';
|
||||
import { TabList } from '@/ui/layout/tab/components/TabList';
|
||||
import { useTabList } from '@/ui/layout/tab/hooks/useTabList';
|
||||
import { WorkflowVariablePicker } from '@/workflow/components/WorkflowVariablePicker';
|
||||
import { serverlessFunctionTestDataFamilyState } from '@/workflow/states/serverlessFunctionTestDataFamilyState';
|
||||
import { ServerlessFunctionExecutionResult } from '@/serverless-functions/components/ServerlessFunctionExecutionResult';
|
||||
import { INDEX_FILE_PATH } from '@/serverless-functions/constants/IndexFilePath';
|
||||
import { InputLabel } from '@/ui/input/components/InputLabel';
|
||||
import { RightDrawerFooter } from '@/ui/layout/right-drawer/components/RightDrawerFooter';
|
||||
import { CmdEnterActionButton } from '@/action-menu/components/CmdEnterActionButton';
|
||||
import { useTestServerlessFunction } from '@/serverless-functions/hooks/useTestServerlessFunction';
|
||||
import { getFunctionOutputSchema } from '@/serverless-functions/utils/getFunctionOutputSchema';
|
||||
import { getFunctionInputFromSourceCode } from '@/serverless-functions/utils/getFunctionInputFromSourceCode';
|
||||
import { mergeDefaultFunctionInputAndFunctionInput } from '@/serverless-functions/utils/mergeDefaultFunctionInputAndFunctionInput';
|
||||
import { WorkflowEditActionFormServerlessFunctionFields } from '@/workflow/workflow-actions/components/WorkflowEditActionFormServerlessFunctionFields';
|
||||
import { WORKFLOW_SERVERLESS_FUNCTION_TAB_LIST_COMPONENT_ID } from '@/workflow/workflow-actions/constants/WorkflowServerlessFunctionTabListComponentId';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
display: flex;
|
||||
@ -45,10 +45,14 @@ const StyledCodeEditorContainer = styled.div`
|
||||
flex-direction: column;
|
||||
`;
|
||||
|
||||
const StyledTabList = styled(TabList)`
|
||||
background: ${({ theme }) => theme.background.secondary};
|
||||
const StyledTabListContainer = styled.div`
|
||||
align-items: center;
|
||||
padding-left: ${({ theme }) => theme.spacing(2)};
|
||||
padding-right: ${({ theme }) => theme.spacing(2)};
|
||||
border-bottom: ${({ theme }) => `1px solid ${theme.border.color.light}`};
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
height: ${({ theme }) => theme.spacing(10)};
|
||||
`;
|
||||
|
||||
type WorkflowEditActionFormServerlessFunctionProps = {
|
||||
@ -263,11 +267,15 @@ export const WorkflowEditActionFormServerlessFunction = ({
|
||||
return (
|
||||
!loading && (
|
||||
<StyledContainer>
|
||||
<StyledTabList
|
||||
tabListInstanceId={WORKFLOW_SERVERLESS_FUNCTION_TAB_LIST_COMPONENT_ID}
|
||||
tabs={tabs}
|
||||
behaveAsLinks={false}
|
||||
/>
|
||||
<StyledTabListContainer>
|
||||
<TabList
|
||||
tabListInstanceId={
|
||||
WORKFLOW_SERVERLESS_FUNCTION_TAB_LIST_COMPONENT_ID
|
||||
}
|
||||
tabs={tabs}
|
||||
behaveAsLinks={false}
|
||||
/>
|
||||
</StyledTabListContainer>
|
||||
<WorkflowStepHeader
|
||||
onTitleChange={(newName: string) => {
|
||||
updateAction({ name: newName });
|
||||
|
Loading…
Reference in New Issue
Block a user