fix: prevent tab synchronization between different records (#17559)
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 --------- Co-authored-by: Eruis <github@eruis.example>
This commit is contained in:
@@ -4,8 +4,9 @@ import { PageLayoutRendererContent } from '@/page-layout/components/PageLayoutRe
|
||||
import { useSetIsPageLayoutInEditMode } from '@/page-layout/hooks/useSetIsPageLayoutInEditMode';
|
||||
import { PageLayoutComponentInstanceContext } from '@/page-layout/states/contexts/PageLayoutComponentInstanceContext';
|
||||
import { type PageLayout } from '@/page-layout/types/PageLayout';
|
||||
import { getTabListInstanceIdFromPageLayoutId } from '@/page-layout/utils/getTabListInstanceIdFromPageLayoutId';
|
||||
import { getTabListInstanceIdFromPageLayoutAndRecord } from '@/page-layout/utils/getTabListInstanceIdFromPageLayoutAndRecord';
|
||||
import { isPageLayoutEmpty } from '@/page-layout/utils/isPageLayoutEmpty';
|
||||
import { useLayoutRenderingContext } from '@/ui/layout/contexts/LayoutRenderingContext';
|
||||
import { TabListComponentInstanceContext } from '@/ui/layout/tab-list/states/contexts/TabListComponentInstanceContext';
|
||||
import 'react-grid-layout/css/styles.css';
|
||||
import 'react-resizable/css/styles.css';
|
||||
@@ -20,6 +21,8 @@ export const PageLayoutRenderer = ({
|
||||
const { setIsPageLayoutInEditMode } =
|
||||
useSetIsPageLayoutInEditMode(pageLayoutId);
|
||||
|
||||
const { targetRecordIdentifier, layoutType } = useLayoutRenderingContext();
|
||||
|
||||
const onInitialized = (pageLayout: PageLayout) => {
|
||||
if (isPageLayoutEmpty(pageLayout)) {
|
||||
setIsPageLayoutInEditMode(true);
|
||||
@@ -28,6 +31,12 @@ export const PageLayoutRenderer = ({
|
||||
}
|
||||
};
|
||||
|
||||
const tabListInstanceId = getTabListInstanceIdFromPageLayoutAndRecord({
|
||||
pageLayoutId,
|
||||
layoutType,
|
||||
targetRecordIdentifier,
|
||||
});
|
||||
|
||||
return (
|
||||
<PageLayoutComponentInstanceContext.Provider
|
||||
value={{
|
||||
@@ -36,7 +45,7 @@ export const PageLayoutRenderer = ({
|
||||
>
|
||||
<TabListComponentInstanceContext.Provider
|
||||
value={{
|
||||
instanceId: getTabListInstanceIdFromPageLayoutId(pageLayoutId),
|
||||
instanceId: tabListInstanceId,
|
||||
}}
|
||||
>
|
||||
<PageLayoutInitializationQueryEffect
|
||||
|
||||
+8
-5
@@ -11,7 +11,7 @@ import { PageLayoutMainContent } from '@/page-layout/PageLayoutMainContent';
|
||||
import { isPageLayoutInEditModeComponentState } from '@/page-layout/states/isPageLayoutInEditModeComponentState';
|
||||
import { pageLayoutTabSettingsOpenTabIdComponentState } from '@/page-layout/states/pageLayoutTabSettingsOpenTabIdComponentState';
|
||||
import { getScrollWrapperInstanceIdFromPageLayoutId } from '@/page-layout/utils/getScrollWrapperInstanceIdFromPageLayoutId';
|
||||
import { getTabListInstanceIdFromPageLayoutId } from '@/page-layout/utils/getTabListInstanceIdFromPageLayoutId';
|
||||
import { getTabListInstanceIdFromPageLayoutAndRecord } from '@/page-layout/utils/getTabListInstanceIdFromPageLayoutAndRecord';
|
||||
import { getTabsByDisplayMode } from '@/page-layout/utils/getTabsByDisplayMode';
|
||||
import { getTabsWithVisibleWidgets } from '@/page-layout/utils/getTabsWithVisibleWidgets';
|
||||
import { shouldEnableTabEditingFeatures } from '@/page-layout/utils/shouldEnableTabEditingFeatures';
|
||||
@@ -52,7 +52,8 @@ const StyledScrollWrapper = styled(ScrollWrapper)`
|
||||
export const PageLayoutRendererContent = () => {
|
||||
const { currentPageLayout } = useCurrentPageLayout();
|
||||
|
||||
const { isInRightDrawer } = useLayoutRenderingContext();
|
||||
const { isInRightDrawer, layoutType, targetRecordIdentifier } =
|
||||
useLayoutRenderingContext();
|
||||
|
||||
const isPageLayoutInEditMode = useRecoilComponentValue(
|
||||
isPageLayoutInEditModeComponentState,
|
||||
@@ -104,9 +105,11 @@ export const PageLayoutRendererContent = () => {
|
||||
isInRightDrawer,
|
||||
});
|
||||
|
||||
const tabListInstanceId = getTabListInstanceIdFromPageLayoutId(
|
||||
currentPageLayout.id,
|
||||
);
|
||||
const tabListInstanceId = getTabListInstanceIdFromPageLayoutAndRecord({
|
||||
pageLayoutId: currentPageLayout.id,
|
||||
layoutType,
|
||||
targetRecordIdentifier,
|
||||
});
|
||||
|
||||
const sortedTabs = sortTabsByPosition(tabsToRenderInTabList);
|
||||
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
import { type TargetRecordIdentifier } from '@/ui/layout/contexts/TargetRecordIdentifier';
|
||||
import { type LayoutRenderingContextType } from '@/ui/layout/contexts/LayoutRenderingContext';
|
||||
import { getTabListInstanceIdFromPageLayoutId } from './getTabListInstanceIdFromPageLayoutId';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const getTabListInstanceIdFromPageLayoutAndRecord = ({
|
||||
pageLayoutId,
|
||||
layoutType,
|
||||
targetRecordIdentifier,
|
||||
}: {
|
||||
pageLayoutId: string;
|
||||
layoutType: LayoutRenderingContextType['layoutType'];
|
||||
targetRecordIdentifier?: TargetRecordIdentifier;
|
||||
}) => {
|
||||
// Include record ID in tab instance ID to prevent tab synchronization between different records
|
||||
// Only for RECORD_PAGE layouts, as DASHBOARD layouts are standalone
|
||||
const recordId =
|
||||
layoutType === 'RECORD_PAGE' ? targetRecordIdentifier?.id : undefined;
|
||||
const baseInstanceId = getTabListInstanceIdFromPageLayoutId(pageLayoutId);
|
||||
return isDefined(recordId) ? `${baseInstanceId}-${recordId}` : baseInstanceId;
|
||||
};
|
||||
Reference in New Issue
Block a user