Skip to content

fix: prevent tab synchronization between different records#17559

Merged
Weiko merged 7 commits intotwentyhq:mainfrom
Eruis2579:fix/tabs-synchronized-between-records
Feb 13, 2026
Merged

fix: prevent tab synchronization between different records#17559
Weiko merged 7 commits intotwentyhq:mainfrom
Eruis2579:fix/tabs-synchronized-between-records

Conversation

@Eruis2579
Copy link

Fixes issue where tabs were synchronized when opening two records of the same type in show page and side panel.

The root cause was that tab instance IDs were only based on pageLayoutId, causing all records using the same page layout to share the same tab state.

This change includes the record ID in the tab instance ID, making tabs unique per record while maintaining backward compatibility for cases where no record ID is available.

Fixes #17522

Include record ID in tab instance ID so that tabs are unique per record,
not just per page layout. This prevents tabs from being synchronized
when opening two records of the same type in show page and side panel.

Fixes twentyhq#17522
@github-actions
Copy link
Contributor

github-actions bot commented Jan 29, 2026

Fails
🚫

node failed.

Log

Details
�[31mError: �[39m SyntaxError: Unexpected token 'C', "Contributo"... is not valid JSON
    at JSON.parse (<anonymous>)
�[90m    at parseJSONFromBytes (node:internal/deps/undici/undici:4259:19)�[39m
�[90m    at successSteps (node:internal/deps/undici/undici:6882:27)�[39m
�[90m    at readAllBytes (node:internal/deps/undici/undici:5807:13)�[39m
�[90m    at process.processTicksAndRejections (node:internal/process/task_queues:103:5)�[39m
danger-results://tmp/danger-results-47737edb.json

Generated by 🚫 dangerJS against 330ea16

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 29, 2026

Greptile Overview

Greptile Summary

Fixed tab synchronization bug where tabs were shared between different records of the same type when opened in show page and side panel. The root cause was that tab instance IDs were only based on pageLayoutId, causing all records using the same page layout to share tab state.

Key Changes:

  • Added record ID from layoutRenderingContext.targetRecordIdentifier.id to tab instance ID computation
  • Maintained backward compatibility by falling back to pageLayoutId-only instance ID when no record ID is available
  • Solution aligns with existing pattern used in ShowPageSubContainer (getShowPageTabListComponentId) which already includes targetObjectId

The fix is simple, focused, and correctly scopes tab state per record instance.

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The fix is straightforward, well-scoped, and follows existing patterns in the codebase. It adds the record ID to tab instance IDs to prevent unwanted synchronization while maintaining backward compatibility. No logical errors, security issues, or side effects identified.
  • No files require special attention

Important Files Changed

Filename Overview
packages/twenty-front/src/modules/page-layout/components/PageLayoutRenderer.tsx Prevented tab synchronization between different records by including record ID in tab instance ID

Sequence Diagram

sequenceDiagram
    participant User
    participant PageLayoutRenderer
    participant LayoutRenderingContext
    participant TabListContext
    participant TabList
    
    User->>PageLayoutRenderer: Opens Record A in show page
    PageLayoutRenderer->>LayoutRenderingContext: useLayoutRenderingContext()
    LayoutRenderingContext-->>PageLayoutRenderer: Returns context with recordId A
    PageLayoutRenderer->>PageLayoutRenderer: Compute tabListInstanceId<br/>(pageLayoutId-tab-list-recordIdA)
    PageLayoutRenderer->>TabListContext: Provide instanceId
    TabListContext->>TabList: Render with unique instance ID
    
    User->>PageLayoutRenderer: Opens Record B in side panel
    PageLayoutRenderer->>LayoutRenderingContext: useLayoutRenderingContext()
    LayoutRenderingContext-->>PageLayoutRenderer: Returns context with recordId B
    PageLayoutRenderer->>PageLayoutRenderer: Compute tabListInstanceId<br/>(pageLayoutId-tab-list-recordIdB)
    PageLayoutRenderer->>TabListContext: Provide different instanceId
    TabListContext->>TabList: Render with separate instance ID
    
    Note over TabList: Tabs remain independent<br/>No synchronization occurs
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 file reviewed, no comments

Edit Code Review Agent Settings | Greptile

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 1 file

@github-actions
Copy link
Contributor

github-actions bot commented Jan 29, 2026

🚀 Preview Environment Ready!

Your preview environment is available at: http://bore.pub:33721

This environment will automatically shut down when the PR is closed or after 5 hours.

Eruis added 2 commits January 29, 2026 16:03
useLayoutRenderingContext() throws if context is missing, so it never
returns undefined. Only targetRecordIdentifier needs optional chaining
since it can be undefined according to the type definition.
This ensures DASHBOARD layouts use the standard tab instance ID without record ID,
fixing Storybook test failures while maintaining tab isolation for record pages.
@Eruis2579
Copy link
Author

hi @Weiko
Could you review my PR, please?
Thank you.

@Weiko
Copy link
Member

Weiko commented Jan 30, 2026

hi @Weiko Could you review my PR, please? Thank you.

Hi, thanks for your contribution.
I've tried locally and see an empty page
Screenshot 2026-01-30 at 17 19 31

This is most likely a mismatch between your change and PageLayoutRendererContent not computing the instanceId with the recordId

Create getTabListInstanceIdFromPageLayoutAndRecord utility function
to ensure both PageLayoutRenderer and PageLayoutRendererContent compute
the tab list instance ID consistently, including record ID for RECORD_PAGE layouts.

This fixes the empty page issue caused by instance ID mismatch.
@Eruis2579
Copy link
Author

hi @Weiko Could you review my PR, please? Thank you.

Hi, thanks for your contribution. I've tried locally and see an empty page Screenshot 2026-01-30 at 17 19 31

This is most likely a mismatch between your change and PageLayoutRendererContent not computing the instanceId with the recordId

Hi, I have fixed this issue.
Please check again.

@Eruis2579
Copy link
Author

Hi, @Weiko
Could you review my PR again please?

@Eruis2579
Copy link
Author

Hi, @Weiko
can you review again please?

@Eruis2579
Copy link
Author

hi @Weiko Could you review my PR, please? Thank you.

Hi, thanks for your contribution. I've tried locally and see an empty page Screenshot 2026-01-30 at 17 19 31

This is most likely a mismatch between your change and PageLayoutRendererContent not computing the instanceId with the recordId

Please review my PR again

@Eruis2579
Copy link
Author

@Weiko please review my PR

@Eruis2579
Copy link
Author

@charlesBochet Please review my PR

@Eruis2579
Copy link
Author

Anyone can review this PR?

@Eruis2579
Copy link
Author

Hi, @Weiko If you have time, please check my PR again.

Copy link
Member

@Weiko Weiko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution. LGTM

@Weiko Weiko added this pull request to the merge queue Feb 13, 2026
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Feb 13, 2026
Eruis added 2 commits February 13, 2026 11:46
Use type-only import for PageLayoutType type annotation and string literal
for enum comparison to avoid TypeScript module resolution issues in CI.
…mport issue

Use indexed access type LayoutRenderingContextType['layoutType'] instead of
directly importing PageLayoutType to avoid TypeScript module resolution
errors in CI environment.
@Eruis2579
Copy link
Author

@github-merge-queue, check merge queue again.

@Eruis2579
Copy link
Author

Hi, @Weiko , Please add this PR to merge queue again. I have fixed some for front build check

@Weiko Weiko added this pull request to the merge queue Feb 13, 2026
Merged via the queue into twentyhq:main with commit befbcef Feb 13, 2026
62 checks passed
@twenty-eng-sync
Copy link

Hey @Weiko! After you've done the QA of your Pull Request, you can mark it as done here. Thank you!

1 similar comment
@twenty-eng-sync
Copy link

Hey @Weiko! After you've done the QA of your Pull Request, you can mark it as done here. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tabs are synchronized when opening two records of the same type in show page and side panel

3 participants