Make project host setup settings navigable

Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
Jinwoo-H
2026-06-11 12:33:58 -07:00
co-authored by Orca
parent 47dea939c9
commit 2994730c32
5 changed files with 83 additions and 22 deletions
@@ -1,7 +1,8 @@
import { getExecutionHostLabel } from '../../../../shared/execution-host'
import type { Repo } from '../../../../shared/types'
import type { ProjectHostSetupState, Repo } from '../../../../shared/types'
import { useAppStore } from '../../store'
import { getProjectHostSetupProjectionFromState } from '../../store/selectors'
import { cn } from '../../lib/utils'
import { Label } from '../ui/label'
import { SearchableSetting } from './SearchableSetting'
import { SettingsBadge } from './SettingsFormControls'
@@ -16,12 +17,38 @@ type RepositoryHostSetupsSectionProps = {
searchEntries: SettingsSearchEntry[]
}
function getSetupStateLabel(setupState: ProjectHostSetupState): string {
switch (setupState) {
case 'ready':
return translate('auto.components.settings.RepositoryPane.hostSetupStateReady', 'Ready')
case 'not-set-up':
return translate(
'auto.components.settings.RepositoryPane.hostSetupStateNotSetUp',
'Not set up'
)
case 'setting-up':
return translate(
'auto.components.settings.RepositoryPane.hostSetupStateSettingUp',
'Setting up'
)
case 'error':
return translate('auto.components.settings.RepositoryPane.hostSetupStateError', 'Error')
case 'unsupported':
return translate(
'auto.components.settings.RepositoryPane.hostSetupStateUnsupported',
'Unsupported'
)
}
}
export function RepositoryHostSetupsSection({
repo,
forceVisible,
searchQuery,
searchEntries
}: RepositoryHostSetupsSectionProps): React.JSX.Element | null {
const openSettingsPage = useAppStore((state) => state.openSettingsPage)
const openSettingsTarget = useAppStore((state) => state.openSettingsTarget)
const projectHostSetupProjection = useAppStore((state) =>
getProjectHostSetupProjectionFromState(state)
)
@@ -64,28 +91,42 @@ export function RepositoryHostSetupsSection({
</p>
</div>
<div className="divide-y divide-border rounded-md border border-border">
{projectHostSetups.map((setup) => (
<div key={setup.id} className="flex items-start gap-3 px-3 py-2.5">
<div className="min-w-0 flex-1">
<div className="flex min-w-0 items-center gap-2">
<span className="truncate text-sm font-medium">
{getExecutionHostLabel(setup.hostId)}
</span>
<SettingsBadge tone={setup.setupState === 'ready' ? 'accent' : 'muted'}>
{setup.setupState}
</SettingsBadge>
{projectHostSetups.map((setup) => {
const isCurrentSetup = setup.repoId === repo.id
return (
<button
key={setup.id}
type="button"
className={cn(
'flex w-full items-start gap-3 px-3 py-2.5 text-left transition-colors',
isCurrentSetup ? 'bg-muted/30' : 'hover:bg-muted/40'
)}
onClick={() => {
openSettingsPage()
openSettingsTarget({ pane: 'repo', repoId: setup.repoId })
}}
>
<div className="min-w-0 flex-1">
<div className="flex min-w-0 items-center gap-2">
<span className="truncate text-sm font-medium">
{getExecutionHostLabel(setup.hostId)}
</span>
<SettingsBadge tone={setup.setupState === 'ready' ? 'accent' : 'muted'}>
{getSetupStateLabel(setup.setupState)}
</SettingsBadge>
</div>
<p className="mt-0.5 truncate font-mono text-[11px] text-muted-foreground">
{setup.path}
</p>
</div>
<p className="mt-0.5 truncate font-mono text-[11px] text-muted-foreground">
{setup.path}
</p>
</div>
{setup.repoId === repo.id ? (
<SettingsBadge>
{translate('auto.components.settings.RepositoryPane.currentSetup', 'Current')}
</SettingsBadge>
) : null}
</div>
))}
{isCurrentSetup ? (
<SettingsBadge>
{translate('auto.components.settings.RepositoryPane.currentSetup', 'Current')}
</SettingsBadge>
) : null}
</button>
)
})}
</div>
</SearchableSetting>
)
+5
View File
@@ -5037,6 +5037,11 @@
"availableHostsDescription": "Hosts where this project is set up.",
"availableHostsHelp": "Project paths and worktree settings are host-specific; creating a workspace can target any ready setup.",
"currentSetup": "Current",
"hostSetupStateReady": "Ready",
"hostSetupStateNotSetUp": "Not set up",
"hostSetupStateSettingUp": "Setting up",
"hostSetupStateError": "Error",
"hostSetupStateUnsupported": "Unsupported",
"499a437335": "Identity"
},
"RepositorySourceControlAiActionRows": {
+5
View File
@@ -5017,6 +5017,11 @@
"availableHostsDescription": "このプロジェクトがセットアップされているホスト。",
"availableHostsHelp": "プロジェクトのパスとワークツリー設定はホストごとに異なります。ワークスペースは準備済みの任意のセットアップで作成できます。",
"currentSetup": "現在",
"hostSetupStateReady": "準備完了",
"hostSetupStateNotSetUp": "未セットアップ",
"hostSetupStateSettingUp": "セットアップ中",
"hostSetupStateError": "エラー",
"hostSetupStateUnsupported": "未対応",
"499a437335": "身元"
},
"RepositorySourceControlAiActionRows": {
+5
View File
@@ -5017,6 +5017,11 @@
"availableHostsDescription": "이 프로젝트가 설정된 호스트입니다.",
"availableHostsHelp": "프로젝트 경로와 워크트리 설정은 호스트별로 다릅니다. 워크스페이스는 준비된 모든 설정에서 만들 수 있습니다.",
"currentSetup": "현재",
"hostSetupStateReady": "준비됨",
"hostSetupStateNotSetUp": "설정되지 않음",
"hostSetupStateSettingUp": "설정 중",
"hostSetupStateError": "오류",
"hostSetupStateUnsupported": "지원되지 않음",
"499a437335": "신원"
},
"RepositorySourceControlAiActionRows": {
+5
View File
@@ -5017,6 +5017,11 @@
"availableHostsDescription": "此项目已设置的主机。",
"availableHostsHelp": "项目路径和工作树设置按主机区分;创建工作区可选择任何已就绪的设置。",
"currentSetup": "当前",
"hostSetupStateReady": "已就绪",
"hostSetupStateNotSetUp": "未设置",
"hostSetupStateSettingUp": "设置中",
"hostSetupStateError": "错误",
"hostSetupStateUnsupported": "不支持",
"499a437335": "身份"
},
"RepositorySourceControlAiActionRows": {