diff --git a/apps/admin-ui/src/api/sites.ts b/apps/admin-ui/src/api/sites.ts index d4f484b..d027287 100644 --- a/apps/admin-ui/src/api/sites.ts +++ b/apps/admin-ui/src/api/sites.ts @@ -38,7 +38,7 @@ export async function updateSiteConfig( siteId: string, body: Partial, ): Promise { - const { data } = await apiClient.put(`/sites/${siteId}/config`, body); + const { data } = await apiClient.patch(`/sites/${siteId}/config`, body); return data; } diff --git a/apps/admin-ui/src/test/sites-api.test.ts b/apps/admin-ui/src/test/sites-api.test.ts new file mode 100644 index 0000000..fce94e6 --- /dev/null +++ b/apps/admin-ui/src/test/sites-api.test.ts @@ -0,0 +1,31 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest'; + +const apiClient = { + get: vi.fn(), + post: vi.fn(), + patch: vi.fn(), + put: vi.fn(), + delete: vi.fn(), +}; + +vi.mock('../api/client', () => ({ + default: apiClient, +})); + +describe('sites API client', () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + it('partially updates site config with PATCH so omitted fields are preserved', async () => { + apiClient.patch.mockResolvedValue({ data: { id: 'cfg-1' } }); + + const { updateSiteConfig } = await import('../api/sites'); + await updateSiteConfig('site-1', { banner_config: { displayMode: 'corner_popup' } }); + + expect(apiClient.patch).toHaveBeenCalledWith('/sites/site-1/config', { + banner_config: { displayMode: 'corner_popup' }, + }); + expect(apiClient.put).not.toHaveBeenCalled(); + }); +}); diff --git a/apps/admin-ui/src/types/api.ts b/apps/admin-ui/src/types/api.ts index cbe23bb..2ef4a9b 100644 --- a/apps/admin-ui/src/types/api.ts +++ b/apps/admin-ui/src/types/api.ts @@ -125,7 +125,7 @@ export interface SiteConfig { banner_config: BannerConfig | null; privacy_policy_url: string | null; terms_url: string | null; - default_language: string | null; + default_language?: string | null; consent_expiry_days: number; scan_enabled: boolean; scan_frequency_hours: number;