mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-03 02:59:07 +08:00
refactor(AssistantPresetsPage): added assistants subscribe settings to AssistantPresetsPage (#11184)
refactor(DataSettings, MCPSettings, AssistantPresetsPage): clean up imports and enhance UI components - Removed unused imports and components from DataSettings for better clarity. - Updated MCPSettings layout by introducing a new Container styled with Scrollbar for improved scrolling. - Added AssistantsSubscribeUrlSettings component to manage subscription URLs in AssistantPresetsPage, enhancing user interaction. - Adjusted button styles and layout in AssistantPresetsPage for a more cohesive design.
This commit is contained in:
parent
2d8555c326
commit
2f66f5b511
@ -23,7 +23,7 @@ import type { AppInfo } from '@renderer/types'
|
|||||||
import { formatFileSize } from '@renderer/utils'
|
import { formatFileSize } from '@renderer/utils'
|
||||||
import { occupiedDirs } from '@shared/config/constant'
|
import { occupiedDirs } from '@shared/config/constant'
|
||||||
import { Button, Progress, Switch, Typography } from 'antd'
|
import { Button, Progress, Switch, Typography } from 'antd'
|
||||||
import { FileText, FolderCog, FolderInput, FolderOpen, SaveIcon, Sparkle } from 'lucide-react'
|
import { FileText, FolderCog, FolderInput, FolderOpen, SaveIcon } from 'lucide-react'
|
||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
@ -38,7 +38,6 @@ import {
|
|||||||
SettingRowTitle,
|
SettingRowTitle,
|
||||||
SettingTitle
|
SettingTitle
|
||||||
} from '..'
|
} from '..'
|
||||||
import AgentsSubscribeUrlSettings from './AgentsSubscribeUrlSettings'
|
|
||||||
import ExportMenuOptions from './ExportMenuSettings'
|
import ExportMenuOptions from './ExportMenuSettings'
|
||||||
import JoplinSettings from './JoplinSettings'
|
import JoplinSettings from './JoplinSettings'
|
||||||
import LocalBackupSettings from './LocalBackupSettings'
|
import LocalBackupSettings from './LocalBackupSettings'
|
||||||
@ -129,11 +128,6 @@ const DataSettings: FC = () => {
|
|||||||
key: 'siyuan',
|
key: 'siyuan',
|
||||||
title: t('settings.data.siyuan.title'),
|
title: t('settings.data.siyuan.title'),
|
||||||
icon: <SiyuanIcon />
|
icon: <SiyuanIcon />
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'agentssubscribe_url',
|
|
||||||
title: t('assistants.presets.settings.title'),
|
|
||||||
icon: <Sparkle size={16} className="icon" />
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -704,7 +698,6 @@ const DataSettings: FC = () => {
|
|||||||
{menu === 'joplin' && <JoplinSettings />}
|
{menu === 'joplin' && <JoplinSettings />}
|
||||||
{menu === 'obsidian' && <ObsidianSettings />}
|
{menu === 'obsidian' && <ObsidianSettings />}
|
||||||
{menu === 'siyuan' && <SiyuanSettings />}
|
{menu === 'siyuan' && <SiyuanSettings />}
|
||||||
{menu === 'agentssubscribe_url' && <AgentsSubscribeUrlSettings />}
|
|
||||||
{menu === 'local_backup' && <LocalBackupSettings />}
|
{menu === 'local_backup' && <LocalBackupSettings />}
|
||||||
</SettingContainer>
|
</SettingContainer>
|
||||||
</Container>
|
</Container>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { loggerService } from '@logger'
|
import { loggerService } from '@logger'
|
||||||
import type { McpError } from '@modelcontextprotocol/sdk/types.js'
|
import type { McpError } from '@modelcontextprotocol/sdk/types.js'
|
||||||
import { DeleteIcon } from '@renderer/components/Icons'
|
import { DeleteIcon } from '@renderer/components/Icons'
|
||||||
|
import Scrollbar from '@renderer/components/Scrollbar'
|
||||||
import { useTheme } from '@renderer/context/ThemeProvider'
|
import { useTheme } from '@renderer/context/ThemeProvider'
|
||||||
import { useMCPServer, useMCPServers } from '@renderer/hooks/useMCPServers'
|
import { useMCPServer, useMCPServers } from '@renderer/hooks/useMCPServers'
|
||||||
import { useMCPServerTrust } from '@renderer/hooks/useMCPServerTrust'
|
import { useMCPServerTrust } from '@renderer/hooks/useMCPServerTrust'
|
||||||
@ -740,51 +741,57 @@ const McpSettings: React.FC = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SettingContainer theme={theme} style={{ width: '100%', paddingTop: 55, backgroundColor: 'transparent' }}>
|
<Container>
|
||||||
<SettingGroup style={{ marginBottom: 0, borderRadius: 'var(--list-item-border-radius)' }}>
|
<SettingContainer theme={theme} style={{ width: '100%', paddingTop: 55, backgroundColor: 'transparent' }}>
|
||||||
<SettingTitle>
|
<SettingGroup style={{ marginBottom: 0, borderRadius: 'var(--list-item-border-radius)' }}>
|
||||||
<Flex justify="space-between" align="center" gap={5} style={{ marginRight: 10 }}>
|
<SettingTitle>
|
||||||
<Flex align="center" gap={8}>
|
<Flex justify="space-between" align="center" gap={5} style={{ marginRight: 10 }}>
|
||||||
<ServerName className="text-nowrap">{server?.name}</ServerName>
|
<Flex align="center" gap={8}>
|
||||||
{serverVersion && <VersionBadge count={serverVersion} color="blue" />}
|
<ServerName className="text-nowrap">{server?.name}</ServerName>
|
||||||
|
{serverVersion && <VersionBadge count={serverVersion} color="blue" />}
|
||||||
|
</Flex>
|
||||||
|
<Button
|
||||||
|
danger
|
||||||
|
icon={<DeleteIcon size={14} className="lucide-custom" />}
|
||||||
|
type="text"
|
||||||
|
onClick={() => onDeleteMcpServer(server)}
|
||||||
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Button
|
<Flex align="center" gap={16}>
|
||||||
danger
|
<Switch
|
||||||
icon={<DeleteIcon size={14} className="lucide-custom" />}
|
value={server.isActive}
|
||||||
type="text"
|
key={server.id}
|
||||||
onClick={() => onDeleteMcpServer(server)}
|
loading={loadingServer === server.id}
|
||||||
/>
|
onChange={onToggleActive}
|
||||||
</Flex>
|
/>
|
||||||
<Flex align="center" gap={16}>
|
<Button
|
||||||
<Switch
|
type="primary"
|
||||||
value={server.isActive}
|
icon={<SaveIcon size={14} />}
|
||||||
key={server.id}
|
onClick={onSave}
|
||||||
loading={loadingServer === server.id}
|
loading={loading}
|
||||||
onChange={onToggleActive}
|
shape="round"
|
||||||
/>
|
disabled={!isFormChanged || activeTab !== 'settings'}>
|
||||||
<Button
|
{t('common.save')}
|
||||||
type="primary"
|
</Button>
|
||||||
icon={<SaveIcon size={14} />}
|
</Flex>
|
||||||
onClick={onSave}
|
</SettingTitle>
|
||||||
loading={loading}
|
<SettingDivider />
|
||||||
shape="round"
|
<Tabs
|
||||||
disabled={!isFormChanged || activeTab !== 'settings'}>
|
defaultActiveKey="settings"
|
||||||
{t('common.save')}
|
items={tabs}
|
||||||
</Button>
|
onChange={(key) => setActiveTab(key as TabKey)}
|
||||||
</Flex>
|
style={{ marginTop: 8, backgroundColor: 'transparent' }}
|
||||||
</SettingTitle>
|
/>
|
||||||
<SettingDivider />
|
</SettingGroup>
|
||||||
<Tabs
|
</SettingContainer>
|
||||||
defaultActiveKey="settings"
|
</Container>
|
||||||
items={tabs}
|
|
||||||
onChange={(key) => setActiveTab(key as TabKey)}
|
|
||||||
style={{ marginTop: 8, backgroundColor: 'transparent' }}
|
|
||||||
/>
|
|
||||||
</SettingGroup>
|
|
||||||
</SettingContainer>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Container = styled(Scrollbar)`
|
||||||
|
height: calc(100vh - var(--navbar-height));
|
||||||
|
`
|
||||||
|
|
||||||
const ServerName = styled.span`
|
const ServerName = styled.span`
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { ImportOutlined, PlusOutlined } from '@ant-design/icons'
|
|
||||||
import { Navbar, NavbarCenter } from '@renderer/components/app/Navbar'
|
import { Navbar, NavbarCenter } from '@renderer/components/app/Navbar'
|
||||||
import { HStack } from '@renderer/components/Layout'
|
import { HStack } from '@renderer/components/Layout'
|
||||||
import ListItem from '@renderer/components/ListItem'
|
import ListItem from '@renderer/components/ListItem'
|
||||||
|
import GeneralPopup from '@renderer/components/Popups/GeneralPopup'
|
||||||
import Scrollbar from '@renderer/components/Scrollbar'
|
import Scrollbar from '@renderer/components/Scrollbar'
|
||||||
import CustomTag from '@renderer/components/Tags/CustomTag'
|
import CustomTag from '@renderer/components/Tags/CustomTag'
|
||||||
import { useAssistantPresets } from '@renderer/hooks/useAssistantPresets'
|
import { useAssistantPresets } from '@renderer/hooks/useAssistantPresets'
|
||||||
@ -11,7 +11,7 @@ import type { AssistantPreset } from '@renderer/types'
|
|||||||
import { uuid } from '@renderer/utils'
|
import { uuid } from '@renderer/utils'
|
||||||
import { Button, Empty, Flex, Input } from 'antd'
|
import { Button, Empty, Flex, Input } from 'antd'
|
||||||
import { omit } from 'lodash'
|
import { omit } from 'lodash'
|
||||||
import { Search } from 'lucide-react'
|
import { Import, Plus, Rss, Search } from 'lucide-react'
|
||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
import { useCallback, useEffect, useMemo, useState } from 'react'
|
import { useCallback, useEffect, useMemo, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
@ -23,6 +23,7 @@ import { groupTranslations } from './assistantPresetGroupTranslations'
|
|||||||
import AddAssistantPresetPopup from './components/AddAssistantPresetPopup'
|
import AddAssistantPresetPopup from './components/AddAssistantPresetPopup'
|
||||||
import AssistantPresetCard from './components/AssistantPresetCard'
|
import AssistantPresetCard from './components/AssistantPresetCard'
|
||||||
import { AssistantPresetGroupIcon } from './components/AssistantPresetGroupIcon'
|
import { AssistantPresetGroupIcon } from './components/AssistantPresetGroupIcon'
|
||||||
|
import AssistantsSubscribeUrlSettings from './components/AssistantsSubscribeUrlSettings'
|
||||||
import ImportAssistantPresetPopup from './components/ImportAssistantPresetPopup'
|
import ImportAssistantPresetPopup from './components/ImportAssistantPresetPopup'
|
||||||
|
|
||||||
const AssistantPresetsPage: FC = () => {
|
const AssistantPresetsPage: FC = () => {
|
||||||
@ -175,6 +176,15 @@ const AssistantPresetsPage: FC = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleSubscribeSettings = () => {
|
||||||
|
GeneralPopup.show({
|
||||||
|
title: t('assistants.presets.settings.title'),
|
||||||
|
content: <AssistantsSubscribeUrlSettings />,
|
||||||
|
footer: null,
|
||||||
|
width: 600
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<Navbar>
|
<Navbar>
|
||||||
@ -246,12 +256,12 @@ const AssistantPresetsPage: FC = () => {
|
|||||||
</CustomTag>
|
</CustomTag>
|
||||||
}
|
}
|
||||||
</AgentsListTitle>
|
</AgentsListTitle>
|
||||||
<Flex gap={8}>
|
<Flex gap={2}>
|
||||||
{isSearchExpanded ? (
|
{isSearchExpanded ? (
|
||||||
<Input
|
<Input
|
||||||
placeholder={t('common.search')}
|
placeholder={t('common.search')}
|
||||||
className="nodrag"
|
className="nodrag"
|
||||||
style={{ width: 300, height: 28, borderRadius: 15, paddingLeft: 12 }}
|
style={{ width: 200, height: 28, borderRadius: 15, paddingLeft: 12 }}
|
||||||
size="small"
|
size="small"
|
||||||
variant="filled"
|
variant="filled"
|
||||||
allowClear
|
allowClear
|
||||||
@ -274,10 +284,13 @@ const AssistantPresetsPage: FC = () => {
|
|||||||
</Button>
|
</Button>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
<Button type="text" onClick={handleImportAgent} icon={<ImportOutlined />}>
|
<Button type="text" onClick={handleImportAgent} icon={<Import size={18} color="var(--color-icon)" />}>
|
||||||
{t('assistants.presets.import.title')}
|
{t('assistants.presets.import.title')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button type="text" onClick={handleAddAgent} icon={<PlusOutlined />}>
|
<Button type="text" onClick={handleSubscribeSettings} icon={<Rss size={18} color="var(--color-icon)" />}>
|
||||||
|
{t('assistants.presets.settings.title')}
|
||||||
|
</Button>
|
||||||
|
<Button type="text" onClick={handleAddAgent} icon={<Plus size={18} color="var(--color-icon)" />}>
|
||||||
{t('assistants.presets.add.title')}
|
{t('assistants.presets.add.title')}
|
||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
import { HStack } from '@renderer/components/Layout'
|
import { HStack } from '@renderer/components/Layout'
|
||||||
import { useTheme } from '@renderer/context/ThemeProvider'
|
import { useTheme } from '@renderer/context/ThemeProvider'
|
||||||
import { useSettings } from '@renderer/hooks/useSettings'
|
import { useSettings } from '@renderer/hooks/useSettings'
|
||||||
|
import { SettingDivider, SettingGroup, SettingRow, SettingRowTitle, SettingTitle } from '@renderer/pages/settings'
|
||||||
import { useAppDispatch } from '@renderer/store'
|
import { useAppDispatch } from '@renderer/store'
|
||||||
import { setAgentssubscribeUrl } from '@renderer/store/settings'
|
import { setAgentssubscribeUrl } from '@renderer/store/settings'
|
||||||
import Input from 'antd/es/input/Input'
|
import Input from 'antd/es/input/Input'
|
||||||
|
import { HelpCircle } from 'lucide-react'
|
||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
import { SettingDivider, SettingGroup, SettingRow, SettingRowTitle, SettingTitle } from '..'
|
const AssistantsSubscribeUrlSettings: FC = () => {
|
||||||
|
|
||||||
const AgentsSubscribeUrlSettings: FC = () => {
|
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { theme } = useTheme()
|
const { theme } = useTheme()
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
@ -20,12 +20,24 @@ const AgentsSubscribeUrlSettings: FC = () => {
|
|||||||
dispatch(setAgentssubscribeUrl(e.target.value))
|
dispatch(setAgentssubscribeUrl(e.target.value))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleHelpClick = () => {
|
||||||
|
window.open('https://docs.cherry-ai.com/data-settings/assistants-subscribe', '_blank')
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SettingGroup theme={theme}>
|
<SettingGroup theme={theme}>
|
||||||
<SettingTitle>
|
<HStack alignItems="center" gap="8px">
|
||||||
{t('assistants.presets.tag.agent')}
|
<SettingTitle>
|
||||||
{t('settings.tool.websearch.subscribe_add')}
|
{t('assistants.presets.tag.agent')}
|
||||||
</SettingTitle>
|
{t('settings.tool.websearch.subscribe_add')}
|
||||||
|
</SettingTitle>
|
||||||
|
<HelpCircle
|
||||||
|
size={16}
|
||||||
|
color="var(--color-icon)"
|
||||||
|
onClick={handleHelpClick}
|
||||||
|
className="hover:!text-[var(--color-primary)] cursor-pointer transition-colors"
|
||||||
|
/>
|
||||||
|
</HStack>
|
||||||
<SettingDivider />
|
<SettingDivider />
|
||||||
<SettingRow>
|
<SettingRow>
|
||||||
<SettingRowTitle>{t('settings.tool.websearch.subscribe_url')}</SettingRowTitle>
|
<SettingRowTitle>{t('settings.tool.websearch.subscribe_url')}</SettingRowTitle>
|
||||||
@ -35,7 +47,7 @@ const AgentsSubscribeUrlSettings: FC = () => {
|
|||||||
value={agentssubscribeUrl || ''}
|
value={agentssubscribeUrl || ''}
|
||||||
onChange={handleAgentChange}
|
onChange={handleAgentChange}
|
||||||
style={{ width: 315 }}
|
style={{ width: 315 }}
|
||||||
placeholder={t('settings.tool.websearch.subscribe_name.placeholder')}
|
placeholder={t('settings.tool.websearch.subscribe_url')}
|
||||||
/>
|
/>
|
||||||
</HStack>
|
</HStack>
|
||||||
</SettingRow>
|
</SettingRow>
|
||||||
@ -43,4 +55,4 @@ const AgentsSubscribeUrlSettings: FC = () => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default AgentsSubscribeUrlSettings
|
export default AssistantsSubscribeUrlSettings
|
||||||
Loading…
Reference in New Issue
Block a user