Compare commits

...
Author SHA1 Message Date
Sonarly Claude Code a65e23e53c fix: render merge preview record without relying on server-side record lookup
https://sonarly.com/issue/21568?type=bug

The merge record preview page renders empty because the dry-run preview record (a temporary record with a new UUID that doesn't exist in the database) is passed to `PageLayoutSingleTabRenderer`, which requires the record to be resolvable through server-side queries and page layout initialization — conditions the ephemeral preview record cannot satisfy.

Fix: ## What changed

Reverted `MergePreviewTab` from using `PageLayoutSingleTabRenderer` back to directly rendering `SummaryCard` within a `Section`. Removed the `usePageLayoutIdForRecord` hook call and the `PageLayoutSingleTabRenderer` import.

## Why

The merge preview record is an **ephemeral dry-run record** — the server creates it with `id: uuidv4()` and it only exists in the Jotai record store (not in the database or Apollo cache). `PageLayoutSingleTabRenderer` depends on `PageLayoutInitializationQueryEffect` completing initialization, which requires server-resolvable records. Since the preview record doesn't exist in the database, the page layout system never initializes, and `PageLayoutSingleTabRendererContent` permanently returns `null`.

The `SummaryCard` component reads directly from the Jotai record store via `recordStoreFamilyState`, so it correctly resolves the ephemeral preview record that was upserted by `usePerformMergePreview`.

## Trade-off

This fix restores the working preview but loses the full page layout rendering (field cards/widgets) that `cfefe9273b` aimed to add. A more complete solution would involve making `PageLayoutSingleTabRenderer` work with store-only records, but that requires deeper changes to the page layout initialization system. This fix prioritizes user-facing functionality over visual completeness.
2026-04-03 14:19:16 +00:00
@@ -1,8 +1,8 @@
import { usePerformMergePreview } from '@/object-record/record-merge/hooks/usePerformMergePreview';
import { PageLayoutSingleTabRenderer } from '@/page-layout/components/PageLayoutSingleTabRenderer';
import { usePageLayoutIdForRecord } from '@/page-layout/hooks/usePageLayoutIdForRecord';
import { SummaryCard } from '@/object-record/record-show/components/SummaryCard';
import { LayoutRenderingProvider } from '@/ui/layout/contexts/LayoutRenderingContext';
import { isDefined } from 'twenty-shared/utils';
import { Section } from 'twenty-ui/layout';
import { PageLayoutType } from '~/generated-metadata/graphql';
type MergePreviewTabProps = {
@@ -16,16 +16,7 @@ export const MergePreviewTab = ({
objectNameSingular,
});
const { pageLayoutId } = usePageLayoutIdForRecord({
id: mergePreviewRecord?.id ?? '',
targetObjectNameSingular: objectNameSingular,
});
if (
!isDefined(mergePreviewRecord) ||
isGeneratingPreview ||
!isDefined(pageLayoutId)
) {
if (!isDefined(mergePreviewRecord) || isGeneratingPreview) {
return null;
}
@@ -42,7 +33,13 @@ export const MergePreviewTab = ({
isInSidePanel: true,
}}
>
<PageLayoutSingleTabRenderer pageLayoutId={pageLayoutId} />
<Section>
<SummaryCard
objectNameSingular={objectNameSingular}
objectRecordId={recordId}
isInSidePanel={true}
/>
</Section>
</LayoutRenderingProvider>
);
};