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:
@ -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} />;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -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} />;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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}`}
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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}
|
||||||
|
|||||||
@ -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'}
|
||||||
|
|||||||
@ -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>
|
|
||||||
);
|
);
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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`
|
||||||
|
|||||||
Reference in New Issue
Block a user