fix: metadata store lifecycle during sign-in, sign-out, and locale change (#18901)
## Summary Fixes metadata lifecycle bugs during sign-in, sign-out, and locale change: - **Cross-tab sign-out**: Broadcasts sign-out via `BroadcastChannel` so other tabs clear their session gracefully instead of hitting stale-token errors - **SSE teardown on sign-out**: Handles `UNAUTHENTICATED`/`FORBIDDEN` errors in the SSE event stream effect instead of throwing unhandled errors - **Locale switch resilience**: `invalidateAndReload` now invalidates collection hashes instead of clearing the store to empty, so components never see 0 metadata items during the reload transition - **Sign-in background mock**: Uses non-throwing `objectMetadataItemFamilySelector` instead of hooks that throw on missing metadata - **View name placeholders**: Guards against `undefined` `viewName` during metadata transitions (the minimal metadata query doesn't include `name`) - **Session cleanup**: Selective `localStorage` clearing (`clearSessionLocalStorageKeys`) preserves metadata keys; `clearAllSessionLocalStorageKeys` for full clears - **Metadata reload API**: New `useMetadataStoreActions` hook as the high-level API for metadata lifecycle operations (`applyMockedMetadata`, `invalidateAndReload`, `loadMockedMetadataAtomic`) ## Test plan - [ ] Sign out on Tab A → Tab A shows sign-in page with no console errors - [ ] Tab B (logged in) receives cross-tab broadcast and redirects to sign-in - [ ] No "Forbidden resource" SSE errors in console during sign-out - [ ] Change language in Settings > Experience → no crash, metadata refreshes in background - [ ] Sign back in after sign-out → metadata loads correctly, app is functional - [ ] Re-sign-in after locale change → correct locale is preserved
This commit is contained in:
+2
-2
@@ -5,7 +5,7 @@ import {
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
import { useMetadataErrorHandler } from '@/metadata-error-handler/hooks/useMetadataErrorHandler';
|
||||
import { useMetadataStore } from '@/metadata-store/hooks/useMetadataStore';
|
||||
import { useUpdateMetadataStoreDraft } from '@/metadata-store/hooks/useUpdateMetadataStoreDraft';
|
||||
import { type FlatFieldMetadataItem } from '@/metadata-store/types/FlatFieldMetadataItem';
|
||||
import { type MetadataRequestResult } from '@/object-metadata/types/MetadataRequestResult.type';
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
@@ -21,7 +21,7 @@ export const useCreateOneFieldMetadataItem = () => {
|
||||
|
||||
const { handleMetadataError } = useMetadataErrorHandler();
|
||||
const { enqueueErrorSnackBar } = useSnackBar();
|
||||
const { addToDraft, applyChanges } = useMetadataStore();
|
||||
const { addToDraft, applyChanges } = useUpdateMetadataStoreDraft();
|
||||
|
||||
const createOneFieldMetadataItem = async (
|
||||
input: CreateFieldInput,
|
||||
|
||||
+3
-2
@@ -7,7 +7,7 @@ import {
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
import { useMetadataErrorHandler } from '@/metadata-error-handler/hooks/useMetadataErrorHandler';
|
||||
import { useMetadataStore } from '@/metadata-store/hooks/useMetadataStore';
|
||||
import { useUpdateMetadataStoreDraft } from '@/metadata-store/hooks/useUpdateMetadataStoreDraft';
|
||||
import { type FlatFieldMetadataItem } from '@/metadata-store/types/FlatFieldMetadataItem';
|
||||
import { type FlatObjectMetadataItem } from '@/metadata-store/types/FlatObjectMetadataItem';
|
||||
import { splitViewWithRelated } from '@/metadata-store/utils/splitViewWithRelated';
|
||||
@@ -26,7 +26,8 @@ export const useCreateOneObjectMetadataItem = () => {
|
||||
const client = useApolloClient();
|
||||
const { handleMetadataError } = useMetadataErrorHandler();
|
||||
const { enqueueErrorSnackBar } = useSnackBar();
|
||||
const { addToDraft, replaceDraft, applyChanges } = useMetadataStore();
|
||||
const { addToDraft, replaceDraft, applyChanges } =
|
||||
useUpdateMetadataStoreDraft();
|
||||
|
||||
const createOneObjectMetadataItem = async (
|
||||
input: CreateObjectInput,
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@ import { DeleteOneFieldMetadataItemDocument } from '~/generated-metadata/graphql
|
||||
|
||||
import { MAIN_CONTEXT_STORE_INSTANCE_ID } from '@/context-store/constants/MainContextStoreInstanceId';
|
||||
import { useMetadataErrorHandler } from '@/metadata-error-handler/hooks/useMetadataErrorHandler';
|
||||
import { useMetadataStore } from '@/metadata-store/hooks/useMetadataStore';
|
||||
import { useUpdateMetadataStoreDraft } from '@/metadata-store/hooks/useUpdateMetadataStoreDraft';
|
||||
import { type MetadataRequestResult } from '@/object-metadata/types/MetadataRequestResult.type';
|
||||
import { recordIndexGroupAggregateFieldMetadataItemComponentState } from '@/object-record/record-index/states/recordIndexGroupAggregateFieldMetadataItemComponentState';
|
||||
import { recordIndexGroupAggregateOperationComponentState } from '@/object-record/record-index/states/recordIndexGroupAggregateOperationComponentState';
|
||||
@@ -22,7 +22,7 @@ export const useDeleteOneFieldMetadataItem = () => {
|
||||
|
||||
const { handleMetadataError } = useMetadataErrorHandler();
|
||||
const { enqueueErrorSnackBar } = useSnackBar();
|
||||
const { removeFromDraft, applyChanges } = useMetadataStore();
|
||||
const { removeFromDraft, applyChanges } = useUpdateMetadataStoreDraft();
|
||||
|
||||
const setRecordIndexGroupAggregateOperation = useSetAtomComponentState(
|
||||
recordIndexGroupAggregateOperationComponentState,
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@ import { useMutation } from '@apollo/client/react';
|
||||
import { DeleteOneObjectMetadataItemDocument } from '~/generated-metadata/graphql';
|
||||
|
||||
import { useMetadataErrorHandler } from '@/metadata-error-handler/hooks/useMetadataErrorHandler';
|
||||
import { useMetadataStore } from '@/metadata-store/hooks/useMetadataStore';
|
||||
import { useUpdateMetadataStoreDraft } from '@/metadata-store/hooks/useUpdateMetadataStoreDraft';
|
||||
import { type MetadataRequestResult } from '@/object-metadata/types/MetadataRequestResult.type';
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import { CombinedGraphQLErrors } from '@apollo/client/errors';
|
||||
@@ -16,7 +16,7 @@ export const useDeleteOneObjectMetadataItem = () => {
|
||||
|
||||
const { handleMetadataError } = useMetadataErrorHandler();
|
||||
const { enqueueErrorSnackBar } = useSnackBar();
|
||||
const { removeFromDraft, applyChanges } = useMetadataStore();
|
||||
const { removeFromDraft, applyChanges } = useUpdateMetadataStoreDraft();
|
||||
|
||||
const deleteOneObjectMetadataItem = async (
|
||||
idToDelete: string,
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@ import {
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
import { useMetadataErrorHandler } from '@/metadata-error-handler/hooks/useMetadataErrorHandler';
|
||||
import { useMetadataStore } from '@/metadata-store/hooks/useMetadataStore';
|
||||
import { useUpdateMetadataStoreDraft } from '@/metadata-store/hooks/useUpdateMetadataStoreDraft';
|
||||
import { type FlatFieldMetadataItem } from '@/metadata-store/types/FlatFieldMetadataItem';
|
||||
import { lastFieldMetadataItemUpdateState } from '@/object-metadata/states/lastFieldMetadataItemUpdateState';
|
||||
import { type MetadataRequestResult } from '@/object-metadata/types/MetadataRequestResult.type';
|
||||
@@ -25,7 +25,7 @@ export const useUpdateOneFieldMetadataItem = () => {
|
||||
const { handleMetadataError } = useMetadataErrorHandler();
|
||||
|
||||
const { enqueueErrorSnackBar } = useSnackBar();
|
||||
const { updateInDraft, applyChanges } = useMetadataStore();
|
||||
const { updateInDraft, applyChanges } = useUpdateMetadataStoreDraft();
|
||||
|
||||
const setLastFieldMetadataItemUpdate = useSetAtomState(
|
||||
lastFieldMetadataItemUpdateState,
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@ import {
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
import { useMetadataErrorHandler } from '@/metadata-error-handler/hooks/useMetadataErrorHandler';
|
||||
import { useMetadataStore } from '@/metadata-store/hooks/useMetadataStore';
|
||||
import { useUpdateMetadataStoreDraft } from '@/metadata-store/hooks/useUpdateMetadataStoreDraft';
|
||||
import { type FlatObjectMetadataItem } from '@/metadata-store/types/FlatObjectMetadataItem';
|
||||
import { type MetadataRequestResult } from '@/object-metadata/types/MetadataRequestResult.type';
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
@@ -22,7 +22,7 @@ export const useUpdateOneObjectMetadataItem = () => {
|
||||
|
||||
const { handleMetadataError } = useMetadataErrorHandler();
|
||||
const { enqueueErrorSnackBar } = useSnackBar();
|
||||
const { updateInDraft, applyChanges } = useMetadataStore();
|
||||
const { updateInDraft, applyChanges } = useUpdateMetadataStoreDraft();
|
||||
|
||||
const updateOneObjectMetadataItem = async ({
|
||||
idToUpdate,
|
||||
|
||||
Reference in New Issue
Block a user