diff --git a/packages/twenty-front/src/modules/activities/inline-cell/components/ActivityTargetsInlineCell.tsx b/packages/twenty-front/src/modules/activities/inline-cell/components/ActivityTargetsInlineCell.tsx index 3bd64f9d62..4e0c2e33b6 100644 --- a/packages/twenty-front/src/modules/activities/inline-cell/components/ActivityTargetsInlineCell.tsx +++ b/packages/twenty-front/src/modules/activities/inline-cell/components/ActivityTargetsInlineCell.tsx @@ -37,8 +37,12 @@ export const ActivityTargetsInlineCell = ({ const { closeInlineCell } = useInlineCell(componentInstanceId); - const { fieldDefinition, isRecordFieldReadOnly: isReadOnly } = - useContext(FieldContext); + const { + fieldDefinition, + isRecordFieldReadOnly: isReadOnly, + anchorId, + onMouseEnter, + } = useContext(FieldContext); const { openActivityTargetCellEditMode } = useOpenActivityTargetCellEditMode(); @@ -61,6 +65,8 @@ export const ActivityTargetsInlineCell = ({ fieldMetadataName={fieldDefinition.metadata.fieldName} fieldPosition={3} overridenIsFieldEmpty={activityTargetObjectRecords.length === 0} + onMouseEnter={onMouseEnter} + anchorId={anchorId} > { + const instanceId = useAvailableComponentInstanceIdOrThrow( + RecordFieldListComponentInstanceContext, + ); + const editModePosition = useRecoilComponentValue( recordFieldListCellEditModePositionComponentState, ); @@ -35,7 +41,7 @@ export const RecordFieldListCellEditModePortal = ({ fieldMetadataItem={editedFieldMetadataItem} objectMetadataItem={objectMetadataItem} recordId={recordId} - anchorIdPrefix={'record-field-list-inline-cell'} + anchorIdPrefix={instanceId} > diff --git a/packages/twenty-front/src/modules/object-record/record-field-list/anchored-portal/components/RecordFieldListCellHoveredPortal.tsx b/packages/twenty-front/src/modules/object-record/record-field-list/anchored-portal/components/RecordFieldListCellHoveredPortal.tsx index 874858985a..6753140d38 100644 --- a/packages/twenty-front/src/modules/object-record/record-field-list/anchored-portal/components/RecordFieldListCellHoveredPortal.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field-list/anchored-portal/components/RecordFieldListCellHoveredPortal.tsx @@ -4,8 +4,10 @@ import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataI import { RecordFieldListCellHoveredPortalContent } from '@/object-record/record-field-list/anchored-portal/components/RecordFieldListCellHoveredPortalContent'; import { RecordFieldListInputContextProvider } from '@/object-record/record-field-list/anchored-portal/components/RecordFieldListInputContextProvider'; import { useFieldListFieldMetadataFromPosition } from '@/object-record/record-field-list/hooks/useFieldListFieldMetadataFromPosition'; +import { RecordFieldListComponentInstanceContext } from '@/object-record/record-field-list/states/contexts/RecordFieldListComponentInstanceContext'; import { recordFieldListHoverPositionComponentState } from '@/object-record/record-field-list/states/recordFieldListHoverPositionComponentState'; import { RecordInlineCellAnchoredPortal } from '@/object-record/record-inline-cell/components/RecordInlineCellAnchoredPortal'; +import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow'; import { isDefined } from 'twenty-shared/utils'; type RecordFieldListCellHoveredPortalProps = { @@ -17,6 +19,10 @@ export const RecordFieldListCellHoveredPortal = ({ objectMetadataItem, recordId, }: RecordFieldListCellHoveredPortalProps) => { + const instanceId = useAvailableComponentInstanceIdOrThrow( + RecordFieldListComponentInstanceContext, + ); + const hoverPosition = useRecoilComponentValue( recordFieldListHoverPositionComponentState, ); @@ -35,7 +41,7 @@ export const RecordFieldListCellHoveredPortal = ({ fieldMetadataItem={hoveredFieldMetadataItem} objectMetadataItem={objectMetadataItem} recordId={recordId} - anchorIdPrefix={'record-field-list-inline-cell'} + anchorIdPrefix={instanceId} > diff --git a/packages/twenty-front/src/modules/object-record/record-field-list/anchored-portal/components/RecordFieldListCellHoveredPortalContent.tsx b/packages/twenty-front/src/modules/object-record/record-field-list/anchored-portal/components/RecordFieldListCellHoveredPortalContent.tsx index 62b990cae9..868bfdfb16 100644 --- a/packages/twenty-front/src/modules/object-record/record-field-list/anchored-portal/components/RecordFieldListCellHoveredPortalContent.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field-list/anchored-portal/components/RecordFieldListCellHoveredPortalContent.tsx @@ -1,3 +1,4 @@ +import { RecordFieldListComponentInstanceContext } from '@/object-record/record-field-list/states/contexts/RecordFieldListComponentInstanceContext'; import { recordFieldListCellEditModePositionComponentState } from '@/object-record/record-field-list/states/recordFieldListCellEditModePositionComponentState'; import { recordFieldListHoverPositionComponentState } from '@/object-record/record-field-list/states/recordFieldListHoverPositionComponentState'; import { FieldDisplay } from '@/object-record/record-field/ui/components/FieldDisplay'; @@ -8,16 +9,28 @@ import { useRecordInlineCellContext } from '@/object-record/record-inline-cell/c import { RecordInlineCellDisplayMode } from '@/object-record/record-inline-cell/components/RecordInlineCellDisplayMode'; import { RecordInlineCellHoveredPortalContent } from '@/object-record/record-inline-cell/components/RecordInlineCellHoveredPortalContent'; import { useInlineCell } from '@/object-record/record-inline-cell/hooks/useInlineCell'; +import { getRecordFieldInputInstanceId } from '@/object-record/utils/getRecordFieldInputId'; +import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow'; import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState'; import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState'; import { useContext } from 'react'; export const RecordFieldListCellHoveredPortalContent = () => { + const instanceId = useAvailableComponentInstanceIdOrThrow( + RecordFieldListComponentInstanceContext, + ); + const { editModeContentOnly, isCentered } = useRecordInlineCellContext(); const { isRecordFieldReadOnly, recordId, fieldDefinition } = useContext(FieldContext); - const { openInlineCell } = useInlineCell(); + const { openInlineCell } = useInlineCell( + getRecordFieldInputInstanceId({ + recordId, + fieldName: fieldDefinition.metadata.fieldName, + prefix: instanceId, + }), + ); const shouldContainerBeClickable = !isRecordFieldReadOnly && !editModeContentOnly; @@ -38,7 +51,7 @@ export const RecordFieldListCellHoveredPortalContent = () => { openFieldInput({ fieldDefinition, recordId, - prefix: 'inline-cell', + prefix: instanceId, }); } }; @@ -51,10 +64,9 @@ export const RecordFieldListCellHoveredPortalContent = () => { - + {editModeContentOnly ? : } diff --git a/packages/twenty-front/src/modules/object-record/record-field-list/components/RecordFieldList.tsx b/packages/twenty-front/src/modules/object-record/record-field-list/components/RecordFieldList.tsx new file mode 100644 index 0000000000..9701d42810 --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/record-field-list/components/RecordFieldList.tsx @@ -0,0 +1,254 @@ +import { ActivityTargetsInlineCell } from '@/activities/inline-cell/components/ActivityTargetsInlineCell'; +import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; +import { type CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import { formatFieldMetadataItemAsColumnDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsColumnDefinition'; +import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions'; +import { RecordFieldListCellEditModePortal } from '@/object-record/record-field-list/anchored-portal/components/RecordFieldListCellEditModePortal'; +import { RecordFieldListCellHoveredPortal } from '@/object-record/record-field-list/anchored-portal/components/RecordFieldListCellHoveredPortal'; +import { useFieldListFieldMetadataItems } from '@/object-record/record-field-list/hooks/useFieldListFieldMetadataItems'; +import { RecordDetailDuplicatesSection } from '@/object-record/record-field-list/record-detail-section/duplicate/components/RecordDetailDuplicatesSection'; +import { RecordDetailRelationSection } from '@/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationSection'; +import { RecordFieldListComponentInstanceContext } from '@/object-record/record-field-list/states/contexts/RecordFieldListComponentInstanceContext'; +import { recordFieldListHoverPositionComponentState } from '@/object-record/record-field-list/states/recordFieldListHoverPositionComponentState'; +import { FieldContext } from '@/object-record/record-field/ui/contexts/FieldContext'; +import { useIsRecordReadOnly } from '@/object-record/record-field/ui/hooks/read-only/useIsRecordReadOnly'; +import { isRecordFieldReadOnly } from '@/object-record/record-field/ui/hooks/read-only/utils/isRecordFieldReadOnly'; +import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/ui/states/contexts/RecordFieldComponentInstanceContext'; +import { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell'; +import { PropertyBox } from '@/object-record/record-inline-cell/property-box/components/PropertyBox'; +import { PropertyBoxSkeletonLoader } from '@/object-record/record-inline-cell/property-box/components/PropertyBoxSkeletonLoader'; +import { useRecordShowContainerActions } from '@/object-record/record-show/hooks/useRecordShowContainerActions'; +import { useRecordShowContainerData } from '@/object-record/record-show/hooks/useRecordShowContainerData'; +import { getRecordFieldInputInstanceId } from '@/object-record/utils/getRecordFieldInputId'; +import { getObjectPermissionsFromMapByObjectMetadataId } from '@/settings/roles/role-permissions/objects-permissions/utils/getObjectPermissionsFromMapByObjectMetadataId'; +import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState'; + +type RecordFieldListProps = { + instanceId: string; + objectNameSingular: string; + objectRecordId: string; + showDuplicatesSection?: boolean; + showRelationSections?: boolean; + excludeFieldMetadataIds?: string[]; + excludeCreatedAtAndUpdatedAt?: boolean; +}; + +export const RecordFieldList = ({ + instanceId, + objectNameSingular, + objectRecordId, + showDuplicatesSection = true, + showRelationSections = true, + excludeFieldMetadataIds = [], + excludeCreatedAtAndUpdatedAt = true, +}: RecordFieldListProps) => { + const { recordLoading, isPrefetchLoading } = useRecordShowContainerData({ + objectRecordId, + }); + + const { objectMetadataItem } = useObjectMetadataItem({ + objectNameSingular, + }); + + const { objectPermissionsByObjectMetadataId } = useObjectPermissions(); + + const { useUpdateOneObjectRecordMutation } = useRecordShowContainerActions({ + objectNameSingular, + objectRecordId, + }); + + const isRecordReadOnly = useIsRecordReadOnly({ + recordId: objectRecordId, + objectMetadataId: objectMetadataItem.id, + }); + + const setRecordFieldListHoverPosition = useSetRecoilComponentState( + recordFieldListHoverPositionComponentState, + instanceId, + ); + + const handleMouseEnter = (index: number) => { + setRecordFieldListHoverPosition(index); + }; + + const { + inlineFieldMetadataItems, + inlineRelationFieldMetadataItems, + boxedRelationFieldMetadataItems, + } = useFieldListFieldMetadataItems({ + objectNameSingular, + excludeFieldMetadataIds, + showRelationSections, + excludeCreatedAtAndUpdatedAt, + }); + + return ( + + + {isPrefetchLoading ? ( + + ) : ( + <> + {inlineRelationFieldMetadataItems?.map( + (fieldMetadataItem, index) => ( + handleMouseEnter(index), + anchorId: `${instanceId}-${index}`, + isRecordFieldReadOnly: isRecordFieldReadOnly({ + isRecordReadOnly, + objectPermissions: + getObjectPermissionsFromMapByObjectMetadataId({ + objectPermissionsByObjectMetadataId, + objectMetadataId: objectMetadataItem.id, + }), + fieldMetadataId: fieldMetadataItem.id, + objectNameSingular, + fieldName: fieldMetadataItem.name, + fieldType: fieldMetadataItem.type, + isCustom: fieldMetadataItem.isCustom ?? false, + }), + }} + > + + + ), + )} + {inlineFieldMetadataItems?.map((fieldMetadataItem, index) => ( + + handleMouseEnter( + index + (inlineRelationFieldMetadataItems?.length ?? 0), + ), + anchorId: `${instanceId}-${ + index + (inlineRelationFieldMetadataItems?.length ?? 0) + }`, + }} + > + + + + + ))} + + )} + + {showDuplicatesSection && ( + + )} + {boxedRelationFieldMetadataItems?.map((fieldMetadataItem, index) => ( + + + + ))} + + + + + ); +}; diff --git a/packages/twenty-front/src/modules/object-record/record-field-list/hooks/useFieldListFieldMetadataItems.ts b/packages/twenty-front/src/modules/object-record/record-field-list/hooks/useFieldListFieldMetadataItems.ts index a5a8cc9f7f..c737012b64 100644 --- a/packages/twenty-front/src/modules/object-record/record-field-list/hooks/useFieldListFieldMetadataItems.ts +++ b/packages/twenty-front/src/modules/object-record/record-field-list/hooks/useFieldListFieldMetadataItems.ts @@ -11,10 +11,16 @@ import { isDefined } from 'twenty-shared/utils'; type UseFieldListFieldMetadataItemsProps = { objectNameSingular: string; + excludeFieldMetadataIds?: string[]; + excludeCreatedAtAndUpdatedAt?: boolean; + showRelationSections?: boolean; }; export const useFieldListFieldMetadataItems = ({ objectNameSingular, + excludeFieldMetadataIds = [], + showRelationSections = true, + excludeCreatedAtAndUpdatedAt = true, }: UseFieldListFieldMetadataItemsProps) => { const { labelIdentifierFieldMetadataItem } = useLabelIdentifierFieldMetadataItem({ @@ -33,7 +39,13 @@ export const useFieldListFieldMetadataItems = ({ .filter( (fieldMetadataItem) => isFieldCellSupported(fieldMetadataItem, objectMetadataItems) && - fieldMetadataItem.id !== labelIdentifierFieldMetadataItem?.id, + fieldMetadataItem.id !== labelIdentifierFieldMetadataItem?.id && + !excludeFieldMetadataIds.includes(fieldMetadataItem.id) && + (!excludeCreatedAtAndUpdatedAt || + (fieldMetadataItem.name !== 'createdAt' && + fieldMetadataItem.name !== 'deletedAt')) && + (showRelationSections || + fieldMetadataItem.type !== FieldMetadataType.RELATION), ) .sort((fieldMetadataItemA, fieldMetadataItemB) => fieldMetadataItemA.name.localeCompare(fieldMetadataItemB.name), diff --git a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRecordsList.tsx b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/components/RecordDetailRecordsListContainer.tsx similarity index 67% rename from packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRecordsList.tsx rename to packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/components/RecordDetailRecordsListContainer.tsx index 0317df9300..e7f670edb1 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRecordsList.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/components/RecordDetailRecordsListContainer.tsx @@ -4,4 +4,4 @@ const StyledRecordsList = styled.div` color: ${({ theme }) => theme.font.color.secondary}; `; -export { StyledRecordsList as RecordDetailRecordsList }; +export { StyledRecordsList as RecordDetailRecordsListContainer }; diff --git a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRecordsListItem.tsx b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/components/RecordDetailRecordsListItemContainer.tsx similarity index 78% rename from packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRecordsListItem.tsx rename to packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/components/RecordDetailRecordsListItemContainer.tsx index ca2762fca2..99a7640358 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRecordsListItem.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/components/RecordDetailRecordsListItemContainer.tsx @@ -8,4 +8,4 @@ const StyledListItem = styled.div` height: ${({ theme }) => theme.spacing(10)}; `; -export { StyledListItem as RecordDetailRecordsListItem }; +export { StyledListItem as RecordDetailRecordsListItemContainer }; diff --git a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailSectionHeader.tsx b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/components/RecordDetailSectionContainer.tsx similarity index 53% rename from packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailSectionHeader.tsx rename to packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/components/RecordDetailSectionContainer.tsx index 03d5f00924..5caddd41f6 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailSectionHeader.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/components/RecordDetailSectionContainer.tsx @@ -1,6 +1,14 @@ import styled from '@emotion/styled'; import { useState } from 'react'; import { Link } from 'react-router-dom'; +import { Section } from 'twenty-ui/layout'; + +const StyledRecordDetailSectionContainer = styled(Section)` + border-top: 1px solid ${({ theme }) => theme.border.color.light}; + padding-top: ${({ theme }) => theme.spacing(3)}; + padding-bottom: ${({ theme }) => theme.spacing(3)}; + width: auto; +`; const StyledHeader = styled.header<{ isDropdownOpen?: boolean; @@ -34,7 +42,8 @@ const StyledLink = styled(Link)` } `; -type RecordDetailSectionHeaderProps = { +type RecordDetailSectionContainerProps = { + children: React.ReactNode; title: string; link?: { to: string; label: string }; rightAdornment?: React.ReactNode; @@ -42,28 +51,31 @@ type RecordDetailSectionHeaderProps = { areRecordsAvailable?: boolean; }; -export const RecordDetailSectionHeader = ({ +export const RecordDetailSectionContainer = ({ + children, title, link, rightAdornment, hideRightAdornmentOnMouseLeave = true, areRecordsAvailable = false, -}: RecordDetailSectionHeaderProps) => { +}: RecordDetailSectionContainerProps) => { const [isHovered, setIsHovered] = useState(false); - return ( - setIsHovered(true)} - onMouseLeave={() => setIsHovered(false)} - > - - {title} - {link && {link.label}} - - {hideRightAdornmentOnMouseLeave && !isHovered && areRecordsAvailable - ? null - : rightAdornment} - + + setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} + > + + {title} + {link && {link.label}} + + {hideRightAdornmentOnMouseLeave && !isHovered && areRecordsAvailable + ? null + : rightAdornment} + + {children} + ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailDuplicatesSection.tsx b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/duplicate/components/RecordDetailDuplicatesSection.tsx similarity index 60% rename from packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailDuplicatesSection.tsx rename to packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/duplicate/components/RecordDetailDuplicatesSection.tsx index 72e23284c9..ad27dd25b7 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailDuplicatesSection.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/duplicate/components/RecordDetailDuplicatesSection.tsx @@ -2,10 +2,9 @@ import { useOpenMergeRecordsPageInCommandMenu } from '@/command-menu/hooks/useOp import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; import { RecordChip } from '@/object-record/components/RecordChip'; import { useFindDuplicateRecords } from '@/object-record/hooks/useFindDuplicateRecords'; -import { RecordDetailRecordsList } from '@/object-record/record-show/record-detail-section/components/RecordDetailRecordsList'; -import { RecordDetailRecordsListItem } from '@/object-record/record-show/record-detail-section/components/RecordDetailRecordsListItem'; -import { RecordDetailSection } from '@/object-record/record-show/record-detail-section/components/RecordDetailSection'; -import { RecordDetailSectionHeader } from '@/object-record/record-show/record-detail-section/components/RecordDetailSectionHeader'; +import { RecordDetailRecordsListContainer } from '@/object-record/record-field-list/record-detail-section/components/RecordDetailRecordsListContainer'; +import { RecordDetailRecordsListItemContainer } from '@/object-record/record-field-list/record-detail-section/components/RecordDetailRecordsListItemContainer'; +import { RecordDetailSectionContainer } from '@/object-record/record-field-list/record-detail-section/components/RecordDetailSectionContainer'; import { isDefined } from 'twenty-shared/utils'; import { IconArrowMerge } from 'twenty-ui/display'; @@ -44,28 +43,27 @@ export const RecordDetailDuplicatesSection = ({ return null; return ( - - - } - /> - + + } + > + {queryResults[0].slice(0, 5).map((duplicateRecord) => ( - + - + ))} - - + + ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/__stories__/RecordDetailDuplicatesSection.stories.tsx b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/duplicate/components/__stories__/RecordDetailDuplicatesSection.stories.tsx similarity index 92% rename from packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/__stories__/RecordDetailDuplicatesSection.stories.tsx rename to packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/duplicate/components/__stories__/RecordDetailDuplicatesSection.stories.tsx index 8a0dbc03af..962215a198 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/__stories__/RecordDetailDuplicatesSection.stories.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/duplicate/components/__stories__/RecordDetailDuplicatesSection.stories.tsx @@ -7,8 +7,8 @@ import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; import { getCompaniesMock } from '~/testing/mock-data/companies'; -import { RecordDetailDuplicatesSection } from '../RecordDetailDuplicatesSection'; import { ComponentDecorator } from 'twenty-ui/testing'; +import { RecordDetailDuplicatesSection } from '../../components/RecordDetailDuplicatesSection'; const companiesMock = getCompaniesMock(); diff --git a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationRecordsList.tsx b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationRecordsList.tsx similarity index 72% rename from packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationRecordsList.tsx rename to packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationRecordsList.tsx index 3ed1c87932..ac02ca7494 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationRecordsList.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationRecordsList.tsx @@ -1,8 +1,8 @@ import { Fragment, useState } from 'react'; -import { RecordDetailRecordsList } from '@/object-record/record-show/record-detail-section/components/RecordDetailRecordsList'; -import { RecordDetailRelationRecordsListItem } from '@/object-record/record-show/record-detail-section/components/RecordDetailRelationRecordsListItem'; -import { RecordDetailRelationRecordsListItemEffect } from '@/object-record/record-show/record-detail-section/components/RecordDetailRelationRecordsListItemEffect'; +import { RecordDetailRecordsListContainer } from '@/object-record/record-field-list/record-detail-section/components/RecordDetailRecordsListContainer'; +import { RecordDetailRelationRecordsListItem } from '@/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationRecordsListItem'; +import { RecordDetailRelationRecordsListItemEffect } from '@/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationRecordsListItemEffect'; import { type ObjectRecord } from '@/object-record/types/ObjectRecord'; type RecordDetailRelationRecordsListProps = { @@ -18,7 +18,7 @@ export const RecordDetailRelationRecordsList = ({ setExpandedItem(recordId === expandedItem ? '' : recordId); return ( - + {relationRecords.slice(0, 5).map((relationRecord) => ( ))} - + ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationRecordsListItem.tsx b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationRecordsListItem.tsx similarity index 66% rename from packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationRecordsListItem.tsx rename to packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationRecordsListItem.tsx index 079ea6a9eb..af6449004e 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationRecordsListItem.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationRecordsListItem.tsx @@ -4,33 +4,21 @@ import { motion } from 'framer-motion'; import { useCallback, useContext } from 'react'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; -import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; -import { formatFieldMetadataItemAsColumnDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsColumnDefinition'; import { getObjectTypename } from '@/object-record/cache/utils/getObjectTypename'; import { RecordChip } from '@/object-record/components/RecordChip'; import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord'; import { useObjectPermissionsForObject } from '@/object-record/hooks/useObjectPermissionsForObject'; import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord'; -import { - FieldContext, - type RecordUpdateHook, - type RecordUpdateHookParams, -} from '@/object-record/record-field/ui/contexts/FieldContext'; +import { RecordFieldList } from '@/object-record/record-field-list/components/RecordFieldList'; +import { RecordDetailRecordsListItemContainer } from '@/object-record/record-field-list/record-detail-section/components/RecordDetailRecordsListItemContainer'; +import { FieldContext } from '@/object-record/record-field/ui/contexts/FieldContext'; import { FieldInputEventContext } from '@/object-record/record-field/ui/contexts/FieldInputEventContext'; -import { useIsRecordReadOnly } from '@/object-record/record-field/ui/hooks/read-only/useIsRecordReadOnly'; -import { isRecordFieldReadOnly } from '@/object-record/record-field/ui/hooks/read-only/utils/isRecordFieldReadOnly'; -import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/ui/states/contexts/RecordFieldComponentInstanceContext'; import { type FieldRelationMetadata } from '@/object-record/record-field/ui/types/FieldMetadata'; -import { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell'; -import { PropertyBox } from '@/object-record/record-inline-cell/property-box/components/PropertyBox'; import { singleRecordPickerSelectedIdComponentState } from '@/object-record/record-picker/single-record-picker/states/singleRecordPickerSelectedIdComponentState'; -import { RecordDetailRecordsListItem } from '@/object-record/record-show/record-detail-section/components/RecordDetailRecordsListItem'; import { getRecordFieldCardRelationPickerDropdownId } from '@/object-record/record-show/utils/getRecordFieldCardRelationPickerDropdownId'; import { type ObjectRecord } from '@/object-record/types/ObjectRecord'; import { getForeignKeyNameFromRelationFieldName } from '@/object-record/utils/getForeignKeyNameFromRelationFieldName'; -import { getRecordFieldInputInstanceId } from '@/object-record/utils/getRecordFieldInputId'; -import { isFieldCellSupported } from '@/object-record/utils/isFieldCellSupported'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; @@ -38,6 +26,7 @@ import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown'; import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState'; import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal'; import { useModal } from '@/ui/layout/modal/hooks/useModal'; +import { useIsInRightDrawerOrThrow } from '@/ui/layout/right-drawer/contexts/RightDrawerContext'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState'; import { createPortal } from 'react-dom'; @@ -53,7 +42,7 @@ import { MenuItem } from 'twenty-ui/navigation'; import { AnimatedEaseInOut } from 'twenty-ui/utilities'; import { RelationType } from '~/generated-metadata/graphql'; -const StyledListItem = styled(RecordDetailRecordsListItem)<{ +const StyledListItem = styled(RecordDetailRecordsListItemContainer)<{ isDropdownOpen?: boolean; }>` ${({ isDropdownOpen, theme }) => @@ -74,14 +63,6 @@ const StyledListItem = styled(RecordDetailRecordsListItem)<{ } `; -const StyledPropertyBox = styled(PropertyBox)` - align-items: flex-start; - display: flex; - padding-left: ${({ theme }) => theme.spacing(0)}; - padding-top: ${({ theme }) => theme.spacing(1)}; - padding-right: ${({ theme }) => theme.spacing(0)}; -`; - const StyledClickableZone = styled.div` align-items: center; cursor: pointer; @@ -133,8 +114,6 @@ export const RecordDetailRelationRecordsListItem = ({ relationObjectMetadataNameSingular, ); - const { objectMetadataItems } = useObjectMetadataItems(); - const relationObjectPermissions = useObjectPermissionsForObject( relationObjectMetadataItem.id, ); @@ -150,18 +129,6 @@ export const RecordDetailRelationRecordsListItem = ({ relationObjectMetadataNameSingular === CoreObjectNameSingular.WorkspaceMember; - const availableRelationFieldMetadataItems = relationObjectMetadataItem.fields - .filter( - (fieldMetadataItem) => - isFieldCellSupported(fieldMetadataItem, objectMetadataItems) && - fieldMetadataItem.id !== - relationObjectMetadataItem.labelIdentifierFieldMetadataId && - fieldMetadataItem.id !== relationFieldMetadataId && - fieldMetadataItem.name !== 'createdAt' && - fieldMetadataItem.name !== 'deletedAt', - ) - .sort(); - const dropdownInstanceId = `record-field-card-menu-${relationFieldMetadataId}-${relationRecord.id}`; const { closeDropdown } = useCloseDropdown(); @@ -213,17 +180,6 @@ export const RecordDetailRelationRecordsListItem = ({ await deleteOneRelationRecord(relationRecord.id); }; - const useUpdateOneObjectRecordMutation: RecordUpdateHook = () => { - const updateEntity = ({ variables }: RecordUpdateHookParams) => { - updateOneRelationRecord?.({ - idToUpdate: variables.where.id as string, - updateOneRecordInput: variables.updateOneRecordInput, - }); - }; - - return [updateEntity, { loading: false }]; - }; - const handleClick = () => onClick(relationRecord.id); const AnimatedIconChevronDown = useCallback( @@ -240,10 +196,7 @@ export const RecordDetailRelationRecordsListItem = ({ [isExpanded], ); - const isRelationRecordReadOnly = useIsRecordReadOnly({ - recordId: relationRecord.id, - objectMetadataId: relationObjectMetadataItem.id, - }); + const { isInRightDrawer } = useIsInRightDrawerOrThrow(); return ( <> @@ -294,49 +247,14 @@ export const RecordDetailRelationRecordsListItem = ({ )} - - {availableRelationFieldMetadataItems.map( - (fieldMetadataItem, index) => ( - - - - - - ), - )} - + {createPortal( - - 0 - ? t`All (${relationRecordsCount})` - : '', - } - : undefined - } - hideRightAdornmentOnMouseLeave={!isDropdownOpen && !isMobile} - areRecordsAvailable={relationRecords.length > 0} - rightAdornment={ - - } - /> + 0 + ? t`All (${relationRecordsCount})` + : '', + } + : undefined + } + hideRightAdornmentOnMouseLeave={!isDropdownOpen && !isMobile} + areRecordsAvailable={relationRecords.length > 0} + rightAdornment={ + + } + > {relationRecords.length > 0 && ( )} - + ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSectionDropdown.tsx b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationSectionDropdown.tsx similarity index 90% rename from packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSectionDropdown.tsx rename to packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationSectionDropdown.tsx index 2003caf014..7e2154ff5b 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSectionDropdown.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationSectionDropdown.tsx @@ -1,11 +1,11 @@ import { useContext } from 'react'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; +import { RecordDetailRelationSectionDropdownToMany } from '@/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationSectionDropdownToMany'; +import { RecordDetailRelationSectionDropdownToOne } from '@/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationSectionDropdownToOne'; import { FieldContext } from '@/object-record/record-field/ui/contexts/FieldContext'; import { useIsRecordReadOnly } from '@/object-record/record-field/ui/hooks/read-only/useIsRecordReadOnly'; import { type FieldRelationMetadata } from '@/object-record/record-field/ui/types/FieldMetadata'; -import { RecordDetailRelationSectionDropdownToMany } from '@/object-record/record-show/record-detail-section/components/RecordDetailRelationSectionDropdownToMany'; -import { RecordDetailRelationSectionDropdownToOne } from '@/object-record/record-show/record-detail-section/components/RecordDetailRelationSectionDropdownToOne'; import { RelationType } from '~/generated-metadata/graphql'; type RecordDetailRelationSectionDropdownProps = { diff --git a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSectionDropdownToMany.tsx b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationSectionDropdownToMany.tsx similarity index 100% rename from packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSectionDropdownToMany.tsx rename to packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationSectionDropdownToMany.tsx diff --git a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSectionDropdownToOne.tsx b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationSectionDropdownToOne.tsx similarity index 100% rename from packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSectionDropdownToOne.tsx rename to packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationSectionDropdownToOne.tsx diff --git a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/__stories__/RecordDetailRelationSection.stories.tsx b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/relation/components/__stories__/RecordDetailRelationSection.stories.tsx similarity index 96% rename from packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/__stories__/RecordDetailRelationSection.stories.tsx rename to packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/relation/components/__stories__/RecordDetailRelationSection.stories.tsx index 2b0d3222a8..cf7af0787a 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/__stories__/RecordDetailRelationSection.stories.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/relation/components/__stories__/RecordDetailRelationSection.stories.tsx @@ -12,6 +12,7 @@ import { getCompaniesMock } from '~/testing/mock-data/companies'; import { ContextStoreComponentInstanceContext } from '@/context-store/states/contexts/ContextStoreComponentInstanceContext'; import { ComponentDecorator } from 'twenty-ui/testing'; import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator'; +import { RightDrawerDecorator } from '~/testing/decorators/RightDrawerDecorator'; import { allMockPersonRecords } from '~/testing/mock-data/people'; import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems'; import { RecordDetailRelationSection } from '../RecordDetailRelationSection'; @@ -52,6 +53,7 @@ const meta: Meta = { ), + RightDrawerDecorator, ComponentDecorator, ObjectMetadataItemsDecorator, SnackBarDecorator, diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/components/FieldContextProvider.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/components/FieldContextProvider.tsx index 9222248291..6d69733ae0 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/components/FieldContextProvider.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/components/FieldContextProvider.tsx @@ -18,6 +18,8 @@ export const FieldContextProvider = ({ objectRecordId, customUseUpdateOneObjectHook, overridenIsFieldEmpty, + onMouseEnter, + anchorId, children, }: { clearable?: boolean; @@ -28,6 +30,8 @@ export const FieldContextProvider = ({ objectRecordId: string; customUseUpdateOneObjectHook?: RecordUpdateHook; overridenIsFieldEmpty?: boolean; + onMouseEnter?: () => void; + anchorId?: string; children: ReactNode; }) => { const { objectMetadataItem } = useObjectMetadataItem({ @@ -81,6 +85,8 @@ export const FieldContextProvider = ({ clearable, overridenIsFieldEmpty, isRecordFieldReadOnly, + onMouseEnter, + anchorId, }} > {children} diff --git a/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellAnchoredPortal.tsx b/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellAnchoredPortal.tsx index c167cce131..ec91c71d50 100644 --- a/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellAnchoredPortal.tsx +++ b/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellAnchoredPortal.tsx @@ -91,7 +91,7 @@ export const RecordInlineCellAnchoredPortal = ({ instanceId: getRecordFieldInputInstanceId({ recordId, fieldName: fieldMetadataItem.name, - prefix: 'inline-cell', + prefix: anchorIdPrefix, }), }} > diff --git a/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellDisplayMode.tsx b/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellDisplayMode.tsx index c3e61c40e8..7bc66e7dae 100644 --- a/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellDisplayMode.tsx +++ b/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellDisplayMode.tsx @@ -64,8 +64,12 @@ const StyledEmptyField = styled.div` export const RecordInlineCellDisplayMode = ({ children, + onClick, isHovered, -}: React.PropsWithChildren<{ isHovered: boolean }>) => { +}: React.PropsWithChildren<{ + isHovered: boolean; + onClick?: () => void; +}>) => { const { t } = useLingui(); const { editModeContentOnly, showLabel, label, buttonIcon } = @@ -86,7 +90,10 @@ export const RecordInlineCellDisplayMode = ({ return ( <> - + {(isDisplayModeContentEmpty && !shouldDisplayEditModeOnFocus) || !children ? ( @@ -96,7 +103,9 @@ export const RecordInlineCellDisplayMode = ({ )} - {showEditButton && } + {showEditButton && ( + + )} ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellEditButton.tsx b/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellEditButton.tsx index 64a333a2e9..ca5781202c 100644 --- a/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellEditButton.tsx +++ b/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellEditButton.tsx @@ -8,10 +8,16 @@ const StyledInlineCellButtonContainer = styled.div` display: flex; `; -export const RecordInlineCellButton = ({ Icon }: { Icon: IconComponent }) => { +export const RecordInlineCellButton = ({ + Icon, + onClick, +}: { + Icon: IconComponent; + onClick?: () => void; +}) => { return ( - + - !readonly && - css` - cursor: pointer; - `}; `; const StyledInlineCellBaseContainer = styled.div<{ readonly: boolean }>` @@ -32,14 +25,12 @@ const StyledInlineCellBaseContainer = styled.div<{ readonly: boolean }>` gap: ${({ theme }) => theme.spacing(1)}; user-select: none; align-items: center; - cursor: ${({ readonly }) => (readonly ? 'default' : 'pointer')}; `; type RecordInlineCellHoveredPortalContentProps = { children: React.ReactNode; readonly: boolean; isCentered?: boolean; - onClick?: () => void; onMouseLeave?: () => void; }; @@ -47,14 +38,12 @@ export const RecordInlineCellHoveredPortalContent = ({ children, isCentered, readonly, - onClick, onMouseLeave, }: RecordInlineCellHoveredPortalContentProps) => { return ( { } return ( - <> - - - - - - + + + + + ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-inline-cell/property-box/components/PropertyBox.tsx b/packages/twenty-front/src/modules/object-record/record-inline-cell/property-box/components/PropertyBox.tsx index 6da09af203..9de21f49cd 100644 --- a/packages/twenty-front/src/modules/object-record/record-inline-cell/property-box/components/PropertyBox.tsx +++ b/packages/twenty-front/src/modules/object-record/record-inline-cell/property-box/components/PropertyBox.tsx @@ -11,8 +11,8 @@ export const StyledPropertyBoxContainer = styled.div` display: flex; flex-direction: column; gap: ${({ theme }) => theme.spacing(2)}; - padding: ${({ theme }) => theme.spacing(3)}; - padding-right: ${({ theme }) => theme.spacing(2)}; + padding-top: ${({ theme }) => theme.spacing(3)}; + padding-bottom: ${({ theme }) => theme.spacing(3)}; `; export const PropertyBox = ({ children, className }: PropertyBoxProps) => ( diff --git a/packages/twenty-front/src/modules/object-record/record-show/components/FieldsCard.tsx b/packages/twenty-front/src/modules/object-record/record-show/components/FieldsCard.tsx index 3345d65811..e0f3863830 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/components/FieldsCard.tsx +++ b/packages/twenty-front/src/modules/object-record/record-show/components/FieldsCard.tsx @@ -1,28 +1,11 @@ -import { ActivityTargetsInlineCell } from '@/activities/inline-cell/components/ActivityTargetsInlineCell'; -import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; -import { type CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; -import { formatFieldMetadataItemAsColumnDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsColumnDefinition'; -import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions'; -import { RecordFieldListCellEditModePortal } from '@/object-record/record-field-list/anchored-portal/components/RecordFieldListCellEditModePortal'; -import { RecordFieldListCellHoveredPortal } from '@/object-record/record-field-list/anchored-portal/components/RecordFieldListCellHoveredPortal'; -import { useFieldListFieldMetadataItems } from '@/object-record/record-field-list/hooks/useFieldListFieldMetadataItems'; -import { RecordFieldListComponentInstanceContext } from '@/object-record/record-field-list/states/contexts/RecordFieldListComponentInstanceContext'; -import { recordFieldListHoverPositionComponentState } from '@/object-record/record-field-list/states/recordFieldListHoverPositionComponentState'; -import { FieldContext } from '@/object-record/record-field/ui/contexts/FieldContext'; -import { useIsRecordReadOnly } from '@/object-record/record-field/ui/hooks/read-only/useIsRecordReadOnly'; -import { isRecordFieldReadOnly } from '@/object-record/record-field/ui/hooks/read-only/utils/isRecordFieldReadOnly'; -import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/ui/states/contexts/RecordFieldComponentInstanceContext'; -import { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell'; -import { PropertyBox } from '@/object-record/record-inline-cell/property-box/components/PropertyBox'; -import { PropertyBoxSkeletonLoader } from '@/object-record/record-inline-cell/property-box/components/PropertyBoxSkeletonLoader'; -import { useRecordShowContainerActions } from '@/object-record/record-show/hooks/useRecordShowContainerActions'; -import { useRecordShowContainerData } from '@/object-record/record-show/hooks/useRecordShowContainerData'; -import { RecordDetailDuplicatesSection } from '@/object-record/record-show/record-detail-section/components/RecordDetailDuplicatesSection'; -import { RecordDetailRelationSection } from '@/object-record/record-show/record-detail-section/components/RecordDetailRelationSection'; -import { getRecordFieldInputInstanceId } from '@/object-record/utils/getRecordFieldInputId'; -import { getObjectPermissionsFromMapByObjectMetadataId } from '@/settings/roles/role-permissions/objects-permissions/utils/getObjectPermissionsFromMapByObjectMetadataId'; +import { RecordFieldList } from '@/object-record/record-field-list/components/RecordFieldList'; import { useIsInRightDrawerOrThrow } from '@/ui/layout/right-drawer/contexts/RightDrawerContext'; -import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState'; +import styled from '@emotion/styled'; + +const StyledPropertyBoxContainer = styled.div` + padding: ${({ theme }) => theme.spacing(3)}; + padding-right: ${({ theme }) => theme.spacing(2)}; +`; type FieldsCardProps = { objectNameSingular: string; @@ -30,219 +13,21 @@ type FieldsCardProps = { showDuplicatesSection?: boolean; }; -const INPUT_ID_PREFIX = 'fields-card'; - export const FieldsCard = ({ objectNameSingular, objectRecordId, showDuplicatesSection = true, }: FieldsCardProps) => { - const { recordLoading, isPrefetchLoading } = useRecordShowContainerData({ - objectRecordId, - }); - - const { objectMetadataItem } = useObjectMetadataItem({ - objectNameSingular, - }); - - const { objectPermissionsByObjectMetadataId } = useObjectPermissions(); - - const { useUpdateOneObjectRecordMutation } = useRecordShowContainerActions({ - objectNameSingular, - objectRecordId, - }); - const { isInRightDrawer } = useIsInRightDrawerOrThrow(); - const isRecordReadOnly = useIsRecordReadOnly({ - recordId: objectRecordId, - objectMetadataId: objectMetadataItem.id, - }); - - const setRecordFieldListHoverPosition = useSetRecoilComponentState( - recordFieldListHoverPositionComponentState, - `fields-list-${objectRecordId}`, - ); - - const handleMouseEnter = (index: number) => { - setRecordFieldListHoverPosition(index); - }; - - const { - inlineFieldMetadataItems, - inlineRelationFieldMetadataItems, - boxedRelationFieldMetadataItems, - } = useFieldListFieldMetadataItems({ - objectNameSingular, - }); - return ( - - - {isPrefetchLoading ? ( - - ) : ( - <> - {inlineRelationFieldMetadataItems?.map( - (fieldMetadataItem, index) => ( - - - - ), - )} - {inlineFieldMetadataItems?.map((fieldMetadataItem, index) => ( - - handleMouseEnter( - index + (inlineRelationFieldMetadataItems?.length ?? 0), - ), - anchorId: `record-field-list-inline-cell-${ - index + (inlineRelationFieldMetadataItems?.length ?? 0) - }`, - }} - > - - - - - ))} - - )} - - {showDuplicatesSection && ( - - )} - {boxedRelationFieldMetadataItems?.map((fieldMetadataItem, index) => ( - - - - ))} - - + - - + ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailSection.tsx b/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailSection.tsx deleted file mode 100644 index 537c2f8e6f..0000000000 --- a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailSection.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import styled from '@emotion/styled'; -import { Section } from 'twenty-ui/layout'; - -const StyledRecordDetailSection = styled(Section)` - border-top: 1px solid ${({ theme }) => theme.border.color.light}; - padding: ${({ theme }) => theme.spacing(3)}; - padding-right: ${({ theme }) => theme.spacing(2)}; - width: auto; -`; - -export { StyledRecordDetailSection as RecordDetailSection };