refactor: group repository settings composition (#34347)

This commit is contained in:
Neil
2026-10-27 02:17:28 -07:00
committed by GitHub
parent 04f5104e15
commit 3b7ee71b0f
20 changed files with 89 additions and 86 deletions
+3 -3
View File
@@ -8731,9 +8731,9 @@
"src/renderer/src/components/settings/ReleaseBuildPicker.test.tsx": 714,
"src/renderer/src/components/settings/ReleaseChannelSection.test.tsx": 2427,
"src/renderer/src/components/settings/RemoteServerUpdateDialog.test.tsx": 333,
"src/renderer/src/components/settings/RepositoryGitHubAccountSection.inventory-lifetime.test.tsx": 587,
"src/renderer/src/components/settings/RepositoryGitHubAccountSection.test.tsx": 662,
"src/renderer/src/components/settings/RepositoryPane.test.ts": 2778,
"src/renderer/src/components/settings/repository/RepositoryGitHubAccountSection.inventory-lifetime.test.tsx": 587,
"src/renderer/src/components/settings/repository/RepositoryGitHubAccountSection.test.tsx": 662,
"src/renderer/src/components/settings/repository/RepositoryPane.test.ts": 2778,
"src/renderer/src/components/settings/repository/source-control/RepositorySourceControlAiSection.test.ts": 365,
"src/renderer/src/components/settings/RuntimeEnvironmentsPane.test.ts": 201,
"src/renderer/src/components/settings/RuntimeHostAccessForm.test.tsx": 307,
@@ -10,7 +10,7 @@ import { isGitRepoKind } from '../../../../shared/repo-kind'
import type { RepoHookSettings } from '../../../../shared/orca-yaml-hook-types'
import type { Repo } from '../../../../shared/repo-types'
import type { Worktree } from '../../../../shared/worktree/types'
import { getRepositoryLocalCommandsSectionId } from '../settings/repository-settings-targets'
import { getRepositoryLocalCommandsSectionId } from '../settings/repository/repository-settings-targets'
import {
requestContextualTourWhenReady,
type RequestContextualTourWhenReadyArgs
@@ -1,4 +1,4 @@
import { getRepositorySourceControlAiSectionId } from '@/components/settings/repository-settings-targets'
import { getRepositorySourceControlAiSectionId } from '@/components/settings/repository/repository-settings-targets'
import type { AppState } from '@/store'
import type { Repo } from '../../../../shared/repo-types'
@@ -25,7 +25,7 @@ import {
type SourceControlActionRecipeOverrideSummary
} from '../../../../shared/source-control-launch-agent-selection'
import { SearchableSetting } from './SearchableSetting'
import { getRepositorySourceControlAiActionRecipeSectionId } from './repository-settings-targets'
import { getRepositorySourceControlAiActionRecipeSectionId } from './repository/repository-settings-targets'
import { matchesSettingsSearch } from './settings-search'
import { SourceControlActionRecipeRow } from './SourceControlActionRecipeRow'
import { SourceControlActionRepoOverrideNote } from './SourceControlActionRepoOverrideNote'
@@ -3,11 +3,11 @@
import React, { act } from 'react'
import { createRoot, type Root } from 'react-dom/client'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import type { Repo } from '../../../../shared/repo-types'
import type { GlobalSettings } from '../../../../shared/global-settings-types'
import type { GhAccountBinding } from '../../../../shared/github/account-binding'
import type { GhAccountBindingInventory } from '../../../../shared/github/auth-types'
import type * as RepositoryGitHubAccountModule from './repository/identity/repository-github-account'
import type { Repo } from '../../../../../shared/repo-types'
import type { GlobalSettings } from '../../../../../shared/global-settings-types'
import type { GhAccountBinding } from '../../../../../shared/github/account-binding'
import type { GhAccountBindingInventory } from '../../../../../shared/github/auth-types'
import type * as RepositoryGitHubAccountModule from './identity/repository-github-account'
import { RepositoryGitHubAccountSection } from './RepositoryGitHubAccountSection'
const { listAccountsMock, validateBindingMock, storeState } = vi.hoisted(() => {
@@ -27,14 +27,14 @@ vi.mock('@/store/index', () => {
vi.mock('@/runtime/runtime-rpc-client', () => ({ callRuntimeRpc: vi.fn() }))
vi.mock('./repository/identity/repository-github-account', async (importOriginal) => ({
vi.mock('./identity/repository-github-account', async (importOriginal) => ({
...(await importOriginal<typeof RepositoryGitHubAccountModule>()),
listRepositoryGhBindableAccounts: listAccountsMock,
validateRepositoryGhAccountBinding: validateBindingMock
}))
// Radix requires layout APIs; the native select retains the account interaction.
vi.mock('../ui/select', () => ({
vi.mock('../../ui/select', () => ({
Select: ({
value,
onValueChange,
@@ -3,15 +3,15 @@
import React, { act } from 'react'
import { createRoot, type Root } from 'react-dom/client'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import type { Repo } from '../../../../shared/repo-types'
import type { Repo } from '../../../../../shared/repo-types'
import type {
GhAccountBindingInventory,
GhAuthAccount,
GhMultiAccountCapability
} from '../../../../shared/github/auth-types'
import type { GhAccountBinding } from '../../../../shared/github/account-binding'
import type * as RepositoryGitHubAccountModule from './repository/identity/repository-github-account'
import { isGhAccountBindingEnforced } from './repository/identity/repository-github-account'
} from '../../../../../shared/github/auth-types'
import type { GhAccountBinding } from '../../../../../shared/github/account-binding'
import type * as RepositoryGitHubAccountModule from './identity/repository-github-account'
import { isGhAccountBindingEnforced } from './identity/repository-github-account'
import { RepositoryGitHubAccountSection } from './RepositoryGitHubAccountSection'
const { listAccountsMock, validateBindingMock, storeState } = vi.hoisted(() => {
@@ -35,14 +35,14 @@ vi.mock('@/store/index', () => {
vi.mock('@/runtime/runtime-rpc-client', () => ({ callRuntimeRpc: vi.fn() }))
vi.mock('./repository/identity/repository-github-account', async (importOriginal) => ({
vi.mock('./identity/repository-github-account', async (importOriginal) => ({
...(await importOriginal<typeof RepositoryGitHubAccountModule>()),
listRepositoryGhBindableAccounts: listAccountsMock,
validateRepositoryGhAccountBinding: validateBindingMock
}))
// Why: Radix Select needs pointer/layout APIs happy-dom lacks; a native select keeps value + disabled testable.
vi.mock('../ui/select', () => ({
vi.mock('../../ui/select', () => ({
Select: ({
value,
onValueChange,
@@ -1,21 +1,21 @@
import { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react'
import { RefreshCw } from 'lucide-react'
import type { GhAccountBinding } from '../../../../shared/github/account-binding'
import type { Repo } from '../../../../shared/repo-types'
import type { GhAccountBindingInventory } from '../../../../shared/github/auth-types'
import { Button } from '../ui/button'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../ui/select'
import { SearchableSetting } from './SearchableSetting'
import type { GhAccountBinding } from '../../../../../shared/github/account-binding'
import type { Repo } from '../../../../../shared/repo-types'
import type { GhAccountBindingInventory } from '../../../../../shared/github/auth-types'
import { Button } from '../../ui/button'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../ui/select'
import { SearchableSetting } from '../SearchableSetting'
import { useAppStore } from '@/store/index'
import { runtimeTargetForOwnerEnvironment } from '@/runtime/runtime-client-target'
import { getRepoExecutionHostId, parseExecutionHostId } from '../../../../shared/execution-host'
import { getRepoExecutionHostId, parseExecutionHostId } from '../../../../../shared/execution-host'
import { translate } from '@/i18n/i18n'
import { searchKeywords } from './settings-search-keywords'
import { searchKeywords } from '../settings-search-keywords'
import {
isGhAccountBindingEnforced,
listRepositoryGhBindableAccounts,
validateRepositoryGhAccountBinding
} from './repository/identity/repository-github-account'
} from './identity/repository-github-account'
type RepositoryGitHubAccountSectionProps = {
repo: Repo
@@ -4,16 +4,17 @@ import React, { act } from 'react'
import { createRoot, type Root } from 'react-dom/client'
import { renderToStaticMarkup } from 'react-dom/server'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { getDefaultSettings } from '../../../../shared/constants'
import type { Project } from '../../../../shared/project-types'
import type { Repo } from '../../../../shared/repo-types'
import type { TerminalTab } from '../../../../shared/terminal-tab-types'
import type { AgentStatusEntry } from '../../../../shared/agent-status-types'
import { getDefaultSettings } from '../../../../../shared/constants'
import type { Project } from '../../../../../shared/project-types'
import type { Repo } from '../../../../../shared/repo-types'
import type { TerminalTab } from '../../../../../shared/terminal-tab-types'
import type { AgentStatusEntry } from '../../../../../shared/agent-status-types'
import { useAppStore } from '@/store/index'
import { getRepositoryPaneSearchEntries, RepositoryPane } from './RepositoryPane'
import { matchesRepositoryIdentitySearch } from './repository/identity/repository-identity-search'
import { matchesSettingsSearch } from './settings-search'
import { TooltipProvider } from '../ui/tooltip'
import { getRepositoryPaneSearchEntries } from './repository-search'
import { RepositoryPane } from './RepositoryPane'
import { matchesRepositoryIdentitySearch } from './identity/repository-identity-search'
import { matchesSettingsSearch } from '../settings-search'
import { TooltipProvider } from '../../ui/tooltip'
let container: HTMLDivElement
let root: Root
@@ -1,37 +1,36 @@
import type { GhAccountBinding } from '../../../../shared/github/account-binding'
import type { GhAccountBinding } from '../../../../../shared/github/account-binding'
import { useCallback, useRef, useState } from 'react'
import type { OrcaHooks, RepoHookSettings } from '../../../../shared/orca-yaml-hook-types'
import type { Project, ProjectUpdateArgs } from '../../../../shared/project-types'
import type { Repo } from '../../../../shared/repo-types'
import { getRepoKindLabel, isFolderRepo } from '../../../../shared/repo-kind'
import { getRepoExecutionHostId, type ExecutionHostId } from '../../../../shared/execution-host'
import { Label } from '../ui/label'
import { Separator } from '../ui/separator'
import type { OrcaHooks, RepoHookSettings } from '../../../../../shared/orca-yaml-hook-types'
import type { Project, ProjectUpdateArgs } from '../../../../../shared/project-types'
import type { Repo } from '../../../../../shared/repo-types'
import { getRepoKindLabel, isFolderRepo } from '../../../../../shared/repo-kind'
import { getRepoExecutionHostId, type ExecutionHostId } from '../../../../../shared/execution-host'
import { Label } from '../../ui/label'
import { Separator } from '../../ui/separator'
import { useShallow } from 'zustand/react/shallow'
import { RepositoryHooksSection } from './repository/execution/RepositoryHooksSection'
import { McpConfigSection } from './McpConfigSection'
import { WorktreeSymlinksSection } from './WorktreeSymlinksSection'
import { SparsePresetSettingsSection } from './SparsePresetSettingsSection'
import { RepositorySourceControlAiSection } from './repository/source-control/RepositorySourceControlAiSection'
import { SearchableSetting } from './SearchableSetting'
import { RepositoryHooksSection } from './execution/RepositoryHooksSection'
import { McpConfigSection } from '../McpConfigSection'
import { WorktreeSymlinksSection } from '../WorktreeSymlinksSection'
import { SparsePresetSettingsSection } from '../SparsePresetSettingsSection'
import { RepositorySourceControlAiSection } from './source-control/RepositorySourceControlAiSection'
import { SearchableSetting } from '../SearchableSetting'
import { RepositoryRemoveProjectButton } from './RepositoryRemoveProjectButton'
import { matchesSettingsSearch } from './settings-search'
import { matchesSettingsSearch } from '../settings-search'
import { useAppStore } from '@/store/index'
import { getRepositoryIconSectionId } from './repository-settings-targets'
import { RepositoryIconPicker } from './repository/identity/RepositoryIconPicker'
import { RepositoryIconPicker } from './identity/RepositoryIconPicker'
import { getRepositoryPaneSearchEntries } from './repository-search'
import { RepositoryHostSetupsSection } from './repository/execution/RepositoryHostSetupsSection'
import { RepoSettingsDraftInput } from './repository/RepositorySettingsDraftInput'
import { RepositoryForkSyncSection } from './repository/identity/RepositoryForkSyncSection'
import { RepositoryHostSetupsSection } from './execution/RepositoryHostSetupsSection'
import { RepoSettingsDraftInput } from './RepositorySettingsDraftInput'
import { RepositoryForkSyncSection } from './identity/RepositoryForkSyncSection'
import { RepositoryGitHubAccountSection } from './RepositoryGitHubAccountSection'
import { translate } from '@/i18n/i18n'
import { RepositoryWindowsRuntimeSection } from './repository/execution/RepositoryWindowsRuntimeSection'
import { matchesRepositoryIdentitySearch } from './repository/identity/repository-identity-search'
import { RepositoryWorktreeDefaultsSection } from './repository/execution/RepositoryWorktreeDefaultsSection'
import { RepositoryJiraProjectSection } from './repository/RepositoryJiraProjectSection'
import { getProjectRuntimeSessionSummary } from './repository/execution/repository-runtime-session-summary'
import { getRepoOwnerWorktreeVisibilityDefaults } from '../../store/worktree-visibility-defaults-by-host'
export { getRepositoryPaneSearchEntries }
import { RepositoryWindowsRuntimeSection } from './execution/RepositoryWindowsRuntimeSection'
import { matchesRepositoryIdentitySearch } from './identity/repository-identity-search'
import { RepositoryWorktreeDefaultsSection } from './execution/RepositoryWorktreeDefaultsSection'
import { RepositoryJiraProjectSection } from './RepositoryJiraProjectSection'
import { getProjectRuntimeSessionSummary } from './execution/repository-runtime-session-summary'
import { getRepoOwnerWorktreeVisibilityDefaults } from '../../../store/worktree-visibility-defaults-by-host'
type RepositoryPaneRepoUpdate = Omit<
Partial<Repo>,
@@ -1,9 +1,9 @@
import { useState } from 'react'
import { Trash2 } from 'lucide-react'
import type { Repo } from '../../../../shared/repo-types'
import { Button } from '../ui/button'
import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip'
import { SearchableSetting } from './SearchableSetting'
import type { Repo } from '../../../../../shared/repo-types'
import { Button } from '../../ui/button'
import { Tooltip, TooltipContent, TooltipTrigger } from '../../ui/tooltip'
import { SearchableSetting } from '../SearchableSetting'
import { translate } from '@/i18n/i18n'
export function RepositoryRemoveProjectButton({
@@ -13,7 +13,7 @@ import { resolveHookCommandSourcePolicy } from '../../../../../../shared/hook-co
import { useAppStore } from '@/store/index'
import { translate } from '@/i18n/i18n'
import { SearchableSetting } from '../../SearchableSetting'
import { getRepositoryLocalCommandsSectionId } from '../../repository-settings-targets'
import { getRepositoryLocalCommandsSectionId } from '../repository-settings-targets'
import {
getLocalHookFields,
getLocalCommandSourcePolicyNotice
@@ -1,7 +1,7 @@
import type { Repo } from '../../../../shared/repo-types'
import type { SettingsSearchEntry } from './settings-search'
import type { Repo } from '../../../../../shared/repo-types'
import type { SettingsSearchEntry } from '../settings-search'
import { translate } from '@/i18n/i18n'
import { translateSearchKeyword } from './settings-search-keywords'
import { translateSearchKeyword } from '../settings-search-keywords'
export function getRepositoryGitAuthorSearchEntries(repo: Repo): SettingsSearchEntry[] {
return [
@@ -1,12 +1,15 @@
import type { Repo } from '../../../../shared/repo-types'
import { isFolderRepo } from '../../../../shared/repo-kind'
import { getRepoExecutionHostId, LOCAL_EXECUTION_HOST_ID } from '../../../../shared/execution-host'
import type { SettingsSearchEntry } from './settings-search'
import type { Repo } from '../../../../../shared/repo-types'
import { isFolderRepo } from '../../../../../shared/repo-kind'
import {
getRepoExecutionHostId,
LOCAL_EXECUTION_HOST_ID
} from '../../../../../shared/execution-host'
import type { SettingsSearchEntry } from '../settings-search'
import { translate } from '@/i18n/i18n'
import { translateSearchKeyword } from './settings-search-keywords'
import { translateSearchKeyword } from '../settings-search-keywords'
import { getRepositoryGitAuthorSearchEntries } from './repository-git-author-search-entries'
import { getRepositoryGitHooksSearchEntries } from './repository/execution/repository-git-hooks-search-entries'
import { getRepositoryGitWorktreeSearchEntries } from './repository/execution/repository-git-worktree-search-entries'
import { getRepositoryGitHooksSearchEntries } from './execution/repository-git-hooks-search-entries'
import { getRepositoryGitWorktreeSearchEntries } from './execution/repository-git-worktree-search-entries'
type RepositoryPaneSearchOptions = {
isLocalWindowsProject?: boolean
@@ -1,4 +1,4 @@
import type { SourceControlActionId } from '../../../../shared/source-control-ai-actions'
import type { SourceControlActionId } from '../../../../../shared/source-control-ai-actions'
export function getRepositoryLocalCommandsSectionId(repoId: string): string {
return `repo-${repoId}-local-commands`
@@ -47,7 +47,7 @@ import {
resolveAgentArgsPlaceholderAgent
} from './repository-source-control-ai-labels'
import { hasOwnActionOverride } from './repository-source-control-ai-draft'
import { getRepositorySourceControlAiActionRecipeSectionId } from '../../repository-settings-targets'
import { getRepositorySourceControlAiActionRecipeSectionId } from '../repository-settings-targets'
import { translate } from '@/i18n/i18n'
import { SourceControlActionOptionField } from '../../SourceControlActionOptionField'
import {
@@ -4,7 +4,7 @@ import type { Repo } from '../../../../../../shared/repo-types'
import { normalizeSourceControlAiSettings } from '../../../../../../shared/source-control-ai-settings'
import type { SourceControlAiRepoUpdate } from '../../../../../../shared/source-control-ai-recipe-save'
import { useAppStore } from '../../../../store/index'
import { getRepositorySourceControlAiSectionId } from '../../repository-settings-targets'
import { getRepositorySourceControlAiSectionId } from '../repository-settings-targets'
import { RepositorySourceControlAiActionRows } from './RepositorySourceControlAiActionRows'
import { RepositorySourceControlAiCustomCommand } from './RepositorySourceControlAiCustomCommand'
import { RepositorySourceControlAiEnablement } from './RepositorySourceControlAiEnablement'
@@ -1,6 +1,6 @@
import { getRepoExecutionHostId, LOCAL_EXECUTION_HOST_ID } from '../../../../shared/execution-host'
import { getRepoHostIdentity } from '../../store/slices/repo-host-identity'
import { RepositoryPane } from './RepositoryPane'
import { RepositoryPane } from './repository/RepositoryPane'
import { SettingsSection } from './SettingsSection'
import { getSettingsEntryHostSelection, getSettingsProjectHostRepo } from './settings-project-list'
import { translate } from '@/i18n/i18n'
@@ -1,4 +1,4 @@
import { getRepositoryLocalCommandsSectionId } from '@/components/settings/repository-settings-targets'
import { getRepositoryLocalCommandsSectionId } from '@/components/settings/repository/repository-settings-targets'
import type { ExecutionHostId } from '../../../../shared/execution-host'
export function openSetupScriptSettings(input: {
@@ -25,7 +25,7 @@ import {
} from '@/components/ui/dropdown-menu'
import { cn } from '@/lib/utils'
import { translate } from '@/i18n/i18n'
import { getRepositoryIconSectionId } from '@/components/settings/repository-settings-targets'
import { getRepositoryIconSectionId } from '@/components/settings/repository/repository-settings-targets'
import type { ProjectGroup } from '../../../../../../shared/project-group-types'
import type { Repo } from '../../../../../../shared/repo-types'
import type { WorktreeVisibilityDefaults } from '../../../../../../shared/global-settings-types'
@@ -3,7 +3,7 @@ import { getDeveloperPermissionsPaneSearchEntries } from '@/components/settings/
import { getExperimentalPaneSearchEntries } from '@/components/settings/experimental-search'
import { getPluginsPaneSearchEntries } from '@/components/settings/plugins-search'
import { getPrivacyPaneSearchEntries } from '@/components/settings/privacy-search'
import { getRepositoryPaneSearchEntries } from '@/components/settings/repository-search'
import { getRepositoryPaneSearchEntries } from '@/components/settings/repository/repository-search'
import { buildSettingsProjectList } from '@/components/settings/settings-project-list'
import { getSshPaneSearchEntries } from '@/components/settings/ssh-search'
import { translate } from '@/i18n/i18n'