import { SYSTEM_DEFAULT } from "../../../../../constant"; import { View } from "../../../data/userView"; import { getSessionKeyPrefix } from "./getSystemDefaultSessionKey"; /** * Which view the toolbar opens on, and the session memory behind it. * * The selection used to be re-derived from the server on every load: * `deserializedScreenView` maps the service's `selected` flag onto **both** * `isDefault` and `isSelected`, so "the selected view" and "the default view" * were the same thing. A route change or a browser refresh therefore always * landed on the default saved view — and when that was a saved view rather than * System Default, `loadSelectedViewData` never took the SYSTEM_DEFAULT branch, * so the snapshot `saveSystemDefaultInSession` had just written was never read * back. The whole `enableDefaultSaveInSession` feature was write-only for any * screen that had a default view. * * Remembering the selection for the tab fixes that, and is the same lifetime as * the snapshot it unlocks — both live in `sessionStorage`, both die with the * tab. It is gated on `enableDefaultSaveInSession` so screens that never opted * into session persistence keep exactly the previous behaviour. */ const SELECTED_VIEW_SUFFIX = "selectedView"; export const getSelectedViewSessionKey = ( uiElementGroupId: string, getUniqueViewId?: (callBack: (response: string) => void) => void, ): string => `${getSessionKeyPrefix(uiElementGroupId, getUniqueViewId)}_${SELECTED_VIEW_SUFFIX}`; export const saveSelectedViewInSession = ( viewId: string, uiElementGroupId: string, getUniqueViewId?: (callBack: (response: string) => void) => void, ): void => { try { sessionStorage.setItem( getSelectedViewSessionKey(uiElementGroupId, getUniqueViewId), viewId, ); } catch (error) { // A full or disabled sessionStorage must not take the toolbar down with it; // the cost is falling back to the server default on the next load. console.error("Error saving the selected view to session:", error); } }; export const clearSelectedViewInSession = ( uiElementGroupId: string, getUniqueViewId?: (callBack: (response: string) => void) => void, ): void => { try { sessionStorage.removeItem( getSelectedViewSessionKey(uiElementGroupId, getUniqueViewId), ); } catch (error) { console.error("Error clearing the selected view from session:", error); } }; /** * The single decision point for "which view is selected" on a load — a route * change, a browser refresh, or the initial mount. * * Order: what this tab was last on → what the server marks selected/default → * System Default → the first view. Every fallback is guarded, so a remembered * view that has since been deleted, or a list with no default at all, resolves * rather than throwing. */ export const resolveSelectedView = ( allViews: View[], options: { uiElementGroupId: string; getUniqueViewId?: (callBack: (response: string) => void) => void; enableDefaultSaveInSession?: boolean; }, ): View | undefined => { if (options.enableDefaultSaveInSession) { let rememberedId: string | null = null; try { rememberedId = sessionStorage.getItem( getSelectedViewSessionKey( options.uiElementGroupId, options.getUniqueViewId, ), ); } catch (error) { console.error("Error reading the selected view from session:", error); } const remembered = rememberedId ? allViews.find((view: View) => view.id === rememberedId) : undefined; if (remembered) return remembered; } return ( allViews.find((view: View) => view.isSelected === true) ?? allViews.find((view: View) => view.id === SYSTEM_DEFAULT) ?? allViews[0] ); }; export default resolveSelectedView;