Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions apps/app/.ladle/story-fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,10 @@ export function makeThreadListEntry(
environmentName: null,
environmentBranchName: null,
environmentWorkspaceDisplayKind: "other",
environmentStatusSummary: {
git: { state: "not_applicable", refreshedAt: 100 },
pullRequest: { state: "not_applicable", refreshedAt: 100 },
},
runtime: { displayStatus: "idle", hostReconnectGraceExpiresAt: null },
};
return { ...base, ...overrides };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ function makeThread(overrides: Partial<ThreadListEntry> = {}): ThreadListEntry {
environmentName: null,
environmentBranchName: null,
environmentWorkspaceDisplayKind: "other",
environmentStatusSummary: {
git: { state: "not_applicable", refreshedAt: 100 },
pullRequest: { state: "not_applicable", refreshedAt: 100 },
},
runtime: { displayStatus: "idle", hostReconnectGraceExpiresAt: null },
...overrides,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ function createThreadListEntry({
environmentId: null,
environmentName: null,
environmentWorkspaceDisplayKind: "other",
environmentStatusSummary: {
git: { state: "not_applicable", refreshedAt: 1000 },
pullRequest: { state: "not_applicable", refreshedAt: 1000 },
},
hasPendingInteraction: false,
id,
lastReadAt: null,
Expand Down
4 changes: 4 additions & 0 deletions apps/app/src/components/sidebar/ThreadRow.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ function createThread(
environmentName: null,
environmentBranchName: null,
environmentWorkspaceDisplayKind: "other",
environmentStatusSummary: {
git: { state: "not_applicable", refreshedAt: 1 },
pullRequest: { state: "not_applicable", refreshedAt: 1 },
},
runtime: {
displayStatus: "idle",
hostReconnectGraceExpiresAt: null,
Expand Down
4 changes: 4 additions & 0 deletions apps/app/src/components/sidebar/pinnedSidebarThreads.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ function createThread(
environmentName: null,
environmentBranchName: null,
environmentWorkspaceDisplayKind: "other",
environmentStatusSummary: {
git: { state: "not_applicable", refreshedAt: 2 },
pullRequest: { state: "not_applicable", refreshedAt: 2 },
},
runtime: {
displayStatus: "idle",
hostReconnectGraceExpiresAt: null,
Expand Down
4 changes: 4 additions & 0 deletions apps/app/src/components/sidebar/projectThreadGroups.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ function createThread(
environmentName: null,
environmentBranchName: null,
environmentWorkspaceDisplayKind: "other",
environmentStatusSummary: {
git: { state: "not_applicable", refreshedAt: 2 },
pullRequest: { state: "not_applicable", refreshedAt: 2 },
},
runtime: {
displayStatus: "idle",
hostReconnectGraceExpiresAt: null,
Expand Down
4 changes: 4 additions & 0 deletions apps/app/src/components/sidebar/sortComparator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ function thread(overrides: Partial<ThreadListEntry>): ThreadListEntry {
environmentName: null,
environmentBranchName: null,
environmentWorkspaceDisplayKind: "other",
environmentStatusSummary: {
git: { state: "not_applicable", refreshedAt: 2 },
pullRequest: { state: "not_applicable", refreshedAt: 2 },
},
runtime: {
displayStatus: "idle",
hostReconnectGraceExpiresAt: null,
Expand Down
9 changes: 8 additions & 1 deletion apps/app/src/hooks/cache-owners/query-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ export function getEnvironmentActionInvalidationQueryKeys({
export function getCachedThreadListPlaceholder(
queryClient: QueryClient,
threadId: string,
): ThreadWithRuntime | undefined {
): ThreadListEntry | undefined {
if (!threadId) {
return undefined;
}
Expand Down Expand Up @@ -584,6 +584,13 @@ export function optimisticallyInsertThread(
hasPendingInteraction: false,
pinSortKey: null,
environmentWorkspaceDisplayKind: "other",
environmentStatusSummary: {
git: { state: "not_applicable", refreshedAt: thread.updatedAt },
pullRequest: {
state: "not_applicable",
refreshedAt: thread.updatedAt,
},
},
},
...data,
]);
Expand Down
7 changes: 7 additions & 0 deletions apps/app/src/hooks/cache-owners/realtime-cache-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,13 @@ export const REALTIME_THREAD_CHANGE_REGISTRY = {
dirtyThreadStorageQueriesForThread, // Thread storage is resolved through the attached environment.
],
},
"environment-status-summary-changed": {
flush: "debounced",
dirty: [
dirtyThreadListQueries, // Sidebar/list rows render environment git and PR signals.
dirtyThreadDetailQueries, // Detail consumers may reuse list-derived environment summary.
],
},
"read-state-changed": {
flush: "debounced",
dirty: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ function makeThreadListEntry(
environmentName: "Environment",
environmentBranchName: "main",
environmentWorkspaceDisplayKind: "managed-worktree",
environmentStatusSummary: {
git: { state: "not_applicable", refreshedAt: 1 },
pullRequest: { state: "not_applicable", refreshedAt: 1 },
},
...thread,
};
}
Expand Down
4 changes: 4 additions & 0 deletions apps/app/src/hooks/mutations/thread-folder-mutations.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ function makeThreadListEntry(
environmentHostId: "host-1",
environmentName: "Environment",
environmentWorkspaceDisplayKind: "managed-worktree",
environmentStatusSummary: {
git: { state: "not_applicable", refreshedAt: 1 },
pullRequest: { state: "not_applicable", refreshedAt: 1 },
},
...thread,
};
}
Expand Down
14 changes: 11 additions & 3 deletions apps/app/src/hooks/mutations/thread-state-mutations.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ function makeThreadResponse(
return {
...makeThreadWithRuntime(thread),
canSpawnChild: true,
environmentStatusSummary: {
git: { state: "not_applicable", refreshedAt: 1 },
pullRequest: { state: "not_applicable", refreshedAt: 1 },
},
...thread,
};
}
Expand All @@ -77,6 +81,10 @@ function makeThreadListEntry(
environmentName: "Environment",
environmentBranchName: "main",
environmentWorkspaceDisplayKind: "managed-worktree",
environmentStatusSummary: {
git: { state: "not_applicable", refreshedAt: 1 },
pullRequest: { state: "not_applicable", refreshedAt: 1 },
},
...thread,
};
}
Expand Down Expand Up @@ -224,9 +232,9 @@ describe("thread state mutations", () => {

await waitFor(() => {
expect(
queryClient.getQueryData<ThreadWithRuntime>(threadQueryKey(threadId))
?.folderId,
).toBe("fld_personal");
queryClient.getQueryData<ThreadWithRuntime>(threadQueryKey(threadId))
?.folderId,
).toBe("fld_personal");
});
expect(
queryClient.getQueryData<ThreadListEntry[]>(threadListKey)?.[0]?.folderId,
Expand Down
65 changes: 2 additions & 63 deletions apps/app/src/hooks/queries/environment-queries.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { createQueryClientTestHarness } from "@/test/queryClientTestHarness";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { environmentPullRequestQueryKey } from "./query-keys";
import {
getEnvironmentPullRequestRefetchInterval,
getEnvironmentPullRequestStaleTime,
useEnvironmentPullRequest,
} from "./environment-queries";
Expand All @@ -28,7 +27,6 @@ vi.mock("@/hooks/useRealtimeSubscription", () => ({
const ENVIRONMENT_ID = "env-1";
const ACTIVE_PULL_REQUEST_STALE_MS = 30_000;
const SETTLED_PULL_REQUEST_STALE_MS = 60 * 60_000;
const ACTIVE_PULL_REQUEST_REFETCH_MS = 5_000;

const pullRequestFixture: ThreadPullRequest = {
number: 128,
Expand Down Expand Up @@ -106,66 +104,7 @@ describe("useEnvironmentPullRequest", () => {
).toBe(SETTLED_PULL_REQUEST_STALE_MS);
});

it("polls open pull requests while checks or mergeability are still settling", () => {
expect(getEnvironmentPullRequestRefetchInterval(null)).toBe(false);
expect(getEnvironmentPullRequestRefetchInterval(undefined)).toBe(false);
expect(getEnvironmentPullRequestRefetchInterval(pullRequestFixture)).toBe(
false,
);
expect(
getEnvironmentPullRequestRefetchInterval({
...pullRequestFixture,
checks: {
...pullRequestFixture.checks,
state: "pending",
pendingCount: 1,
},
attention: "checks_pending",
}),
).toBe(ACTIVE_PULL_REQUEST_REFETCH_MS);
expect(
getEnvironmentPullRequestRefetchInterval({
...pullRequestFixture,
mergeability: {
state: "unknown",
mergeStateStatus: "UNKNOWN",
mergeable: "UNKNOWN",
},
attention: "none",
}),
).toBe(ACTIVE_PULL_REQUEST_REFETCH_MS);
});

it("does not poll draft or settled pull requests", () => {
expect(
getEnvironmentPullRequestRefetchInterval({
...pullRequestFixture,
state: "draft",
mergeability: {
state: "draft",
mergeStateStatus: "DRAFT",
mergeable: "UNKNOWN",
},
attention: "draft",
}),
).toBe(false);
expect(
getEnvironmentPullRequestRefetchInterval({
...pullRequestFixture,
state: "closed",
attention: "closed",
}),
).toBe(false);
expect(
getEnvironmentPullRequestRefetchInterval({
...pullRequestFixture,
state: "merged",
attention: "merged",
}),
).toBe(false);
});

it("refetches stale pull request data on mount and always refetches on window focus", async () => {
it("refetches stale pull request data on mount and window focus without polling", async () => {
const { wrapper, queryClient } = createQueryClientTestHarness();
vi.mocked(api.getEnvironmentPullRequest).mockResolvedValue(
pullRequestResponse(pullRequestFixture),
Expand All @@ -185,9 +124,9 @@ describe("useEnvironmentPullRequest", () => {
expect.objectContaining({
refetchOnMount: true,
refetchOnWindowFocus: "always",
refetchInterval: expect.any(Function),
staleTime: expect.any(Function),
}),
);
expect(query?.options).not.toHaveProperty("refetchInterval");
});
});
18 changes: 0 additions & 18 deletions apps/app/src/hooks/queries/environment-queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ interface UseEnvironmentDiffFilesOptions extends QueryOptions {

const ENVIRONMENT_PULL_REQUEST_STALE_MS = 30_000;
const ENVIRONMENT_SETTLED_PULL_REQUEST_STALE_MS = 60 * 60_000;
const ENVIRONMENT_ACTIVE_PULL_REQUEST_REFETCH_MS = 5_000;
const MERGE_BASE_BRANCHES_STALE_MS = 30_000;
const MERGE_BASE_BRANCHES_LIMIT = 50;
/** Staleness window for the environment diff TOC query. */
Expand Down Expand Up @@ -133,21 +132,6 @@ export function getEnvironmentPullRequestStaleTime(
: ENVIRONMENT_PULL_REQUEST_STALE_MS;
}

export function getEnvironmentPullRequestRefetchInterval(
pullRequest: ThreadPullRequest | null | undefined,
): number | false {
if (!pullRequest || pullRequest.state !== "open") {
return false;
}
if (
pullRequest.checks.state === "pending" ||
pullRequest.mergeability.state === "unknown"
) {
return ENVIRONMENT_ACTIVE_PULL_REQUEST_REFETCH_MS;
}
return false;
}

export function useEnvironmentPullRequest(
environmentId: string | null | undefined,
options?: QueryOptions,
Expand All @@ -165,8 +149,6 @@ export function useEnvironmentPullRequest(
enabled,
refetchOnMount: true,
refetchOnWindowFocus: "always",
refetchInterval: (query) =>
getEnvironmentPullRequestRefetchInterval(query.state.data?.pullRequest),
staleTime: (query) =>
getEnvironmentPullRequestStaleTime(query.state.data?.pullRequest),
});
Expand Down
4 changes: 4 additions & 0 deletions apps/app/src/hooks/queries/query-helpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,10 @@ describe("resolveThreadPlaceholder", () => {
const previousThread: ThreadResponse = {
...makeThreadWithRuntime({ id: "thread-1" }),
canSpawnChild: false,
environmentStatusSummary: {
git: { state: "not_applicable", refreshedAt: 1 },
pullRequest: { state: "not_applicable", refreshedAt: 1 },
},
};

expect(
Expand Down
4 changes: 2 additions & 2 deletions apps/app/src/hooks/queries/thread-queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { useDebounceValue } from "usehooks-ts";
import type {
PendingInteraction,
ResolvedThreadExecutionOptions,
ThreadWithRuntime,
ThreadListEntry,
} from "@bb/domain";
import type {
PromptHistoryResponse,
Expand Down Expand Up @@ -518,7 +518,7 @@ export function useThread(id: string, options?: QueryOptions) {
// placeholder; the real single-thread response, which carries the server-
// computed value, resolves moments later.
function liftThreadListPlaceholder(
thread: ThreadWithRuntime | undefined,
thread: ThreadListEntry | undefined,
): ThreadResponse | undefined {
if (thread === undefined) {
return undefined;
Expand Down
4 changes: 4 additions & 0 deletions apps/app/src/views/RootComposeMobileRecents.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ function makeThread(args: MakeThreadArgs): ThreadListEntry {
environmentName: null,
environmentBranchName: null,
environmentWorkspaceDisplayKind: "other",
environmentStatusSummary: {
git: { state: "not_applicable", refreshedAt: 100 },
pullRequest: { state: "not_applicable", refreshedAt: 100 },
},
runtime: {
displayStatus: "idle",
hostReconnectGraceExpiresAt: null,
Expand Down
4 changes: 4 additions & 0 deletions apps/app/src/views/RootComposeView.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ function makeThread(args: MakeThreadArgs): ThreadListEntry {
environmentName: null,
environmentBranchName: null,
environmentWorkspaceDisplayKind: "other",
environmentStatusSummary: {
git: { state: "not_applicable", refreshedAt: 100 },
pullRequest: { state: "not_applicable", refreshedAt: 100 },
},
runtime: {
displayStatus: "idle",
hostReconnectGraceExpiresAt: null,
Expand Down
10 changes: 5 additions & 5 deletions apps/app/src/views/thread-detail/ThreadDetailView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import {
isActiveTerminalSessionStatus,
resolveEnvironmentMergeBaseBranch,
type ThreadPullRequest,
type ThreadListEntry,
type ThreadWithRuntime,
} from "@bb/domain";
Expand All @@ -36,7 +37,6 @@ import { useSendThreadMessage } from "../../hooks/mutations/thread-runtime-mutat
import { useUpdateEnvironment } from "../../hooks/mutations/environment-mutations";
import {
useEnvironment,
useEnvironmentPullRequest,
useEnvironmentWorkStatus,
} from "../../hooks/queries/environment-queries";
import {
Expand Down Expand Up @@ -1282,10 +1282,10 @@ export function ThreadDetailView(props: ThreadDetailViewProps) {
workStatusResponse?.outcome === "unavailable"
? workStatusResponse.failure
: undefined;
const pullRequestQuery = useEnvironmentPullRequest(thread?.environmentId, {
enabled: canUseGitUi && environment !== undefined,
});
const pullRequest = pullRequestQuery.data?.pullRequest ?? null;
const pullRequest = useMemo<ThreadPullRequest | null>(() => {
const summary = thread?.environmentStatusSummary.pullRequest;
return summary?.state === "available" ? summary.pullRequest : null;
}, [thread?.environmentStatusSummary.pullRequest]);
const handlePullRequestReady = useCallback(async () => {
const environmentId = thread?.environmentId;
if (!environmentId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ function makeThread(overrides: ThreadListEntryOverrides = {}): ThreadListEntry {
environmentId: null,
environmentName: null,
environmentWorkspaceDisplayKind: "other",
environmentStatusSummary: {
git: { state: "not_applicable", refreshedAt: 1 },
pullRequest: { state: "not_applicable", refreshedAt: 1 },
},
hasPendingInteraction: false,
id: "thr_1",
lastReadAt: null,
Expand Down
Loading
Loading