Fix fields widget flash during reset (#19726)

Summary

- Remove the evictViewMetadataForViewIds step from the page-layout reset
flow. It synchronously cleared viewFields/viewFieldGroups rows from the
metadata store, leaving a window where
useFieldsWidgetGroups saw a view with no fields and fell back to
buildDefaultFieldsWidgetGroups, briefly rendering a synthetic "General"
+ "Other" layout before the real reset defaults
arrived.
- invalidateMetadataStore() alone is sufficient: it marks the
collections stale and triggers MinimalMetadataLoadEffect to refetch,
which replaces current atomically. The UI now
transitions old-layout → new-default with no synthetic flash.
- Simplified refreshPageLayoutAfterReset to no longer take a
collectAffectedViewIds callback, and updated both tab/widget reset call
sites plus ObjectLayout.tsx accordingly.
- Deleted the now-unused evictViewMetadataForViewIds and
collectViewIdsFromWidgets utils.
This commit is contained in:
Weiko
2026-04-15 18:08:24 +02:00
committed by GitHub
parent 725171bfd3
commit 56d6e13b5d
7 changed files with 40 additions and 129 deletions
@@ -1,20 +0,0 @@
import { isDefined } from 'twenty-shared/utils';
import { type PageLayoutWidget } from '@/page-layout/types/PageLayoutWidget';
import { getWidgetConfigurationViewId } from '@/page-layout/utils/getWidgetConfigurationViewId';
export const collectViewIdsFromWidgets = (
widgets: PageLayoutWidget[],
): Set<string> => {
const viewIds = new Set<string>();
for (const widget of widgets) {
const viewId = getWidgetConfigurationViewId(widget.configuration);
if (isDefined(viewId)) {
viewIds.add(viewId);
}
}
return viewIds;
};
@@ -1,31 +0,0 @@
import type { useStore } from 'jotai';
import { isDefined } from 'twenty-shared/utils';
import {
type MetadataEntityKey,
metadataStoreState,
} from '@/metadata-store/states/metadataStoreState';
const VIEW_RELATED_METADATA_KEYS: MetadataEntityKey[] = [
'viewFields',
'viewFieldGroups',
];
export const evictViewMetadataForViewIds = (
store: ReturnType<typeof useStore>,
viewIds: Set<string>,
) => {
if (viewIds.size === 0) {
return;
}
for (const key of VIEW_RELATED_METADATA_KEYS) {
store.set(metadataStoreState.atomFamily(key), (prev) => ({
...prev,
current: (prev.current as { viewId?: string }[]).filter(
(item) => !isDefined(item.viewId) || !viewIds.has(item.viewId),
),
currentCollectionHash: undefined,
}));
}
};