mirror of
https://github.com/stablyai/orca.git
synced 2026-10-21 00:03:46 +00:00
Extract GitHub task search commit debouncing into a hook
Move debounce logic from TaskPage into useGitHubTaskSearchCommit to prevent excessive GitHub API calls on every keystroke. Uses a 750ms idle window before committing search values. Add tests for the new hook.
This commit is contained in:
@@ -431,6 +431,7 @@ import {
|
||||
type LinearOrderBy,
|
||||
type LinearViewMode
|
||||
} from '@/components/task-page-localized-options'
|
||||
import { useGitHubTaskSearchCommit } from '@/components/use-github-task-search-commit'
|
||||
|
||||
function isGitLabMRFilter(value: GitLabTaskFilter | GitLabIssueFilter): value is GitLabTaskFilter {
|
||||
return value === 'opened' || value === 'merged' || value === 'closed' || value === 'all'
|
||||
@@ -6533,19 +6534,21 @@ export default function TaskPage(): React.JSX.Element {
|
||||
]
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (!taskResumeApplied) {
|
||||
return
|
||||
}
|
||||
const timeout = window.setTimeout(() => {
|
||||
const scoped = scopeGitHubTaskSearch(taskSearchInput, activeGithubTaskKind)
|
||||
const commitTaskSearch = useCallback(
|
||||
(value: string): void => {
|
||||
const scoped = scopeGitHubTaskSearch(value, activeGithubTaskKind)
|
||||
if (scoped !== appliedTaskSearch) {
|
||||
setTasksFiltering(true)
|
||||
}
|
||||
setAppliedTaskSearch(scoped)
|
||||
}, TASK_SEARCH_DEBOUNCE_MS)
|
||||
return () => window.clearTimeout(timeout)
|
||||
}, [activeGithubTaskKind, appliedTaskSearch, taskSearchInput, taskResumeApplied])
|
||||
},
|
||||
[activeGithubTaskKind, appliedTaskSearch]
|
||||
)
|
||||
useGitHubTaskSearchCommit({
|
||||
enabled: taskResumeApplied,
|
||||
onCommit: commitTaskSearch,
|
||||
value: taskSearchInput
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
if (!taskResumeApplied) {
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
// @vitest-environment happy-dom
|
||||
|
||||
import { act, renderHook } from '@testing-library/react'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import {
|
||||
GITHUB_TASK_SEARCH_IDLE_MS,
|
||||
useGitHubTaskSearchCommit
|
||||
} from './use-github-task-search-commit'
|
||||
|
||||
describe('useGitHubTaskSearchCommit', () => {
|
||||
beforeEach(() => vi.useFakeTimers())
|
||||
afterEach(() => vi.useRealTimers())
|
||||
|
||||
it('commits only the final value after a full idle window', () => {
|
||||
const onCommit = vi.fn()
|
||||
const view = renderHook(
|
||||
({ value }) => useGitHubTaskSearchCommit({ enabled: true, onCommit, value }),
|
||||
{ initialProps: { value: 'r' } }
|
||||
)
|
||||
|
||||
act(() => vi.advanceTimersByTime(400))
|
||||
view.rerender({ value: 'ra' })
|
||||
act(() => vi.advanceTimersByTime(400))
|
||||
view.rerender({ value: 'rate' })
|
||||
act(() => vi.advanceTimersByTime(GITHUB_TASK_SEARCH_IDLE_MS - 1))
|
||||
|
||||
expect(onCommit).not.toHaveBeenCalled()
|
||||
|
||||
act(() => vi.advanceTimersByTime(1))
|
||||
expect(onCommit).toHaveBeenCalledOnce()
|
||||
expect(onCommit).toHaveBeenCalledWith('rate')
|
||||
})
|
||||
|
||||
it('does not schedule a commit while disabled', () => {
|
||||
const onCommit = vi.fn()
|
||||
renderHook(() => useGitHubTaskSearchCommit({ enabled: false, onCommit, value: 'rate' }))
|
||||
|
||||
act(() => vi.runAllTimers())
|
||||
expect(onCommit).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,27 @@
|
||||
import { useEffect, useRef } from 'react'
|
||||
|
||||
// Remote GitHub fan-out needs a longer idle window; Enter still commits immediately.
|
||||
export const GITHUB_TASK_SEARCH_IDLE_MS = 750
|
||||
|
||||
type GitHubTaskSearchCommitOptions = {
|
||||
enabled: boolean
|
||||
onCommit: (value: string) => void
|
||||
value: string
|
||||
}
|
||||
|
||||
export function useGitHubTaskSearchCommit({
|
||||
enabled,
|
||||
onCommit,
|
||||
value
|
||||
}: GitHubTaskSearchCommitOptions): void {
|
||||
const onCommitRef = useRef(onCommit)
|
||||
onCommitRef.current = onCommit
|
||||
|
||||
useEffect(() => {
|
||||
if (!enabled) {
|
||||
return
|
||||
}
|
||||
const timeout = window.setTimeout(() => onCommitRef.current(value), GITHUB_TASK_SEARCH_IDLE_MS)
|
||||
return () => window.clearTimeout(timeout)
|
||||
}, [enabled, value])
|
||||
}
|
||||
Reference in New Issue
Block a user