mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-06 02:48:13 +00:00
fix(ui): let another tab's column save replace a toggle this tab could not save
A column toggle that localStorage refused was kept in memory and read ahead of storage, so a later save from another tab stayed hidden until this tab saved again. A storage event now drops the in-memory copy for its key, or all of them when another tab clears storage
This commit is contained in:
parent
adc937c493
commit
d29753c521
2 changed files with 45 additions and 3 deletions
|
|
@ -109,8 +109,9 @@ describe("usePersistedColumnVisibility", () => {
|
|||
});
|
||||
|
||||
it("applies new defaults passed after mount", () => {
|
||||
const initialProps: { defaults: VisibilityState } = { defaults: { spend: false } };
|
||||
const { result, rerender } = renderHook(({ defaults }) => usePersistedColumnVisibility("keys", defaults), {
|
||||
initialProps: { defaults: { spend: false } },
|
||||
initialProps,
|
||||
});
|
||||
|
||||
rerender({ defaults: { name: false } });
|
||||
|
|
@ -146,6 +147,35 @@ describe("usePersistedColumnVisibility", () => {
|
|||
expect(stored("full")).toEqual({ name: false });
|
||||
});
|
||||
|
||||
it("shows another tab's save over a toggle this tab could not save", () => {
|
||||
vi.spyOn(console, "warn").mockImplementation(() => {});
|
||||
vi.spyOn(Storage.prototype, "setItem").mockImplementationOnce(() => {
|
||||
throw new Error("QuotaExceededError");
|
||||
});
|
||||
const { result } = renderHook(() => usePersistedColumnVisibility("shadowed"));
|
||||
act(() => result.current.onColumnVisibilityChange({ email: false }));
|
||||
|
||||
act(() => {
|
||||
localStorage.setItem(keyFor("shadowed"), JSON.stringify({ name: false }));
|
||||
window.dispatchEvent(new StorageEvent("storage", { key: keyFor("shadowed") }));
|
||||
});
|
||||
|
||||
expect(result.current.columnVisibility).toEqual({ name: false });
|
||||
});
|
||||
|
||||
it("drops a toggle this tab could not save once another tab clears storage", () => {
|
||||
vi.spyOn(console, "warn").mockImplementation(() => {});
|
||||
vi.spyOn(Storage.prototype, "setItem").mockImplementationOnce(() => {
|
||||
throw new Error("QuotaExceededError");
|
||||
});
|
||||
const { result } = renderHook(() => usePersistedColumnVisibility("cleared", { spend: false }));
|
||||
act(() => result.current.onColumnVisibilityChange({ email: false }));
|
||||
|
||||
act(() => window.dispatchEvent(new StorageEvent("storage", { key: null })));
|
||||
|
||||
expect(result.current.columnVisibility).toEqual({ spend: false });
|
||||
});
|
||||
|
||||
it("returns the defaults without throwing when storage is unavailable", () => {
|
||||
vi.spyOn(console, "warn").mockImplementation(() => {});
|
||||
vi.spyOn(Storage.prototype, "getItem").mockImplementation(() => {
|
||||
|
|
|
|||
|
|
@ -18,11 +18,23 @@ function storageKey(tableId: string): string {
|
|||
return `${STORAGE_KEY_PREFIX}${tableId}`;
|
||||
}
|
||||
|
||||
function forgetUnsavedWrite(event: StorageEvent): void {
|
||||
if (event.key === null) {
|
||||
unsavedWrites.clear();
|
||||
return;
|
||||
}
|
||||
unsavedWrites.delete(event.key);
|
||||
}
|
||||
|
||||
function subscribe(onChange: () => void): () => void {
|
||||
window.addEventListener("storage", onChange);
|
||||
const onStorage = (event: StorageEvent): void => {
|
||||
forgetUnsavedWrite(event);
|
||||
onChange();
|
||||
};
|
||||
window.addEventListener("storage", onStorage);
|
||||
window.addEventListener(LOCAL_STORAGE_EVENT, onChange);
|
||||
return () => {
|
||||
window.removeEventListener("storage", onChange);
|
||||
window.removeEventListener("storage", onStorage);
|
||||
window.removeEventListener(LOCAL_STORAGE_EVENT, onChange);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue