mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-11-06 02:25:24 +00:00
fix: save every ui pref key changed in one burst so dashboard reset sticks
This commit is contained in:
1 parent
19bdd589f3
commit
4aead47049
3 files changed
+41
-2
No files matched your search
@@ -29,6 +29,7 @@
|
|||||||
- The Secure your account setup step no longer shows up empty when no passkey or authenticator plugin is on
|
- The Secure your account setup step no longer shows up empty when no passkey or authenticator plugin is on
|
||||||
- An installed plugin update older than the copy in a newer image is removed at startup instead of logging an error every boot
|
- An installed plugin update older than the copy in a newer image is removed at startup instead of logging an error every boot
|
||||||
- Canceling a download to the desktop app right as it starts no longer leaves a partial file behind
|
- Canceling a download to the desktop app right as it starts no longer leaves a partial file behind
|
||||||
|
- Changing two interface settings at once, like resetting the dashboard, now saves both instead of only the last one
|
||||||
|
|
||||||
## 26.11.0
|
## 26.11.0
|
||||||
|
|
||||||
|
|||||||
@@ -179,10 +179,24 @@ export function UiPreferencesProvider({
|
|||||||
const merged = { ...pendingPatch.current };
|
const merged = { ...pendingPatch.current };
|
||||||
for (const [key, value] of Object.entries(patch)) {
|
for (const [key, value] of Object.entries(patch)) {
|
||||||
if (key === "overrides" && value && typeof value === "object") {
|
if (key === "overrides" && value && typeof value === "object") {
|
||||||
merged.overrides = {
|
// Two levels deep like the server, so two keys set in one area
|
||||||
|
// in the same burst both get sent.
|
||||||
|
const areas = {
|
||||||
...((merged.overrides as Record<string, unknown>) ?? {}),
|
...((merged.overrides as Record<string, unknown>) ?? {}),
|
||||||
...(value as Record<string, unknown>),
|
|
||||||
};
|
};
|
||||||
|
for (const [area, keys] of Object.entries(
|
||||||
|
value as Record<string, unknown>,
|
||||||
|
)) {
|
||||||
|
const prev = areas[area];
|
||||||
|
areas[area] =
|
||||||
|
keys &&
|
||||||
|
typeof keys === "object" &&
|
||||||
|
prev &&
|
||||||
|
typeof prev === "object"
|
||||||
|
? { ...prev, ...keys }
|
||||||
|
: keys;
|
||||||
|
}
|
||||||
|
merged.overrides = areas;
|
||||||
} else if (key === "onboarding" && value && typeof value === "object") {
|
} else if (key === "onboarding" && value && typeof value === "object") {
|
||||||
const prev = (merged.onboarding ?? {}) as Record<string, unknown>;
|
const prev = (merged.onboarding ?? {}) as Record<string, unknown>;
|
||||||
const next = value as Record<string, unknown>;
|
const next = value as Record<string, unknown>;
|
||||||
|
|||||||
@@ -185,6 +185,30 @@ describe("UiPreferencesProvider", () => {
|
|||||||
expect(result.current?.preferences.overrides).toEqual({});
|
expect(result.current?.preferences.overrides).toEqual({});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("sends every key set in one area within a burst", async () => {
|
||||||
|
vi.useFakeTimers();
|
||||||
|
api.getUserPreferences.mockResolvedValue({ storageMode: "cloud" });
|
||||||
|
api.getUiPreferences.mockResolvedValue({
|
||||||
|
...defaultUiPreferences(),
|
||||||
|
overrides: { "plugin:x": { grid: ["a"], slots: ["b"] } },
|
||||||
|
});
|
||||||
|
|
||||||
|
const { result } = renderHook(() => useUiPreferencesContext(), { wrapper });
|
||||||
|
await vi.waitFor(() => expect(result.current?.loaded).toBe(true));
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current?.setPluginOverride("x", "grid", null);
|
||||||
|
result.current?.setPluginOverride("x", "slots", null);
|
||||||
|
});
|
||||||
|
await act(async () => {
|
||||||
|
await vi.advanceTimersByTimeAsync(1000);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(api.saveUiPreferences).toHaveBeenCalledWith({
|
||||||
|
overrides: { "plugin:x": { grid: null, slots: null } },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("prunes an area once its last override is cleared", async () => {
|
it("prunes an area once its last override is cleared", async () => {
|
||||||
api.getUiPreferences.mockResolvedValue({
|
api.getUiPreferences.mockResolvedValue({
|
||||||
...defaultUiPreferences(),
|
...defaultUiPreferences(),
|
||||||
|
|||||||
Reference in new issue
Block a user