Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion wework/src/components/layout/DesktopSettingsMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import type { User as UserProfile } from '@/types/api'

interface DesktopSettingsMenuProps {
user: UserProfile | null
onOpenSettings: () => void
onLogout: () => void
}

export function DesktopSettingsMenu({ user, onLogout }: DesktopSettingsMenuProps) {
export function DesktopSettingsMenu({ user, onOpenSettings, onLogout }: DesktopSettingsMenuProps) {
const { t } = useTranslation('common')
const accountLabel =
user?.email || user?.user_name || t('workbench.account_fallback', '当前账号')
Expand All @@ -33,6 +34,7 @@ export function DesktopSettingsMenu({ user, onLogout }: DesktopSettingsMenuProps
<button
type="button"
data-testid="settings-menu-button"
onClick={onOpenSettings}
className="flex h-11 w-full items-center gap-3 px-4 text-left text-sm font-medium text-[#333] hover:bg-muted"
>
<Settings className="h-5 w-5 shrink-0 text-[#555]" />
Expand Down
13 changes: 12 additions & 1 deletion wework/src/components/layout/DesktopSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ interface DesktopSidebarProps {
onCollapse: () => void
onSelectProject: (projectId: number) => void
onOpenTask: (taskId: number) => void
onOpenSettings: () => void
onLogout: () => void
}

Expand Down Expand Up @@ -93,6 +94,7 @@ export function DesktopSidebar({
onCollapse,
onSelectProject,
onOpenTask,
onOpenSettings,
onLogout,
}: DesktopSidebarProps) {
const { t } = useTranslation('common')
Expand Down Expand Up @@ -176,7 +178,16 @@ export function DesktopSidebar({
<Settings className="h-4 w-4" />
{t('workbench.settings', '设置')}
</button>
{settingsMenuOpen && <DesktopSettingsMenu user={user} onLogout={onLogout} />}
{settingsMenuOpen && (
<DesktopSettingsMenu
user={user}
onOpenSettings={() => {
setSettingsMenuOpen(false)
onOpenSettings()
}}
onLogout={onLogout}
/>
)}

<button
type="button"
Expand Down
66 changes: 66 additions & 0 deletions wework/src/components/layout/DesktopWorkbenchLayout.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,72 @@ describe('DesktopWorkbenchLayout', () => {
expect(screen.getByText('退出登录')).toBeInTheDocument()
})

test('opens the independent connection settings page from the settings menu', async () => {
render(<DesktopWorkbenchLayout {...baseProps} />)

await userEvent.click(screen.getByTestId('settings-button'))
await userEvent.click(screen.getByTestId('settings-menu-button'))

expect(screen.getByTestId('wework-settings-page')).toBeInTheDocument()
expect(screen.getByTestId('settings-back-button')).toHaveTextContent('返回')
expect(screen.queryByText('返回应用')).not.toBeInTheDocument()
expect(screen.getByRole('heading', { name: '连接' })).toBeInTheDocument()
expect(screen.getByText('连接设备')).toBeInTheDocument()
expect(screen.queryByText('连接这台设备')).not.toBeInTheDocument()
expect(screen.queryByText('链接这台设备')).not.toBeInTheDocument()
expect(screen.queryByText('控制其他设备')).not.toBeInTheDocument()
expect(screen.queryByText('SSH')).not.toBeInTheDocument()
expect(screen.getByTestId('settings-nav-connections')).toBeInTheDocument()
expect(screen.getByTestId('settings-nav-projects')).toBeInTheDocument()
expect(screen.getByText('项目')).toBeInTheDocument()
expect(screen.queryByTestId('settings-nav-general')).not.toBeInTheDocument()
expect(screen.queryByText('Personal Devices')).not.toBeInTheDocument()
expect(screen.queryByText('Linux-Device-481b616e8e0b')).not.toBeInTheDocument()
expect(screen.getByText('可连接的设备')).toBeInTheDocument()
expect(screen.queryByText('可连接这台设备的云设备')).not.toBeInTheDocument()
expect(screen.getByText('云设备')).toBeInTheDocument()
expect(
screen.getByTestId('connection-device-icon-24a59054-4638-4744-983d-372706c30fcd'),
).toHaveClass('text-[#3c4043]')
expect(
screen.getByTestId('connection-device-icon-24a59054-4638-4744-983d-372706c30fcd'),
).not.toHaveClass('bg-[#f7f7f8]')
expect(screen.getByText('yunpeng7-executor-372706c30fcd')).toBeInTheDocument()
expect(screen.getByText('v1.712')).toBeInTheDocument()
expect(screen.getByText('在线')).toBeInTheDocument()
expect(screen.queryByText('Online')).not.toBeInTheDocument()
expect(
screen.getByTestId('connection-terminal-button-24a59054-4638-4744-983d-372706c30fcd'),
).toBeInTheDocument()
expect(
screen.getByTestId('connection-code-server-button-24a59054-4638-4744-983d-372706c30fcd'),
).toBeInTheDocument()
expect(
screen.getByTestId('connection-vnc-button-24a59054-4638-4744-983d-372706c30fcd'),
).toBeInTheDocument()
expect(screen.getByText('终端')).toBeInTheDocument()
expect(screen.getByText('IDE')).toBeInTheDocument()
expect(screen.getByText('桌面')).toBeInTheDocument()
expect(screen.queryByText('Terminal')).not.toBeInTheDocument()
expect(screen.queryByText('Code Server')).not.toBeInTheDocument()
expect(screen.queryByText('桌面 VNC')).not.toBeInTheDocument()
expect(screen.getByText('CPU')).toBeInTheDocument()
expect(screen.getByText('MEM')).toBeInTheDocument()
expect(screen.getByText('磁盘')).toBeInTheDocument()
expect(screen.getByText('42%')).toBeInTheDocument()
expect(screen.getByText('68%')).toBeInTheDocument()
expect(screen.getByText('57%')).toBeInTheDocument()
expect(screen.getByTestId('connection-scale-wiki')).toBeInTheDocument()
expect(screen.getByText('说明')).toBeInTheDocument()
expect(screen.queryByText('扩容 Wiki')).not.toBeInTheDocument()
expect(screen.getByText(/持续超过 80%/)).toBeInTheDocument()
expect(screen.queryByText('a8791aa3-4e8a-4076-b9a6-481b616e8e0b')).not.toBeInTheDocument()
expect(screen.queryByText('Nevis')).not.toBeInTheDocument()
expect(screen.queryByText('Cloud computing powered by Nevis')).not.toBeInTheDocument()
expect(screen.queryByText('其他设置')).not.toBeInTheDocument()
expect(screen.queryByText('Start Task')).not.toBeInTheDocument()
})

test('opens and resizes the right workspace panel', async () => {
render(<DesktopWorkbenchLayout {...baseProps} />)

Expand Down
29 changes: 18 additions & 11 deletions wework/src/components/layout/DesktopWorkbenchLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useState } from 'react'
import type { WorkbenchMessage, WorkbenchState } from '@/types/workbench'
import { DesktopSidebar } from './DesktopSidebar'
import { DesktopWorkbenchMain } from './DesktopWorkbenchMain'
import { ConnectionsSettingsPage } from '@/components/settings/ConnectionsSettingsPage'

interface DesktopWorkbenchLayoutProps {
state: WorkbenchState
Expand All @@ -23,10 +24,11 @@ export function DesktopWorkbenchLayout({
onLogout,
}: DesktopWorkbenchLayoutProps) {
const [sidebarCollapsed, setSidebarCollapsed] = useState(false)
const [settingsOpen, setSettingsOpen] = useState(false)

return (
<div className="flex h-screen overflow-hidden bg-base text-text-primary">
{!sidebarCollapsed && (
{!settingsOpen && !sidebarCollapsed && (
<DesktopSidebar
user={state.user}
projects={state.projects}
Expand All @@ -35,20 +37,25 @@ export function DesktopWorkbenchLayout({
onCollapse={() => setSidebarCollapsed(true)}
onSelectProject={onSelectProject}
onOpenTask={onOpenTask}
onOpenSettings={() => setSettingsOpen(true)}
onLogout={onLogout}
/>
)}

<DesktopWorkbenchMain
sidebarCollapsed={sidebarCollapsed}
currentTask={state.currentTask}
messages={messages}
input={state.input}
isSending={state.isSending}
onExpandSidebar={() => setSidebarCollapsed(false)}
onInputChange={onInputChange}
onSend={onSend}
/>
{settingsOpen ? (
<ConnectionsSettingsPage onBack={() => setSettingsOpen(false)} />
) : (
<DesktopWorkbenchMain
sidebarCollapsed={sidebarCollapsed}
currentTask={state.currentTask}
messages={messages}
input={state.input}
isSending={state.isSending}
onExpandSidebar={() => setSidebarCollapsed(false)}
onInputChange={onInputChange}
onSend={onSend}
/>
)}
</div>
)
}
Loading
Loading