truncate the string if overlow the text (#6166)

This PR aims to fix #6102 

I think we should dicuss a bit about how we should manage the lenght and
set the variables globally

Edit : 

@RobertoSimonini1 I used this PR to fix various problems that were left
unsolved :
- Refactor TextDisplay component, EllipsisDisplay was redundant with
OverflowingTextWithTooltip
- Removed maxWidth on TextDisplay for all other components, as it wasn't
the right way to do it, the parent container should be responsible for
width not the TextDisplay (code smell)
- Drilled-down isCentered to respect its intent in the RecordInlineCell
display of the record show page title
- Fixed RecordInlineCellEditMode so that the portal is well centered
above the record show page title
- Fixed DoubleTextInput width so that it expands normally and takes all
its parent available space.

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
RobertoSimonini1
2024-07-19 14:25:57 +02:00
committed by GitHub
parent 1b0759ef2f
commit 7b615cf97e
11 changed files with 44 additions and 24 deletions

View File

@ -1,7 +1,7 @@
import { isNonEmptyString } from '@sniptt/guards'; import { isNonEmptyString } from '@sniptt/guards';
import { useFullNameFieldDisplay } from '@/object-record/record-field/meta-types/hooks/useFullNameFieldDisplay'; import { useFullNameFieldDisplay } from '@/object-record/record-field/meta-types/hooks/useFullNameFieldDisplay';
import { TextDisplay } from '@/ui/field/display/components/TextDisplay'; import { OverflowingTextWithTooltip } from 'twenty-ui';
export const FullNameFieldDisplay = () => { export const FullNameFieldDisplay = () => {
const { fieldValue } = useFullNameFieldDisplay(); const { fieldValue } = useFullNameFieldDisplay();
@ -10,5 +10,5 @@ export const FullNameFieldDisplay = () => {
.filter(isNonEmptyString) .filter(isNonEmptyString)
.join(' '); .join(' ');
return <TextDisplay text={content} />; return <OverflowingTextWithTooltip text={content} />;
}; };

View File

@ -2,7 +2,7 @@ import { useTextFieldDisplay } from '@/object-record/record-field/meta-types/hoo
import { TextDisplay } from '@/ui/field/display/components/TextDisplay'; import { TextDisplay } from '@/ui/field/display/components/TextDisplay';
export const TextFieldDisplay = () => { export const TextFieldDisplay = () => {
const { fieldValue, maxWidth } = useTextFieldDisplay(); const { fieldValue } = useTextFieldDisplay();
return <TextDisplay text={fieldValue} maxWidth={maxWidth} />; return <TextDisplay text={fieldValue} />;
}; };

View File

@ -5,8 +5,7 @@ import { useRecordFieldValue } from '@/object-record/record-store/contexts/Recor
import { FieldContext } from '../../contexts/FieldContext'; import { FieldContext } from '../../contexts/FieldContext';
export const useTextFieldDisplay = () => { export const useTextFieldDisplay = () => {
const { entityId, fieldDefinition, hotkeyScope, maxWidth } = const { entityId, fieldDefinition, hotkeyScope } = useContext(FieldContext);
useContext(FieldContext);
const fieldName = fieldDefinition.metadata.fieldName; const fieldName = fieldDefinition.metadata.fieldName;
@ -14,7 +13,6 @@ export const useTextFieldDisplay = () => {
useRecordFieldValue<string | undefined>(entityId, fieldName) ?? ''; useRecordFieldValue<string | undefined>(entityId, fieldName) ?? '';
return { return {
maxWidth,
fieldDefinition, fieldDefinition,
fieldValue, fieldValue,
hotkeyScope, hotkeyScope,

View File

@ -18,11 +18,14 @@ import { RecordInlineCellContainer } from './RecordInlineCellContainer';
type RecordInlineCellProps = { type RecordInlineCellProps = {
readonly?: boolean; readonly?: boolean;
loading?: boolean; loading?: boolean;
isCentered?: boolean;
}; };
// TODO: refactor props drilling with a RecordInlineCellContext
export const RecordInlineCell = ({ export const RecordInlineCell = ({
readonly, readonly,
loading, loading,
isCentered,
}: RecordInlineCellProps) => { }: RecordInlineCellProps) => {
const { fieldDefinition, entityId } = useContext(FieldContext); const { fieldDefinition, entityId } = useContext(FieldContext);
const buttonIcon = useGetButtonIcon(); const buttonIcon = useGetButtonIcon();
@ -86,6 +89,7 @@ export const RecordInlineCell = ({
label={fieldDefinition.label} label={fieldDefinition.label}
labelWidth={fieldDefinition.labelWidth} labelWidth={fieldDefinition.labelWidth}
showLabel={fieldDefinition.showLabel} showLabel={fieldDefinition.showLabel}
isCentered={isCentered}
editModeContent={ editModeContent={
<FieldInput <FieldInput
recordFieldInputdId={`${entityId}-${fieldDefinition?.metadata?.fieldName}`} recordFieldInputdId={`${entityId}-${fieldDefinition?.metadata?.fieldName}`}

View File

@ -1,6 +1,6 @@
import React, { ReactElement, useContext } from 'react';
import { useTheme } from '@emotion/react'; import { useTheme } from '@emotion/react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { ReactElement, useContext } from 'react';
import { AppTooltip, IconComponent, TooltipDelay } from 'twenty-ui'; import { AppTooltip, IconComponent, TooltipDelay } from 'twenty-ui';
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext'; import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
@ -52,6 +52,8 @@ const StyledInlineCellBaseContainer = styled.div`
gap: ${({ theme }) => theme.spacing(1)}; gap: ${({ theme }) => theme.spacing(1)};
user-select: none; user-select: none;
justify-content: center;
`; `;
export const StyledSkeletonDiv = styled.div` export const StyledSkeletonDiv = styled.div`
@ -72,8 +74,10 @@ export type RecordInlineCellContainerProps = {
isDisplayModeFixHeight?: boolean; isDisplayModeFixHeight?: boolean;
disableHoverEffect?: boolean; disableHoverEffect?: boolean;
loading?: boolean; loading?: boolean;
isCentered?: boolean;
}; };
// TODO: refactor props drilling with a RecordInlineCellContext
export const RecordInlineCellContainer = ({ export const RecordInlineCellContainer = ({
readonly, readonly,
IconLabel, IconLabel,
@ -88,6 +92,7 @@ export const RecordInlineCellContainer = ({
isDisplayModeFixHeight, isDisplayModeFixHeight,
disableHoverEffect, disableHoverEffect,
loading = false, loading = false,
isCentered,
}: RecordInlineCellContainerProps) => { }: RecordInlineCellContainerProps) => {
const { entityId, fieldDefinition } = useContext(FieldContext); const { entityId, fieldDefinition } = useContext(FieldContext);
@ -153,6 +158,7 @@ export const RecordInlineCellContainer = ({
loading, loading,
readonly, readonly,
showLabel, showLabel,
isCentered,
}} }}
/> />
</StyledValueContainer> </StyledValueContainer>

View File

@ -1,7 +1,7 @@
import { useContext } from 'react';
import { createPortal } from 'react-dom';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { autoUpdate, flip, offset, useFloating } from '@floating-ui/react'; import { autoUpdate, flip, offset, useFloating } from '@floating-ui/react';
import { useContext } from 'react';
import { createPortal } from 'react-dom';
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext'; import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
@ -19,7 +19,8 @@ const StyledInlineCellInput = styled.div`
display: flex; display: flex;
min-height: 32px; min-height: 32px;
min-width: 200px; min-width: 320px;
width: inherit; width: inherit;
z-index: 1000; z-index: 1000;
@ -29,6 +30,7 @@ type RecordInlineCellEditModeProps = {
children: React.ReactNode; children: React.ReactNode;
}; };
// TODO: Refactor this to avoid setting absolute px values.
export const RecordInlineCellEditMode = ({ export const RecordInlineCellEditMode = ({
children, children,
}: RecordInlineCellEditModeProps) => { }: RecordInlineCellEditModeProps) => {
@ -41,7 +43,8 @@ export const RecordInlineCellEditMode = ({
offset( offset(
isCentered isCentered
? { ? {
mainAxis: -30, mainAxis: -32,
crossAxis: 160,
} }
: { : {
crossAxis: -4, crossAxis: -4,

View File

@ -8,11 +8,20 @@ import { RecordInlineCellEditMode } from '@/object-record/record-inline-cell/com
import { RecordInlineCellSkeletonLoader } from '@/object-record/record-inline-cell/components/RecordInlineCellSkeletonLoader'; import { RecordInlineCellSkeletonLoader } from '@/object-record/record-inline-cell/components/RecordInlineCellSkeletonLoader';
import { useInlineCell } from '@/object-record/record-inline-cell/hooks/useInlineCell'; import { useInlineCell } from '@/object-record/record-inline-cell/hooks/useInlineCell';
const StyledClickableContainer = styled.div<{ readonly?: boolean }>` const StyledClickableContainer = styled.div<{
readonly?: boolean;
isCentered?: boolean;
}>`
display: flex; display: flex;
gap: ${({ theme }) => theme.spacing(1)}; gap: ${({ theme }) => theme.spacing(1)};
width: 100%; width: 100%;
${({ isCentered }) =>
isCentered === true &&
`
justify-content: center;
`};
${({ readonly }) => ${({ readonly }) =>
!readonly && !readonly &&
css` css`
@ -33,6 +42,7 @@ type RecordInlineCellValueProps = Pick<
| 'loading' | 'loading'
| 'showLabel' | 'showLabel'
| 'label' | 'label'
| 'isCentered'
>; >;
export const RecordInlineCellValue = ({ export const RecordInlineCellValue = ({
@ -47,6 +57,7 @@ export const RecordInlineCellValue = ({
loading, loading,
showLabel, showLabel,
label, label,
isCentered,
}: RecordInlineCellValueProps) => { }: RecordInlineCellValueProps) => {
const { isFocused } = useFieldFocus(); const { isFocused } = useFieldFocus();
@ -68,7 +79,7 @@ export const RecordInlineCellValue = ({
<RecordInlineCellEditMode>{editModeContent}</RecordInlineCellEditMode> <RecordInlineCellEditMode>{editModeContent}</RecordInlineCellEditMode>
)} )}
{editModeContentOnly ? ( {editModeContentOnly ? (
<StyledClickableContainer readonly={readonly}> <StyledClickableContainer readonly={readonly} isCentered={isCentered}>
<RecordInlineCellDisplayMode <RecordInlineCellDisplayMode
disableHoverEffect={disableHoverEffect} disableHoverEffect={disableHoverEffect}
isDisplayModeFixHeight={isDisplayModeFixHeight} isDisplayModeFixHeight={isDisplayModeFixHeight}
@ -82,6 +93,7 @@ export const RecordInlineCellValue = ({
<StyledClickableContainer <StyledClickableContainer
readonly={readonly} readonly={readonly}
onClick={handleDisplayModeClick} onClick={handleDisplayModeClick}
isCentered={isCentered}
> >
<RecordInlineCellDisplayMode <RecordInlineCellDisplayMode
disableHoverEffect={disableHoverEffect} disableHoverEffect={disableHoverEffect}

View File

@ -171,7 +171,7 @@ export const RecordShowContainer = ({
isCentered: true, isCentered: true,
}} }}
> >
<RecordInlineCell readonly={isReadOnly} /> <RecordInlineCell readonly={isReadOnly} isCentered={true} />
</FieldContext.Provider> </FieldContext.Provider>
} }
avatarType={recordIdentifier?.avatarType ?? 'rounded'} avatarType={recordIdentifier?.avatarType ?? 'rounded'}

View File

@ -1,14 +1,9 @@
import { OverflowingTextWithTooltip } from 'twenty-ui'; import { OverflowingTextWithTooltip } from 'twenty-ui';
import { EllipsisDisplay } from './EllipsisDisplay';
type TextDisplayProps = { type TextDisplayProps = {
text: string; text: string;
maxWidth?: number;
}; };
export const TextDisplay = ({ text, maxWidth }: TextDisplayProps) => ( export const TextDisplay = ({ text }: TextDisplayProps) => (
<EllipsisDisplay maxWidth={maxWidth}> <OverflowingTextWithTooltip text={text} />
<OverflowingTextWithTooltip text={text} />
</EllipsisDisplay>
); );

View File

@ -1,3 +1,4 @@
import styled from '@emotion/styled';
import { import {
ChangeEvent, ChangeEvent,
ClipboardEvent, ClipboardEvent,
@ -5,7 +6,6 @@ import {
useRef, useRef,
useState, useState,
} from 'react'; } from 'react';
import styled from '@emotion/styled';
import { Key } from 'ts-key-enum'; import { Key } from 'ts-key-enum';
import { FieldDoubleText } from '@/object-record/record-field/types/FieldDoubleText'; import { FieldDoubleText } from '@/object-record/record-field/types/FieldDoubleText';
@ -21,7 +21,7 @@ const StyledContainer = styled.div`
justify-content: space-between; justify-content: space-between;
input { input {
width: ${({ theme }) => theme.spacing(24)}; width: 100%;
} }
& > input:last-child { & > input:last-child {

View File

@ -52,6 +52,8 @@ const StyledTitle = styled.div`
font-size: ${({ theme }) => theme.font.size.xl}; font-size: ${({ theme }) => theme.font.size.xl};
font-weight: ${({ theme }) => theme.font.weight.semiBold}; font-weight: ${({ theme }) => theme.font.weight.semiBold};
justify-content: center; justify-content: center;
width: 100%;
`; `;
const StyledAvatarWrapper = styled.div` const StyledAvatarWrapper = styled.div`