diff --git a/ui/litellm-dashboard/src/components/shared/advanced_date_picker.test.tsx b/ui/litellm-dashboard/src/components/shared/advanced_date_picker.test.tsx index 90d75df75e4..b2824e02390 100644 --- a/ui/litellm-dashboard/src/components/shared/advanced_date_picker.test.tsx +++ b/ui/litellm-dashboard/src/components/shared/advanced_date_picker.test.tsx @@ -180,4 +180,43 @@ describe("AdvancedDatePicker", () => { expect(applyButton).toBeDisabled(); }); }); + + it("should close dropdown when Apply is clicked", async () => { + const { container } = render(); + + openDropdown(container); + expect(screen.getByText("Today")).toBeInTheDocument(); + + fireEvent.click(screen.getByText("Apply")); + + await waitFor(() => { + expect(screen.queryByText("Today")).not.toBeInTheDocument(); + }); + }); + + it("should close dropdown on Apply even without requestIdleCallback (Safari)", async () => { + // Safari has never implemented requestIdleCallback. Simulate that by + // removing the polyfill installed in the beforeAll above for this one + // test, so a regression that puts setIsOpen(false) after the + // requestIdleCallback call (and lets its ReferenceError swallow it) + // fails here instead of only in real Safari. + const original = window.requestIdleCallback; + // @ts-expect-error - deleting a browser API to emulate Safari's absence of it + delete window.requestIdleCallback; + + try { + const { container } = render(); + + openDropdown(container); + expect(screen.getByText("Today")).toBeInTheDocument(); + + fireEvent.click(screen.getByText("Apply")); + + await waitFor(() => { + expect(screen.queryByText("Today")).not.toBeInTheDocument(); + }); + } finally { + window.requestIdleCallback = original; + } + }); }); diff --git a/ui/litellm-dashboard/src/components/shared/advanced_date_picker.tsx b/ui/litellm-dashboard/src/components/shared/advanced_date_picker.tsx index 30969a4cef0..4e83eeddbfe 100644 --- a/ui/litellm-dashboard/src/components/shared/advanced_date_picker.tsx +++ b/ui/litellm-dashboard/src/components/shared/advanced_date_picker.tsx @@ -179,16 +179,21 @@ const AdvancedDatePicker: React.FC = ({ // First call with immediate value for UI responsiveness onValueChange(tempValue); - // Then do the same background adjustment logic as the original component - requestIdleCallback( - () => { - const adjustedValue = adjustDateRange(tempValue); - onValueChange(adjustedValue); - }, - { timeout: 100 }, - ); - + // Close immediately - Safari has no requestIdleCallback, and scheduling + // the close after it (as before) meant the thrown ReferenceError there + // silently skipped this line, leaving the dropdown stuck open. setIsOpen(false); + + // Then do the same background adjustment logic as the original component. + // Safari doesn't implement requestIdleCallback, so fall back to setTimeout. + const scheduleIdle: (callback: () => void) => void = + typeof requestIdleCallback === "function" + ? (callback) => requestIdleCallback(callback, { timeout: 100 }) + : (callback) => setTimeout(callback, 0); + scheduleIdle(() => { + const adjustedValue = adjustDateRange(tempValue); + onValueChange(adjustedValue); + }); } };