fix(ai-providers): keep custom header editing stable in modals

This commit is contained in:
Supra4E8C
2026-01-10 14:00:50 +08:00
parent 161d5d1e7f
commit 73ee6eb2f3
7 changed files with 39 additions and 34 deletions

View File

@@ -6,7 +6,7 @@ import { Input } from '@/components/ui/Input';
import { Modal } from '@/components/ui/Modal';
import { ModelInputList, modelsToEntries } from '@/components/ui/ModelInputList';
import type { ProviderKeyConfig } from '@/types';
import { buildHeaderObject, headersToEntries } from '@/utils/headers';
import { headersToEntries } from '@/utils/headers';
import { excludedModelsToText } from '../utils';
import type { ProviderFormState, ProviderModalProps } from '../types';
@@ -19,7 +19,7 @@ const buildEmptyForm = (): ProviderFormState => ({
prefix: '',
baseUrl: '',
proxyUrl: '',
headers: {},
headers: [],
models: [],
excludedModels: [],
modelEntries: [{ name: '', alias: '' }],
@@ -43,7 +43,7 @@ export function ClaudeModal({
// eslint-disable-next-line react-hooks/set-state-in-effect
setForm({
...initialData,
headers: initialData.headers ?? {},
headers: headersToEntries(initialData.headers),
modelEntries: modelsToEntries(initialData.models),
excludedText: excludedModelsToText(initialData.excludedModels),
});
@@ -95,8 +95,8 @@ export function ClaudeModal({
onChange={(e) => setForm((prev) => ({ ...prev, proxyUrl: e.target.value }))}
/>
<HeaderInputList
entries={headersToEntries(form.headers)}
onChange={(entries) => setForm((prev) => ({ ...prev, headers: buildHeaderObject(entries) }))}
entries={form.headers}
onChange={(entries) => setForm((prev) => ({ ...prev, headers: entries }))}
addLabel={t('common.custom_headers_add')}
keyPlaceholder={t('common.custom_headers_key_placeholder')}
valuePlaceholder={t('common.custom_headers_value_placeholder')}

View File

@@ -5,7 +5,7 @@ import { HeaderInputList } from '@/components/ui/HeaderInputList';
import { Input } from '@/components/ui/Input';
import { Modal } from '@/components/ui/Modal';
import type { ProviderKeyConfig } from '@/types';
import { buildHeaderObject, headersToEntries } from '@/utils/headers';
import { headersToEntries } from '@/utils/headers';
import { modelsToEntries } from '@/components/ui/ModelInputList';
import { excludedModelsToText } from '../utils';
import type { ProviderFormState, ProviderModalProps } from '../types';
@@ -19,7 +19,7 @@ const buildEmptyForm = (): ProviderFormState => ({
prefix: '',
baseUrl: '',
proxyUrl: '',
headers: {},
headers: [],
models: [],
excludedModels: [],
modelEntries: [{ name: '', alias: '' }],
@@ -43,7 +43,7 @@ export function CodexModal({
// eslint-disable-next-line react-hooks/set-state-in-effect
setForm({
...initialData,
headers: initialData.headers ?? {},
headers: headersToEntries(initialData.headers),
modelEntries: modelsToEntries(initialData.models),
excludedText: excludedModelsToText(initialData.excludedModels),
});
@@ -95,8 +95,8 @@ export function CodexModal({
onChange={(e) => setForm((prev) => ({ ...prev, proxyUrl: e.target.value }))}
/>
<HeaderInputList
entries={headersToEntries(form.headers)}
onChange={(entries) => setForm((prev) => ({ ...prev, headers: buildHeaderObject(entries) }))}
entries={form.headers}
onChange={(entries) => setForm((prev) => ({ ...prev, headers: entries }))}
addLabel={t('common.custom_headers_add')}
keyPlaceholder={t('common.custom_headers_key_placeholder')}
valuePlaceholder={t('common.custom_headers_value_placeholder')}

View File

@@ -5,7 +5,7 @@ import { HeaderInputList } from '@/components/ui/HeaderInputList';
import { Input } from '@/components/ui/Input';
import { Modal } from '@/components/ui/Modal';
import type { GeminiKeyConfig } from '@/types';
import { buildHeaderObject, headersToEntries } from '@/utils/headers';
import { headersToEntries } from '@/utils/headers';
import { excludedModelsToText } from '../utils';
import type { GeminiFormState, ProviderModalProps } from '../types';
@@ -17,7 +17,7 @@ const buildEmptyForm = (): GeminiFormState => ({
apiKey: '',
prefix: '',
baseUrl: '',
headers: {},
headers: [],
excludedModels: [],
excludedText: '',
});
@@ -39,7 +39,7 @@ export function GeminiModal({
// eslint-disable-next-line react-hooks/set-state-in-effect
setForm({
...initialData,
headers: initialData.headers ?? {},
headers: headersToEntries(initialData.headers),
excludedText: excludedModelsToText(initialData.excludedModels),
});
return;
@@ -91,8 +91,8 @@ export function GeminiModal({
onChange={(e) => setForm((prev) => ({ ...prev, baseUrl: e.target.value }))}
/>
<HeaderInputList
entries={headersToEntries(form.headers)}
onChange={(entries) => setForm((prev) => ({ ...prev, headers: buildHeaderObject(entries) }))}
entries={form.headers}
onChange={(entries) => setForm((prev) => ({ ...prev, headers: entries }))}
addLabel={t('common.custom_headers_add')}
keyPlaceholder={t('common.custom_headers_key_placeholder')}
valuePlaceholder={t('common.custom_headers_value_placeholder')}

View File

@@ -6,7 +6,7 @@ import { Input } from '@/components/ui/Input';
import { Modal } from '@/components/ui/Modal';
import { ModelInputList, modelsToEntries } from '@/components/ui/ModelInputList';
import type { ProviderKeyConfig } from '@/types';
import { buildHeaderObject, headersToEntries } from '@/utils/headers';
import { headersToEntries } from '@/utils/headers';
import type { ProviderModalProps, VertexFormState } from '../types';
interface VertexModalProps extends ProviderModalProps<ProviderKeyConfig, VertexFormState> {
@@ -18,7 +18,7 @@ const buildEmptyForm = (): VertexFormState => ({
prefix: '',
baseUrl: '',
proxyUrl: '',
headers: {},
headers: [],
models: [],
modelEntries: [{ name: '', alias: '' }],
});
@@ -40,7 +40,7 @@ export function VertexModal({
// eslint-disable-next-line react-hooks/set-state-in-effect
setForm({
...initialData,
headers: initialData.headers ?? {},
headers: headersToEntries(initialData.headers),
modelEntries: modelsToEntries(initialData.models),
});
return;
@@ -94,8 +94,8 @@ export function VertexModal({
onChange={(e) => setForm((prev) => ({ ...prev, proxyUrl: e.target.value }))}
/>
<HeaderInputList
entries={headersToEntries(form.headers)}
onChange={(entries) => setForm((prev) => ({ ...prev, headers: buildHeaderObject(entries) }))}
entries={form.headers}
onChange={(entries) => setForm((prev) => ({ ...prev, headers: entries }))}
addLabel={t('common.custom_headers_add')}
keyPlaceholder={t('common.custom_headers_key_placeholder')}
valuePlaceholder={t('common.custom_headers_value_placeholder')}

View File

@@ -32,14 +32,19 @@ export interface AmpcodeFormState {
mappingEntries: ModelEntry[];
}
export type GeminiFormState = GeminiKeyConfig & { excludedText: string };
export type GeminiFormState = Omit<GeminiKeyConfig, 'headers'> & {
headers: HeaderEntry[];
excludedText: string;
};
export type ProviderFormState = ProviderKeyConfig & {
export type ProviderFormState = Omit<ProviderKeyConfig, 'headers'> & {
headers: HeaderEntry[];
modelEntries: ModelEntry[];
excludedText: string;
};
export type VertexFormState = Omit<ProviderKeyConfig, 'excludedModels'> & {
export type VertexFormState = Omit<ProviderKeyConfig, 'headers' | 'excludedModels'> & {
headers: HeaderEntry[];
modelEntries: ModelEntry[];
};