feat: add explicit save for settings (#1686)

This commit is contained in:
Carlos Florêncio
2026-07-19 14:21:36 +01:00
committed by GitHub
parent 1a42c07abe
commit 5fb1923a9a
248 changed files with 14103 additions and 5080 deletions
@@ -1,5 +1,5 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import { act, renderHook, waitFor } from "@testing-library/react";
import { renderHook, waitFor } from "@testing-library/react";
import { fetchUserSettings, updateUserSettings } from "@/lib/api/domains/settings-api";
import {
fetchGitHubWorkspaceSettings,
@@ -14,6 +14,7 @@ import {
const STORAGE_KEY = "kandev:github-default-queries:v1";
const WORKSPACE_ID = "ws-1";
const SETTINGS_TIMESTAMP = "2026-01-01T00:00:00Z";
const DEFAULT_QUERIES_LOADING_ERROR = "Default queries are still loading";
vi.mock("@/lib/api/domains/settings-api", () => ({
fetchUserSettings: vi.fn(),
@@ -107,14 +108,14 @@ describe("useDefaultQueryPresets workspace sync", () => {
expect(updateGitHubWorkspaceSettings).not.toHaveBeenCalled();
});
it("does not save or reset while workspace defaults are still loading", () => {
it("does not save or reset while workspace defaults are still loading", async () => {
vi.mocked(fetchGitHubWorkspaceSettings).mockReturnValue(new Promise(() => {}));
const { result } = renderHook(() => useDefaultQueryPresets(WORKSPACE_ID));
act(() => {
result.current.save({ pr: [preset], issue: [] });
result.current.reset();
});
await expect(result.current.save({ pr: [preset], issue: [] })).rejects.toThrow(
DEFAULT_QUERIES_LOADING_ERROR,
);
await expect(result.current.reset()).rejects.toThrow(DEFAULT_QUERIES_LOADING_ERROR);
expect(updateGitHubWorkspaceSettings).not.toHaveBeenCalled();
});
@@ -125,10 +126,10 @@ describe("useDefaultQueryPresets workspace sync", () => {
await waitFor(() => expect(fetchGitHubWorkspaceSettings).toHaveBeenCalled());
act(() => {
result.current.save({ pr: [preset], issue: [] });
result.current.reset();
});
await expect(result.current.save({ pr: [preset], issue: [] })).rejects.toThrow(
DEFAULT_QUERIES_LOADING_ERROR,
);
await expect(result.current.reset()).rejects.toThrow(DEFAULT_QUERIES_LOADING_ERROR);
expect(updateGitHubWorkspaceSettings).not.toHaveBeenCalled();
});
@@ -159,33 +159,38 @@ export function useDefaultQueryPresets(workspaceId: string | null = null) {
);
const save = useCallback(
(defaults: StoredDefaults) => {
if (workspaceId && workspaceDefaults === undefined) return;
async (defaults: StoredDefaults) => {
if (workspaceId && workspaceDefaults === undefined) {
throw new Error("Default queries are still loading");
}
if (workspaceId) {
await syncWorkspaceDefaultQueryPresets(workspaceId, defaults);
setWorkspaceDefaults(defaults);
void syncWorkspaceDefaultQueryPresets(workspaceId, defaults).catch(() => {});
return;
}
await syncServer(defaults);
publish(defaults);
void syncServer(defaults);
},
[workspaceId, workspaceDefaults, setWorkspaceDefaults],
);
const reset = useCallback(() => {
if (workspaceId && workspaceDefaults === undefined) return;
const reset = useCallback(async () => {
if (workspaceId && workspaceDefaults === undefined) {
throw new Error("Default queries are still loading");
}
if (workspaceId) {
await syncWorkspaceDefaultQueryPresets(workspaceId, null);
setWorkspaceDefaults(null);
void syncWorkspaceDefaultQueryPresets(workspaceId, null).catch(() => {});
return;
}
await syncServer(null);
publish(null);
void syncServer(null);
}, [workspaceId, workspaceDefaults, setWorkspaceDefaults]);
const isCustomized = effectiveStored !== null && effectiveStored !== undefined;
const isReady = !workspaceId || workspaceDefaults !== undefined;
return { prPresets, issuePresets, save, reset, isCustomized };
return { prPresets, issuePresets, save, reset, isCustomized, isReady };
}
/** Resolve full PresetOption[] by merging stored presets with icon lookups from builtins. */