Replace sign-in mocked metadata with hardcoded BackgroundMock (#20308)
## Summary When the user is logged out, we render the auth modal on top of a sample table to make the empty page feel alive. So far this was achieved by **loading a full set of mocked object / field / view / navigation-menu metadata into the runtime metadata store** and then mounting the real `RecordTable` and `AppNavigationDrawer` behind the modal. This had a few downsides: - Significant bundle weight pulled in for unauthenticated users (mocked GraphQL fixtures + the real `RecordTable` virtualization stack). - Plenty of code paths that had to know about the "showAuthModal" case (`useRecordIndexTableQuery`, `useTriggerInitialRecordTableDataLoad`, `MainContextStoreProvider`, `IsMinimalMetadataReadyEffect`...). - Any change to metadata-store internals or to the record-table runtime risked breaking the logged-out background. This PR replaces the entire flow with a small, self-contained `BackgroundMock` component tree that **does not consume any metadata** and **does not load any mocked metadata at runtime**. ### What changed - New module under `sign-in-background-mock`: - `BackgroundMockPage` + `BackgroundMockViewBar` + `BackgroundMockTable` + `BackgroundMockTableRow` render a hardcoded "Companies" table that visually mirrors the real one. - `BackgroundMockNavigationDrawer` renders a hardcoded sidebar with People / Companies / Opportunities / Tasks / Notes (with their standard colors). - Hardcoded constants in `BackgroundMockCompanies.ts`, `BackgroundMockColumns.ts`, `BackgroundMockNavigationItems.ts`. - `MinimalMetadataLoadEffect` no longer calls `loadMockedMetadataAtomic` for unauthenticated users — it just doesn't load anything. - `IsMinimalMetadataReadyEffect` now reports ready immediately when there is no access token pair, so the skeleton loader doesn't hang waiting for metadata that will never come. - `MainContextStoreProvider`, `useRecordIndexTableQuery`, and `useTriggerInitialRecordTableDataLoad` drop their `showAuthModal` branches — the real `RecordTable` is no longer mounted behind the modal. - `DefaultLayout` and `NotFound` now lazily load `BackgroundMockPage` / `BackgroundMockNavigationDrawer` instead of the deleted `SignInBackgroundMockPage` / `SignInAppNavigationDrawerMock`. - Removed: `SignInBackgroundMockPage`, `SignInBackgroundMockContainer`, `SignInBackgroundMockContainerEffect`, `SignInAppNavigationDrawerMock`, `SignInBackgroundMockColumnDefinitions`, `SignInBackgroundMockCompanies`, `SignInBackgroundMockViewFields`. `useLoadMockedMetadata` and `preloadMockedMetadata` are kept on purpose: Storybook decorators (`ObjectMetadataItemsDecorator`, `WorkflowStepDecorator`) still rely on the mocked metadata fixtures, but **production** unauthenticated runtime no longer touches them. ### Visual parity Side-by-side at 1440×900 on `/sign-in`: **Before** (loads mocked metadata + real RecordTable):  **After** (purely hardcoded BackgroundMock):  ## Test plan - [ ] `npx nx typecheck twenty-front` ✅ (passes locally) - [ ] `npx nx lint:diff-with-main twenty-front` ✅ (oxlint + prettier clean) - [ ] `npx jest useRecordIndexTableQuery` ✅ - [ ] Manually verify `/sign-in` renders the table + nav drawer behind the modal - [ ] Manually verify `/not-found` still renders the background - [ ] Verify CI: storybook, unit tests, e2e tests
This commit is contained in:
+2
-7
@@ -2,12 +2,8 @@ import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadata
|
||||
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
|
||||
import { useRelevantRecordsGqlFields } from '@/object-record/record-field/hooks/useRelevantRecordsGqlFields';
|
||||
import { useFindManyRecordIndexTableParams } from '@/object-record/record-index/hooks/useFindManyRecordIndexTableParams';
|
||||
import { SIGN_IN_BACKGROUND_MOCK_COMPANIES } from '@/sign-in-background-mock/constants/SignInBackgroundMockCompanies';
|
||||
import { useShowAuthModal } from '@/ui/layout/hooks/useShowAuthModal';
|
||||
|
||||
export const useRecordIndexTableQuery = (objectNameSingular: string) => {
|
||||
const showAuthModal = useShowAuthModal();
|
||||
|
||||
const params = useFindManyRecordIndexTableParams(objectNameSingular);
|
||||
|
||||
const { objectMetadataItem } = useObjectMetadataItem({
|
||||
@@ -28,12 +24,11 @@ export const useRecordIndexTableQuery = (objectNameSingular: string) => {
|
||||
} = useFindManyRecords({
|
||||
...params,
|
||||
recordGqlFields,
|
||||
skip: showAuthModal,
|
||||
});
|
||||
|
||||
return {
|
||||
records: showAuthModal ? SIGN_IN_BACKGROUND_MOCK_COMPANIES : records,
|
||||
loading: showAuthModal ? false : loading,
|
||||
records,
|
||||
loading,
|
||||
hasNextPage,
|
||||
queryIdentifier,
|
||||
totalCount,
|
||||
|
||||
+26
-36
@@ -30,8 +30,6 @@ import { recordIdByRealIndexComponentState } from '@/object-record/record-table/
|
||||
import { scrollAtRealIndexComponentState } from '@/object-record/record-table/virtualization/states/scrollAtRealIndexComponentState';
|
||||
import { totalNumberOfRecordsToVirtualizeComponentState } from '@/object-record/record-table/virtualization/states/totalNumberOfRecordsToVirtualizeComponentState';
|
||||
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { SIGN_IN_BACKGROUND_MOCK_COMPANIES } from '@/sign-in-background-mock/constants/SignInBackgroundMockCompanies';
|
||||
import { useShowAuthModal } from '@/ui/layout/hooks/useShowAuthModal';
|
||||
import { useAtomComponentFamilyStateCallbackState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilyStateCallbackState';
|
||||
import { useAtomComponentSelectorCallbackState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentSelectorCallbackState';
|
||||
import { useAtomComponentStateCallbackState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateCallbackState';
|
||||
@@ -41,8 +39,6 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
export const useTriggerInitialRecordTableDataLoad = () => {
|
||||
const { recordTableId, objectNameSingular } = useRecordTableContextOrThrow();
|
||||
|
||||
const showAuthModal = useShowAuthModal();
|
||||
|
||||
const { findManyRecordsLazy } =
|
||||
useRecordIndexTableLazyQuery(objectNameSingular);
|
||||
|
||||
@@ -155,40 +151,35 @@ export const useTriggerInitialRecordTableDataLoad = () => {
|
||||
let records: ObjectRecord[] | null = null;
|
||||
let totalCount = 0;
|
||||
|
||||
if (showAuthModal) {
|
||||
records = SIGN_IN_BACKGROUND_MOCK_COMPANIES;
|
||||
totalCount = SIGN_IN_BACKGROUND_MOCK_COMPANIES.length;
|
||||
} else {
|
||||
const newRecordIdByRealIndex = new Map(
|
||||
store.get(recordIdByRealIndexCallbackState),
|
||||
);
|
||||
const newDataLoadingStatusByRealIndex = new Map(
|
||||
store.get(dataLoadingStatusByRealIndexCallbackState),
|
||||
);
|
||||
const newRecordIdByRealIndex = new Map(
|
||||
store.get(recordIdByRealIndexCallbackState),
|
||||
);
|
||||
const newDataLoadingStatusByRealIndex = new Map(
|
||||
store.get(dataLoadingStatusByRealIndexCallbackState),
|
||||
);
|
||||
|
||||
for (const [realIndex] of currentRecordIds.entries()) {
|
||||
newDataLoadingStatusByRealIndex.set(realIndex, 'not-loaded');
|
||||
newRecordIdByRealIndex.delete(realIndex);
|
||||
}
|
||||
|
||||
store.set(recordIdByRealIndexCallbackState, newRecordIdByRealIndex);
|
||||
store.set(
|
||||
dataLoadingStatusByRealIndexCallbackState,
|
||||
newDataLoadingStatusByRealIndex,
|
||||
);
|
||||
|
||||
store.set(
|
||||
recordIndexRecordIdsByGroupFamilyState(NO_RECORD_GROUP_FAMILY_KEY),
|
||||
[],
|
||||
);
|
||||
|
||||
const { records: findManyRecords, totalCount: findManyTotalCount } =
|
||||
await findManyRecordsLazy();
|
||||
|
||||
records = findManyRecords;
|
||||
totalCount = findManyTotalCount;
|
||||
for (const [realIndex] of currentRecordIds.entries()) {
|
||||
newDataLoadingStatusByRealIndex.set(realIndex, 'not-loaded');
|
||||
newRecordIdByRealIndex.delete(realIndex);
|
||||
}
|
||||
|
||||
store.set(recordIdByRealIndexCallbackState, newRecordIdByRealIndex);
|
||||
store.set(
|
||||
dataLoadingStatusByRealIndexCallbackState,
|
||||
newDataLoadingStatusByRealIndex,
|
||||
);
|
||||
|
||||
store.set(
|
||||
recordIndexRecordIdsByGroupFamilyState(NO_RECORD_GROUP_FAMILY_KEY),
|
||||
[],
|
||||
);
|
||||
|
||||
const { records: findManyRecords, totalCount: findManyTotalCount } =
|
||||
await findManyRecordsLazy();
|
||||
|
||||
records = findManyRecords;
|
||||
totalCount = findManyTotalCount;
|
||||
|
||||
store.set(totalNumberOfRecordsToVirtualizeCallbackState, totalCount);
|
||||
|
||||
if (isDefined(records)) {
|
||||
@@ -230,7 +221,6 @@ export const useTriggerInitialRecordTableDataLoad = () => {
|
||||
recordIndexAllRecordIds,
|
||||
recordIndexRecordIdsByGroupFamilyState,
|
||||
store,
|
||||
showAuthModal,
|
||||
dataPagesLoadedCallbackState,
|
||||
isRecordTableInitialLoading,
|
||||
lastScrollPositionCallbackState,
|
||||
|
||||
Reference in New Issue
Block a user