fix(dashboard): dashboard filters not inherited in charts in Safari sometimes due to race condition (#38851)

Co-authored-by: madhushree agarwal <madhushree_agarwal@apple.com>
This commit is contained in:
madhushreeag
2026-03-31 12:46:05 -07:00
committed by GitHub
parent 8559786cc2
commit 1e2d0faa55
3 changed files with 64 additions and 7 deletions

View File

@@ -22,7 +22,9 @@ import {
parseUrl,
toQueryString,
getDashboardUrlParams,
getUrlParam,
} from './urlUtils';
import { URL_PARAMS } from '../constants';
test('isUrlExternal', () => {
expect(isUrlExternal('http://google.com')).toBeTruthy();
@@ -145,3 +147,45 @@ test('getDashboardUrlParams should exclude multiple parameters when provided', (
// Restore original location
window.location = originalLocation;
});
test('getUrlParam reads from window.location.search by default', () => {
const originalLocation = window.location;
Object.defineProperty(window, 'location', {
value: { ...originalLocation, search: '?dashboard_page_id=from-window' },
writable: true,
configurable: true,
});
expect(getUrlParam(URL_PARAMS.dashboardPageId)).toBe('from-window');
Object.defineProperty(window, 'location', {
value: originalLocation,
writable: true,
configurable: true,
});
});
test('getUrlParam uses provided search string instead of window.location.search (Safari race condition fix)', () => {
// Simulate Safari race condition: window.location.search is stale (empty),
// but the correct search string is passed in from React Router's useLocation()
const originalLocation = window.location;
Object.defineProperty(window, 'location', {
value: { ...originalLocation, search: '' },
writable: true,
configurable: true,
});
// Without the search override, window.location.search is stale — returns null (the bug)
expect(getUrlParam(URL_PARAMS.dashboardPageId)).toBeNull();
// With the search override (the fix), returns the correct value
expect(
getUrlParam(URL_PARAMS.dashboardPageId, '?dashboard_page_id=correct-id'),
).toBe('correct-id');
Object.defineProperty(window, 'location', {
value: originalLocation,
writable: true,
configurable: true,
});
});

View File

@@ -38,22 +38,35 @@ export type UrlParamType = 'string' | 'number' | 'boolean' | 'object' | 'rison';
export type UrlParam = (typeof URL_PARAMS)[keyof typeof URL_PARAMS];
export function getUrlParam(
param: UrlParam & { type: 'string' },
search?: string,
): string | null;
export function getUrlParam(
param: UrlParam & { type: 'number' },
search?: string,
): number | null;
export function getUrlParam(
param: UrlParam & { type: 'boolean' },
search?: string,
): boolean | null;
export function getUrlParam(
param: UrlParam & { type: 'object' },
search?: string,
): object | null;
export function getUrlParam(param: UrlParam & { type: 'rison' }): object | null;
export function getUrlParam(
param: UrlParam & { type: 'rison' },
search?: string,
): string | object | null;
export function getUrlParam(
param: UrlParam & { type: 'rison | string' },
search?: string,
): string | object | null;
export function getUrlParam({ name, type }: UrlParam): unknown {
const urlParam = new URLSearchParams(window.location.search).get(name);
export function getUrlParam(
{ name, type }: UrlParam,
search?: string,
): unknown {
const urlParam = new URLSearchParams(search ?? window.location.search).get(
name,
);
switch (type) {
case 'number':
if (!urlParam) {