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
10 changes: 10 additions & 0 deletions packages/core/src/archive/archiveOrchestration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class Harness {
disableFocus: vi.fn().mockResolvedValue(undefined),
disconnectFromTask: vi.fn().mockResolvedValue(undefined),
archive: vi.fn().mockResolvedValue(undefined),
clearReadState: vi.fn(),
logError: vi.fn(),
cache: {
cancelPathFilter: vi.fn().mockResolvedValue(undefined),
Expand Down Expand Up @@ -60,10 +61,19 @@ describe("archiveTask", () => {

expect(harness.deps.archive).toHaveBeenCalledWith(TASK_ID);
expect(harness.deps.disconnectFromTask).toHaveBeenCalledWith(TASK_ID);
expect(harness.deps.clearReadState).toHaveBeenCalledWith(TASK_ID);
expect(harness.ids).toContain(TASK_ID);
expect(harness.list.some((a) => a.taskId === TASK_ID)).toBe(true);
});

it("does not clear read state when the archive request fails", async () => {
harness.deps.archive = vi.fn().mockRejectedValue(new Error("boom"));

await expect(archiveTask(TASK_ID, harness.deps)).rejects.toThrow("boom");

expect(harness.deps.clearReadState).not.toHaveBeenCalled();
});

it("with optimistic:false, defers cache writes until archive resolves", async () => {
let idsWhenArchiveCalled: string[] = ["sentinel"];
harness.deps.archive = vi.fn().mockImplementation(async () => {
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/archive/archiveOrchestration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export interface ArchiveOrchestrationDeps {
disableFocus(): Promise<void>;
disconnectFromTask(taskId: string): Promise<void>;
archive(taskId: string): Promise<void>;
clearReadState(taskId: string): void;
logError(message: string, error: unknown): void;
cache: ArchiveCacheWriter;
}
Expand Down Expand Up @@ -101,6 +102,9 @@ export async function archiveTask(
try {
await deps.disconnectFromTask(taskId);
await deps.archive(taskId);
// Read state is per-task review convenience; an archived task won't be
// re-reviewed, so drop it once the archive is confirmed.
deps.clearReadState(taskId);
// Non-optimistic flows keep the row visible during the request, then remove
// it the moment the archive succeeds.
if (!optimistic) {
Expand Down
3 changes: 3 additions & 0 deletions packages/ui/src/features/archive/useArchiveTask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
type HostTrpcClient,
} from "@posthog/host-router/client";
import { useHostTRPC } from "@posthog/host-router/react";
import { useReviewViewedStore } from "@posthog/ui/features/code-review/reviewViewedStore";
import { useCommandCenterStore } from "@posthog/ui/features/command-center/commandCenterStore";
import { useFocusStore } from "@posthog/ui/features/focus/focusStore";
import { pinnedTasksApi } from "@posthog/ui/features/sidebar/taskMetaApi";
Expand Down Expand Up @@ -138,6 +139,8 @@ function makeOrchestrationDeps(
),
archive: (taskId) =>
hostClient.archive.archive.mutate({ taskId }).then(() => undefined),
clearReadState: (taskId) =>
useReviewViewedStore.getState().clearTasks([taskId]),
logError: (message, error) => log.error(message, error),
cache: makeCacheWriter(queryClient, keys),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
ReviewShell,
useReviewState,
} from "./ReviewShell";
import { changedFileSignature } from "./reviewItemBuilders";

interface CloudReviewPageProps {
task: Task;
Expand Down Expand Up @@ -50,7 +51,10 @@ export function CloudReviewPage({ task }: CloudReviewPageProps) {
expandAll,
collapseAll,
uncollapseFile,
} = useReviewState(reviewFiles, allPaths);
collapseFiles,
viewedRecord,
toggleViewed,
} = useReviewState(reviewFiles, allPaths, taskId);

const toolCallFallbacks = useMemo(
() =>
Expand All @@ -70,6 +74,7 @@ export function CloudReviewPage({ task }: CloudReviewPageProps) {
return {
key: file.path,
scrollKey: file.path,
sig: changedFileSignature(file),
node: (
<PatchedFileDiff
file={file}
Expand All @@ -81,6 +86,7 @@ export function CloudReviewPage({ task }: CloudReviewPageProps) {
commentThreads={showReviewComments ? commentThreads : undefined}
fallback={toolCallFallbacks?.get(file.path) ?? null}
externalUrl={githubFileUrl}
viewedKey={file.path}
/>
),
};
Expand Down Expand Up @@ -130,8 +136,11 @@ export function CloudReviewPage({ task }: CloudReviewPageProps) {
onExpandAll={expandAll}
onCollapseAll={collapseAll}
onUncollapseFile={uncollapseFile}
onCollapseFiles={collapseFiles}
items={items}
itemIndexByFilePath={itemIndexByFilePath}
viewedRecord={viewedRecord}
onToggleViewed={toggleViewed}
/>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ interface PatchedFileDiffProps {
externalUrl?: string;
prUrl?: string | null;
commentThreads?: Map<number, PrCommentThread>;
viewedKey?: string;
}

export function PatchedFileDiff({
Expand All @@ -28,6 +29,7 @@ export function PatchedFileDiff({
externalUrl,
prUrl,
commentThreads,
viewedKey,
}: PatchedFileDiffProps) {
const fileDiff = useMemo((): FileDiffMetadata | undefined => {
if (!file.patch) return undefined;
Expand Down Expand Up @@ -56,6 +58,7 @@ export function PatchedFileDiff({
collapsed={collapsed}
onToggle={onToggle}
externalUrl={externalUrl}
viewedKey={viewedKey}
/>
);
}
Expand All @@ -72,6 +75,7 @@ export function PatchedFileDiff({
fileDiff={fd}
collapsed={collapsed}
onToggle={onToggle}
viewedKey={viewedKey}
/>
)}
/>
Expand Down
22 changes: 20 additions & 2 deletions packages/ui/src/features/code-review/components/ReviewPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,10 @@ export function ReviewPage({ task }: ReviewPageProps) {
expandAll,
collapseAll,
uncollapseFile,
} = useReviewState(changedFiles, allPaths);
collapseFiles,
viewedRecord,
toggleViewed,
} = useReviewState(changedFiles, allPaths, taskId);

const stagedPathSet = useMemo(
() => new Set(stagedParsedFiles.map((f) => f.name ?? f.prevName ?? "")),
Expand Down Expand Up @@ -186,6 +189,9 @@ export function ReviewPage({ task }: ReviewPageProps) {
expandAll={expandAll}
collapseAll={collapseAll}
uncollapseFile={uncollapseFile}
collapseFiles={collapseFiles}
viewedRecord={viewedRecord}
toggleViewed={toggleViewed}
refetch={refetch}
hasStagedFiles={hasStagedFiles}
stagedParsedFiles={stagedParsedFiles}
Expand Down Expand Up @@ -218,6 +224,9 @@ function LocalReviewContent({
expandAll,
collapseAll,
uncollapseFile,
collapseFiles,
viewedRecord,
toggleViewed,
refetch,
hasStagedFiles,
stagedParsedFiles,
Expand Down Expand Up @@ -246,6 +255,9 @@ function LocalReviewContent({
expandAll: () => void;
collapseAll: () => void;
uncollapseFile: (filePath: string) => void;
collapseFiles: (keys: string[]) => void;
viewedRecord: Record<string, string>;
toggleViewed: (key: string, sig: string | null) => void;
refetch: () => void;
hasStagedFiles: boolean;
stagedParsedFiles: ReturnType<typeof parsePatchFiles>[number]["files"];
Expand Down Expand Up @@ -350,13 +362,16 @@ function LocalReviewContent({
onExpandAll={expandAll}
onCollapseAll={collapseAll}
onUncollapseFile={uncollapseFile}
onCollapseFiles={collapseFiles}
onRefresh={refetch}
effectiveSource={effectiveSource}
branchSourceAvailable={branchSourceAvailable}
prSourceAvailable={prSourceAvailable}
defaultBranch={defaultBranch}
items={items}
itemIndexByFilePath={itemIndexByFilePath}
viewedRecord={viewedRecord}
onToggleViewed={toggleViewed}
/>
);
}
Expand Down Expand Up @@ -401,7 +416,7 @@ function RemoteReviewPage({
: prLoading && files.length === 0;

const allPaths = useMemo(() => files.map((f) => f.path), [files]);
const reviewState = useReviewState(files, allPaths);
const reviewState = useReviewState(files, allPaths, taskId);

const items = useMemo(
() =>
Expand Down Expand Up @@ -438,12 +453,15 @@ function RemoteReviewPage({
onExpandAll={reviewState.expandAll}
onCollapseAll={reviewState.collapseAll}
onUncollapseFile={reviewState.uncollapseFile}
onCollapseFiles={reviewState.collapseFiles}
effectiveSource={effectiveSource}
branchSourceAvailable={branchSourceAvailable}
prSourceAvailable={prSourceAvailable}
defaultBranch={defaultBranch}
items={items}
itemIndexByFilePath={itemIndexByFilePath}
viewedRecord={reviewState.viewedRecord}
onToggleViewed={reviewState.toggleViewed}
/>
);
}
Expand Down
10 changes: 9 additions & 1 deletion packages/ui/src/features/code-review/components/ReviewRows.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,10 @@ export const PatchRow = memo(function PatchRow({
collapsed={collapsed}
onToggle={onToggle}
onOpenFile={onOpenFile}
viewedKey={itemKey}
/>
),
[collapsed, onToggle, onOpenFile],
[collapsed, onToggle, onOpenFile, itemKey],
);
return (
<InteractiveFileDiff
Expand Down Expand Up @@ -113,6 +114,7 @@ export const UntrackedRow = memo(function UntrackedRow({
collapsed={collapsed}
onToggle={onToggle}
taskId={taskId}
viewedKey={itemKey}
/>
);
});
Expand Down Expand Up @@ -152,6 +154,7 @@ export const RemoteRow = memo(function RemoteRow({
onToggle={onToggle}
commentThreads={commentThreads}
externalUrl={externalUrl}
viewedKey={file.path}
/>
);
});
Expand All @@ -163,13 +166,15 @@ function UntrackedFileDiff({
options,
collapsed,
onToggle,
viewedKey,
}: {
file: ChangedFile;
repoPath: string;
taskId: string;
options: DiffOptions;
collapsed: boolean;
onToggle: () => void;
viewedKey?: string;
}) {
const [containerRef, inView] = useInView<HTMLDivElement>({
rootMargin: REVIEW_PREFETCH_ROOT_MARGIN,
Expand Down Expand Up @@ -211,6 +216,7 @@ function UntrackedFileDiff({
reason="line-limit"
collapsed={collapsed}
onToggle={onToggle}
viewedKey={viewedKey}
/>
);
}
Expand All @@ -231,6 +237,7 @@ function UntrackedFileDiff({
fileDiff={fd}
collapsed={collapsed}
onToggle={onToggle}
viewedKey={viewedKey}
/>
)}
/>
Expand All @@ -242,6 +249,7 @@ function UntrackedFileDiff({
deletions={0}
collapsed={collapsed}
onToggle={onToggle}
viewedKey={viewedKey}
/>
)}
</div>
Expand Down
Loading
Loading