Default the session sidebar filter to My sessions
The session-filter preference defaulted to "All sessions" for a first-time viewer (nothing persisted yet). Default it to "mine" instead so a viewer lands on their own sessions first; anyone can still switch to "All sessions" and the pick persists. On a single-user server "mine" and "all" show the same set, so the default is safe there too. Co-authored-by: Isaac Signed-off-by: Bryan Qiu <bryan.qiu@databricks.com>
This commit is contained in:
@@ -11,10 +11,10 @@ afterEach(() => {
|
||||
});
|
||||
|
||||
describe("sessionFilterPreferences", () => {
|
||||
it('defaults to "all" when nothing is stored', () => {
|
||||
// A first-time viewer sees the whole list, as before persistence existed.
|
||||
expect(DEFAULT_SESSION_FILTER).toBe("all");
|
||||
expect(readSessionFilter(true)).toBe("all");
|
||||
it('defaults to "mine" when nothing is stored', () => {
|
||||
// A first-time viewer lands on their own sessions rather than the whole list.
|
||||
expect(DEFAULT_SESSION_FILTER).toBe("mine");
|
||||
expect(readSessionFilter(true)).toBe("mine");
|
||||
});
|
||||
|
||||
it("round-trips every filter value", () => {
|
||||
@@ -28,17 +28,17 @@ describe("sessionFilterPreferences", () => {
|
||||
// Guards against a hand-edited entry or a filter this build dropped:
|
||||
// scoping the list to a slice with no menu entry would strand the viewer.
|
||||
localStorage.setItem("omnigent:session-filter", "starred");
|
||||
expect(readSessionFilter(true)).toBe("all");
|
||||
expect(readSessionFilter(true)).toBe("mine");
|
||||
|
||||
localStorage.setItem("omnigent:session-filter", "");
|
||||
expect(readSessionFilter(true)).toBe("all");
|
||||
expect(readSessionFilter(true)).toBe("mine");
|
||||
});
|
||||
|
||||
it('ignores a stored "shared" on a single-user server', () => {
|
||||
// A loopback-only server drops "Shared sessions" from the menu, so honoring
|
||||
// it would show an empty list the viewer has no control to leave.
|
||||
writeSessionFilter("shared");
|
||||
expect(readSessionFilter(false)).toBe("all");
|
||||
expect(readSessionFilter(false)).toBe("mine");
|
||||
// Still honored where the option exists.
|
||||
expect(readSessionFilter(true)).toBe("shared");
|
||||
});
|
||||
@@ -59,6 +59,6 @@ describe("sessionFilterPreferences", () => {
|
||||
throw new Error("access denied");
|
||||
});
|
||||
expect(() => writeSessionFilter("mine")).not.toThrow();
|
||||
expect(readSessionFilter(true)).toBe("all");
|
||||
expect(readSessionFilter(true)).toBe("mine");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// The sidebar keeps its live React state as the source of truth; these helpers
|
||||
// only seed that state on mount and snapshot it when the visible tab changes,
|
||||
// so a reload lands on the slice the viewer was last looking at instead of
|
||||
// snapping back to "All sessions". It's a device-local view preference — no
|
||||
// snapping back to the default. It's a device-local view preference — no
|
||||
// account or session state is changed — so it lives in localStorage like the
|
||||
// other `*Preferences` helpers.
|
||||
|
||||
@@ -17,7 +17,12 @@ const STORAGE_KEY = "omnigent:session-filter";
|
||||
*/
|
||||
export type SessionFilter = "all" | "mine" | "shared" | "archived";
|
||||
|
||||
export const DEFAULT_SESSION_FILTER: SessionFilter = "all";
|
||||
// A first-time viewer lands on their own sessions ("My sessions") rather than
|
||||
// the full list: on a shared server the account's own work is what they almost
|
||||
// always want first, and on a single-user server "mine" and "all" show the same
|
||||
// set, so this is a safe default there too. It's a device-local view
|
||||
// preference, so anyone can switch to "All sessions" and the pick persists.
|
||||
export const DEFAULT_SESSION_FILTER: SessionFilter = "mine";
|
||||
|
||||
const SESSION_FILTERS = new Set<string>(["all", "mine", "shared", "archived"]);
|
||||
|
||||
|
||||
@@ -364,7 +364,7 @@ describe("Sidebar session list", () => {
|
||||
expect(row.className).not.toContain("focus-within");
|
||||
});
|
||||
|
||||
it("offers the four display filters and defaults to All sessions", () => {
|
||||
it("offers the four display filters and defaults to My sessions", () => {
|
||||
mockConversations(THREE_TYPE_CONVERSATIONS);
|
||||
renderSidebar();
|
||||
|
||||
@@ -377,9 +377,9 @@ describe("Sidebar session list", () => {
|
||||
for (const value of ["all", "mine", "shared", "archived"]) {
|
||||
expect(screen.getByTestId(`session-filter-${value}`)).toBeInTheDocument();
|
||||
}
|
||||
// Radio semantics: exactly one option is checked, and it's "All sessions".
|
||||
expect(screen.getByTestId("session-filter-all")).toHaveAttribute("aria-checked", "true");
|
||||
expect(screen.getByTestId("session-filter-mine")).toHaveAttribute("aria-checked", "false");
|
||||
// Radio semantics: exactly one option is checked, and it's "My sessions".
|
||||
expect(screen.getByTestId("session-filter-mine")).toHaveAttribute("aria-checked", "true");
|
||||
expect(screen.getByTestId("session-filter-all")).toHaveAttribute("aria-checked", "false");
|
||||
});
|
||||
|
||||
it("keeps the picked filter across a remount", () => {
|
||||
@@ -389,22 +389,24 @@ describe("Sidebar session list", () => {
|
||||
]);
|
||||
renderSidebar();
|
||||
|
||||
selectSessionFilter("mine");
|
||||
expect(screen.queryByText("conv_shared")).toBeNull();
|
||||
// Pick a non-default slice (default is "mine") so the remount below proves
|
||||
// the pick was persisted, not just that we landed back on the default.
|
||||
selectSessionFilter("shared");
|
||||
expect(screen.queryByText("conv_mine")).toBeNull();
|
||||
|
||||
// Fresh mount re-reads localStorage: still scoped to the viewer's own
|
||||
// sessions. If this fails, the pick lived only in memory and a reload
|
||||
// silently snapped the list back to "All sessions".
|
||||
// Fresh mount re-reads localStorage: still scoped to shared sessions. If
|
||||
// this fails, the pick lived only in memory and a reload silently snapped
|
||||
// the list back to the default.
|
||||
cleanup();
|
||||
renderSidebar();
|
||||
expect(screen.getByText("conv_mine")).toBeInTheDocument();
|
||||
expect(screen.queryByText("conv_shared")).toBeNull();
|
||||
expect(screen.getByText("conv_shared")).toBeInTheDocument();
|
||||
expect(screen.queryByText("conv_mine")).toBeNull();
|
||||
fireEvent.pointerDown(screen.getByTestId("session-filter"), {
|
||||
button: 0,
|
||||
ctrlKey: false,
|
||||
pointerType: "mouse",
|
||||
});
|
||||
expect(screen.getByTestId("session-filter-mine")).toHaveAttribute("aria-checked", "true");
|
||||
expect(screen.getByTestId("session-filter-shared")).toHaveAttribute("aria-checked", "true");
|
||||
});
|
||||
|
||||
it("drops a persisted Shared filter on a single-user server", () => {
|
||||
@@ -422,7 +424,7 @@ describe("Sidebar session list", () => {
|
||||
ctrlKey: false,
|
||||
pointerType: "mouse",
|
||||
});
|
||||
expect(screen.getByTestId("session-filter-all")).toHaveAttribute("aria-checked", "true");
|
||||
expect(screen.getByTestId("session-filter-mine")).toHaveAttribute("aria-checked", "true");
|
||||
expect(screen.queryByTestId("session-filter-shared")).toBeNull();
|
||||
});
|
||||
|
||||
@@ -460,21 +462,21 @@ describe("Sidebar session list", () => {
|
||||
archived: screen.queryByText("conv_archived") !== null,
|
||||
});
|
||||
|
||||
// Default: everything except archived.
|
||||
expect(visible()).toEqual({ owned: true, shared: true, archived: false });
|
||||
|
||||
selectSessionFilter("mine");
|
||||
// Default: the viewer's own sessions only ("My sessions").
|
||||
expect(visible()).toEqual({ owned: true, shared: false, archived: false });
|
||||
|
||||
selectSessionFilter("all");
|
||||
expect(visible()).toEqual({ owned: true, shared: true, archived: false });
|
||||
|
||||
selectSessionFilter("shared");
|
||||
expect(visible()).toEqual({ owned: false, shared: true, archived: false });
|
||||
|
||||
selectSessionFilter("archived");
|
||||
expect(visible()).toEqual({ owned: false, shared: false, archived: true });
|
||||
|
||||
// Back to All: leaving Archived restores the unarchived rows.
|
||||
selectSessionFilter("all");
|
||||
expect(visible()).toEqual({ owned: true, shared: true, archived: false });
|
||||
// Back to My sessions: leaving Archived restores the viewer's own rows.
|
||||
selectSessionFilter("mine");
|
||||
expect(visible()).toEqual({ owned: true, shared: false, archived: false });
|
||||
|
||||
// And Archived is still reachable a second time (state isn't one-shot).
|
||||
selectSessionFilter("archived");
|
||||
@@ -999,7 +1001,8 @@ describe("Sidebar sections", () => {
|
||||
]);
|
||||
renderSidebar();
|
||||
|
||||
// Default ("All sessions"): everything the viewer can see.
|
||||
// "All sessions": everything the viewer can see.
|
||||
selectSessionFilter("all");
|
||||
const recentSection = screen.getByText("Sessions").closest("section")!;
|
||||
expect(within(recentSection).getByText("conv_mine_legacy")).toBeInTheDocument();
|
||||
expect(within(recentSection).getByText("conv_mine_acl")).toBeInTheDocument();
|
||||
@@ -1158,9 +1161,11 @@ describe("Sidebar tabs", () => {
|
||||
]);
|
||||
renderSidebar();
|
||||
|
||||
// The owned session is filed (peeled out of the flat list into its
|
||||
// collapsed folder), but the shared collision stays in the flat Sessions
|
||||
// list rather than being pulled into the viewer's folder.
|
||||
// The shared session shows on "All sessions" (the default "My sessions" tab
|
||||
// scopes it out). The owned session is filed (peeled out of the flat list
|
||||
// into its collapsed folder), but the shared collision stays in the flat
|
||||
// Sessions list rather than being pulled into the viewer's folder.
|
||||
selectSessionFilter("all");
|
||||
const sessionsSection = screen.getByText("Sessions").closest("section")!;
|
||||
expect(within(sessionsSection).queryByText("conv_owned")).toBeNull();
|
||||
expect(within(sessionsSection).getByText("conv_shared_alpha")).toBeInTheDocument();
|
||||
|
||||
Reference in New Issue
Block a user