Skip to content
18 changes: 11 additions & 7 deletions frontend/src/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2253,13 +2253,17 @@ describe("App, authenticated", () => {
"no_comparison_group" as const,
"No other visible posts share this comparison group yet. Request reconstruction after more posts arrive, or read Keyman and evaluation.",
],
])("explains an empty focused Event Lineage graph: %s", async (lineageIsolationReason, message) => {
stubBackend({ lineageIsolationReason });
render(<App showLabPanels />);
await userEvent.click(await screen.findByRole("button", { name: "View post: Public post" }));
expect(await screen.findByText(message)).toBeInTheDocument();
expect(screen.queryByText("No linked posts yet.")).not.toBeInTheDocument();
});
])(
"explains an empty focused Event Lineage graph: %s",
async (lineageIsolationReason, message) => {
stubBackend({ lineageIsolationReason });
render(<App showLabPanels />);
await userEvent.click(await screen.findByRole("button", { name: "View post: Public post" }));
expect(await screen.findByText(message)).toBeInTheDocument();
expect(screen.queryByText("No linked posts yet.")).not.toBeInTheDocument();
},
15_000,
);

it("shows an embedded invoice image instead of the raw base64 string", async () => {
const tinyPng =
Expand Down
11 changes: 6 additions & 5 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { AdminPanel } from "./components/AdminPanel";
import { LeftoverPairList } from "./components/LeftoverPairList";
import { WorkspaceCalendar } from "./components/WorkspaceCalendar";
import { focusedGraphMustReset } from "./focusedGraphSelection";

import { useCallback, useEffect, useRef, useState, type ReactNode } from "react";
import { useAuth } from "react-oidc-context";
Expand Down Expand Up @@ -3823,7 +3824,6 @@ function PostList({
onPostOpened?: () => void;
}) {
const [posts, setPosts] = useState<PostSummary[] | null>(null);
const [graph, setGraph] = useState<LineageGraph | null>(null);
const [focusedGraph, setFocusedGraph] = useState<LineageGraph | null>(null);
const [error, setError] = useState<string | null>(null);
const [selectedPostId, setSelectedPostId] = useState<string | null>(null);
Expand Down Expand Up @@ -3886,8 +3886,10 @@ function PostList({
}

function selectPost(postId: string, options?: SelectPostOptions) {
if (focusedGraphMustReset(selectedPostId, postId)) {
setFocusedGraph(null);
}
setSelectedPostId(postId);
setFocusedGraph(null);
setOpenedAfterCutoff(Boolean(options?.liveAfterCutoff));
setOpenedCutoffIso(options?.knowledgeCutoff ?? null);
setOpenedFromReportMember(Boolean(options?.fromReportMember));
Expand Down Expand Up @@ -3955,7 +3957,6 @@ function PostList({
}, [loadPostPage]);

useEffect(() => {
fetchLineageGraph(accessToken).then(setGraph).catch(() => setGraph({ nodes: [], edges: [] }));
fetchMe(accessToken)
.then((me) => {
setCanRebuild(me.permission_codes.includes("post_admin"));
Expand All @@ -3974,6 +3975,7 @@ function PostList({
setFocusedGraph(null);
return;
}
setFocusedGraph(null);
Comment thread
seonghobae marked this conversation as resolved.
let active = true;
fetchLineageGraph(accessToken, selectedPostId)
.then((nextGraph) => {
Comment thread
seonghobae marked this conversation as resolved.
Expand All @@ -3992,7 +3994,6 @@ function PostList({
setRebuildError(null);
try {
await rebuildLineage(accessToken);
setGraph(await fetchLineageGraph(accessToken));
} catch (err) {
setRebuildError(String(err));
} finally {
Comment thread
seonghobae marked this conversation as resolved.
Expand Down Expand Up @@ -4304,7 +4305,7 @@ function PostList({
postId={selectedPostId}
accessToken={accessToken}
canExtract={canRebuild}
graph={focusedGraph ?? graph}
graph={focusedGraph}
liveBodyWarning={
openedAfterCutoff ? analysisRunOpenedBodyWarning(openedCutoffIso) : null
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/WorkspaceCalendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export function WorkspaceCalendar({
<section className="popup-section" aria-labelledby={`${headingId}-observed`}>
<h3 id={`${headingId}-observed`}>{t("Observed calendar events")}</h3>
{events.length === 0 ? (
<p className="popup-placeholder" role="status">
<p className="popup-placeholder">
Comment thread
seonghobae marked this conversation as resolved.
{naruonAvailable
? t("No observed calendar events are available.")
: failClosedCopy}
Expand Down
9 changes: 9 additions & 0 deletions frontend/src/focusedGraphSelection.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { describe, expect, it } from "vitest";
import { focusedGraphMustReset } from "./focusedGraphSelection";

describe("focusedGraphMustReset", () => {
it("retains a loaded graph when the already-open post is selected again", () => {
expect(focusedGraphMustReset("post-1", "post-1")).toBe(false);
expect(focusedGraphMustReset("post-1", "post-2")).toBe(true);
});
});
4 changes: 4 additions & 0 deletions frontend/src/focusedGraphSelection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/** Return whether selecting a post requires discarding the currently focused graph. */
export function focusedGraphMustReset(currentPostId: string | null, nextPostId: string): boolean {
return currentPostId !== nextPostId;
}
Loading