feat(FN-1277): hydrate dashboard theme settings from backend
- Hydrate useTheme from global settings while seeding initial state from localStorage cache to prevent flash - Add write-through theme persistence so setter updates local cache immediately and asynchronously saves via updateGlobalSettings - Clarify Settings modal save behavior for intentional idempotent global theme writes - Expand useTheme and App tests to cover backend hydration, fallback handling, and new global settings fetch expectations
This commit is contained in:
@@ -500,7 +500,10 @@ export function SettingsModal({
|
||||
}
|
||||
}
|
||||
|
||||
// Save both scopes in parallel if they have changes
|
||||
// Save both scopes in parallel if they have changes.
|
||||
// Note: themeMode/colorTheme may also be write-through via useTheme callbacks
|
||||
// in the Appearance section; duplicate global writes are intentional/idempotent,
|
||||
// while this save path persists the full settings form in one action.
|
||||
await Promise.all([
|
||||
Object.keys(globalPatch).length > 0 ? updateGlobalSettings(globalPatch) : Promise.resolve(),
|
||||
Object.keys(projectPatch).length > 0 ? updateSettings(projectPatch, projectId) : Promise.resolve(),
|
||||
|
||||
@@ -538,7 +538,7 @@ describe("App auto-open Settings on unauthenticated", () => {
|
||||
});
|
||||
|
||||
it("auto-opens Settings to Authentication tab when all providers are unauthenticated but onboarding IS complete", async () => {
|
||||
(fetchGlobalSettings as ReturnType<typeof vi.fn>).mockResolvedValueOnce({
|
||||
(fetchGlobalSettings as ReturnType<typeof vi.fn>).mockResolvedValue({
|
||||
modelOnboardingComplete: true,
|
||||
});
|
||||
|
||||
@@ -567,7 +567,7 @@ describe("App auto-open Settings on unauthenticated", () => {
|
||||
{ id: "github", name: "GitHub", authenticated: false },
|
||||
],
|
||||
});
|
||||
(fetchGlobalSettings as ReturnType<typeof vi.fn>).mockResolvedValueOnce({
|
||||
(fetchGlobalSettings as ReturnType<typeof vi.fn>).mockResolvedValue({
|
||||
defaultProvider: "anthropic",
|
||||
defaultModelId: "claude-sonnet-4-5",
|
||||
});
|
||||
@@ -591,7 +591,7 @@ describe("App auto-open Settings on unauthenticated", () => {
|
||||
],
|
||||
});
|
||||
// No defaultProvider or defaultModelId → setup incomplete
|
||||
(fetchGlobalSettings as ReturnType<typeof vi.fn>).mockResolvedValueOnce({
|
||||
(fetchGlobalSettings as ReturnType<typeof vi.fn>).mockResolvedValue({
|
||||
modelOnboardingComplete: false,
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user