mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-04 11:49:02 +08:00
refactor(agent-settings): extract shared components and improve styling
- Move common components (AgentLabel, SettingsTitle, SettingsInline) to shared file - Update CSS to use @layer base for better organization - Fix agent type label translation key in AgentModal - Add agent type label utility function
This commit is contained in:
parent
bfe2e87f59
commit
ea62294bd8
@ -11,12 +11,14 @@
|
|||||||
@import '../fonts/ubuntu/ubuntu.css';
|
@import '../fonts/ubuntu/ubuntu.css';
|
||||||
@import '../fonts/country-flag-fonts/flag.css';
|
@import '../fonts/country-flag-fonts/flag.css';
|
||||||
|
|
||||||
*,
|
@layer base {
|
||||||
*::before,
|
*,
|
||||||
*::after {
|
*::before,
|
||||||
box-sizing: border-box;
|
*::after {
|
||||||
/* margin: 0; */
|
box-sizing: border-box;
|
||||||
font-weight: normal;
|
/* margin: 0; */
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*:focus {
|
*:focus {
|
||||||
|
|||||||
@ -317,7 +317,7 @@ export const AgentModal: React.FC<Props> = ({ agent, trigger, isOpen: _isOpen, o
|
|||||||
selectedKeys={[form.type]}
|
selectedKeys={[form.type]}
|
||||||
onChange={onAgentTypeChange}
|
onChange={onAgentTypeChange}
|
||||||
items={agentOptions}
|
items={agentOptions}
|
||||||
label={t('agent.add.type.label')}
|
label={t('agent.type.label')}
|
||||||
placeholder={t('agent.add.type.placeholder')}
|
placeholder={t('agent.add.type.placeholder')}
|
||||||
renderValue={renderOption}>
|
renderValue={renderOption}>
|
||||||
{(option) => (
|
{(option) => (
|
||||||
|
|||||||
@ -5,7 +5,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { loggerService } from '@logger'
|
import { loggerService } from '@logger'
|
||||||
import { BuiltinMCPServerName, BuiltinMCPServerNames, BuiltinOcrProviderId, ThinkingOption } from '@renderer/types'
|
import {
|
||||||
|
AgentType,
|
||||||
|
BuiltinMCPServerName,
|
||||||
|
BuiltinMCPServerNames,
|
||||||
|
BuiltinOcrProviderId,
|
||||||
|
ThinkingOption
|
||||||
|
} from '@renderer/types'
|
||||||
|
|
||||||
import i18n from './index'
|
import i18n from './index'
|
||||||
|
|
||||||
@ -339,3 +345,11 @@ export const getBuiltinOcrProviderLabel = (key: BuiltinOcrProviderId) => {
|
|||||||
else if (key == 'paddleocr') return 'PaddleOCR'
|
else if (key == 'paddleocr') return 'PaddleOCR'
|
||||||
else return getLabel(builtinOcrProviderKeyMap, key)
|
else return getLabel(builtinOcrProviderKeyMap, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const agentTypeKeyMap = {
|
||||||
|
'claude-code': 'Claude Code'
|
||||||
|
} as const satisfies Record<AgentType, string>
|
||||||
|
|
||||||
|
export const getAgentTypeLabel = (key: AgentType) => {
|
||||||
|
return getLabel(agentTypeKeyMap, key, t('agent.type.unknown'))
|
||||||
|
}
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
import { Avatar } from '@heroui/react'
|
import { HStack } from '@renderer/components/Layout'
|
||||||
import { Box, HStack } from '@renderer/components/Layout'
|
|
||||||
import { getAgentAvatar } from '@renderer/config/agent'
|
|
||||||
import { useUpdateAgent } from '@renderer/hooks/agents/useUpdateAgent'
|
import { useUpdateAgent } from '@renderer/hooks/agents/useUpdateAgent'
|
||||||
import { AgentEntity, UpdateAgentForm } from '@renderer/types'
|
import { AgentEntity, UpdateAgentForm } from '@renderer/types'
|
||||||
import { Input } from 'antd'
|
import { Input } from 'antd'
|
||||||
import { FC, useState } from 'react'
|
import { FC, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
|
import { SettingDivider } from '..'
|
||||||
|
import { AgentLabel, SettingsInline, SettingsTitle } from './shared'
|
||||||
|
|
||||||
interface AgentEssentialSettingsProps {
|
interface AgentEssentialSettingsProps {
|
||||||
agent: AgentEntity | undefined | null
|
agent: AgentEntity | undefined | null
|
||||||
update: ReturnType<typeof useUpdateAgent>
|
update: ReturnType<typeof useUpdateAgent>
|
||||||
@ -26,11 +27,13 @@ const AgentEssentialSettings: FC<AgentEssentialSettingsProps> = ({ agent, update
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-1 flex-col overflow-hidden">
|
<div className="flex flex-1 flex-col overflow-hidden">
|
||||||
<Box mb={8} style={{ fontWeight: 'bold' }}>
|
<SettingsInline>
|
||||||
{t('common.name')}
|
<SettingsTitle>{t('agent.type.label')}</SettingsTitle>
|
||||||
</Box>
|
<AgentLabel type={agent.type} />
|
||||||
|
</SettingsInline>
|
||||||
|
<SettingDivider />
|
||||||
|
<SettingsTitle>{t('common.name')}</SettingsTitle>
|
||||||
<HStack gap={8} alignItems="center">
|
<HStack gap={8} alignItems="center">
|
||||||
<Avatar src={getAgentAvatar(agent.type)} title={agent.type} className="h-5 w-5" />
|
|
||||||
<Input
|
<Input
|
||||||
placeholder={t('common.assistant') + t('common.name')}
|
placeholder={t('common.assistant') + t('common.name')}
|
||||||
value={name}
|
value={name}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import CodeEditor from '@renderer/components/CodeEditor'
|
import CodeEditor from '@renderer/components/CodeEditor'
|
||||||
import { Box, HSpaceBetweenStack, HStack } from '@renderer/components/Layout'
|
import { HSpaceBetweenStack } from '@renderer/components/Layout'
|
||||||
import { RichEditorRef } from '@renderer/components/RichEditor/types'
|
import { RichEditorRef } from '@renderer/components/RichEditor/types'
|
||||||
import { useUpdateAgent } from '@renderer/hooks/agents/useUpdateAgent'
|
import { useUpdateAgent } from '@renderer/hooks/agents/useUpdateAgent'
|
||||||
import { usePromptProcessor } from '@renderer/hooks/usePromptProcessor'
|
import { usePromptProcessor } from '@renderer/hooks/usePromptProcessor'
|
||||||
@ -12,6 +12,8 @@ import { useTranslation } from 'react-i18next'
|
|||||||
import ReactMarkdown from 'react-markdown'
|
import ReactMarkdown from 'react-markdown'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
|
import { SettingsTitle } from './shared'
|
||||||
|
|
||||||
interface AgentPromptSettingsProps {
|
interface AgentPromptSettingsProps {
|
||||||
agent: AgentEntity | undefined | null
|
agent: AgentEntity | undefined | null
|
||||||
update: ReturnType<typeof useUpdateAgent>
|
update: ReturnType<typeof useUpdateAgent>
|
||||||
@ -50,12 +52,12 @@ const AgentPromptSettings: FC<AgentPromptSettingsProps> = ({ agent, update }) =>
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<HStack mb={8} alignItems="center" gap={4}>
|
<SettingsTitle>
|
||||||
<Box style={{ fontWeight: 'bold' }}>{t('common.prompt')}</Box>
|
{t('common.prompt')}
|
||||||
<Popover title={t('agents.add.prompt.variables.tip.title')} content={promptVarsContent}>
|
<Popover title={t('agents.add.prompt.variables.tip.title')} content={promptVarsContent}>
|
||||||
<HelpCircle size={14} color="var(--color-text-2)" />
|
<HelpCircle size={14} color="var(--color-text-2)" />
|
||||||
</Popover>
|
</Popover>
|
||||||
</HStack>
|
</SettingsTitle>
|
||||||
<TextAreaContainer>
|
<TextAreaContainer>
|
||||||
<RichEditorContainer>
|
<RichEditorContainer>
|
||||||
{showPreview ? (
|
{showPreview ? (
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
import { Avatar } from '@heroui/react'
|
|
||||||
import { HStack } from '@renderer/components/Layout'
|
import { HStack } from '@renderer/components/Layout'
|
||||||
import { TopView } from '@renderer/components/TopView'
|
import { TopView } from '@renderer/components/TopView'
|
||||||
import { getAgentAvatar } from '@renderer/config/agent'
|
|
||||||
import { useAgent } from '@renderer/hooks/agents/useAgent'
|
import { useAgent } from '@renderer/hooks/agents/useAgent'
|
||||||
import { useUpdateAgent } from '@renderer/hooks/agents/useUpdateAgent'
|
import { useUpdateAgent } from '@renderer/hooks/agents/useUpdateAgent'
|
||||||
import { Menu, Modal } from 'antd'
|
import { Menu, Modal } from 'antd'
|
||||||
@ -11,6 +9,7 @@ import styled from 'styled-components'
|
|||||||
|
|
||||||
import AgentEssentialSettings from './AgentEssentialSettings'
|
import AgentEssentialSettings from './AgentEssentialSettings'
|
||||||
import AgentPromptSettings from './AgentPromptSettings'
|
import AgentPromptSettings from './AgentPromptSettings'
|
||||||
|
import { AgentLabel } from './shared'
|
||||||
|
|
||||||
interface AgentSettingPopupShowParams {
|
interface AgentSettingPopupShowParams {
|
||||||
agentId: string
|
agentId: string
|
||||||
@ -65,10 +64,12 @@ const AgentSettingPopupContainer: React.FC<AgentSettingPopupParams> = ({ tab, ag
|
|||||||
maskClosable={false}
|
maskClosable={false}
|
||||||
footer={null}
|
footer={null}
|
||||||
title={
|
title={
|
||||||
<div className="flex items-center">
|
<AgentLabel
|
||||||
<Avatar size="sm" className="mr-2 h-5 w-5" src={agent ? getAgentAvatar(agent.type) : undefined} />
|
type={agent?.type ?? 'claude-code'}
|
||||||
<span className="font-extrabold text-xl">{agent?.name ?? ''}</span>
|
name={agent?.name}
|
||||||
</div>
|
classNames={{ name: 'text-lg font-extrabold' }}
|
||||||
|
avatarProps={{ size: 'sm' }}
|
||||||
|
/>
|
||||||
}
|
}
|
||||||
transitionName="animation-move-down"
|
transitionName="animation-move-down"
|
||||||
styles={{
|
styles={{
|
||||||
|
|||||||
33
src/renderer/src/pages/settings/AgentSettings/shared.tsx
Normal file
33
src/renderer/src/pages/settings/AgentSettings/shared.tsx
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import { Avatar, AvatarProps, cn } from '@heroui/react'
|
||||||
|
import { getAgentAvatar } from '@renderer/config/agent'
|
||||||
|
import { getAgentTypeLabel } from '@renderer/i18n/label'
|
||||||
|
import { AgentType } from '@renderer/types'
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
export const SettingsTitle: React.FC<React.PropsWithChildren> = ({ children }) => {
|
||||||
|
return <div className="mb-1 flex items-center gap-2 font-bold">{children}</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SettingsInline: React.FC<React.PropsWithChildren> = ({ children }) => {
|
||||||
|
return <div className="flex items-center justify-between gap-2">{children}</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AgentLabelProps = {
|
||||||
|
type: AgentType
|
||||||
|
name?: string
|
||||||
|
classNames?: {
|
||||||
|
container?: string
|
||||||
|
avatar?: string
|
||||||
|
name?: string
|
||||||
|
}
|
||||||
|
avatarProps?: AvatarProps
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AgentLabel: React.FC<AgentLabelProps> = ({ type, name, classNames, avatarProps }) => {
|
||||||
|
return (
|
||||||
|
<div className={cn('flex items-center gap-2', classNames?.container)}>
|
||||||
|
<Avatar src={getAgentAvatar(type)} title={type} {...avatarProps} className={cn('h-5 w-5', classNames?.avatar)} />
|
||||||
|
<span className={classNames?.name}>{name ?? getAgentTypeLabel(type)}</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user