mirror of
https://github.com/stablyai/orca.git
synced 2026-11-15 18:37:24 +00:00
fix(sync): regenerate rpc catalog and locale runtime catalogs; drop retired zh keys; split ProjectCombobox keys/props under max-lines; arming a cloud row closes the Add project cascade
This commit is contained in:
@@ -1485,7 +1485,6 @@
|
||||
"updateDesktop": "请更新 {{desktop}} 上的 Orca,以使用自动化。"
|
||||
},
|
||||
"emptyState": {
|
||||
"connectedDescription": "桌面将显示在这里。所有数据均采用端到端加密",
|
||||
"connectedTitle": "已连接",
|
||||
"description": "与电脑上的 Orca 配对,即可在手机上查看智能体、进入任意终端并推进工作",
|
||||
"openDesktopDescription": "前往“设置” → “移动端”,生成配对二维码",
|
||||
|
||||
@@ -5,7 +5,6 @@ import { isWithinAddProjectMenu } from '@/components/sidebar/project-admission/m
|
||||
import { Popover, PopoverAnchor, PopoverContent } from '@/components/ui/popover'
|
||||
import { cn } from '@/lib/class-names'
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
|
||||
import type { NewWorkspaceProjectOption } from '@/lib/workspace/creation/new-workspace-project-options'
|
||||
import { useTranslate } from '@/i18n/use-translate'
|
||||
import {
|
||||
getAmbiguousProjectOptionIds,
|
||||
@@ -13,19 +12,21 @@ import {
|
||||
sectionProjectOptions
|
||||
} from './project-combobox-matching'
|
||||
import {
|
||||
focusCascadedAddProjectMenuFirstItem,
|
||||
ProjectComboboxAddProjectOption,
|
||||
type ProjectComboboxAddProjectMenu
|
||||
} from './ProjectComboboxAddProjectOption'
|
||||
import {
|
||||
handleProjectComboboxKeyDown,
|
||||
PROJECT_COMBOBOX_ADD_PROJECT_KEY
|
||||
} from './project-combobox-keydown'
|
||||
import { ProjectOptionMark, ProjectOptionRow } from './ProjectComboboxRow'
|
||||
import { useRecentProjectIds } from './use-recent-project-ids'
|
||||
import { isWithinComboboxRoot, useTypeAheadCombobox } from './use-type-ahead-combobox'
|
||||
import type { ProjectComboboxProps } from './project-combobox-props'
|
||||
import { COMBOBOX_FIELD_SHELL, COMBOBOX_POPOVER_SURFACE } from './type-ahead-combobox-styles'
|
||||
import type { OrcaCloudGitHubRepository } from '@/lib/orca-cloud/use-orca-cloud-github-repositories'
|
||||
import {
|
||||
CLOUD_REPO_MORE_KEY,
|
||||
CLOUD_REPO_SHOW_MORE_KEY,
|
||||
cloudRepoKey,
|
||||
cloudRowKeys,
|
||||
commitCloudRow,
|
||||
filterCloudRepos,
|
||||
ProjectComboboxCloudSection,
|
||||
@@ -34,35 +35,7 @@ import {
|
||||
|
||||
export type { ProjectComboboxAddProjectMenu }
|
||||
|
||||
type ProjectComboboxProps = {
|
||||
options: readonly NewWorkspaceProjectOption[]
|
||||
value: string | null
|
||||
onValueChange: (projectId: string) => void
|
||||
onValueSelected?: (projectId: string) => void
|
||||
onAddProject?: () => void
|
||||
addProjectMenu?: ProjectComboboxAddProjectMenu
|
||||
placeholder?: string
|
||||
triggerClassName?: string
|
||||
invalid?: boolean
|
||||
describedBy?: string
|
||||
/** D4: GitHub repositories with no clone here, listed while Orca Cloud is the Run on target. */
|
||||
cloudRepos?: readonly OrcaCloudGitHubRepository[] | null
|
||||
/** The picked cloud-only repository (owner/name); it replaces the project in the field. */
|
||||
cloudRepoValue?: string | null
|
||||
onCloudRepoSelected?: (fullName: string) => void
|
||||
onMoreCloudAccess?: () => void
|
||||
/** Present while GitHub has more repositories than are listed. */
|
||||
onShowMoreCloudRepos?: (() => void) | null
|
||||
/** Bumped to open the list at its cloud-only section ("Choose a GitHub repository"). */
|
||||
openSignal?: number
|
||||
/**
|
||||
* Bumped to move focus here quietly (RR-c1: a stopped Create points at the field's error): no
|
||||
* path tooltip on that focus, since the error is already speaking. Hover and Tab still show it.
|
||||
*/
|
||||
focusSignal?: number
|
||||
}
|
||||
|
||||
const ADD_PROJECT_KEY = 'add-project'
|
||||
const ADD_PROJECT_KEY = PROJECT_COMBOBOX_ADD_PROJECT_KEY
|
||||
const ROOT_ATTRIBUTE = 'data-project-combobox-root'
|
||||
|
||||
/** Use one search field and one shared pointer/keyboard cursor; pin Add project so empty/long lists keep it reachable. */
|
||||
@@ -101,11 +74,7 @@ export default function ProjectCombobox({
|
||||
query,
|
||||
recentIds
|
||||
).flatMap((section) => section.items.map((match) => match.option.id)),
|
||||
...(cloudRepos
|
||||
? filterCloudRepos(cloudRepos, query).map((repo) => cloudRepoKey(repo.fullName))
|
||||
: []),
|
||||
...(cloudRepos && onShowMoreCloudRepos ? [CLOUD_REPO_SHOW_MORE_KEY] : []),
|
||||
...(cloudRepos && onMoreCloudAccess ? [CLOUD_REPO_MORE_KEY] : []),
|
||||
...cloudRowKeys(cloudRepos, query, onShowMoreCloudRepos, onMoreCloudAccess),
|
||||
...(hasAddProjectRow ? [ADD_PROJECT_KEY] : [])
|
||||
],
|
||||
[cloudRepos, hasAddProjectRow, onMoreCloudAccess, onShowMoreCloudRepos, options, recentIds]
|
||||
@@ -199,53 +168,30 @@ export default function ProjectCombobox({
|
||||
onValueSelected?.(key)
|
||||
}
|
||||
|
||||
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>): void => {
|
||||
if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
|
||||
event.preventDefault()
|
||||
setCascadeOpen(false)
|
||||
setOpen(true)
|
||||
moveArm(event.key === 'ArrowDown' ? 1 : -1)
|
||||
return
|
||||
}
|
||||
if (
|
||||
(event.key === 'Enter' || event.key === 'ArrowRight') &&
|
||||
open &&
|
||||
armedKey === ADD_PROJECT_KEY &&
|
||||
addProjectMenu
|
||||
) {
|
||||
event.preventDefault()
|
||||
setCascadeAutoFocus(true)
|
||||
if (cascadeOpen) {
|
||||
focusCascadedAddProjectMenuFirstItem()
|
||||
} else {
|
||||
setCascadeOpen(true)
|
||||
}
|
||||
return
|
||||
}
|
||||
if (event.key === 'Enter' && open) {
|
||||
event.preventDefault()
|
||||
commit(armedKey)
|
||||
return
|
||||
}
|
||||
// Handle Escape even while closed to clear stranded queries; bubble only when there is no committed display to restore.
|
||||
if (event.key === 'Escape' && (open || query.length > 0)) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
if (cascadeOpen) {
|
||||
setCascadeOpen(false)
|
||||
return
|
||||
}
|
||||
close()
|
||||
return
|
||||
}
|
||||
if (event.key === 'Backspace' && committed) {
|
||||
event.preventDefault()
|
||||
setCascadeOpen(false)
|
||||
setQuery(committedName)
|
||||
setOpen(true)
|
||||
}
|
||||
// Arming a list row closes an open Add project cascade beside it.
|
||||
const armClosingCascade = (key: string): void => {
|
||||
setCascadeOpen(false)
|
||||
arm(key)
|
||||
}
|
||||
|
||||
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>): void =>
|
||||
handleProjectComboboxKeyDown(event, {
|
||||
open,
|
||||
armedKey,
|
||||
query,
|
||||
committed,
|
||||
committedName,
|
||||
cascadeOpen,
|
||||
hasAddProjectMenu: Boolean(addProjectMenu),
|
||||
setOpen,
|
||||
setQuery,
|
||||
setCascadeOpen,
|
||||
setCascadeAutoFocus,
|
||||
moveArm,
|
||||
commit,
|
||||
close
|
||||
})
|
||||
|
||||
return (
|
||||
<Popover open={open} onOpenChange={handleOpenChange}>
|
||||
<Tooltip
|
||||
@@ -434,12 +380,7 @@ export default function ProjectCombobox({
|
||||
current={scored.option.id === value}
|
||||
ambiguous={ambiguous.has(scored.option.id)}
|
||||
optionId={armedKey === scored.option.id ? `${listId}-armed` : undefined}
|
||||
onArm={() => {
|
||||
if (cascadeOpen) {
|
||||
setCascadeOpen(false)
|
||||
}
|
||||
arm(scored.option.id)
|
||||
}}
|
||||
onArm={() => armClosingCascade(scored.option.id)}
|
||||
onCommit={() => commit(scored.option.id)}
|
||||
/>
|
||||
))}
|
||||
@@ -451,7 +392,7 @@ export default function ProjectCombobox({
|
||||
value={cloudRepoValue ? cloudRepoKey(cloudRepoValue) : null}
|
||||
armedKey={armedKey}
|
||||
armedId={`${listId}-armed`}
|
||||
onArm={arm}
|
||||
onArm={armClosingCascade}
|
||||
onCommit={commit}
|
||||
showMoreAccess={Boolean(onMoreCloudAccess)}
|
||||
showMoreRepos={Boolean(onShowMoreCloudRepos)}
|
||||
|
||||
@@ -60,6 +60,23 @@ export function commitCloudRow(
|
||||
}
|
||||
|
||||
/** Case-insensitive substring match; the list is short and names are owner/repo. */
|
||||
/** The cloud-only rows' keys, in list order, for the shared keyboard cursor. */
|
||||
export function cloudRowKeys(
|
||||
cloudRepos: readonly OrcaCloudGitHubRepository[] | null,
|
||||
query: string,
|
||||
onShowMoreCloudRepos: (() => void) | null,
|
||||
onMoreCloudAccess: (() => void) | undefined
|
||||
): string[] {
|
||||
if (!cloudRepos) {
|
||||
return []
|
||||
}
|
||||
return [
|
||||
...filterCloudRepos(cloudRepos, query).map((repo) => cloudRepoKey(repo.fullName)),
|
||||
...(onShowMoreCloudRepos ? [CLOUD_REPO_SHOW_MORE_KEY] : []),
|
||||
...(onMoreCloudAccess ? [CLOUD_REPO_MORE_KEY] : [])
|
||||
]
|
||||
}
|
||||
|
||||
export function filterCloudRepos(
|
||||
repos: readonly OrcaCloudGitHubRepository[],
|
||||
query: string
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
import type React from 'react'
|
||||
import { focusCascadedAddProjectMenuFirstItem } from './ProjectComboboxAddProjectOption'
|
||||
|
||||
export const PROJECT_COMBOBOX_ADD_PROJECT_KEY = 'add-project'
|
||||
|
||||
export type ProjectComboboxKeyDownState = {
|
||||
open: boolean
|
||||
armedKey: string | null
|
||||
query: string
|
||||
committed: boolean
|
||||
committedName: string
|
||||
cascadeOpen: boolean
|
||||
hasAddProjectMenu: boolean
|
||||
setOpen: (open: boolean) => void
|
||||
setQuery: (query: string) => void
|
||||
setCascadeOpen: (open: boolean) => void
|
||||
setCascadeAutoFocus: (autoFocus: boolean) => void
|
||||
moveArm: (step: number) => void
|
||||
commit: (key: string | null) => void
|
||||
close: () => void
|
||||
}
|
||||
|
||||
/** The project field's keys: arrows move the shared cursor, Enter/→ on Add project opens its cascade. */
|
||||
export function handleProjectComboboxKeyDown(
|
||||
event: React.KeyboardEvent<HTMLInputElement>,
|
||||
state: ProjectComboboxKeyDownState
|
||||
): void {
|
||||
if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
|
||||
event.preventDefault()
|
||||
state.setCascadeOpen(false)
|
||||
state.setOpen(true)
|
||||
state.moveArm(event.key === 'ArrowDown' ? 1 : -1)
|
||||
return
|
||||
}
|
||||
if (
|
||||
(event.key === 'Enter' || event.key === 'ArrowRight') &&
|
||||
state.open &&
|
||||
state.armedKey === PROJECT_COMBOBOX_ADD_PROJECT_KEY &&
|
||||
state.hasAddProjectMenu
|
||||
) {
|
||||
event.preventDefault()
|
||||
state.setCascadeAutoFocus(true)
|
||||
if (state.cascadeOpen) {
|
||||
focusCascadedAddProjectMenuFirstItem()
|
||||
} else {
|
||||
state.setCascadeOpen(true)
|
||||
}
|
||||
return
|
||||
}
|
||||
if (event.key === 'Enter' && state.open) {
|
||||
event.preventDefault()
|
||||
state.commit(state.armedKey)
|
||||
return
|
||||
}
|
||||
// Handle Escape even while closed to clear stranded queries; bubble only when there is no committed display to restore.
|
||||
if (event.key === 'Escape' && (state.open || state.query.length > 0)) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
if (state.cascadeOpen) {
|
||||
state.setCascadeOpen(false)
|
||||
return
|
||||
}
|
||||
state.close()
|
||||
return
|
||||
}
|
||||
if (event.key === 'Backspace' && state.committed) {
|
||||
event.preventDefault()
|
||||
state.setCascadeOpen(false)
|
||||
state.setQuery(state.committedName)
|
||||
state.setOpen(true)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import type { NewWorkspaceProjectOption } from '@/lib/workspace/creation/new-workspace-project-options'
|
||||
import type { OrcaCloudGitHubRepository } from '@/lib/orca-cloud/use-orca-cloud-github-repositories'
|
||||
import type { ProjectComboboxAddProjectMenu } from './ProjectComboboxAddProjectOption'
|
||||
|
||||
export type ProjectComboboxProps = {
|
||||
options: readonly NewWorkspaceProjectOption[]
|
||||
value: string | null
|
||||
onValueChange: (projectId: string) => void
|
||||
onValueSelected?: (projectId: string) => void
|
||||
onAddProject?: () => void
|
||||
addProjectMenu?: ProjectComboboxAddProjectMenu
|
||||
placeholder?: string
|
||||
triggerClassName?: string
|
||||
invalid?: boolean
|
||||
describedBy?: string
|
||||
/** D4: GitHub repositories with no clone here, listed while Orca Cloud is the Run on target. */
|
||||
cloudRepos?: readonly OrcaCloudGitHubRepository[] | null
|
||||
/** The picked cloud-only repository (owner/name); it replaces the project in the field. */
|
||||
cloudRepoValue?: string | null
|
||||
onCloudRepoSelected?: (fullName: string) => void
|
||||
onMoreCloudAccess?: () => void
|
||||
/** Present while GitHub has more repositories than are listed. */
|
||||
onShowMoreCloudRepos?: (() => void) | null
|
||||
/** Bumped to open the list at its cloud-only section ("Choose a GitHub repository"). */
|
||||
openSignal?: number
|
||||
/**
|
||||
* Bumped to move focus here quietly (RR-c1: a stopped Create points at the field's error): no
|
||||
* path tooltip on that focus, since the error is already speaking. Hover and Tab still show it.
|
||||
*/
|
||||
focusSignal?: number
|
||||
}
|
||||
+4
-4
@@ -1472,14 +1472,14 @@
|
||||
"symlink": "Symbolic links cannot be attached.",
|
||||
"unsupported": "Unsupported file type."
|
||||
},
|
||||
"orcaCloudSession": {
|
||||
"sandboxRestartsInMinutes_one": "Sandbox for {{name}} restarts in {{count}} minute",
|
||||
"sandboxRestartsInMinutes_other": "Sandbox for {{name}} restarts in {{count}} minutes"
|
||||
},
|
||||
"emulator": {
|
||||
"androidSdkNotFound": "Android SDK not found. Install Android Studio and set ANDROID_HOME.",
|
||||
"xcodeSimulatorToolsUnavailable": "Xcode Simulator tools are unavailable. Install full Xcode, open it once, then select it with `sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer`."
|
||||
},
|
||||
"orcaCloudSession": {
|
||||
"sandboxRestartsInMinutes_one": "Sandbox for {{name}} restarts in {{count}} minute",
|
||||
"sandboxRestartsInMinutes_other": "Sandbox for {{name}} restarts in {{count}} minutes"
|
||||
},
|
||||
"rateLimits": {
|
||||
"errors": {
|
||||
"chatgptAuthRequired": "ChatGPT authentication required to read rate limits",
|
||||
|
||||
@@ -2317,7 +2317,6 @@
|
||||
"hostConnectionFailed": "连接失败",
|
||||
"defaultBranchUpdateFailed": "无法更新项目的默认分支,请重试",
|
||||
"setLocation": "设置项目位置",
|
||||
"setLocationOnHost": "设置项目在 {{host}} 上的位置",
|
||||
"setLocationTooltip": "选择文件夹,或将此项目克隆到 {{host}}",
|
||||
"connect": "连接",
|
||||
"reconnect": "重新连接",
|
||||
@@ -3404,7 +3403,6 @@
|
||||
"dabd226118": "关闭",
|
||||
"34dd5ee38b": "重试",
|
||||
"532aea14ce": "取消",
|
||||
"767951265d": "创建工作树时出现问题",
|
||||
"cancelProvisioning": "取消"
|
||||
}
|
||||
}
|
||||
@@ -18046,7 +18044,6 @@
|
||||
"signout": {
|
||||
"confirm": {
|
||||
"title": "退出 Orca?",
|
||||
"description": "重新登录前,产物和 Orca Relay 将不可用,本地项目和工作树不会受到影响",
|
||||
"cancel": "取消",
|
||||
"action": "退出登录"
|
||||
}
|
||||
@@ -20470,7 +20467,6 @@
|
||||
"startInTerminal": "在终端中启动 {{value0}}"
|
||||
},
|
||||
"newWorkspace": {
|
||||
"agentOptional": "代理 [可选]",
|
||||
"createDescription": "选择项目和工作区名称,如果想启动代理,请选择一个",
|
||||
"directSetup": {
|
||||
"run": "Run setup",
|
||||
|
||||
@@ -44,6 +44,7 @@ import {
|
||||
LocalCommandSettleParamsSchema
|
||||
} from '../local-commands/local-command-contract'
|
||||
import { MobileWebBundleChunkParamsSchema } from '../mobile-web-bundle/bundle-rpc-contract'
|
||||
import { MobileWebBundleLocaleCatalogParamsSchema } from '../mobile-web-bundle/locale-catalog-contract'
|
||||
import { OrcaCloudEnrollDeviceParamsSchema } from '../orca-cloud-device-enrollment-contract'
|
||||
import { OrcadDiskUsageParamsSchema } from '../orcad-disk-usage'
|
||||
import { OrcadMigrationBlobChunkRequestSchema } from '../orcad-migration/orcad-migration-blob-transfer'
|
||||
@@ -1421,6 +1422,7 @@ export const RPC_PARAMS_BY_METHOD = {
|
||||
'orcad.migration.stageSnapshotChunk': OrcadMigrationSnapshotChunkRequestSchema,
|
||||
'orcad.terminalCensus': OrcadTerminalCensusParamsSchema,
|
||||
'orcad.workVerdict': OrcadWorkVerdictParamsSchema,
|
||||
'orchestration.approvalAnswer': ApprovalAnswerParams,
|
||||
'orchestration.ask': AskParams,
|
||||
'orchestration.callerShow': null,
|
||||
'orchestration.check': CheckParams,
|
||||
@@ -1701,6 +1703,7 @@ export const RPC_PARAMS_BY_METHOD = {
|
||||
'updater.download': null,
|
||||
'updater.getStatus': null,
|
||||
'updater.install': null,
|
||||
'workspaceCleanup.scan': WorkspaceCleanupScanParams,
|
||||
'workspacePorts.forwardTunnel': WorkspacePortForwardTunnelParams,
|
||||
'workspacePorts.kill': WorkspacePortKillParams,
|
||||
'workspacePorts.killHost': WorkspacePortKillHostParams,
|
||||
|
||||
Reference in New Issue
Block a user