fix(admin-ui): patch site config updates instead of replacing
Some checks failed
CI / Banner Lint & Typecheck (push) Has been cancelled
CI / Detect changes (push) Has been cancelled
CI / API Lint (push) Has been cancelled
CI / API Tests (push) Has been cancelled
CI / Scanner Lint (push) Has been cancelled
CI / Scanner Tests (push) Has been cancelled
CI / Banner Tests (push) Has been cancelled
CI / Banner Build (push) Has been cancelled
CI / Admin UI Typecheck (push) Has been cancelled
CI / Admin UI Tests (push) Has been cancelled
CI / Admin UI Build (push) Has been cancelled

The admin UI sends partial SiteConfig bodies from Configuration and Banner
Builder tabs. Using PUT replaced omitted fields with backend defaults, which
reset default_language to null whenever banner_config was saved.

Switch updateSiteConfig() to PATCH so omitted fields are preserved, make the
new default_language field optional for older config shapes, and add a
regression test that ensures partial updates do not use PUT.
This commit is contained in:
Kunthawat Greethong
2026-06-15 21:44:08 +07:00
parent cc707f4887
commit fb6793d05f
3 changed files with 33 additions and 2 deletions

View File

@@ -38,7 +38,7 @@ export async function updateSiteConfig(
siteId: string,
body: Partial<SiteConfig>,
): Promise<SiteConfig> {
const { data } = await apiClient.put<SiteConfig>(`/sites/${siteId}/config`, body);
const { data } = await apiClient.patch<SiteConfig>(`/sites/${siteId}/config`, body);
return data;
}

View File

@@ -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();
});
});

View File

@@ -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;