Rpl various fixes (#19668)

This commit is contained in:
Baptiste Devessier
2026-04-14 11:46:15 +02:00
committed by GitHub
parent 9c07ecd363
commit b817bdca02
8 changed files with 58 additions and 89 deletions
@@ -58,6 +58,7 @@ const StyledContainer = styled.div`
box-sizing: border-box;
display: flex;
height: ${TAB_LIST_HEIGHT};
padding-left: ${themeCssVariables.spacing[2]};
position: relative;
user-select: none;
width: 100%;
@@ -28,7 +28,6 @@ import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { SidePanelPages } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { useIsMobile } from 'twenty-ui/utilities';
import { FeatureFlagKey } from '~/generated-metadata/graphql';
@@ -47,10 +46,6 @@ const StyledTabsAndDashboardContainer = styled.div`
overflow: hidden;
`;
const StyledPageLayoutTabListContainer = styled.div`
padding-left: ${themeCssVariables.spacing[2]};
`;
const StyledScrollWrapperContainer = styled.div`
flex: 1;
min-height: 0;
@@ -168,27 +163,25 @@ export const PageLayoutTabsRenderer = () => {
}
/>
{(sortedTabs.length > 1 || isPageLayoutInEditMode) && (
<StyledPageLayoutTabListContainer>
<PageLayoutTabList
tabs={sortedTabs}
behaveAsLinks={!isInSidePanel && !isPageLayoutInEditMode}
isInSidePanel={isInSidePanel}
componentInstanceId={tabListInstanceId}
onAddTab={handleAddTab}
isReorderEnabled={canEnableTabEditing}
onReorder={
canEnableTabEditing
? (result, provided) =>
reorderRecordPageTabs(
result,
provided,
isDefined(pinnedLeftTab),
)
: undefined
}
pageLayoutType={currentPageLayout.type}
/>
</StyledPageLayoutTabListContainer>
<PageLayoutTabList
tabs={sortedTabs}
behaveAsLinks={!isInSidePanel && !isPageLayoutInEditMode}
isInSidePanel={isInSidePanel}
componentInstanceId={tabListInstanceId}
onAddTab={handleAddTab}
isReorderEnabled={canEnableTabEditing}
onReorder={
canEnableTabEditing
? (result, provided) =>
reorderRecordPageTabs(
result,
provided,
isDefined(pinnedLeftTab),
)
: undefined
}
pageLayoutType={currentPageLayout.type}
/>
)}
<StyledScrollWrapperContainer>
@@ -87,7 +87,7 @@ export const PageLayoutVerticalListEditor = ({
<StyledVerticalListContainer
ref={provided.innerRef}
variant={variant}
shouldUseWhiteBackground={isMobile || isInSidePanel}
shouldUseWhiteBackground={!isInPinnedTab || isMobile}
// oxlint-disable-next-line react/jsx-props-no-spreading
{...provided.droppableProps}
>
@@ -45,7 +45,7 @@ export const PageLayoutVerticalListViewer = ({
return (
<StyledVerticalListContainer
variant={variant}
shouldUseWhiteBackground={isMobile || isInSidePanel}
shouldUseWhiteBackground={!isInPinnedTab || isMobile}
>
{widgets.map((widget) => (
<div key={widget.id}>
@@ -9,7 +9,6 @@ import { useResolveFieldMetadataIdFromNameOrId } from '@/page-layout/hooks/useRe
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 { useAtomFamilySelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilySelectorValue';
import { indexViewIdFromObjectMetadataItemFamilySelector } from '@/views/states/selectors/indexViewIdFromObjectMetadataItemFamilySelector';
import { styled } from '@linaria/react';
@@ -24,7 +23,6 @@ import {
TooltipPosition,
} from 'twenty-ui/display';
import { LightIconButton } from 'twenty-ui/input';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { RelationType } from '~/generated-metadata/graphql';
const StyledLinkContainer = styled.div`
@@ -35,21 +33,14 @@ const StyledLinkContainer = styled.div`
}
`;
const StyledSeeAllButtonWrapper = styled.div<{ isMobile: boolean }>`
opacity: ${({ isMobile }) => (isMobile ? '1' : '0')};
pointer-events: none;
transition: opacity ${themeCssVariables.animation.duration.instant}s ease;
.widget:hover & {
opacity: 1;
pointer-events: auto;
}
const StyledSeeAllButtonWrapper = styled.div`
opacity: 1;
pointer-events: auto;
`;
export const WidgetActionFieldSeeAll = () => {
const widget = useCurrentWidget();
const targetRecord = useTargetRecord();
const isMobile = useIsMobile();
const { objectMetadataItem } = useObjectMetadataItem({
objectNameSingular: targetRecord.targetObjectNameSingular,
@@ -145,7 +136,7 @@ export const WidgetActionFieldSeeAll = () => {
<div id={tooltipId}>
<StyledLinkContainer>
<Link to={filterLinkHref} data-testid="widget-see-all-link">
<StyledSeeAllButtonWrapper isMobile={isMobile}>
<StyledSeeAllButtonWrapper>
<LightIconButton Icon={IconArrowUpRight} accent="secondary" />
</StyledSeeAllButtonWrapper>
</Link>
@@ -205,6 +205,10 @@ export const WidgetRenderer = ({ widget }: WidgetRendererProps) => {
variant={variant}
hasHeader={showHeader}
isEditable={isWidgetEditable}
isInVerticalListTab={
layoutMode === PageLayoutTabLayoutMode.VERTICAL_LIST
}
isMobile={isMobile}
hasInteractiveContent={widget.type === WidgetType.RECORD_TABLE}
>
{hasAccess ? (
@@ -1,5 +1,4 @@
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
import { useRecordFieldsScopeContextOrThrow } from '@/object-record/record-field-list/contexts/RecordFieldsScopeContext';
import { RecordDetailMorphRelationSectionDropdown } from '@/object-record/record-field-list/record-detail-section/relation/components/RecordDetailMorphRelationSectionDropdown';
import { RecordDetailRelationSectionDropdown } from '@/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationSectionDropdown';
import {
@@ -17,15 +16,11 @@ import {
type FieldRelationMetadata,
} from '@/object-record/record-field/ui/types/FieldMetadata';
import { isFieldMorphRelation } from '@/object-record/record-field/ui/types/guards/isFieldMorphRelation';
import { getRecordFieldCardRelationPickerDropdownId } from '@/object-record/record-show/utils/getRecordFieldCardRelationPickerDropdownId';
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { styled } from '@linaria/react';
import { CustomError } from 'twenty-shared/utils';
import { IconPencil } from 'twenty-ui/display';
import { IconPencil, IconPlus } from 'twenty-ui/display';
import { LightIconButton } from 'twenty-ui/input';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { RelationType } from '~/generated-metadata/graphql';
type FieldWidgetRelationEditActionProps = {
fieldDefinition:
@@ -34,30 +29,15 @@ type FieldWidgetRelationEditActionProps = {
recordId: string;
};
const StyledEditButtonWrapper = styled.div<{
isDropdownOpen: boolean;
isMobile: boolean;
}>`
opacity: ${({ isDropdownOpen, isMobile }) =>
isDropdownOpen ? '1' : isMobile ? '1' : '0'};
pointer-events: ${({ isDropdownOpen }) => (isDropdownOpen ? 'auto' : 'none')};
transition: ${({ isDropdownOpen }) =>
isDropdownOpen
? 'none'
: `opacity ${themeCssVariables.animation.duration.instant}s ease`};
.widget:hover & {
opacity: 1;
pointer-events: auto;
}
const StyledEditButtonWrapper = styled.div`
opacity: 1;
pointer-events: auto;
`;
export const FieldWidgetRelationEditAction = ({
fieldDefinition,
recordId,
}: FieldWidgetRelationEditActionProps) => {
const { scopeInstanceId } = useRecordFieldsScopeContextOrThrow();
const { objectMetadataItems } = useObjectMetadataItems();
const objectMetadataItem = objectMetadataItems.find(
(item) =>
@@ -92,26 +72,14 @@ export const FieldWidgetRelationEditAction = ({
const isMorphRelation = isFieldMorphRelation(fieldDefinition);
const relationSelectionDropdownId =
getRecordFieldCardRelationPickerDropdownId({
fieldDefinition,
recordId,
instanceId: scopeInstanceId,
});
const isDropdownOpen = useAtomComponentStateValue(
isDropdownOpenComponentState,
relationSelectionDropdownId,
);
const isMobile = useIsMobile();
const triggerIcon =
fieldDefinition.metadata.relationType === RelationType.MANY_TO_ONE
? IconPencil
: IconPlus;
const dropdownTriggerClickableComponent = (
<StyledEditButtonWrapper
isDropdownOpen={isDropdownOpen}
isMobile={isMobile}
>
<LightIconButton Icon={IconPencil} accent="secondary" />
<StyledEditButtonWrapper>
<LightIconButton Icon={triggerIcon} accent="secondary" />
</StyledEditButtonWrapper>
);
@@ -1,14 +1,20 @@
import { styled } from '@linaria/react';
import { type WidgetCardVariant } from '~/modules/page-layout/widgets/types/WidgetCardVariant';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { type WidgetCardVariant } from '~/modules/page-layout/widgets/types/WidgetCardVariant';
type WidgetCardContentStyledProps = {
variant: WidgetCardVariant;
hasHeader: boolean;
isEditable: boolean;
isInVerticalListTab: boolean;
isMobile: boolean;
};
const StyledWidgetCardContent = styled.div<WidgetCardContentStyledProps>`
background-color: ${({ variant, isInVerticalListTab, isMobile }) =>
variant === 'record-page' && isInVerticalListTab && !isMobile
? themeCssVariables.background.secondary
: 'transparent'};
border: ${({ variant, isEditable }) =>
variant === 'record-page' || (variant === 'side-column' && isEditable)
? `1px solid ${themeCssVariables.border.color.medium}`
@@ -40,10 +46,10 @@ const StyledWidgetCardContent = styled.div<WidgetCardContentStyledProps>`
}};
&:empty {
margin-top: ${({ hasHeader, variant, isEditable }) => {
if (hasHeader && variant === 'side-column' && !isEditable) return '0';
return hasHeader ? themeCssVariables.spacing[2] : '0';
}};
border: none;
border-radius: 0;
margin-top: 0;
padding: 0;
}
`;
@@ -51,6 +57,8 @@ type WidgetCardContentProps = {
variant: WidgetCardVariant;
hasHeader: boolean;
isEditable: boolean;
isInVerticalListTab: boolean;
isMobile: boolean;
hasInteractiveContent?: boolean;
className?: string;
children?: React.ReactNode;
@@ -60,6 +68,8 @@ export const WidgetCardContent = ({
variant,
hasHeader,
isEditable,
isInVerticalListTab,
isMobile,
hasInteractiveContent = false,
className,
children,
@@ -77,6 +87,8 @@ export const WidgetCardContent = ({
variant={variant}
hasHeader={hasHeader}
isEditable={isEditable}
isInVerticalListTab={isInVerticalListTab}
isMobile={isMobile}
className={className}
onClick={handleContentClick}
>