refactor(task-page): colocate cross-provider composition owners (#33913)

This commit is contained in:
Neil
2026-10-26 04:30:52 -07:00
committed by GitHub
parent 15fc7a6769
commit 34f55ca5e1
70 changed files with 120 additions and 120 deletions
+8 -8
View File
@@ -9601,7 +9601,7 @@
"src/renderer/src/components/tab-group/useTabGroupTabCloseCommands.test.tsx": 1581,
"src/renderer/src/components/tab-group/useTabGroupWorkspaceModel.focus.test.ts": 1412,
"src/renderer/src/components/tab-group/workspace-tab-close-commands.floating-reclaim.test.ts": 1321,
"src/renderer/src/components/task-page-cache-selectors.test.ts": 76,
"src/renderer/src/components/task-page/task-page-cache-selectors.test.ts": 76,
"src/renderer/src/components/task-page-checks-pill.test.ts": 45,
"src/renderer/src/components/task-page-empty-state.test.ts": 106,
"src/renderer/src/components/task-page-jira-board-detail-integration.test.tsx": 1526,
@@ -9629,14 +9629,14 @@
"src/renderer/src/components/task-page-jira-text-fallback-notice.test.tsx": 375,
"src/renderer/src/components/task-page-jira-workspace-actions.test.tsx": 1971,
"src/renderer/src/components/task-page/task-page-list-chrome-visibility.test.ts": 33,
"src/renderer/src/components/task-page-localized-options.test.ts": 211,
"src/renderer/src/components/task-page-mutation-page-allocation.test.ts": 128,
"src/renderer/src/components/task-page-new-issue-draft.test.ts": 76,
"src/renderer/src/components/task-page/task-page-localized-options.test.ts": 211,
"src/renderer/src/components/task-page/task-page-mutation-page-allocation.test.ts": 128,
"src/renderer/src/components/task-page/task-page-new-issue-draft.test.ts": 76,
"src/renderer/src/components/task-page/task-page-pr-check-summary.test.ts": 34,
"src/renderer/src/components/task-page-repo-source-context.test.ts": 407,
"src/renderer/src/components/task-page-repo-source-divergence.test.ts": 1043,
"src/renderer/src/components/task-page-task-source-host-availability.test.ts": 401,
"src/renderer/src/components/task-page-work-item-pagination.test.ts": 56,
"src/renderer/src/components/task-page/task-page-repo-source-context.test.ts": 407,
"src/renderer/src/components/task-page/task-page-repo-source-divergence.test.ts": 1043,
"src/renderer/src/components/task-page/task-page-task-source-host-availability.test.ts": 401,
"src/renderer/src/components/task-page/task-page-work-item-pagination.test.ts": 56,
"src/renderer/src/components/task-page/github/rows-twin-host-routing.test.tsx": 1521,
"src/renderer/src/components/task-page/github/task-page-github-dialog-state-authority.test.ts": 71,
"src/renderer/src/components/task-page/github/task-page-github-list-scroll-restore.test.ts": 178,
@@ -74,8 +74,8 @@ import {
runGHEditLabelToggle,
runGHEditStateChange
} from '../../src/renderer/src/components/github-item-dialog/edit-item-fields/gh-edit-section-mutations'
import { findTaskPageDialogWorkItem } from '../../src/renderer/src/components/task-page-cache-selectors'
import { getTaskPageRepoSourceContext } from '../../src/renderer/src/components/task-page-source-context'
import { findTaskPageDialogWorkItem } from '../../src/renderer/src/components/task-page/task-page-cache-selectors'
import { getTaskPageRepoSourceContext } from '../../src/renderer/src/components/task-page/task-page-source-context'
import { workItemsCacheKey } from '../../src/renderer/src/store/github/cache-identity'
import { createTestStore } from '../../src/renderer/src/store/slices/github-slice-test-harness'
import { getTaskSourceCacheScope } from '../../src/shared/task-source-context'
@@ -18,7 +18,7 @@ import {
type TaskSourceContext
} from '../../../../shared/task-source-context'
import type { CmdJTaskSearchResult } from './task-search-results'
import { getJiraIssueWorkspaceSeed } from '../task-page-source-context'
import { getJiraIssueWorkspaceSeed } from '../task-page/task-page-source-context'
function sourceMatches(source: TaskSourceContext, target: TaskSourceContext): boolean {
if (source.provider !== target.provider || source.hostId !== target.hostId) {
@@ -21,7 +21,7 @@ import type { GlobalSettings } from '../../../../shared/global-settings-types'
import type { PaletteFilterState } from './palette-filter'
import { getTaskEligibleRepos } from '../task-page/task-page-default-repo-selection'
import { getRepoBackedProviderAvailability } from '../task-source-provider-availability'
import { getTaskPageRepoSourceContext } from '../task-page-source-context'
import { getTaskPageRepoSourceContext } from '../task-page/task-page-source-context'
import { searchJiraIssuesByKeyOrText } from '../jira-key-or-text-search'
import { bindTaskPageJiraItemSourceContext } from '../task-page-jira-item-source-context'
import { makeCmdJTaskSearchResult, type CmdJTaskSearchResult } from './task-search-results'
@@ -4,7 +4,7 @@ import {
canonicalizeLinearIssueAttributeFilter,
type LinearIssueAttributeFilter
} from '../../../shared/linear/issue-attribute-filter'
import { getLinearPriorityLabel } from './task-page-localized-options'
import { getLinearPriorityLabel } from './task-page/task-page-localized-options'
import { isLinearMetadataGroupSelectionPartial } from './linear-issue-attribute-filter-team-ids'
import type {
LinearIssueFilterGroupedOption,
@@ -12,7 +12,7 @@ import {
LINEAR_ISSUE_ATTRIBUTE_FILTER_MAX_STATE_IDS,
type LinearIssueAttributeFilter
} from '../../../shared/linear/issue-attribute-filter'
import { getLinearPriorityLabel } from './task-page-localized-options'
import { getLinearPriorityLabel } from './task-page/task-page-localized-options'
import { LinearFacetCoverageNotice } from './linear-issue-attribute-filter-coverage-notice'
import {
expandLinearMetadataGroupKeys,
@@ -16,7 +16,7 @@ import { TaskPageJiraBoard, jiraBoardIssueRefKey } from './task-page-jira-board'
import type { TaskPageJiraBoardSection } from './task-page-jira-board-sections'
import { JiraBoardMoveDialog, type JiraBoardMovePrompt } from './task-page-jira-board-move-dialog'
import { applyJiraBoardMove, getJiraBoardMoveTransitions } from './task-page-jira-board-move'
import { formatRelativeTime } from './task-page-source-context'
import { formatRelativeTime } from './task-page/task-page-source-context'
import { enqueueJiraIssueMutation, jiraIssueRequestScope } from './jira-issue-mutation-queue'
type Props = {
@@ -6,7 +6,7 @@ import { X, ExternalLink } from 'lucide-react'
import { toast } from 'sonner'
import { cn } from '@/lib/utils'
import { LinearScopeSelector } from '@/components/linear-scope-selector'
import { getGitHubProjectSourceSummary } from '../task-page-source-context'
import { getGitHubProjectSourceSummary } from './task-page-source-context'
import {
Select,
SelectTrigger,
@@ -1,5 +1,5 @@
import type { TaskPageComposerActionsModel } from '../use-task-page-composer-actions'
import { getGitHubTaskKindPresets } from '@/components/task-page-localized-options'
import { getGitHubTaskKindPresets } from '@/components/task-page/task-page-localized-options'
import { cn } from '@/lib/utils'
import PRFilterDropdowns from '@/components/github/PRFilterDropdowns'
import { Search, X, Plus, LoaderCircle, RefreshCw } from 'lucide-react'
@@ -7,11 +7,11 @@ import { Input } from '@/components/ui/input'
import { translate } from '@/i18n/i18n'
import { Tooltip, TooltipTrigger, TooltipContent } from '@/components/ui/tooltip'
import { Button } from '@/components/ui/button'
import { resolveNewIssueOpenSeed } from '@/components/task-page-new-issue-draft'
import { resolveNewIssueOpenSeed } from '@/components/task-page/task-page-new-issue-draft'
import { useAppStore } from '@/store'
import { useShallow } from 'zustand/react/shallow'
import { getGitHubRepoRoutingTarget } from '@/lib/github-source-runtime-context'
import { hasUpstreamCandidateDivergence, hasDivergentSources } from '../../task-page-draft-storage'
import { hasUpstreamCandidateDivergence, hasDivergentSources } from '../task-page-draft-storage'
import IssueSourceIndicator from '@/components/github/IssueSourceIndicator'
import IssueSourceSelector, { issueSourceChipClass } from '@/components/github/IssueSourceSelector'
import RepoBadgeLabel from '@/components/repo/RepoBadgeLabel'
@@ -20,7 +20,7 @@ import {
SelectContent,
SelectItem
} from '@/components/ui/select'
import { resolveUserRepoSwitchReset } from '@/components/task-page-new-issue-draft'
import { resolveUserRepoSwitchReset } from '@/components/task-page/task-page-new-issue-draft'
import RepoBadgeLabel from '@/components/repo/RepoBadgeLabel'
import { Input } from '@/components/ui/input'
import { GitHubMarkdownComposer } from '@/components/github/GitHubMarkdownComposer'
@@ -7,7 +7,7 @@ import {
GITHUB_TASK_STICKY_TITLE_HEADER_CLASS,
GITHUB_TASK_STICKY_ID_CELL_CLASS,
GITHUB_TASK_STICKY_TITLE_CELL_CLASS
} from '../../task-page-source-context'
} from '../task-page-source-context'
import { translate } from '@/i18n/i18n'
import { Button } from '@/components/ui/button'
import { LoaderCircle } from 'lucide-react'
@@ -25,7 +25,7 @@ import {
GITHUB_TASK_STICKY_TITLE_CELL_CLASS,
getTaskPageRepoSourceContext,
formatRelativeTime
} from '../../task-page-source-context'
} from '../task-page-source-context'
import { Tooltip, TooltipTrigger, TooltipContent } from '@/components/ui/tooltip'
import { translate } from '@/i18n/i18n'
import { TaskPageGitHubWorkItemStateBadge } from '@/components/task-page/github/task-page-github-work-item-status-badge'
@@ -6,7 +6,7 @@ import {
TASK_PAGE_GITHUB_RESUME_FRESH_MS
} from '@/components/task-page/github/task-page-github-resume-cache'
import type { GitHubWorkItem } from '../../../../../shared/github/work-item-types'
import { getTaskPageRepoSourceContext } from '../../task-page-source-context'
import { getTaskPageRepoSourceContext } from '../task-page-source-context'
import { sortWorkItemsByNumber, taskPageToGitHubApiPage } from '../../../../../shared/work-items'
import {
materializeTaskPageItemList,
@@ -15,13 +15,13 @@ import {
} from '@/components/task-page/github/task-page-github-work-item-mutation-pages'
import { clearTaskPageGitHubAuthorityThroughGeneration } from '@/components/task-page/github/task-page-github-work-item-authority-refresh'
import { getOrCreateQuietRevalidateState } from '@/components/task-page/github/task-page-github-work-item-quiet-state'
import { resolveEmptyPageOutcome } from '@/components/task-page-work-item-pagination'
import { resolveEmptyPageOutcome } from '@/components/task-page/task-page-work-item-pagination'
import {
deriveTaskPageGitHubWorkItemsFetchOptions,
shouldReplaceTaskPageItemsAfterRefresh,
shouldResetTaskPagePaginationAfterLandingRefresh,
reconcileTaskPagePagesAfterLandingRefresh
} from '@/components/task-page-cache-selectors'
} from '@/components/task-page/task-page-cache-selectors'
export function runTaskPageGitHubLandingRefresh(model: TaskPageGitHubSearchPaginationModel) {
const {
fetchWorkItemsAcrossRepos,
@@ -26,7 +26,7 @@ import {
LAG_BACKOFF_MS
} from '@/components/task-page/github/task-page-github-work-item-quiet-adopt'
import { stripRepoQualifiers } from '../../../../../shared/task-query'
import { getTaskPageRepoSourceContext } from '../../task-page-source-context'
import { getTaskPageRepoSourceContext } from '../task-page-source-context'
import type { GitHubWorkItem } from '../../../../../shared/github/work-item-types'
import { taskPageToGitHubApiPage } from '../../../../../shared/work-items'
import { useAppStore } from '@/store/index'
@@ -11,7 +11,7 @@ import {
buildTaskPageRepoSourceState,
selectTaskPageUnresolvedSourceRepos,
reconcileTaskPagePagesWithWorkItemsCache
} from '@/components/task-page-cache-selectors'
} from '@/components/task-page/task-page-cache-selectors'
import { toast } from 'sonner'
import { translate } from '@/i18n/i18n'
export function useTaskPageGitHubCacheReconciliation(model: TaskPageGitHubDetailModel) {
@@ -8,13 +8,13 @@ import { useShallow } from 'zustand/react/shallow'
import {
selectTaskPageWorkItemsCacheEntries,
findTaskPageDialogWorkItem
} from '@/components/task-page-cache-selectors'
} from '@/components/task-page/task-page-cache-selectors'
import type { GitHubWorkItem } from '../../../../../shared/github/work-item-types'
import type { GitLabWorkItem } from '../../../../../shared/gitlab-types'
import {
getTaskPageRepoCacheInput,
getTaskPageRepoSourceContext
} from '../../task-page-source-context'
} from '../task-page-source-context'
import { startGitHubListScrollRestore } from './task-page-github-list-scroll-restore'
function getTaskPageScrollTop(
@@ -7,8 +7,8 @@ import { useRepoLabels, useRepoAssignees } from '@/hooks/useGitHubRepoMetadata'
import {
resolveVanishedNewIssueRepoReset,
isNewIssueDraftContentful
} from '@/components/task-page-new-issue-draft'
import { getTaskPageRepoSourceContext } from '../../task-page-source-context'
} from '@/components/task-page/task-page-new-issue-draft'
import { getTaskPageRepoSourceContext } from '../task-page-source-context'
export function useTaskPageGitHubIssueDraft(model: TaskPageGitHubCacheReconciliationModel) {
const { settings, repos, selectedRepos } = model
const [newIssueOpen, setNewIssueOpen] = useState(false)
@@ -4,13 +4,13 @@ import { useCallback, useMemo, useEffect } from 'react'
import type { GitHubWorkItem } from '../../../../../shared/github/work-item-types'
import { taskPageGitHubItemKey } from '@/components/task-page/github/task-page-github-work-item-mutation-keys'
import { deriveTaskPagePRCheckSummary } from '../task-page-pr-check-summary'
import { deriveAdvertisedTotalPages } from '@/components/task-page-work-item-pagination'
import { deriveAdvertisedTotalPages } from '@/components/task-page/task-page-work-item-pagination'
import {
GITHUB_PR_TASK_GRID_CLASS,
GITHUB_TASK_GRID_CLASS,
PR_CHECKS_EAGER_PREFETCH_LIMIT,
getTaskPageRepoSourceContext
} from '../../task-page-source-context'
} from '../task-page-source-context'
import { sameOptionalGitHubOwnerRepo } from './task-page-github-review-model'
export function useTaskPageGitHubListProjection(model: TaskPageJiraCreationMetadataModel) {
const {
@@ -14,7 +14,7 @@ import {
} from '@/components/task-page/github/task-page-github-resume-cache'
import { useAppStore } from '@/store/index'
import type { GitHubListRestoreWrite } from './task-page-github-list-scroll-restore'
import { getTaskPageRepoSourceContext } from '../../task-page-source-context'
import { getTaskPageRepoSourceContext } from '../task-page-source-context'
export function useTaskPageGitHubListState(model: TaskPageProviderStateModel) {
const {
pageData,
@@ -12,7 +12,7 @@ import { useAppStore } from '@/store/index'
import { useTaskPageGitHubWorkItemMutation } from '@/hooks/useTaskPageGitHubWorkItemMutation'
import { rebuildSoftHiddenKeysFromPendingAndSticky } from '@/components/task-page/github/task-page-github-work-item-mutation-composition'
import { buildGitHubRepoUrl } from '../../../../../shared/github/links'
import { getTaskPageRepoSourceContext } from '../../task-page-source-context'
import { getTaskPageRepoSourceContext } from '../task-page-source-context'
export function useTaskPageGitHubMutationState(model: TaskPageLinearCreationStateModel) {
const {
selectedRepos,
@@ -6,13 +6,13 @@ import {
resolveEmptyPageOutcome,
applyWindowPageLimit,
applyEmptyPageClamp
} from '@/components/task-page-work-item-pagination'
} from '@/components/task-page/task-page-work-item-pagination'
import { toast } from 'sonner'
import { translate } from '@/i18n/i18n'
import { overlayPendingOnTaskPagePages } from '@/components/task-page/github/task-page-github-work-item-mutation-pages'
import { scopeGitHubTaskSearch } from '../../../../../shared/task-github-search'
import { useGitHubTaskSearchCommit } from '@/components/use-github-task-search-commit'
import { getTaskPageRepoSourceContext } from '../../task-page-source-context'
import { getTaskPageRepoSourceContext } from '../task-page-source-context'
export function useTaskPageGitHubSearchPagination(model: TaskPageGitHubListProjectionModel) {
const {
setTaskResumeState,
@@ -1,5 +1,5 @@
import { describe, expect, it, afterEach, vi } from 'vitest'
import { isGitLabIssueFilter, isGitLabMRFilter } from '../../task-page-source-context'
import { isGitLabIssueFilter, isGitLabMRFilter } from '../task-page-source-context'
describe('isGitLabMRFilter', () => {
it('accepts MR statuses including all', () => {
@@ -10,7 +10,7 @@ import {
getTaskPageRepoSourceContext,
isGitLabIssueFilter,
isGitLabMRFilter
} from '../../task-page-source-context'
} from '../task-page-source-context'
// Leave headroom below the runtime RPC foreground concurrency of eight for sidebar and other callers.
export const GITLAB_TASK_FETCH_CONCURRENCY = 6
@@ -13,7 +13,7 @@ import { TaskPageJiraTextFallbackNotice } from '../../task-page-jira-text-fallba
import { TaskPageJiraIssueList } from '@/components/task-page-jira-issue-list'
import { TaskPageJiraBoardView } from '@/components/task-page-jira-board-view'
import { TaskPageJiraViewControls } from '@/components/task-page-jira-view-controls'
import { formatRelativeTime } from '../../task-page-source-context'
import { formatRelativeTime } from '../task-page-source-context'
import { getJiraStatusTone } from '@/components/task-page-jira-status-tone'
import JiraIssueWorkspace from '@/components/JiraIssueWorkspace'
import { TaskPageLinearContent } from '../linear/Content'
@@ -1,7 +1,7 @@
import type { TaskPageComposerActionsModel } from '../use-task-page-composer-actions'
import LinearIssueWorkspace from '@/components/LinearIssueWorkspace'
import { LoaderCircle } from 'lucide-react'
import { LinearIcon } from '@/components/task-page-localized-options'
import { LinearIcon } from '@/components/task-page/task-page-localized-options'
import { translate } from '@/i18n/i18n'
import { Button } from '@/components/ui/button'
import { TaskPageLinearProjectOverview } from './ProjectOverview'
@@ -5,13 +5,13 @@ import {
shouldOfferLinearIssueFetchMore
} from './task-page-linear-issue-empty-state'
import { Button } from '@/components/ui/button'
import { LinearIcon } from '@/components/task-page-localized-options'
import { LinearIcon } from '@/components/task-page/task-page-localized-options'
import { isIntegrationCredentialDecryptionError } from '../../../../../shared/integration-credential-errors'
import {
clampLinearIssueListLimit,
LINEAR_ISSUE_LIST_MAX
} from '../../../../../shared/linear/issue-read-limits'
import { LINEAR_ITEM_LIMIT } from '../../task-page-source-context'
import { LINEAR_ITEM_LIMIT } from '../task-page-source-context'
import { TaskPageLinearIssueBoardColumns } from './IssueBoardColumns'
import { TaskPageLinearIssueTable } from './IssueTable'
export function TaskPageLinearIssueBoard({
@@ -8,7 +8,7 @@ import { Button } from '@/components/ui/button'
import { translate } from '@/i18n/i18n'
import { FolderOpen, ArrowRight, ExternalLink } from 'lucide-react'
import { LinearStateCell } from './task-page-linear-issue-model'
import { formatRelativeTime } from '../../task-page-source-context'
import { formatRelativeTime } from '../task-page-source-context'
export function TaskPageLinearIssueBoardColumns({
model
}: {
@@ -7,7 +7,7 @@ import { LinearPriorityIcon } from '@/components/linear-priority-icon'
import { LinearStateCell } from './task-page-linear-issue-model'
import { translate } from '@/i18n/i18n'
import { Tooltip, TooltipTrigger, TooltipContent } from '@/components/ui/tooltip'
import { formatRelativeTime } from '../../task-page-source-context'
import { formatRelativeTime } from '../task-page-source-context'
import { Button } from '@/components/ui/button'
export function TaskPageLinearIssueTable({
model
@@ -18,7 +18,7 @@ import type {
LinearViewMode,
LinearGroupBy,
LinearOrderBy
} from '@/components/task-page-localized-options'
} from '../../../../../shared/linear/issue-view-resume-state'
export function TaskPageLinearIssueToolbar({
model
}: {
@@ -3,7 +3,7 @@ import type { TaskPageComposerActionsModel } from '../use-task-page-composer-act
import { translate } from '@/i18n/i18n'
import { Popover, PopoverTrigger, PopoverContent } from '@/components/ui/popover'
import { LinearPriorityIcon } from '@/components/linear-priority-icon'
import { getLinearPriorityLabel } from '@/components/task-page-localized-options'
import { getLinearPriorityLabel } from '@/components/task-page/task-page-localized-options'
import { ChevronDown, Check, UserRound, LoaderCircle, Users, Tag, Clock3 } from 'lucide-react'
import { cn } from '@/lib/utils'
export function TaskPageLinearProjectFields({
@@ -1,7 +1,7 @@
import type { CacheEntry } from '@/store/github/cache-model'
import type { LinearIssue } from '../../../../../shared/linear/issue-types'
import type { LinearCollectionResult } from '../../../../../shared/linear/workspace-types'
import { sortedStrings } from '../../task-page-work-item-signatures'
import { sortedStrings } from '../task-page-work-item-signatures'
type LinearIssueCache = Record<string, CacheEntry<LinearIssue>>
type LinearSearchCache = Record<string, CacheEntry<LinearIssue[]>>
@@ -1,6 +1,6 @@
import type { LinearIssue } from '../../../../../shared/linear/issue-types'
import type { GitHubWorkItem } from '../../../../../shared/github/work-item-types'
import { getLinearPriorityLabel } from '@/components/task-page-localized-options'
import { getLinearPriorityLabel } from '@/components/task-page/task-page-localized-options'
import type {
LinearOrderBy,
LinearGroupBy,
@@ -1,6 +1,6 @@
import type { TaskPageLinearInOrcaEffectsModel } from './use-task-page-linear-in-orca-effects'
import { useEffect } from 'react'
import { LINEAR_ITEM_LIMIT } from '../../task-page-source-context'
import { LINEAR_ITEM_LIMIT } from '../task-page-source-context'
import { useTaskSearchDebouncedApply } from '../use-task-search-debounced-apply'
import { clampLinearIssueListLimit } from '../../../../../shared/linear/issue-read-limits'
import { useTaskPageLinearCustomViewEffects } from './use-task-page-linear-custom-view-effects'
@@ -2,7 +2,7 @@ import { useCallback } from 'react'
import { toast } from 'sonner'
import { translate } from '@/i18n/i18n'
import type { LinearMode } from '@/components/task-page-localized-options'
import type { LinearMode } from '@/components/task-page/task-page-localized-options'
import type { LinearCollectionResult } from '../../../../../shared/linear/workspace-types'
import type { LinearIssue } from '../../../../../shared/linear/issue-types'
import type {
@@ -10,7 +10,7 @@ import type {
LinearProjectSummary
} from '../../../../../shared/linear/project-types'
import { LINEAR_ITEM_LIMIT } from '../../task-page-source-context'
import { LINEAR_ITEM_LIMIT } from '../task-page-source-context'
import type { TaskPageLinearContextStatePreludeModel } from './use-task-page-linear-context-state'
export function useTaskPageLinearContextActions(model: TaskPageLinearContextStatePreludeModel) {
@@ -6,7 +6,7 @@ import type {
LinearCustomViewSummary,
LinearProjectSummary
} from '../../../../../shared/linear/project-types'
import { LINEAR_ITEM_LIMIT } from '../../task-page-source-context'
import { LINEAR_ITEM_LIMIT } from '../task-page-source-context'
import { useTaskPageLinearContextActions } from './use-task-page-linear-context-actions'
export function useTaskPageLinearContextStatePrelude(model: TaskPageLinearViewStatePreludeModel) {
const [linearCustomViewsResult, setLinearCustomViewsResult] = useState<
@@ -4,7 +4,7 @@ import { useTeamMembers, useTeamLabels, useTeamStates } from '@/hooks/useIssueMe
import { useTaskCreationDraftRetention } from '@/components/use-task-creation-draft-retention'
import { useNewLinearIssueProjects } from '../../use-new-linear-issue-projects'
import { useContextualTour } from '@/components/contextual-tours/use-contextual-tour'
import { writeNewLinearIssueDraft, writeNewLinearProjectDraft } from '../../task-page-draft-storage'
import { writeNewLinearIssueDraft, writeNewLinearProjectDraft } from '../task-page-draft-storage'
import { defaultScopeSource } from '@/lib/default-creation-host'
export function useTaskPageLinearCreationState(model: TaskPageJiraListProjectionModel) {
const {
@@ -4,7 +4,7 @@ import {
LINEAR_CUSTOM_VIEW_MODELS,
mergeLinearCollectionResults
} from './task-page-linear-issue-model'
import { LINEAR_ITEM_LIMIT } from '../../task-page-source-context'
import { LINEAR_ITEM_LIMIT } from '../task-page-source-context'
import type { LinearCollectionResult } from '../../../../../shared/linear/workspace-types'
import type { LinearIssue } from '../../../../../shared/linear/issue-types'
import type {
@@ -6,7 +6,7 @@ import {
linearIssueAttributeFilterSignature
} from '../../../../../shared/linear/issue-attribute-filter'
import { setLinearWorkspaceIssueFilter } from '../../../../../shared/linear/issue-view-resume-state'
import { LINEAR_ITEM_LIMIT } from '../../task-page-source-context'
import { LINEAR_ITEM_LIMIT } from '../task-page-source-context'
import {
type LinearPrimaryTeamObservation,
shouldClearTeamDerivedFacets,
@@ -17,7 +17,7 @@ import type { LinearIssue } from '../../../../../shared/linear/issue-types'
import type { LinearCollectionResult } from '../../../../../shared/linear/workspace-types'
import { linearIssueAttributeFilterSignature } from '../../../../../shared/linear/issue-attribute-filter'
import { reconcileTaskPageLinearIssuesAfterLandingRefresh } from './task-page-linear-cache-selectors'
import { LINEAR_ITEM_LIMIT } from '../../task-page-source-context'
import { LINEAR_ITEM_LIMIT } from '../task-page-source-context'
import { useTaskSearchDebouncedApply } from '../use-task-search-debounced-apply'
export function useTaskPageLinearListEffects(model: TaskPageGlobalEffectsModel) {
const {
@@ -6,7 +6,7 @@ import {
LINEAR_ISSUE_LIST_MAX
} from '../../../../../shared/linear/issue-read-limits'
import { compareLinearIssues } from './task-page-linear-jira-list-model'
import { LINEAR_ITEM_LIMIT } from '../../task-page-source-context'
import { LINEAR_ITEM_LIMIT } from '../task-page-source-context'
import { useTaskPageLinearListPresentation } from './use-task-page-linear-list-presentation'
export function useTaskPageLinearListProjectionPrelude(model: TaskPageLinearListSelectionModel) {
const {
@@ -1,6 +1,6 @@
import type { TaskPageDetailRoutingModel } from '../use-task-page-detail-routing'
import { useState, useMemo, useRef } from 'react'
import type { LinearMode } from '@/components/task-page-localized-options'
import type { LinearMode } from '@/components/task-page/task-page-localized-options'
import {
type LinearViewMode,
type LinearGroupBy,
@@ -18,7 +18,7 @@ import type {
LinearProjectSummary,
LinearProjectDetail
} from '../../../../../shared/linear/project-types'
import { LINEAR_ITEM_LIMIT } from '../../task-page-source-context'
import { LINEAR_ITEM_LIMIT } from '../task-page-source-context'
import type { LinearIssueAttributeFilter } from '../../../../../shared/linear/issue-attribute-filter'
import type {
LinearIssueListFilterRead,
@@ -3,9 +3,9 @@ import { shallow } from 'zustand/shallow'
import { workItemsCacheKey } from '@/store/github/cache-identity'
import type { CacheEntry } from '@/store/github/cache-model'
import type { GitHubWorkItem } from '../../../shared/github/work-item-types'
import type { LinearIssue } from '../../../shared/linear/issue-types'
import type { LinearCollectionResult } from '../../../shared/linear/workspace-types'
import type { GitHubWorkItem } from '../../../../shared/github/work-item-types'
import type { LinearIssue } from '../../../../shared/linear/issue-types'
import type { LinearCollectionResult } from '../../../../shared/linear/workspace-types'
import {
buildTaskPageRepoSourceState,
selectTaskPageUnresolvedSourceRepos,
@@ -21,7 +21,7 @@ import {
import {
findTaskPageLinearIssue,
reconcileTaskPageLinearIssuesAfterLandingRefresh
} from './task-page/linear/task-page-linear-cache-selectors'
} from './linear/task-page-linear-cache-selectors'
function entry<T>(data: T): CacheEntry<T> {
return { data, fetchedAt: 1 }
@@ -1,11 +1,11 @@
import { workItemsCacheKey } from '@/store/github/cache-identity'
import { getRepoExecutionHostId, type ExecutionHostId } from '../../../shared/execution-host'
import { getRepoExecutionHostId, type ExecutionHostId } from '../../../../shared/execution-host'
import type {
CacheEntry,
WorkItemsCacheError,
WorkItemsCacheSources
} from '@/store/github/cache-model'
import type { GitHubWorkItem } from '../../../shared/github/work-item-types'
import type { GitHubWorkItem } from '../../../../shared/github/work-item-types'
import {
taskPageWorkItemKey,
taskPageWorkItemStatusSignature,
@@ -1,5 +1,5 @@
import type { TaskPageRepoSourceState } from '@/components/task-page-cache-selectors'
import type { GitHubOwnerRepo } from '../../../shared/github/pull-request-types'
import type { TaskPageRepoSourceState } from '@/components/task-page/task-page-cache-selectors'
import type { GitHubOwnerRepo } from '../../../../shared/github/pull-request-types'
import { sameGitHubOwnerRepo } from '@/components/github/IssueSourceIndicator'
import {
type NewLinearProjectDraft,
@@ -7,7 +7,7 @@ import {
type NewLinearIssueDraft,
type NewJiraIssueDraft
} from '@/store/slices/task-creation-drafts'
import { useAppStore } from '@/store'
import { useAppStore } from '@/store/index'
export const hasDivergentSources = (
s: TaskPageRepoSourceState
): s is TaskPageRepoSourceState & {
@@ -13,10 +13,10 @@ import {
type LinearGroupBy,
type LinearOrderBy,
type LinearViewMode
} from '../../../shared/linear/issue-view-resume-state'
import { getTaskPresetQuery } from '../../../shared/task-preset-query'
import type { TaskProvider } from '../../../shared/task-providers'
import type { TaskViewPresetId } from '../../../shared/ui-chrome-types'
} from '../../../../shared/linear/issue-view-resume-state'
import { getTaskPresetQuery } from '../../../../shared/task-preset-query'
import type { TaskProvider } from '../../../../shared/task-providers'
import type { TaskViewPresetId } from '../../../../shared/ui-chrome-types'
export type GitLabTaskFilter = 'opened' | 'merged' | 'closed' | 'all'
export type GitLabIssueFilter = 'opened' | 'assigned-to-me'
@@ -42,12 +42,6 @@ export type JiraPreset = { id: JiraPresetId; label: string }
export type GitHubModeButton = { id: GitHubTaskKind | 'project'; label: string }
export type LinearMode = 'issues' | 'projects' | 'views' | 'in-orca'
export type {
LinearDisplayProperty,
LinearGroupBy,
LinearOrderBy,
LinearViewMode
} from '../../../shared/linear/issue-view-resume-state'
export function LinearIcon({ className }: { className?: string }): React.JSX.Element {
return (
@@ -1,6 +1,6 @@
import { expect, it } from 'vitest'
import type { GitHubWorkItem } from '../../../shared/github/work-item-types'
import { patchTaskPageGitHubWorkItemPages } from './task-page/github/task-page-github-work-item-mutation-pages'
import type { GitHubWorkItem } from '../../../../shared/github/work-item-types'
import { patchTaskPageGitHubWorkItemPages } from './github/task-page-github-work-item-mutation-pages'
function item(id: string): GitHubWorkItem {
return {
@@ -6,7 +6,7 @@ import {
resolveVanishedNewIssueRepoReset
} from './task-page-new-issue-draft'
import type { NewIssueDraft } from '@/store/slices/new-issue-draft'
import type { GitHubAssignableUser } from '../../../shared/github/pull-request-types'
import type { GitHubAssignableUser } from '../../../../shared/github/pull-request-types'
const assignee: GitHubAssignableUser = { login: 'octocat', name: 'Octo', avatarUrl: '' }
@@ -1,4 +1,4 @@
import type { GitHubAssignableUser } from '../../../shared/github/pull-request-types'
import type { GitHubAssignableUser } from '../../../../shared/github/pull-request-types'
import type { NewIssueDraft } from '@/store/slices/new-issue-draft'
export type NewIssueOpenSeed = {
@@ -1,6 +1,6 @@
import { describe, expect, it, afterEach, vi } from 'vitest'
import { buildGitLabProviderIdentity, getTaskPageRepoCacheInput } from './task-page-source-context'
import type { Repo } from '../../../shared/repo-types'
import type { Repo } from '../../../../shared/repo-types'
describe('buildGitLabProviderIdentity', () => {
it('splits namespace and project and builds the web URL', () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest'
import type { TaskPageRepoSourceState } from '@/components/task-page-cache-selectors'
import type { TaskPageRepoSourceState } from '@/components/task-page/task-page-cache-selectors'
import { hasDivergentSources, hasUpstreamCandidateDivergence } from './task-page-draft-storage'
function state(
@@ -1,24 +1,27 @@
import type { GitLabTaskFilter, GitLabIssueFilter } from '@/components/task-page-localized-options'
import type { GitHubWorkItem } from '../../../shared/github/work-item-types'
import type { GitLabProjectRef, GitLabWorkItem } from '../../../shared/gitlab-types'
import type { JiraIssue } from '../../../shared/jira/jira-types'
import type { Repo } from '../../../shared/repo-types'
import type {
GitLabTaskFilter,
GitLabIssueFilter
} from '@/components/task-page/task-page-localized-options'
import type { GitHubWorkItem } from '../../../../shared/github/work-item-types'
import type { GitLabProjectRef, GitLabWorkItem } from '../../../../shared/gitlab-types'
import type { JiraIssue } from '../../../../shared/jira/jira-types'
import type { Repo } from '../../../../shared/repo-types'
import { getLinkedWorkItemWorkspaceName, getLinkedWorkItemSuggestedName } from '@/lib/new-workspace'
import { getJiraIssueKeyCasingSeedOptions } from '@/lib/jira-issue-key-casing'
import {
type TaskSourceContext,
normalizeTaskSourceContext,
getTaskSourceCacheScope
} from '../../../shared/task-source-context'
import { projectHostSetupProjectionFromRepos } from '../../../shared/project-host-setup-projection'
import { getRepoExecutionHostId } from '../../../shared/execution-host'
import type { ExecutionHostRegistryEntry } from '../../../shared/execution-host-registry'
} from '../../../../shared/task-source-context'
import { projectHostSetupProjectionFromRepos } from '../../../../shared/project-host-setup-projection'
import { getRepoExecutionHostId } from '../../../../shared/execution-host'
import type { ExecutionHostRegistryEntry } from '../../../../shared/execution-host-registry'
import {
getAccountBackedTaskSourceSummary,
type TaskSourceContextSummary,
type TaskSourceHostAvailability
} from './task-source-context-summary'
import { TASK_SOURCE_CONTEXT_RUNTIME_CAPABILITY } from '../../../shared/protocol-version'
} from '../task-source-context-summary'
import { TASK_SOURCE_CONTEXT_RUNTIME_CAPABILITY } from '../../../../shared/protocol-version'
import { cn } from '@/lib/utils'
import { formatUiRelativeTimeFromDate } from '@/i18n/relative-time-format'
export function isGitLabMRFilter(
@@ -1,6 +1,6 @@
import { describe, expect, it, afterEach, vi } from 'vitest'
import { TASK_SOURCE_CONTEXT_RUNTIME_CAPABILITY } from '../../../shared/protocol-version'
import type { ExecutionHostRegistryEntry } from '../../../shared/execution-host-registry'
import { TASK_SOURCE_CONTEXT_RUNTIME_CAPABILITY } from '../../../../shared/protocol-version'
import type { ExecutionHostRegistryEntry } from '../../../../shared/execution-host-registry'
import {
getGitHubProjectSourceSummary,
getTaskSourceHostAvailabilityForHost
@@ -1,5 +1,5 @@
import { describe, expect, it, vi } from 'vitest'
import type { GitHubWorkItem } from '../../../shared/github/work-item-types'
import type { GitHubWorkItem } from '../../../../shared/github/work-item-types'
import {
accumulateWorkItemPages,
applyEmptyPageClamp,
@@ -1,5 +1,5 @@
import type { ClassifiedError } from '../../../shared/classified-error'
import type { GitHubWorkItem } from '../../../shared/github/work-item-types'
import type { ClassifiedError } from '../../../../shared/classified-error'
import type { GitHubWorkItem } from '../../../../shared/github/work-item-types'
/** Inclusive updatedAt cursors preserve timestamp ties; dedup boundary rows and backfill full display pages, flushing partials on exhaustion/stall. */
@@ -1,4 +1,4 @@
import type { GitHubWorkItem } from '../../../shared/github/work-item-types'
import type { GitHubWorkItem } from '../../../../shared/github/work-item-types'
// Why the host: a twin's two hosts return the same PR under one repo id.
export function taskPageWorkItemKey(item: GitHubWorkItem): string {
@@ -12,7 +12,7 @@ import { translate } from '@/i18n/i18n'
import { bindTaskPageJiraItemSourceContext } from '../task-page-jira-item-source-context'
import type { LinkedWorkItemSummary } from '@/lib/new-workspace'
import { shouldHideTaskPageListChrome } from './task-page-list-chrome-visibility'
import { getJiraIssueWorkspaceSeed } from '../task-page-source-context'
import { getJiraIssueWorkspaceSeed } from './task-page-source-context'
import { findJiraIssueDefaultRepo } from '../../../../shared/jira/jira-project-reference'
import { getRepoWorkspaceCreationTargetHint } from '@/lib/project-host-workspace-target'
export function useTaskPageComposerActions(model: TaskPageJiraListEffectsModel) {
@@ -1,10 +1,13 @@
import type { TaskPageSourceAvailabilityModel } from './use-task-page-source-availability'
import { useRef, useState, useEffect, useMemo } from 'react'
import { resolveVisibleTaskProvider } from '../../../../shared/task-providers'
import type { GitLabTaskFilter, GitLabIssueFilter } from '@/components/task-page-localized-options'
import type {
GitLabTaskFilter,
GitLabIssueFilter
} from '@/components/task-page/task-page-localized-options'
import type { GitLabWorkItem, GitLabTodo } from '../../../../shared/gitlab-types'
import { getRepoBackedTaskEmptyState } from './task-page-empty-state'
import { isGitLabIssueFilter, isGitLabMRFilter } from '../task-page-source-context'
import { isGitLabIssueFilter, isGitLabMRFilter } from './task-page-source-context'
export function useTaskPageProviderState(model: TaskPageSourceAvailabilityModel) {
const {
settings,
@@ -7,7 +7,7 @@ import {
getTaskProjectPickerGroups
} from '@/components/task-page/task-page-default-repo-selection'
import { areStringSetsEqual } from '@/components/task-page/task-page-string-set-equality'
import { buildSelectedReposKey } from '@/components/task-page-work-item-pagination'
import { buildSelectedReposKey } from '@/components/task-page/task-page-work-item-pagination'
import {
normalizeVisibleTaskProviders,
restoreAvailableDefaultTaskProvider,
@@ -25,10 +25,10 @@ import {
getLinearGroupOptions,
getLinearOrderOptions,
getLinearDisplayProperties
} from '@/components/task-page-localized-options'
} from '@/components/task-page/task-page-localized-options'
import { toast } from 'sonner'
import { translate } from '@/i18n/i18n'
import { getTaskPageRepoSourceContext } from '../task-page-source-context'
import { getTaskPageRepoSourceContext } from './task-page-source-context'
export function useTaskPageRepoSelection(model: TaskPageStoreBindingsModel) {
const {
settings,
@@ -11,7 +11,7 @@ import { parseExecutionHostId } from '../../../../shared/execution-host'
import { TASK_SOURCE_CONTEXT_RUNTIME_CAPABILITY } from '../../../../shared/task-source-runtime-capabilities'
import { callRuntimeRpc } from '@/runtime/runtime-rpc-client'
import type { PreflightStatus } from '../../../../preload/api/preflight-api'
import { getTaskPageRepoSourceContext } from '../task-page-source-context'
import { getTaskPageRepoSourceContext } from './task-page-source-context'
export function useTaskPageRuntimeHosts(model: TaskPageRepoSelectionModel) {
const {
settings,
@@ -9,7 +9,7 @@ import { withQualifier } from '../../../../shared/task-query'
import type { TaskViewPresetId } from '../../../../shared/ui-chrome-types'
import { toast } from 'sonner'
import { translate } from '@/i18n/i18n'
import type { GitHubTaskKind } from '@/components/task-page-localized-options'
import type { GitHubTaskKind } from '@/components/task-page/task-page-localized-options'
import { getTaskPresetQuery } from '../../../../shared/task-preset-query'
import { shouldSuppressEnterSubmit } from '@/lib/new-workspace-enter-guard'
import { addAppKeyListener, removeAppKeyListener } from '@/lib/app-keyboard-router'
@@ -5,7 +5,7 @@ import type { Repo } from '../../../../shared/repo-types'
import {
getTaskPageRepoSourceContext,
getTaskSourceHostAvailabilityForHost
} from '../task-page-source-context'
} from './task-page-source-context'
import type { TaskSourceHostAvailability } from '../task-source-context-summary'
import { getRepoBackedProviderAvailability } from '@/components/task-source-provider-availability'
import { getSettingsFocusedExecutionHostId } from '../../../../shared/execution-host'
@@ -9,7 +9,7 @@ import type { TaskSourceContext } from '../../../../shared/task-source-context'
import {
getTaskSourceHostAvailabilityForHost,
getTaskPageRepoSourceContext
} from '../task-page-source-context'
} from './task-page-source-context'
import { getRepoBackedProviderAvailability } from '@/components/task-source-provider-availability'
import {
getTaskSourceAvailabilityNotice,
@@ -13,7 +13,7 @@ import {
getGitHubWorkItemWorkspaceSeed,
getGitLabWorkItemWorkspaceSeed,
getTaskPageRepoSourceContext
} from '../task-page-source-context'
} from './task-page-source-context'
export function useTaskPageWorkspaceActions(model: TaskPageSearchActionsModel) {
const { repos, openModal } = model
const openComposerForItem = useCallback(
@@ -1,5 +1,5 @@
import { useEffect } from 'react'
import { TASK_SEARCH_DEBOUNCE_MS } from '../task-page-source-context'
import { TASK_SEARCH_DEBOUNCE_MS } from './task-page-source-context'
/** Applies a task search input after the shared debounce, once resume state has landed. */
export function useTaskSearchDebouncedApply(
@@ -2,7 +2,7 @@ import type { TaskPageGitHubMutationStateModel } from './task-page/github/use-ta
import { useState, useRef, useEffect } from 'react'
import type { JiraIssueType, JiraCreateField } from '../../../shared/jira/jira-types'
import { useTaskCreationDraftRetention } from '@/components/use-task-creation-draft-retention'
import { writeNewJiraIssueDraft } from './task-page-draft-storage'
import { writeNewJiraIssueDraft } from './task-page/task-page-draft-storage'
import { useTaskPageJiraCreationProjects } from './use-task-page-jira-creation-projects'
export function useTaskPageJiraCreationStatePrelude(model: TaskPageGitHubMutationStateModel) {
const {
@@ -15,7 +15,7 @@ import {
} from '@/components/task-page-jira-status-order'
import { createTaskPageJiraLoadFailureState } from '@/components/task-page-jira-load-state'
import { searchTaskPageJiraIssues } from '@/components/task-page-jira-search'
import { JIRA_ITEM_LIMIT } from './task-page-source-context'
import { JIRA_ITEM_LIMIT } from './task-page/task-page-source-context'
import { useTaskSearchDebouncedApply } from './task-page/use-task-search-debounced-apply'
import { readLinkedJiraIssues } from './task-page-jira-linked-issues'
import { ipcOrRuntimeTargetForHostId } from '@/runtime/runtime-client-target'
@@ -13,7 +13,7 @@ import type {
} from '../../../shared/jira/jira-types'
import type { TaskPageJiraLoadError } from '@/components/task-page-jira-load-state'
import type { TaskPageJiraJqlRejection } from '@/components/task-page-jira-search'
import type { JiraPresetId } from '@/components/task-page-localized-options'
import type { JiraPresetId } from '@/components/task-page/task-page-localized-options'
import type {
JiraIssueSortColumn,
JiraIssueSortDirection,
@@ -1,6 +1,6 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { createTestStore, mockApi, resetRemoteRuntimeMocks } from './github-slice-test-harness'
import { selectTaskPageWorkItemsCacheEntries } from '../../components/task-page-cache-selectors'
import { selectTaskPageWorkItemsCacheEntries } from '../../components/task-page/task-page-cache-selectors'
import type { GitHubWorkItem } from '../../../../shared/github/work-item-types'
import type { Repo } from '../../../../shared/repo-types'
@@ -6,8 +6,8 @@ import {
type RuntimeEnvironmentCallRequest
} from '../../runtime/runtime-compatibility-test-fixture'
import { clearRuntimeCompatibilityCacheForTests } from '../../runtime/runtime-rpc-client'
import { buildTaskPageRepoSourceState } from '../../components/task-page-cache-selectors'
import { getTaskPageRepoCacheInput } from '../../components/task-page-source-context'
import { buildTaskPageRepoSourceState } from '../../components/task-page/task-page-cache-selectors'
import { getTaskPageRepoCacheInput } from '../../components/task-page/task-page-source-context'
const localTwin: Repo = {
id: 'twin',