Refactored table unnamed cells behaviour (#9264)

Closes: #7851 

[Screencast from 2024-12-28
00-53-55.webm](https://github.com/user-attachments/assets/17b05ebf-d375-4e19-a4e8-699bce876f5d)

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
Harsh Singh
2024-12-31 19:02:32 +05:30
committed by GitHub
parent 09cdfaa254
commit 45f14c8020
5 changed files with 42 additions and 8 deletions

View File

@ -1,6 +1,7 @@
import { useGetStandardObjectIcon } from '@/object-metadata/hooks/useGetStandardObjectIcon'; import { useGetStandardObjectIcon } from '@/object-metadata/hooks/useGetStandardObjectIcon';
import { useRecordChipData } from '@/object-record/hooks/useRecordChipData'; import { useRecordChipData } from '@/object-record/hooks/useRecordChipData';
import { ObjectRecord } from '@/object-record/types/ObjectRecord'; import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { isNonEmptyString } from '@sniptt/guards';
import { AvatarChip, AvatarChipVariant, ChipSize } from 'twenty-ui'; import { AvatarChip, AvatarChipVariant, ChipSize } from 'twenty-ui';
export type RecordIdentifierChipProps = { export type RecordIdentifierChipProps = {
@ -27,6 +28,11 @@ export const RecordIdentifierChip = ({
const { Icon: LeftIcon, IconColor: LeftIconColor } = const { Icon: LeftIcon, IconColor: LeftIconColor } =
useGetStandardObjectIcon(objectNameSingular); useGetStandardObjectIcon(objectNameSingular);
if (!isNonEmptyString(recordChipData.name.trim())) {
return null;
}
return ( return (
<AvatarChip <AvatarChip
placeholderColorSeed={record.id} placeholderColorSeed={record.id}

View File

@ -1,3 +1,4 @@
import { Theme, withTheme } from '@emotion/react';
import { styled } from '@linaria/react'; import { styled } from '@linaria/react';
import { Ref } from 'react'; import { Ref } from 'react';
@ -21,12 +22,18 @@ const StyledInnerContainer = styled.div`
white-space: nowrap; white-space: nowrap;
`; `;
const StyledEmptyPlaceholderField = withTheme(styled.div<{ theme: Theme }>`
color: ${({ theme }) => theme.font.color.light};
padding-left: 4px;
`);
export type EditableCellDisplayContainerProps = { export type EditableCellDisplayContainerProps = {
softFocus?: boolean; softFocus?: boolean;
onClick?: () => void; onClick?: () => void;
scrollRef?: Ref<HTMLDivElement>; scrollRef?: Ref<HTMLDivElement>;
isHovered?: boolean; isHovered?: boolean;
onContextMenu?: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void; onContextMenu?: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
placeholderForEmptyCell?: string;
}; };
export const RecordTableCellDisplayContainer = ({ export const RecordTableCellDisplayContainer = ({
@ -35,6 +42,7 @@ export const RecordTableCellDisplayContainer = ({
onClick, onClick,
scrollRef, scrollRef,
onContextMenu, onContextMenu,
placeholderForEmptyCell,
}: React.PropsWithChildren<EditableCellDisplayContainerProps>) => ( }: React.PropsWithChildren<EditableCellDisplayContainerProps>) => (
<StyledOuterContainer <StyledOuterContainer
data-testid={ data-testid={
@ -45,6 +53,12 @@ export const RecordTableCellDisplayContainer = ({
hasSoftFocus={softFocus} hasSoftFocus={softFocus}
onContextMenu={onContextMenu} onContextMenu={onContextMenu}
> >
<StyledInnerContainer>{children}</StyledInnerContainer> {placeholderForEmptyCell ? (
<StyledEmptyPlaceholderField>
{'Set ' + placeholderForEmptyCell}
</StyledEmptyPlaceholderField>
) : (
<StyledInnerContainer>{children}</StyledInnerContainer>
)}
</StyledOuterContainer> </StyledOuterContainer>
); );

View File

@ -33,7 +33,7 @@ export const RecordTableCellSoftFocusMode = ({
editModeContent, editModeContent,
nonEditModeContent, nonEditModeContent,
}: RecordTableCellSoftFocusModeProps) => { }: RecordTableCellSoftFocusModeProps) => {
const { columnIndex } = useContext(RecordTableCellContext); const { columnIndex, columnDefinition } = useContext(RecordTableCellContext);
const { recordId } = useContext(FieldContext); const { recordId } = useContext(FieldContext);
const { onActionMenuDropdownOpened } = useRecordTableBodyContextOrThrow(); const { onActionMenuDropdownOpened } = useRecordTableBodyContextOrThrow();
@ -128,7 +128,11 @@ export const RecordTableCellSoftFocusMode = ({
}; };
const handleButtonClick = () => { const handleButtonClick = () => {
handleClick(); if (!isFieldInputOnly && isFirstColumn) {
openTableCell(undefined, false, true);
} else {
openTableCell();
}
/* /*
Disabling sidepanel access for now, TODO: launch Disabling sidepanel access for now, TODO: launch
if (!isFieldInputOnly) { if (!isFieldInputOnly) {
@ -148,13 +152,13 @@ export const RecordTableCellSoftFocusMode = ({
: customButtonIcon; : customButtonIcon;
const showButton = const showButton =
isDefined(buttonIcon) && isDefined(buttonIcon) && !editModeContentOnly && !isFieldReadOnly;
!editModeContentOnly &&
(!isFirstColumn || !isEmpty) &&
!isFieldReadOnly;
const dontShowContent = isEmpty && isFieldReadOnly; const dontShowContent = isEmpty && isFieldReadOnly;
const showPlaceholder =
!editModeContentOnly && !isFieldReadOnly && isFirstColumn && isEmpty;
return ( return (
<> <>
<RecordTableCellDisplayContainer <RecordTableCellDisplayContainer
@ -162,6 +166,9 @@ export const RecordTableCellSoftFocusMode = ({
scrollRef={scrollRef} scrollRef={scrollRef}
softFocus softFocus
onContextMenu={handleActionMenuDropdown} onContextMenu={handleActionMenuDropdown}
placeholderForEmptyCell={
showPlaceholder ? columnDefinition.label : undefined
}
> >
{dontShowContent ? ( {dontShowContent ? (
<></> <></>

View File

@ -43,6 +43,7 @@ export const useOpenRecordTableCellFromCell = () => {
const openTableCell = ( const openTableCell = (
initialValue?: string, initialValue?: string,
isActionButtonClick = false, isActionButtonClick = false,
isNavigating = false,
) => { ) => {
onOpenTableCell({ onOpenTableCell({
cellPosition, cellPosition,
@ -54,6 +55,7 @@ export const useOpenRecordTableCellFromCell = () => {
objectNameSingular, objectNameSingular,
initialValue, initialValue,
isActionButtonClick, isActionButtonClick,
isNavigating,
}); });
}; };

View File

@ -42,6 +42,7 @@ export type OpenTableCellArgs = {
fieldDefinition: FieldDefinition<FieldMetadata>; fieldDefinition: FieldDefinition<FieldMetadata>;
recordId: string; recordId: string;
isActionButtonClick: boolean; isActionButtonClick: boolean;
isNavigating: boolean;
}; };
export const useOpenRecordTableCellV2 = (tableScopeId: string) => { export const useOpenRecordTableCellV2 = (tableScopeId: string) => {
@ -84,6 +85,7 @@ export const useOpenRecordTableCellV2 = (tableScopeId: string) => {
fieldDefinition, fieldDefinition,
recordId, recordId,
isActionButtonClick, isActionButtonClick,
isNavigating,
}: OpenTableCellArgs) => { }: OpenTableCellArgs) => {
if (isReadOnly) { if (isReadOnly) {
return; return;
@ -106,7 +108,10 @@ export const useOpenRecordTableCellV2 = (tableScopeId: string) => {
fieldValue, fieldValue,
}); });
if (isFirstColumnCell && !isEmpty && !isActionButtonClick) { if (
(isFirstColumnCell && !isEmpty && !isActionButtonClick) ||
isNavigating
) {
leaveTableFocus(); leaveTableFocus();
navigate(indexIdentifierUrl(recordId)); navigate(indexIdentifierUrl(recordId));