diff --git a/src/renderer/src/components/Popups/ApiKeyListPopup/list.tsx b/src/renderer/src/components/Popups/ApiKeyListPopup/list.tsx index b5770b5d02..9d330b6b41 100644 --- a/src/renderer/src/components/Popups/ApiKeyListPopup/list.tsx +++ b/src/renderer/src/components/Popups/ApiKeyListPopup/list.tsx @@ -10,6 +10,7 @@ import { Button, Card, Flex, List, Popconfirm, Space, Tooltip, Typography } from import { Trash } from 'lucide-react' import { FC, useState } from 'react' import { useTranslation } from 'react-i18next' +import styled from 'styled-components' import { isLlmProvider, useApiKeys } from './hook' import ApiKeyItem from './item' @@ -87,7 +88,7 @@ export const ApiKeyList: FC = ({ provider, updateProvider, prov : keys return ( - <> + {/* Keys 列表 */} = ({ provider, updateProvider, prov )} - + {/* 帮助文本 */} {t('settings.provider.api_key.tip')} @@ -166,7 +167,7 @@ export const ApiKeyList: FC = ({ provider, updateProvider, prov - + ) } @@ -222,3 +223,8 @@ export const DocPreprocessApiKeyList: FC = ({ /> ) } + +const ListContainer = styled.div` + padding-top: 15px; + padding-bottom: 15px; +` diff --git a/src/renderer/src/pages/settings/ProviderSettings/CustomHeaderPopup.tsx b/src/renderer/src/pages/settings/ProviderSettings/CustomHeaderPopup.tsx new file mode 100644 index 0000000000..79a872ef7e --- /dev/null +++ b/src/renderer/src/pages/settings/ProviderSettings/CustomHeaderPopup.tsx @@ -0,0 +1,102 @@ +import CodeEditor from '@renderer/components/CodeEditor' +import { TopView } from '@renderer/components/TopView' +import { useProvider } from '@renderer/hooks/useProvider' +import { Provider } from '@renderer/types' +import { Modal, Space } from 'antd' +import { useCallback, useState } from 'react' +import { useTranslation } from 'react-i18next' + +import { SettingHelpText } from '..' + +interface ShowParams { + provider: Provider +} + +interface Props extends ShowParams { + resolve: (data: any) => void +} + +const PopupContainer: React.FC = ({ provider, resolve }) => { + const [open, setOpen] = useState(true) + const { t } = useTranslation() + const { updateProvider } = useProvider(provider.id) + const [headerText, setHeaderText] = useState(JSON.stringify(provider.extra_headers || {}, null, 2)) + + const onUpdateHeaders = useCallback(() => { + try { + const headers = headerText.trim() ? JSON.parse(headerText) : {} + updateProvider({ ...provider, extra_headers: headers }) + window.message.success({ content: t('message.save.success.title') }) + } catch (error) { + window.message.error({ content: t('settings.provider.copilot.invalid_json') }) + } + }, [headerText, provider, updateProvider, t]) + + const onOk = () => { + onUpdateHeaders() + setOpen(false) + } + + const onCancel = () => { + setOpen(false) + } + + const onClose = () => { + resolve({}) + } + + CustomHeaderPopup.hide = onCancel + + return ( + + + {t('settings.provider.copilot.headers_description')} + setHeaderText(value)} + placeholder={`{\n "Header-Name": "Header-Value"\n}`} + options={{ + lint: true, + collapsible: false, + wrappable: true, + lineNumbers: true, + foldGutter: true, + highlightActiveLine: true, + keymap: true + }} + /> + + + ) +} + +const TopViewKey = 'CustomHeaderPopup' + +export default class CustomHeaderPopup { + static topviewId = 0 + static hide() { + TopView.hide(TopViewKey) + } + static show(props: ShowParams) { + return new Promise((resolve) => { + TopView.show( + { + resolve(v) + TopView.hide(TopViewKey) + }} + />, + TopViewKey + ) + }) + } +} diff --git a/src/renderer/src/pages/settings/ProviderSettings/ProviderSetting.tsx b/src/renderer/src/pages/settings/ProviderSettings/ProviderSetting.tsx index da28985c0c..214646f70d 100644 --- a/src/renderer/src/pages/settings/ProviderSettings/ProviderSetting.tsx +++ b/src/renderer/src/pages/settings/ProviderSettings/ProviderSetting.tsx @@ -1,7 +1,6 @@ import { CheckOutlined, CloseCircleFilled, LoadingOutlined } from '@ant-design/icons' import { isOpenAIProvider } from '@renderer/aiCore/clients/ApiClientFactory' import OpenAIAlert from '@renderer/components/Alert/OpenAIAlert' -import CodeEditor from '@renderer/components/CodeEditor' import { StreamlineGoodHealthAndWellBeing } from '@renderer/components/Icons/SVGIcon' import { HStack } from '@renderer/components/Layout' import { ApiKeyConnectivity, ApiKeyListPopup } from '@renderer/components/Popups/ApiKeyListPopup' @@ -19,7 +18,7 @@ import { lightbulbVariants } from '@renderer/utils/motionVariants' import { Button, Divider, Flex, Input, Space, Switch, Tooltip } from 'antd' import Link from 'antd/es/typography/Link' import { debounce, isEmpty } from 'lodash' -import { List, Settings2, SquareArrowOutUpRight } from 'lucide-react' +import { Settings2, SquareArrowOutUpRight } from 'lucide-react' import { motion } from 'motion/react' import { FC, useCallback, useDeferredValue, useEffect, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' @@ -33,6 +32,7 @@ import { SettingSubtitle, SettingTitle } from '..' +import CustomHeaderPopup from './CustomHeaderPopup' import DMXAPISettings from './DMXAPISettings' import GithubCopilotSettings from './GithubCopilotSettings' import GPUStackSettings from './GPUStackSettings' @@ -80,8 +80,6 @@ const ProviderSetting: FC = ({ providerId }) => { checking: false }) - const [headerText, setHeaderText] = useState(JSON.stringify(provider.extra_headers || {}, null, 2)) - // eslint-disable-next-line react-hooks/exhaustive-deps const debouncedUpdateApiKey = useCallback( debounce((value) => { @@ -311,16 +309,6 @@ const ProviderSetting: FC = ({ providerId }) => { setApiHost(provider.apiHost) }, [provider.apiHost, provider.id]) - const onUpdateHeaders = useCallback(() => { - try { - const headers = headerText.trim() ? JSON.parse(headerText) : {} - updateProvider({ ...provider, extra_headers: headers }) - window.message.success({ content: t('message.save.success.title') }) - } catch (error) { - window.message.error({ content: t('settings.provider.copilot.invalid_json') }) - } - }, [headerText, provider, updateProvider, t]) - return ( @@ -367,7 +355,7 @@ const ProviderSetting: FC = ({ providerId }) => { {t('settings.provider.api_key')} {provider.id !== 'copilot' && ( -