mirror of
https://github.com/router-for-me/Cli-Proxy-API-Management-Center.git
synced 2026-02-02 19:00:49 +08:00
fix(ai-providers): keep custom header editing stable in modals
This commit is contained in:
14
package-lock.json
generated
14
package-lock.json
generated
@@ -3780,9 +3780,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-router": {
|
"node_modules/react-router": {
|
||||||
"version": "7.10.1",
|
"version": "7.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.10.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.12.0.tgz",
|
||||||
"integrity": "sha512-gHL89dRa3kwlUYtRQ+m8NmxGI6CgqN+k4XyGjwcFoQwwCWF6xXpOCUlDovkXClS0d0XJN/5q7kc5W3kiFEd0Yw==",
|
"integrity": "sha512-kTPDYPFzDVGIIGNLS5VJykK0HfHLY5MF3b+xj0/tTyNYL1gF1qs7u67Z9jEhQk2sQ98SUaHxlG31g1JtF7IfVw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cookie": "^1.0.1",
|
"cookie": "^1.0.1",
|
||||||
@@ -3802,12 +3802,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-router-dom": {
|
"node_modules/react-router-dom": {
|
||||||
"version": "7.10.1",
|
"version": "7.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.10.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.12.0.tgz",
|
||||||
"integrity": "sha512-JNBANI6ChGVjA5bwsUIwJk7LHKmqB4JYnYfzFwyp2t12Izva11elds2jx7Yfoup2zssedntwU0oZ5DEmk5Sdaw==",
|
"integrity": "sha512-pfO9fiBcpEfX4Tx+iTYKDtPbrSLLCbwJ5EqP+SPYQu1VYCXdy79GSj0wttR0U4cikVdlImZuEZ/9ZNCgoaxwBA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"react-router": "7.10.1"
|
"react-router": "7.12.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=20.0.0"
|
"node": ">=20.0.0"
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { Input } from '@/components/ui/Input';
|
|||||||
import { Modal } from '@/components/ui/Modal';
|
import { Modal } from '@/components/ui/Modal';
|
||||||
import { ModelInputList, modelsToEntries } from '@/components/ui/ModelInputList';
|
import { ModelInputList, modelsToEntries } from '@/components/ui/ModelInputList';
|
||||||
import type { ProviderKeyConfig } from '@/types';
|
import type { ProviderKeyConfig } from '@/types';
|
||||||
import { buildHeaderObject, headersToEntries } from '@/utils/headers';
|
import { headersToEntries } from '@/utils/headers';
|
||||||
import { excludedModelsToText } from '../utils';
|
import { excludedModelsToText } from '../utils';
|
||||||
import type { ProviderFormState, ProviderModalProps } from '../types';
|
import type { ProviderFormState, ProviderModalProps } from '../types';
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ const buildEmptyForm = (): ProviderFormState => ({
|
|||||||
prefix: '',
|
prefix: '',
|
||||||
baseUrl: '',
|
baseUrl: '',
|
||||||
proxyUrl: '',
|
proxyUrl: '',
|
||||||
headers: {},
|
headers: [],
|
||||||
models: [],
|
models: [],
|
||||||
excludedModels: [],
|
excludedModels: [],
|
||||||
modelEntries: [{ name: '', alias: '' }],
|
modelEntries: [{ name: '', alias: '' }],
|
||||||
@@ -43,7 +43,7 @@ export function ClaudeModal({
|
|||||||
// eslint-disable-next-line react-hooks/set-state-in-effect
|
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||||
setForm({
|
setForm({
|
||||||
...initialData,
|
...initialData,
|
||||||
headers: initialData.headers ?? {},
|
headers: headersToEntries(initialData.headers),
|
||||||
modelEntries: modelsToEntries(initialData.models),
|
modelEntries: modelsToEntries(initialData.models),
|
||||||
excludedText: excludedModelsToText(initialData.excludedModels),
|
excludedText: excludedModelsToText(initialData.excludedModels),
|
||||||
});
|
});
|
||||||
@@ -95,8 +95,8 @@ export function ClaudeModal({
|
|||||||
onChange={(e) => setForm((prev) => ({ ...prev, proxyUrl: e.target.value }))}
|
onChange={(e) => setForm((prev) => ({ ...prev, proxyUrl: e.target.value }))}
|
||||||
/>
|
/>
|
||||||
<HeaderInputList
|
<HeaderInputList
|
||||||
entries={headersToEntries(form.headers)}
|
entries={form.headers}
|
||||||
onChange={(entries) => setForm((prev) => ({ ...prev, headers: buildHeaderObject(entries) }))}
|
onChange={(entries) => setForm((prev) => ({ ...prev, headers: entries }))}
|
||||||
addLabel={t('common.custom_headers_add')}
|
addLabel={t('common.custom_headers_add')}
|
||||||
keyPlaceholder={t('common.custom_headers_key_placeholder')}
|
keyPlaceholder={t('common.custom_headers_key_placeholder')}
|
||||||
valuePlaceholder={t('common.custom_headers_value_placeholder')}
|
valuePlaceholder={t('common.custom_headers_value_placeholder')}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { HeaderInputList } from '@/components/ui/HeaderInputList';
|
|||||||
import { Input } from '@/components/ui/Input';
|
import { Input } from '@/components/ui/Input';
|
||||||
import { Modal } from '@/components/ui/Modal';
|
import { Modal } from '@/components/ui/Modal';
|
||||||
import type { ProviderKeyConfig } from '@/types';
|
import type { ProviderKeyConfig } from '@/types';
|
||||||
import { buildHeaderObject, headersToEntries } from '@/utils/headers';
|
import { headersToEntries } from '@/utils/headers';
|
||||||
import { modelsToEntries } from '@/components/ui/ModelInputList';
|
import { modelsToEntries } from '@/components/ui/ModelInputList';
|
||||||
import { excludedModelsToText } from '../utils';
|
import { excludedModelsToText } from '../utils';
|
||||||
import type { ProviderFormState, ProviderModalProps } from '../types';
|
import type { ProviderFormState, ProviderModalProps } from '../types';
|
||||||
@@ -19,7 +19,7 @@ const buildEmptyForm = (): ProviderFormState => ({
|
|||||||
prefix: '',
|
prefix: '',
|
||||||
baseUrl: '',
|
baseUrl: '',
|
||||||
proxyUrl: '',
|
proxyUrl: '',
|
||||||
headers: {},
|
headers: [],
|
||||||
models: [],
|
models: [],
|
||||||
excludedModels: [],
|
excludedModels: [],
|
||||||
modelEntries: [{ name: '', alias: '' }],
|
modelEntries: [{ name: '', alias: '' }],
|
||||||
@@ -43,7 +43,7 @@ export function CodexModal({
|
|||||||
// eslint-disable-next-line react-hooks/set-state-in-effect
|
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||||
setForm({
|
setForm({
|
||||||
...initialData,
|
...initialData,
|
||||||
headers: initialData.headers ?? {},
|
headers: headersToEntries(initialData.headers),
|
||||||
modelEntries: modelsToEntries(initialData.models),
|
modelEntries: modelsToEntries(initialData.models),
|
||||||
excludedText: excludedModelsToText(initialData.excludedModels),
|
excludedText: excludedModelsToText(initialData.excludedModels),
|
||||||
});
|
});
|
||||||
@@ -95,8 +95,8 @@ export function CodexModal({
|
|||||||
onChange={(e) => setForm((prev) => ({ ...prev, proxyUrl: e.target.value }))}
|
onChange={(e) => setForm((prev) => ({ ...prev, proxyUrl: e.target.value }))}
|
||||||
/>
|
/>
|
||||||
<HeaderInputList
|
<HeaderInputList
|
||||||
entries={headersToEntries(form.headers)}
|
entries={form.headers}
|
||||||
onChange={(entries) => setForm((prev) => ({ ...prev, headers: buildHeaderObject(entries) }))}
|
onChange={(entries) => setForm((prev) => ({ ...prev, headers: entries }))}
|
||||||
addLabel={t('common.custom_headers_add')}
|
addLabel={t('common.custom_headers_add')}
|
||||||
keyPlaceholder={t('common.custom_headers_key_placeholder')}
|
keyPlaceholder={t('common.custom_headers_key_placeholder')}
|
||||||
valuePlaceholder={t('common.custom_headers_value_placeholder')}
|
valuePlaceholder={t('common.custom_headers_value_placeholder')}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { HeaderInputList } from '@/components/ui/HeaderInputList';
|
|||||||
import { Input } from '@/components/ui/Input';
|
import { Input } from '@/components/ui/Input';
|
||||||
import { Modal } from '@/components/ui/Modal';
|
import { Modal } from '@/components/ui/Modal';
|
||||||
import type { GeminiKeyConfig } from '@/types';
|
import type { GeminiKeyConfig } from '@/types';
|
||||||
import { buildHeaderObject, headersToEntries } from '@/utils/headers';
|
import { headersToEntries } from '@/utils/headers';
|
||||||
import { excludedModelsToText } from '../utils';
|
import { excludedModelsToText } from '../utils';
|
||||||
import type { GeminiFormState, ProviderModalProps } from '../types';
|
import type { GeminiFormState, ProviderModalProps } from '../types';
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ const buildEmptyForm = (): GeminiFormState => ({
|
|||||||
apiKey: '',
|
apiKey: '',
|
||||||
prefix: '',
|
prefix: '',
|
||||||
baseUrl: '',
|
baseUrl: '',
|
||||||
headers: {},
|
headers: [],
|
||||||
excludedModels: [],
|
excludedModels: [],
|
||||||
excludedText: '',
|
excludedText: '',
|
||||||
});
|
});
|
||||||
@@ -39,7 +39,7 @@ export function GeminiModal({
|
|||||||
// eslint-disable-next-line react-hooks/set-state-in-effect
|
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||||
setForm({
|
setForm({
|
||||||
...initialData,
|
...initialData,
|
||||||
headers: initialData.headers ?? {},
|
headers: headersToEntries(initialData.headers),
|
||||||
excludedText: excludedModelsToText(initialData.excludedModels),
|
excludedText: excludedModelsToText(initialData.excludedModels),
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@@ -91,8 +91,8 @@ export function GeminiModal({
|
|||||||
onChange={(e) => setForm((prev) => ({ ...prev, baseUrl: e.target.value }))}
|
onChange={(e) => setForm((prev) => ({ ...prev, baseUrl: e.target.value }))}
|
||||||
/>
|
/>
|
||||||
<HeaderInputList
|
<HeaderInputList
|
||||||
entries={headersToEntries(form.headers)}
|
entries={form.headers}
|
||||||
onChange={(entries) => setForm((prev) => ({ ...prev, headers: buildHeaderObject(entries) }))}
|
onChange={(entries) => setForm((prev) => ({ ...prev, headers: entries }))}
|
||||||
addLabel={t('common.custom_headers_add')}
|
addLabel={t('common.custom_headers_add')}
|
||||||
keyPlaceholder={t('common.custom_headers_key_placeholder')}
|
keyPlaceholder={t('common.custom_headers_key_placeholder')}
|
||||||
valuePlaceholder={t('common.custom_headers_value_placeholder')}
|
valuePlaceholder={t('common.custom_headers_value_placeholder')}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { Input } from '@/components/ui/Input';
|
|||||||
import { Modal } from '@/components/ui/Modal';
|
import { Modal } from '@/components/ui/Modal';
|
||||||
import { ModelInputList, modelsToEntries } from '@/components/ui/ModelInputList';
|
import { ModelInputList, modelsToEntries } from '@/components/ui/ModelInputList';
|
||||||
import type { ProviderKeyConfig } from '@/types';
|
import type { ProviderKeyConfig } from '@/types';
|
||||||
import { buildHeaderObject, headersToEntries } from '@/utils/headers';
|
import { headersToEntries } from '@/utils/headers';
|
||||||
import type { ProviderModalProps, VertexFormState } from '../types';
|
import type { ProviderModalProps, VertexFormState } from '../types';
|
||||||
|
|
||||||
interface VertexModalProps extends ProviderModalProps<ProviderKeyConfig, VertexFormState> {
|
interface VertexModalProps extends ProviderModalProps<ProviderKeyConfig, VertexFormState> {
|
||||||
@@ -18,7 +18,7 @@ const buildEmptyForm = (): VertexFormState => ({
|
|||||||
prefix: '',
|
prefix: '',
|
||||||
baseUrl: '',
|
baseUrl: '',
|
||||||
proxyUrl: '',
|
proxyUrl: '',
|
||||||
headers: {},
|
headers: [],
|
||||||
models: [],
|
models: [],
|
||||||
modelEntries: [{ name: '', alias: '' }],
|
modelEntries: [{ name: '', alias: '' }],
|
||||||
});
|
});
|
||||||
@@ -40,7 +40,7 @@ export function VertexModal({
|
|||||||
// eslint-disable-next-line react-hooks/set-state-in-effect
|
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||||
setForm({
|
setForm({
|
||||||
...initialData,
|
...initialData,
|
||||||
headers: initialData.headers ?? {},
|
headers: headersToEntries(initialData.headers),
|
||||||
modelEntries: modelsToEntries(initialData.models),
|
modelEntries: modelsToEntries(initialData.models),
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@@ -94,8 +94,8 @@ export function VertexModal({
|
|||||||
onChange={(e) => setForm((prev) => ({ ...prev, proxyUrl: e.target.value }))}
|
onChange={(e) => setForm((prev) => ({ ...prev, proxyUrl: e.target.value }))}
|
||||||
/>
|
/>
|
||||||
<HeaderInputList
|
<HeaderInputList
|
||||||
entries={headersToEntries(form.headers)}
|
entries={form.headers}
|
||||||
onChange={(entries) => setForm((prev) => ({ ...prev, headers: buildHeaderObject(entries) }))}
|
onChange={(entries) => setForm((prev) => ({ ...prev, headers: entries }))}
|
||||||
addLabel={t('common.custom_headers_add')}
|
addLabel={t('common.custom_headers_add')}
|
||||||
keyPlaceholder={t('common.custom_headers_key_placeholder')}
|
keyPlaceholder={t('common.custom_headers_key_placeholder')}
|
||||||
valuePlaceholder={t('common.custom_headers_value_placeholder')}
|
valuePlaceholder={t('common.custom_headers_value_placeholder')}
|
||||||
|
|||||||
@@ -32,14 +32,19 @@ export interface AmpcodeFormState {
|
|||||||
mappingEntries: ModelEntry[];
|
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[];
|
modelEntries: ModelEntry[];
|
||||||
excludedText: string;
|
excludedText: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type VertexFormState = Omit<ProviderKeyConfig, 'excludedModels'> & {
|
export type VertexFormState = Omit<ProviderKeyConfig, 'headers' | 'excludedModels'> & {
|
||||||
|
headers: HeaderEntry[];
|
||||||
modelEntries: ModelEntry[];
|
modelEntries: ModelEntry[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import {
|
|||||||
import { ampcodeApi, providersApi } from '@/services/api';
|
import { ampcodeApi, providersApi } from '@/services/api';
|
||||||
import { useAuthStore, useConfigStore, useNotificationStore, useThemeStore } from '@/stores';
|
import { useAuthStore, useConfigStore, useNotificationStore, useThemeStore } from '@/stores';
|
||||||
import type { GeminiKeyConfig, OpenAIProviderConfig, ProviderKeyConfig } from '@/types';
|
import type { GeminiKeyConfig, OpenAIProviderConfig, ProviderKeyConfig } from '@/types';
|
||||||
import { buildHeaderObject, headersToEntries } from '@/utils/headers';
|
import { buildHeaderObject } from '@/utils/headers';
|
||||||
import styles from './AiProvidersPage.module.scss';
|
import styles from './AiProvidersPage.module.scss';
|
||||||
|
|
||||||
export function AiProvidersPage() {
|
export function AiProvidersPage() {
|
||||||
@@ -151,7 +151,7 @@ export function AiProvidersPage() {
|
|||||||
apiKey: form.apiKey.trim(),
|
apiKey: form.apiKey.trim(),
|
||||||
prefix: form.prefix?.trim() || undefined,
|
prefix: form.prefix?.trim() || undefined,
|
||||||
baseUrl: form.baseUrl?.trim() || undefined,
|
baseUrl: form.baseUrl?.trim() || undefined,
|
||||||
headers: buildHeaderObject(headersToEntries(form.headers)),
|
headers: buildHeaderObject(form.headers),
|
||||||
excludedModels: parseExcludedModels(form.excludedText),
|
excludedModels: parseExcludedModels(form.excludedText),
|
||||||
};
|
};
|
||||||
const nextList =
|
const nextList =
|
||||||
@@ -307,7 +307,7 @@ export function AiProvidersPage() {
|
|||||||
prefix: form.prefix?.trim() || undefined,
|
prefix: form.prefix?.trim() || undefined,
|
||||||
baseUrl,
|
baseUrl,
|
||||||
proxyUrl: form.proxyUrl?.trim() || undefined,
|
proxyUrl: form.proxyUrl?.trim() || undefined,
|
||||||
headers: buildHeaderObject(headersToEntries(form.headers)),
|
headers: buildHeaderObject(form.headers),
|
||||||
models: entriesToModels(form.modelEntries),
|
models: entriesToModels(form.modelEntries),
|
||||||
excludedModels: parseExcludedModels(form.excludedText),
|
excludedModels: parseExcludedModels(form.excludedText),
|
||||||
};
|
};
|
||||||
@@ -390,7 +390,7 @@ export function AiProvidersPage() {
|
|||||||
prefix: form.prefix?.trim() || undefined,
|
prefix: form.prefix?.trim() || undefined,
|
||||||
baseUrl,
|
baseUrl,
|
||||||
proxyUrl: form.proxyUrl?.trim() || undefined,
|
proxyUrl: form.proxyUrl?.trim() || undefined,
|
||||||
headers: buildHeaderObject(headersToEntries(form.headers)),
|
headers: buildHeaderObject(form.headers),
|
||||||
models: form.modelEntries
|
models: form.modelEntries
|
||||||
.map((entry) => {
|
.map((entry) => {
|
||||||
const name = entry.name.trim();
|
const name = entry.name.trim();
|
||||||
|
|||||||
Reference in New Issue
Block a user