Make all widgets of record page layouts non-editable except Fields widgets (#18471)

## Demo


https://github.com/user-attachments/assets/d5746f81-beae-4c46-abfe-9723da9bcc1d
This commit is contained in:
Baptiste Devessier
2026-03-09 09:06:07 +00:00
committed by GitHub
parent 0acc08c333
commit a9696705c1
3 changed files with 40 additions and 19 deletions
@@ -39,15 +39,17 @@ export const PageLayoutContent = () => {
}
if (isVerticalList) {
return isPageLayoutInEditMode ? (
<PageLayoutVerticalListEditor
widgets={activeTab.widgets}
onReorder={reorderWidgets}
isReorderEnabled={!isRecordPageLayout}
/>
) : (
<PageLayoutVerticalListViewer widgets={activeTab.widgets} />
);
if (!isRecordPageLayout && isPageLayoutInEditMode) {
return (
<PageLayoutVerticalListEditor
widgets={activeTab.widgets}
onReorder={reorderWidgets}
isReorderEnabled={true}
/>
);
}
return <PageLayoutVerticalListViewer widgets={activeTab.widgets} />;
}
return <PageLayoutGridLayout tabId={tabId} />;
@@ -8,6 +8,7 @@ import { WidgetRenderer } from '@/page-layout/widgets/components/WidgetRenderer'
import { useIsInPinnedTab } from '@/page-layout/widgets/hooks/useIsInPinnedTab';
import { useLayoutRenderingContext } from '@/ui/layout/contexts/LayoutRenderingContext';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { WidgetType } from '~/generated-metadata/graphql';
const StyledVerticalListContainer = styled.div<{
variant: PageLayoutVerticalListViewerVariant;
@@ -25,6 +26,13 @@ const StyledVerticalListContainer = styled.div<{
variant === 'side-column' ? 0 : themeCssVariables.spacing[2]};
`;
const StyledFieldsWidgetWrapper = styled.div<{
variant: PageLayoutVerticalListViewerVariant;
}>`
padding: ${({ variant }) =>
variant === 'side-column' ? themeCssVariables.spacing[1] : '0'};
`;
type PageLayoutVerticalListViewerProps = {
widgets: PageLayoutWidget[];
};
@@ -47,11 +55,17 @@ export const PageLayoutVerticalListViewer = ({
variant={variant}
shouldUseWhiteBackground={isMobile || isInSidePanel}
>
{widgets.map((widget) => (
<div key={widget.id}>
<WidgetRenderer widget={widget} />
</div>
))}
{widgets.map((widget) =>
widget.type === WidgetType.FIELDS ? (
<StyledFieldsWidgetWrapper key={widget.id} variant={variant}>
<WidgetRenderer widget={widget} />
</StyledFieldsWidgetWrapper>
) : (
<div key={widget.id}>
<WidgetRenderer widget={widget} />
</div>
),
)}
</StyledVerticalListContainer>
);
};
@@ -28,12 +28,12 @@ import { styled } from '@linaria/react';
import { type MouseEvent, useContext } from 'react';
import { ErrorBoundary } from 'react-error-boundary';
import { IconLock } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme-constants';
import {
PageLayoutTabLayoutMode,
PageLayoutType,
WidgetType,
} from '~/generated-metadata/graphql';
import { ThemeContext } from 'twenty-ui/theme-constants';
const StyledNoAccessContainer = styled.div`
align-items: center;
@@ -89,6 +89,11 @@ export const WidgetRenderer = ({ widget }: WidgetRendererProps) => {
const isDeletingWidgetEnabled =
currentPageLayout.type !== PageLayoutType.RECORD_PAGE;
const isWidgetEditable =
isPageLayoutInEditMode &&
(currentPageLayout.type !== PageLayoutType.RECORD_PAGE ||
widget.type === WidgetType.FIELDS);
// TODO: when we have more widgets without headers, we should use a more generic approach to hide the header
// each widget type could have metadata (e.g., hasHeader: boolean or headerMode: 'always' | 'editOnly' | 'never')
const isRichTextWidget = widget.type === WidgetType.STANDALONE_RICH_TEXT;
@@ -137,8 +142,8 @@ export const WidgetRenderer = ({ widget }: WidgetRendererProps) => {
<WidgetCard
headerLess={!showHeader}
variant={variant}
isEditable={isPageLayoutInEditMode}
onClick={isPageLayoutInEditMode ? handleClick : undefined}
isEditable={isWidgetEditable}
onClick={isWidgetEditable ? handleClick : undefined}
isEditing={isEditing}
isDragging={isDragging}
isResizing={isResizing}
@@ -153,7 +158,7 @@ export const WidgetRenderer = ({ widget }: WidgetRendererProps) => {
<WidgetCardHeader
widgetId={widget.id}
variant={variant}
isInEditMode={isPageLayoutInEditMode}
isInEditMode={isWidgetEditable}
isResizing={isResizing}
isReorderEnabled={isReorderEnabled}
isDeletingWidgetEnabled={isDeletingWidgetEnabled}
@@ -174,7 +179,7 @@ export const WidgetRenderer = ({ widget }: WidgetRendererProps) => {
<WidgetCardContent
variant={variant}
hasHeader={showHeader}
isEditable={isPageLayoutInEditMode}
isEditable={isWidgetEditable}
>
{hasAccess ? (
<ErrorBoundary