Fix dashboard creation + role permission page design (#18565)
1. **Creating a new dashboard crashes with "Tab not found"** and widgets can't be added after the crash is prevented. **Root cause:** `initializePageLayout` wrapped both the persisted and draft state updates behind an `isDeeplyEqual` guard. After navigation, `resetPageLayoutEditMode` resets the draft atom to its default but leaves the persisted atom untouched. On re-initialization, `isDeeplyEqual` returns true (persisted unchanged), so the draft is never repopulated. But edit mode is still activated. **Fix**: Move the draft store.set outside the isDeeplyEqual guard so it's always set on initialization. Also add a defensive check in `PageLayoutRendererContent` to prevent the crash when activeTabId doesn't match available tabs. https://github.com/user-attachments/assets/bcd69866-63eb-4e5e-a1bb-655e71ba6dc5 2. **Permission role page design broken** Before <img width="573" height="1130" alt="role-page-broken" src="https://github.com/user-attachments/assets/09f60fd2-ef08-4133-bb28-034b15579481" /> After <img width="573" height="266" alt="Capture d’écran 2026-03-11 à 14 25 55" src="https://github.com/user-attachments/assets/c34f9993-51e1-4108-a7e6-f434f558edfd" />
This commit is contained in:
+19
-14
@@ -1,11 +1,13 @@
|
||||
import { useBasePageLayout } from '@/page-layout/hooks/useBasePageLayout';
|
||||
import { usePageLayoutWithRelationWidgets } from '@/page-layout/hooks/usePageLayoutWithRelationWidgets';
|
||||
import { useSetIsPageLayoutInEditMode } from '@/page-layout/hooks/useSetIsPageLayoutInEditMode';
|
||||
import { pageLayoutCurrentLayoutsComponentState } from '@/page-layout/states/pageLayoutCurrentLayoutsComponentState';
|
||||
import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDraftComponentState';
|
||||
import { pageLayoutIsInitializedComponentState } from '@/page-layout/states/pageLayoutIsInitializedComponentState';
|
||||
import { pageLayoutPersistedComponentState } from '@/page-layout/states/pageLayoutPersistedComponentState';
|
||||
import { type PageLayout } from '@/page-layout/types/PageLayout';
|
||||
import { convertPageLayoutToTabLayouts } from '@/page-layout/utils/convertPageLayoutToTabLayouts';
|
||||
import { isPageLayoutEmpty } from '@/page-layout/utils/isPageLayoutEmpty';
|
||||
import { useAtomComponentStateCallbackState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateCallbackState';
|
||||
import { useAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentState';
|
||||
import { useStore } from 'jotai';
|
||||
@@ -15,12 +17,10 @@ import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
|
||||
type PageLayoutInitializationQueryEffectProps = {
|
||||
pageLayoutId: string;
|
||||
onInitialized?: (pageLayout: PageLayout) => void;
|
||||
};
|
||||
|
||||
export const PageLayoutInitializationQueryEffect = ({
|
||||
pageLayoutId,
|
||||
onInitialized,
|
||||
}: PageLayoutInitializationQueryEffectProps) => {
|
||||
const [pageLayoutIsInitialized, setPageLayoutIsInitialized] =
|
||||
useAtomComponentState(pageLayoutIsInitializedComponentState);
|
||||
@@ -29,6 +29,9 @@ export const PageLayoutInitializationQueryEffect = ({
|
||||
|
||||
const pageLayout = usePageLayoutWithRelationWidgets(basePageLayout);
|
||||
|
||||
const { setIsPageLayoutInEditMode } =
|
||||
useSetIsPageLayoutInEditMode(pageLayoutId);
|
||||
|
||||
const pageLayoutPersistedComponentCallbackState =
|
||||
useAtomComponentStateCallbackState(pageLayoutPersistedComponentState);
|
||||
|
||||
@@ -48,22 +51,26 @@ export const PageLayoutInitializationQueryEffect = ({
|
||||
|
||||
if (!isDeeplyEqual(layout, currentPersisted)) {
|
||||
store.set(pageLayoutPersistedComponentCallbackState, layout);
|
||||
store.set(pageLayoutDraftComponentCallbackState, {
|
||||
id: layout.id,
|
||||
name: layout.name,
|
||||
type: layout.type,
|
||||
objectMetadataId: layout.objectMetadataId,
|
||||
tabs: layout.tabs,
|
||||
});
|
||||
|
||||
const tabLayouts = convertPageLayoutToTabLayouts(layout);
|
||||
store.set(pageLayoutCurrentLayoutsComponentCallbackState, tabLayouts);
|
||||
}
|
||||
|
||||
store.set(pageLayoutDraftComponentCallbackState, {
|
||||
id: layout.id,
|
||||
name: layout.name,
|
||||
type: layout.type,
|
||||
objectMetadataId: layout.objectMetadataId,
|
||||
tabs: layout.tabs,
|
||||
});
|
||||
|
||||
const tabLayouts = convertPageLayoutToTabLayouts(layout);
|
||||
store.set(pageLayoutCurrentLayoutsComponentCallbackState, tabLayouts);
|
||||
|
||||
setIsPageLayoutInEditMode(isPageLayoutEmpty(layout));
|
||||
},
|
||||
[
|
||||
pageLayoutCurrentLayoutsComponentCallbackState,
|
||||
pageLayoutDraftComponentCallbackState,
|
||||
pageLayoutPersistedComponentCallbackState,
|
||||
setIsPageLayoutInEditMode,
|
||||
store,
|
||||
],
|
||||
);
|
||||
@@ -71,14 +78,12 @@ export const PageLayoutInitializationQueryEffect = ({
|
||||
useEffect(() => {
|
||||
if (!pageLayoutIsInitialized && isDefined(pageLayout)) {
|
||||
initializePageLayout(pageLayout);
|
||||
onInitialized?.(pageLayout);
|
||||
setPageLayoutIsInitialized(true);
|
||||
}
|
||||
}, [
|
||||
initializePageLayout,
|
||||
pageLayoutIsInitialized,
|
||||
pageLayout,
|
||||
onInitialized,
|
||||
setPageLayoutIsInitialized,
|
||||
]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user