diff --git a/packages/twenty-front/src/modules/page-layout/components/PageLayoutRendererContent.tsx b/packages/twenty-front/src/modules/page-layout/components/PageLayoutRendererContent.tsx index cb98ae65b8..16894efd4c 100644 --- a/packages/twenty-front/src/modules/page-layout/components/PageLayoutRendererContent.tsx +++ b/packages/twenty-front/src/modules/page-layout/components/PageLayoutRendererContent.tsx @@ -1,7 +1,6 @@ import { useNavigatePageLayoutCommandMenu } from '@/command-menu/pages/page-layout/hooks/useNavigatePageLayoutCommandMenu'; import { CommandMenuPages } from '@/command-menu/types/CommandMenuPages'; import { PageLayoutLeftPanel } from '@/page-layout/components/PageLayoutLeftPanel'; -import { PageLayoutTabHeader } from '@/page-layout/components/PageLayoutTabHeader'; import { PageLayoutTabList } from '@/page-layout/components/PageLayoutTabList'; import { PageLayoutTabListEffect } from '@/page-layout/components/PageLayoutTabListEffect'; import { PAGE_LAYOUT_LEFT_PANEL_CONTAINER_WIDTH } from '@/page-layout/constants/PageLayoutLeftPanelContainerWidth'; @@ -21,8 +20,8 @@ import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTab import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState'; -import { t } from '@lingui/core/macro'; import styled from '@emotion/styled'; +import { t } from '@lingui/core/macro'; import { isDefined } from 'twenty-shared/utils'; import { useIsMobile } from 'twenty-ui/utilities'; @@ -129,8 +128,6 @@ export const PageLayoutRendererContent = () => { /> )} - - { - const { currentPageLayout } = useCurrentPageLayout(); - const targetRecordIdentifier = useTargetRecord(); - const { isInRightDrawer } = useLayoutRenderingContext(); - const isMobile = useIsMobile(); - - if ( - currentPageLayout?.type !== PageLayoutType.RECORD_PAGE || - !(isMobile || isInRightDrawer) - ) { - return null; - } - - return ( - - ); -}; diff --git a/packages/twenty-front/src/modules/page-layout/constants/DefaultCompanyRecordPageLayout.ts b/packages/twenty-front/src/modules/page-layout/constants/DefaultCompanyRecordPageLayout.ts index 163508face..8f13d2b3a2 100644 --- a/packages/twenty-front/src/modules/page-layout/constants/DefaultCompanyRecordPageLayout.ts +++ b/packages/twenty-front/src/modules/page-layout/constants/DefaultCompanyRecordPageLayout.ts @@ -19,8 +19,8 @@ export const DEFAULT_COMPANY_RECORD_PAGE_LAYOUT: PageLayout = { { __typename: 'PageLayoutTab', id: 'company-tab-fields', - title: 'Fields', - icon: 'IconList', + title: 'Home', + icon: 'IconHome', position: 100, layoutMode: 'vertical-list', pageLayoutId: DEFAULT_COMPANY_RECORD_PAGE_LAYOUT_ID, diff --git a/packages/twenty-front/src/modules/page-layout/constants/DefaultNoteRecordPageLayout.ts b/packages/twenty-front/src/modules/page-layout/constants/DefaultNoteRecordPageLayout.ts index 4f2c8f7e6d..bb84d90b94 100644 --- a/packages/twenty-front/src/modules/page-layout/constants/DefaultNoteRecordPageLayout.ts +++ b/packages/twenty-front/src/modules/page-layout/constants/DefaultNoteRecordPageLayout.ts @@ -15,8 +15,8 @@ export const DEFAULT_NOTE_RECORD_PAGE_LAYOUT: PageLayout = { { __typename: 'PageLayoutTab', id: 'note-tab-fields', - title: 'Fields', - icon: 'IconList', + title: 'Home', + icon: 'IconHome', position: 100, layoutMode: 'vertical-list', pageLayoutId: DEFAULT_NOTE_RECORD_PAGE_LAYOUT_ID, diff --git a/packages/twenty-front/src/modules/page-layout/constants/DefaultOpportunityRecordPageLayout.ts b/packages/twenty-front/src/modules/page-layout/constants/DefaultOpportunityRecordPageLayout.ts index b1a861b7af..efb1918daa 100644 --- a/packages/twenty-front/src/modules/page-layout/constants/DefaultOpportunityRecordPageLayout.ts +++ b/packages/twenty-front/src/modules/page-layout/constants/DefaultOpportunityRecordPageLayout.ts @@ -19,8 +19,8 @@ export const DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT: PageLayout = { { __typename: 'PageLayoutTab', id: 'opportunity-tab-fields', - title: 'Fields', - icon: 'IconList', + title: 'Home', + icon: 'IconHome', position: 100, layoutMode: 'vertical-list', pageLayoutId: DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT_ID, diff --git a/packages/twenty-front/src/modules/page-layout/constants/DefaultPersonRecordPageLayout.ts b/packages/twenty-front/src/modules/page-layout/constants/DefaultPersonRecordPageLayout.ts index eae962217f..fda7b1cc6b 100644 --- a/packages/twenty-front/src/modules/page-layout/constants/DefaultPersonRecordPageLayout.ts +++ b/packages/twenty-front/src/modules/page-layout/constants/DefaultPersonRecordPageLayout.ts @@ -15,8 +15,8 @@ export const DEFAULT_PERSON_RECORD_PAGE_LAYOUT: PageLayout = { { __typename: 'PageLayoutTab', id: 'person-tab-fields', - title: 'Fields', - icon: 'IconList', + title: 'Home', + icon: 'IconHome', position: 100, layoutMode: 'vertical-list', pageLayoutId: DEFAULT_PERSON_RECORD_PAGE_LAYOUT_ID, diff --git a/packages/twenty-front/src/modules/page-layout/constants/DefaultRecordPageLayout.ts b/packages/twenty-front/src/modules/page-layout/constants/DefaultRecordPageLayout.ts index 23b686112d..183c6a77fd 100644 --- a/packages/twenty-front/src/modules/page-layout/constants/DefaultRecordPageLayout.ts +++ b/packages/twenty-front/src/modules/page-layout/constants/DefaultRecordPageLayout.ts @@ -15,8 +15,8 @@ export const DEFAULT_RECORD_PAGE_LAYOUT: PageLayout = { { __typename: 'PageLayoutTab', id: 'default-tab-fields', - title: 'Fields', - icon: 'IconList', + title: 'Home', + icon: 'IconHome', position: 100, layoutMode: 'vertical-list', pageLayoutId: DEFAULT_RECORD_PAGE_LAYOUT_ID, diff --git a/packages/twenty-front/src/modules/page-layout/constants/DefaultTaskRecordPageLayout.ts b/packages/twenty-front/src/modules/page-layout/constants/DefaultTaskRecordPageLayout.ts index 7f9ed918ae..50bb968b00 100644 --- a/packages/twenty-front/src/modules/page-layout/constants/DefaultTaskRecordPageLayout.ts +++ b/packages/twenty-front/src/modules/page-layout/constants/DefaultTaskRecordPageLayout.ts @@ -15,8 +15,8 @@ export const DEFAULT_TASK_RECORD_PAGE_LAYOUT: PageLayout = { { __typename: 'PageLayoutTab', id: 'task-tab-fields', - title: 'Fields', - icon: 'IconList', + title: 'Home', + icon: 'IconHome', position: 100, layoutMode: 'vertical-list', pageLayoutId: DEFAULT_TASK_RECORD_PAGE_LAYOUT_ID, diff --git a/packages/twenty-front/src/modules/page-layout/constants/DefaultWorkflowRunPageLayout.ts b/packages/twenty-front/src/modules/page-layout/constants/DefaultWorkflowRunPageLayout.ts index 8bc38cef00..6f96d57156 100644 --- a/packages/twenty-front/src/modules/page-layout/constants/DefaultWorkflowRunPageLayout.ts +++ b/packages/twenty-front/src/modules/page-layout/constants/DefaultWorkflowRunPageLayout.ts @@ -21,10 +21,10 @@ export const DEFAULT_WORKFLOW_RUN_PAGE_LAYOUT: PageLayout = { { __typename: 'PageLayoutTab', id: 'workflow-run-tab-fields', - title: 'Fields', + title: 'Home', position: 100, layoutMode: 'vertical-list', - icon: 'IconList', + icon: 'IconHome', pageLayoutId: DEFAULT_WORKFLOW_RUN_PAGE_LAYOUT_ID, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), diff --git a/packages/twenty-front/src/modules/page-layout/constants/DefaultWorkflowVersionPageLayout.ts b/packages/twenty-front/src/modules/page-layout/constants/DefaultWorkflowVersionPageLayout.ts index 76249f98f6..b9811c4d75 100644 --- a/packages/twenty-front/src/modules/page-layout/constants/DefaultWorkflowVersionPageLayout.ts +++ b/packages/twenty-front/src/modules/page-layout/constants/DefaultWorkflowVersionPageLayout.ts @@ -21,8 +21,8 @@ export const DEFAULT_WORKFLOW_VERSION_PAGE_LAYOUT: PageLayout = { { __typename: 'PageLayoutTab', id: 'workflow-version-tab-fields', - title: 'Fields', - icon: 'IconList', + title: 'Home', + icon: 'IconHome', position: 100, layoutMode: 'vertical-list', pageLayoutId: DEFAULT_WORKFLOW_VERSION_PAGE_LAYOUT_ID, diff --git a/packages/twenty-front/src/modules/page-layout/hooks/useTemporaryFieldsConfiguration.ts b/packages/twenty-front/src/modules/page-layout/hooks/useTemporaryFieldsConfiguration.ts index 3dd9f2b870..3565e07bf3 100644 --- a/packages/twenty-front/src/modules/page-layout/hooks/useTemporaryFieldsConfiguration.ts +++ b/packages/twenty-front/src/modules/page-layout/hooks/useTemporaryFieldsConfiguration.ts @@ -3,30 +3,24 @@ import { type FieldsConfiguration } from '@/page-layout/types/FieldsConfiguratio import { useLingui } from '@lingui/react/macro'; import { useMemo } from 'react'; import { isDefined } from 'twenty-shared/utils'; -import { FieldMetadataType } from '~/generated-metadata/graphql'; export const useTemporaryFieldsConfiguration = ( objectNameSingular: string, -): FieldsConfiguration | null => { +): FieldsConfiguration => { const { t } = useLingui(); const { objectMetadataItem } = useObjectMetadataItem({ objectNameSingular, }); - const configuration = useMemo(() => { + const configuration = useMemo(() => { if (!isDefined(objectMetadataItem)) { - return null; + throw new Error('Object metadata item is not defined'); } - const fieldsToDisplay = objectMetadataItem.fields.filter( - (field) => - field.type !== FieldMetadataType.RELATION && - field.type !== FieldMetadataType.MORPH_RELATION && - field.type !== FieldMetadataType.RICH_TEXT_V2, - ); + const fieldsToDisplay = objectMetadataItem.fields; if (fieldsToDisplay.length === 0) { - return null; + throw new Error('No fields to display'); } const generalFields: Array<{ fieldMetadataId: string; position: number }> = @@ -72,7 +66,7 @@ export const useTemporaryFieldsConfiguration = ( } if (sections.length === 0) { - return null; + throw new Error('No sections to display'); } return { diff --git a/packages/twenty-front/src/modules/page-layout/widgets/components/WidgetActionFieldSeeAll.tsx b/packages/twenty-front/src/modules/page-layout/widgets/components/WidgetActionFieldSeeAll.tsx index d99973742c..d440633e2c 100644 --- a/packages/twenty-front/src/modules/page-layout/widgets/components/WidgetActionFieldSeeAll.tsx +++ b/packages/twenty-front/src/modules/page-layout/widgets/components/WidgetActionFieldSeeAll.tsx @@ -9,16 +9,22 @@ import { isFieldWidget } from '@/page-layout/widgets/field/utils/isFieldWidget'; import { useCurrentWidget } from '@/page-layout/widgets/hooks/useCurrentWidget'; import { useTargetRecord } from '@/ui/layout/contexts/useTargetRecord'; import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; +import { coreIndexViewIdFromObjectMetadataItemFamilySelector } from '@/views/states/selectors/coreIndexViewIdFromObjectMetadataItemFamilySelector'; import { css } from '@emotion/react'; import styled from '@emotion/styled'; +import { t } from '@lingui/core/macro'; +import { Link } from 'react-router-dom'; import { useRecoilValue } from 'recoil'; import { AppPath, ViewFilterOperand } from 'twenty-shared/types'; import { getAppPath, isDefined } from 'twenty-shared/utils'; -import { IconArrowUpRight } from 'twenty-ui/display'; +import { + AppTooltip, + IconArrowUpRight, + TooltipDelay, + TooltipPosition, +} from 'twenty-ui/display'; import { LightIconButton } from 'twenty-ui/input'; import { RelationType } from '~/generated-metadata/graphql'; -import { coreIndexViewIdFromObjectMetadataItemFamilySelector } from '@/views/states/selectors/coreIndexViewIdFromObjectMetadataItemFamilySelector'; -import { Link } from 'react-router-dom'; const StyledLink = styled(Link)` display: flex; @@ -120,13 +126,30 @@ export const WidgetActionFieldSeeAll = () => { filterQueryParams, ); + const tooltipId = `widget-see-all-${widget.id}`; + const relationLabelPlural = + relationObjectMetadataItem.labelPlural.toLowerCase(); + const tooltipContent = t`See all ${relationLabelPlural} linked to this record`; + return ( - - +
+ + + +
+ -
+ ); }; diff --git a/packages/twenty-front/src/modules/page-layout/widgets/fields/components/FieldsWidget.tsx b/packages/twenty-front/src/modules/page-layout/widgets/fields/components/FieldsWidget.tsx index 5936d67818..3a12e62bea 100644 --- a/packages/twenty-front/src/modules/page-layout/widgets/fields/components/FieldsWidget.tsx +++ b/packages/twenty-front/src/modules/page-layout/widgets/fields/components/FieldsWidget.tsx @@ -1,4 +1,6 @@ +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 { useIsRecordReadOnly } from '@/object-record/read-only/hooks/useIsRecordReadOnly'; @@ -6,6 +8,7 @@ import { isRecordFieldReadOnly } from '@/object-record/read-only/utils/isRecordF import { RecordFieldsScopeContextProvider } from '@/object-record/record-field-list/contexts/RecordFieldsScopeContext'; import { RecordFieldListComponentInstanceContext } from '@/object-record/record-field-list/states/contexts/RecordFieldListComponentInstanceContext'; import { recordFieldListHoverPositionComponentState } from '@/object-record/record-field-list/states/recordFieldListHoverPositionComponentState'; +import { isActivityTargetField } from '@/object-record/record-field-list/utils/categorizeRelationFields'; import { FieldContext } from '@/object-record/record-field/ui/contexts/FieldContext'; import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/ui/states/contexts/RecordFieldComponentInstanceContext'; import { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell'; @@ -90,7 +93,9 @@ export const FieldsWidget = ({ widget }: FieldsWidgetProps) => { targetRecord.targetObjectNameSingular, ); - if (sectionsWithFieldIndices.length === 0) { + const hasFieldsToDisplay = sectionsWithFieldIndices.length > 0; + + if (!hasFieldsToDisplay) { return ( @@ -133,6 +138,11 @@ export const FieldsWidget = ({ widget }: FieldsWidgetProps) => { <> {section.fields.map( ({ field: fieldMetadataItem, globalIndex }) => { + const isActivityTarget = isActivityTargetField( + fieldMetadataItem.name, + targetRecord.targetObjectNameSingular, + ); + return ( { })}`, }} > - - - + {isActivityTarget ? ( + + ) : ( + + + + )} ); }, diff --git a/packages/twenty-front/src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetFieldMetadataItems.ts b/packages/twenty-front/src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetFieldMetadataItems.ts index 432a79f19a..3c49ba1654 100644 --- a/packages/twenty-front/src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetFieldMetadataItems.ts +++ b/packages/twenty-front/src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetFieldMetadataItems.ts @@ -1,4 +1,3 @@ -import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; import { useFieldListFieldMetadataItems } from '@/object-record/record-field-list/hooks/useFieldListFieldMetadataItems'; type UseFieldsWidgetFieldMetadataItemsProps = { @@ -7,13 +6,17 @@ type UseFieldsWidgetFieldMetadataItemsProps = { export const useFieldsWidgetFieldMetadataItems = ({ objectNameSingular, -}: UseFieldsWidgetFieldMetadataItemsProps): FieldMetadataItem[] => { - const { inlineFieldMetadataItems } = useFieldListFieldMetadataItems({ - objectNameSingular, - excludeFieldMetadataIds: [], - excludeCreatedAtAndUpdatedAt: true, - showRelationSections: false, - }); +}: UseFieldsWidgetFieldMetadataItemsProps) => { + const { inlineFieldMetadataItems, legacyActivityTargetFieldMetadataItems } = + useFieldListFieldMetadataItems({ + objectNameSingular, + excludeFieldMetadataIds: [], + excludeCreatedAtAndUpdatedAt: true, + showRelationSections: true, + }); - return inlineFieldMetadataItems ?? []; + return { + inlineFieldMetadataItems, + legacyActivityTargetFieldMetadataItems, + }; }; diff --git a/packages/twenty-front/src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetSectionsWithFields.ts b/packages/twenty-front/src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetSectionsWithFields.ts index ea719be779..a8981495c7 100644 --- a/packages/twenty-front/src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetSectionsWithFields.ts +++ b/packages/twenty-front/src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetSectionsWithFields.ts @@ -10,21 +10,23 @@ export const useFieldsWidgetSectionsWithFields = ( ) => { const isMobile = useIsMobile(); const { isInRightDrawer } = useLayoutRenderingContext(); - const fieldMetadataItems = useFieldsWidgetFieldMetadataItems({ - objectNameSingular, - }); + const { inlineFieldMetadataItems, legacyActivityTargetFieldMetadataItems } = + useFieldsWidgetFieldMetadataItems({ + objectNameSingular, + }); const temporaryConfiguration = useTemporaryFieldsConfiguration(objectNameSingular); const context = buildWidgetVisibilityContext({ isMobile, isInRightDrawer }); + const allFieldMetadataItems = [ + ...legacyActivityTargetFieldMetadataItems, + ...inlineFieldMetadataItems, + ]; + const sectionsWithFields = filterAndOrderFieldsFromConfiguration({ - configuration: temporaryConfiguration ?? { - __typename: 'FieldsConfiguration', - configurationType: 'FIELDS', - sections: [], - }, - availableFieldMetadataItems: fieldMetadataItems, + configuration: temporaryConfiguration, + availableFieldMetadataItems: allFieldMetadataItems, context, });