Skip to content

Commit d671990

Browse files
committed
refactor: restructure AgentSettingsPopup and SessionSettingsPopup for improved modularity
- Refactored AgentSettingsPopup and SessionSettingsPopup to utilize a new BaseSettingsPopup component, enhancing code reusability and maintainability. - Removed the AvatarSetting component as it was deemed unnecessary. - Introduced several new components (e.g., AdvancedSettings, EssentialSettings, PermissionModeSettings) to better organize settings management. - Updated the handling of menu items and tab content rendering to streamline the user interface and improve user experience. - Enhanced type definitions for better clarity and consistency across settings components.
1 parent 9da6ad2 commit d671990

21 files changed

+282
-413
lines changed

src/renderer/src/pages/settings/AgentSettings/AgentSettingsPopup.tsx

Lines changed: 51 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -1,170 +1,78 @@
1-
import { Center } from '@renderer/components/Layout'
21
import { TopView } from '@renderer/components/TopView'
32
import { useAgent } from '@renderer/hooks/agents/useAgent'
43
import { useUpdateAgent } from '@renderer/hooks/agents/useUpdateAgent'
5-
import { Alert, Spin } from 'antd'
6-
import { useState } from 'react'
4+
import { useMemo } from 'react'
75
import { useTranslation } from 'react-i18next'
86

9-
import AdvancedSettings from './AdvancedSettings'
10-
import EssentialSettings from './EssentialSettings'
11-
import PermissionModeSettings from './PermissionModeSettings'
12-
import { InstalledPluginsSettings, PluginBrowserSettings } from './PluginsSettings/PluginsSettings'
13-
import PromptSettings from './PromptSettings'
14-
import { AgentLabel, LeftMenu, Settings, StyledMenu, StyledModal } from './shared'
15-
import ToolsSettings from './ToolsSettings'
7+
import { BaseSettingsPopup, type SettingsMenuItem, type SettingsPopupTab } from './BaseSettingsPopup'
8+
import AdvancedSettings from './components/AdvancedSettings'
9+
import EssentialSettings from './components/EssentialSettings'
10+
import PermissionModeSettings from './components/PermissionModeSettings'
11+
import { InstalledPluginsSettings, PluginBrowserSettings } from './components/PluginsSettings/PluginsSettings'
12+
import PromptSettings from './components/PromptSettings'
13+
import ToolsSettings from './components/ToolsSettings'
14+
import { AgentLabel } from './shared'
1615

1716
interface AgentSettingPopupShowParams {
1817
agentId: string
19-
tab?: AgentSettingPopupTab
18+
tab?: SettingsPopupTab
2019
}
2120

2221
interface AgentSettingPopupParams extends AgentSettingPopupShowParams {
2322
resolve: () => void
2423
}
2524

26-
type AgentSettingPopupTab =
27-
| 'essential'
28-
| 'prompt'
29-
| 'permission-mode'
30-
| 'tools-mcp'
31-
| 'advanced'
32-
| 'plugins'
33-
| 'installed'
34-
| 'session-mcps'
35-
3625
const AgentSettingPopupContainer: React.FC<AgentSettingPopupParams> = ({ tab, agentId, resolve }) => {
37-
const [open, setOpen] = useState(true)
3826
const { t } = useTranslation()
39-
const [menu, setMenu] = useState<AgentSettingPopupTab>(tab || 'essential')
40-
4127
const { agent, isLoading, error } = useAgent(agentId)
4228
const { updateAgent } = useUpdateAgent()
4329

44-
const onOk = () => {
45-
setOpen(false)
46-
}
47-
48-
const onCancel = () => {
49-
setOpen(false)
50-
}
51-
52-
const afterClose = () => {
53-
resolve()
54-
}
55-
56-
const items = [
57-
{
58-
key: 'essential',
59-
label: t('agent.settings.essential')
60-
},
61-
{
62-
key: 'prompt',
63-
label: t('agent.settings.prompt')
64-
},
65-
{
66-
key: 'permission-mode',
67-
label: t('agent.settings.permissionMode.tab', 'Permission Mode')
68-
},
69-
{
70-
key: 'tools-mcp',
71-
label: t('agent.settings.toolsMcp.tab', 'Tools & MCP')
72-
},
73-
{
74-
key: 'plugins',
75-
label: t('agent.settings.plugins.available.title', 'Available Plugins')
76-
},
77-
{
78-
key: 'installed',
79-
label: t('agent.settings.plugins.installed.title', 'Installed Plugins')
80-
},
81-
{
82-
key: 'advanced',
83-
label: t('agent.settings.advance.title', 'Advanced Settings')
84-
}
85-
] as const satisfies { key: AgentSettingPopupTab; label: string }[]
86-
87-
const renderModalContent = () => {
88-
if (isLoading) {
89-
// TODO: use skeleton for better ux
90-
return (
91-
<Center flex={1}>
92-
<Spin />
93-
</Center>
94-
)
95-
}
96-
97-
if (error) {
98-
return (
99-
<Center flex={1}>
100-
<Alert type="error" message={t('agent.get.error.failed')} />
101-
</Center>
102-
)
103-
}
30+
const menuItems: SettingsMenuItem[] = useMemo(
31+
() => [
32+
{ key: 'essential', label: t('agent.settings.essential') },
33+
{ key: 'prompt', label: t('agent.settings.prompt') },
34+
{ key: 'permission-mode', label: t('agent.settings.permissionMode.tab', 'Permission Mode') },
35+
{ key: 'tools-mcp', label: t('agent.settings.toolsMcp.tab', 'Tools & MCP') },
36+
{ key: 'plugins', label: t('agent.settings.plugins.available.title', 'Available Plugins') },
37+
{ key: 'installed', label: t('agent.settings.plugins.installed.title', 'Installed Plugins') },
38+
{ key: 'advanced', label: t('agent.settings.advance.title', 'Advanced Settings') }
39+
],
40+
[t]
41+
)
10442

105-
if (!agent) {
106-
return null
43+
const renderTabContent = (currentTab: SettingsPopupTab) => {
44+
if (!agent) return null
45+
46+
switch (currentTab) {
47+
case 'essential':
48+
return <EssentialSettings agentBase={agent} update={updateAgent} />
49+
case 'prompt':
50+
return <PromptSettings agentBase={agent} update={updateAgent} />
51+
case 'permission-mode':
52+
return <PermissionModeSettings agentBase={agent} update={updateAgent} />
53+
case 'tools-mcp':
54+
return <ToolsSettings agentBase={agent} update={updateAgent} />
55+
case 'plugins':
56+
return <PluginBrowserSettings agentBase={agent} update={updateAgent} />
57+
case 'installed':
58+
return <InstalledPluginsSettings agentBase={agent} update={updateAgent} />
59+
case 'advanced':
60+
return <AdvancedSettings agentBase={agent} update={updateAgent} />
61+
default:
62+
return null
10763
}
108-
109-
return (
110-
<div className="flex w-full flex-1">
111-
<LeftMenu>
112-
<StyledMenu
113-
defaultSelectedKeys={[tab || 'essential'] satisfies AgentSettingPopupTab[]}
114-
mode="vertical"
115-
selectedKeys={[menu]}
116-
items={items}
117-
onSelect={({ key }) => setMenu(key as AgentSettingPopupTab)}
118-
/>
119-
</LeftMenu>
120-
<Settings>
121-
{menu === 'essential' && <EssentialSettings agentBase={agent} update={updateAgent} />}
122-
{menu === 'prompt' && <PromptSettings agentBase={agent} update={updateAgent} />}
123-
{menu === 'permission-mode' && <PermissionModeSettings agentBase={agent} update={updateAgent} />}
124-
{menu === 'tools-mcp' && <ToolsSettings agentBase={agent} update={updateAgent} />}
125-
{menu === 'plugins' && <PluginBrowserSettings agentBase={agent} update={updateAgent} />}
126-
{menu === 'installed' && <InstalledPluginsSettings agentBase={agent} update={updateAgent} />}
127-
{menu === 'advanced' && <AdvancedSettings agentBase={agent} update={updateAgent} />}
128-
</Settings>
129-
</div>
130-
)
13164
}
13265

13366
return (
134-
<StyledModal
135-
open={open}
136-
onOk={onOk}
137-
onCancel={onCancel}
138-
afterClose={afterClose}
139-
maskClosable={menu !== 'prompt'}
140-
footer={null}
141-
title={<AgentLabel agent={agent} />}
142-
transitionName="animation-move-down"
143-
styles={{
144-
content: {
145-
padding: 0,
146-
overflow: 'hidden',
147-
height: '80vh',
148-
display: 'flex',
149-
flexDirection: 'column'
150-
},
151-
header: {
152-
padding: '10px 15px',
153-
paddingRight: '32px',
154-
borderBottom: '0.5px solid var(--color-border)',
155-
margin: 0,
156-
borderRadius: 0
157-
},
158-
body: {
159-
padding: 0,
160-
display: 'flex',
161-
flex: 1
162-
}
163-
}}
164-
width="min(900px, 70vw)"
165-
centered>
166-
{renderModalContent()}
167-
</StyledModal>
67+
<BaseSettingsPopup
68+
isLoading={isLoading}
69+
error={error}
70+
initialTab={tab}
71+
onClose={resolve}
72+
titleContent={<AgentLabel agent={agent} />}
73+
menuItems={menuItems}
74+
renderTabContent={renderTabContent}
75+
/>
16876
)
16977
}
17078

src/renderer/src/pages/settings/AgentSettings/AvatarSetting.tsx

Lines changed: 0 additions & 49 deletions
This file was deleted.
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import { Center } from '@renderer/components/Layout'
2+
import type { MenuProps } from 'antd'
3+
import { Alert, Spin } from 'antd'
4+
import type { ReactNode } from 'react'
5+
import { useState } from 'react'
6+
import { useTranslation } from 'react-i18next'
7+
8+
import { LeftMenu, Settings, settingsModalStyles, StyledMenu, StyledModal } from './shared'
9+
10+
export type SettingsPopupTab =
11+
| 'essential'
12+
| 'prompt'
13+
| 'permission-mode'
14+
| 'tools-mcp'
15+
| 'advanced'
16+
| 'plugins'
17+
| 'installed'
18+
19+
export type SettingsMenuItem = NonNullable<MenuProps['items']>[number] & {
20+
key: SettingsPopupTab
21+
}
22+
23+
interface BaseSettingsPopupProps {
24+
isLoading: boolean
25+
error: Error | null
26+
initialTab?: SettingsPopupTab
27+
onClose: () => void
28+
titleContent: ReactNode
29+
menuItems: SettingsMenuItem[]
30+
renderTabContent: (tab: SettingsPopupTab) => ReactNode
31+
}
32+
33+
export const BaseSettingsPopup: React.FC<BaseSettingsPopupProps> = ({
34+
isLoading,
35+
error,
36+
initialTab = 'essential',
37+
onClose,
38+
titleContent,
39+
menuItems,
40+
renderTabContent
41+
}) => {
42+
const [open, setOpen] = useState(true)
43+
const { t } = useTranslation()
44+
const [menu, setMenu] = useState<SettingsPopupTab>(initialTab)
45+
46+
const handleClose = () => {
47+
setOpen(false)
48+
}
49+
50+
const afterClose = () => {
51+
onClose()
52+
}
53+
54+
const renderContent = () => {
55+
if (isLoading) {
56+
return (
57+
<Center flex={1}>
58+
<Spin />
59+
</Center>
60+
)
61+
}
62+
63+
if (error) {
64+
return (
65+
<Center flex={1}>
66+
<Alert type="error" message={t('agent.get.error.failed')} />
67+
</Center>
68+
)
69+
}
70+
71+
return (
72+
<div className="flex w-full flex-1">
73+
<LeftMenu>
74+
<StyledMenu
75+
defaultSelectedKeys={[initialTab]}
76+
mode="vertical"
77+
selectedKeys={[menu]}
78+
items={menuItems}
79+
onSelect={({ key }) => setMenu(key as SettingsPopupTab)}
80+
/>
81+
</LeftMenu>
82+
<Settings>{renderTabContent(menu)}</Settings>
83+
</div>
84+
)
85+
}
86+
87+
return (
88+
<StyledModal
89+
open={open}
90+
onOk={handleClose}
91+
onCancel={handleClose}
92+
afterClose={afterClose}
93+
maskClosable={menu !== 'prompt'}
94+
footer={null}
95+
title={titleContent}
96+
transitionName="animation-move-down"
97+
styles={settingsModalStyles}
98+
width="min(900px, 70vw)"
99+
centered>
100+
{renderContent()}
101+
</StyledModal>
102+
)
103+
}

0 commit comments

Comments
 (0)