mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-27 19:52:49 +00:00
sidebar history: drop workspace filter, project-only
Removes the Workspace section from the Sessions filter dropdown. Final dropdown is All + Project. Simplifies the filter discriminated union (drops the "workspace" variant), the predicate, and the hook-derived option list. Workspace mapping is still used internally to map session cwd to project for the Project filter and for hiding unmapped agents. E2E journey simplified — the workspace-filter step is gone, including its brittle accessible-name regex.
This commit is contained in:
@@ -256,10 +256,6 @@ async function chooseSessionsFilter(page: Page, name: string | RegExp) {
|
||||
await page.getByRole("button", { name }).click();
|
||||
}
|
||||
|
||||
async function chooseWorkspaceSessionsFilter(page: Page, workspaceId: string) {
|
||||
await chooseSessionsFilter(page, new RegExp(`^${escapeRegex(workspaceId)}\\s`));
|
||||
}
|
||||
|
||||
async function chooseProjectSessionsFilter(page: Page, projectName: string) {
|
||||
await chooseSessionsFilter(page, new RegExp(`^${escapeRegex(projectName)}$`));
|
||||
}
|
||||
@@ -319,11 +315,6 @@ async function runSidebarHistorySessionsJourney(page: Page) {
|
||||
await switchSidebarToWorkspaces(page, seeded);
|
||||
|
||||
await switchSidebarToSessions(page);
|
||||
await chooseWorkspaceSessionsFilter(page, seeded.firstWorkspace.workspaceId);
|
||||
await expectOnlySidebarSessionRows(page, {
|
||||
visible: [middle, oldest],
|
||||
hidden: [newest],
|
||||
});
|
||||
await chooseProjectSessionsFilter(page, seeded.secondProjectName);
|
||||
await expectOnlySidebarSessionRows(page, {
|
||||
visible: [newest],
|
||||
@@ -351,9 +342,7 @@ async function runSidebarHistorySessionsJourney(page: Page) {
|
||||
test.describe("Sidebar History Sessions journey", () => {
|
||||
test.describe.configure({ timeout: 300_000 });
|
||||
|
||||
test("toggles sessions, filters by workspace and project, and opens a session tab", async ({
|
||||
page,
|
||||
}) => {
|
||||
test("toggles sessions, filters by project, and opens a session tab", async ({ page }) => {
|
||||
await runSidebarHistorySessionsJourney(page);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,14 +14,14 @@ describe("useSidebarSessionsController", () => {
|
||||
|
||||
act(() => {
|
||||
result.current.setSidebarSessionFilter({
|
||||
type: "workspace",
|
||||
workspaceKey: "server-1:workspace-1",
|
||||
type: "project",
|
||||
projectKey: "project-a",
|
||||
});
|
||||
});
|
||||
|
||||
expect(result.current.sidebarSessionFilter).toEqual({
|
||||
type: "workspace",
|
||||
workspaceKey: "server-1:workspace-1",
|
||||
type: "project",
|
||||
projectKey: "project-a",
|
||||
});
|
||||
|
||||
rerender({ serverId: "server-2" });
|
||||
|
||||
@@ -76,20 +76,6 @@ describe("sidebar session filtering", () => {
|
||||
expect(visibleIds).toEqual(["main", "docs", "api"]);
|
||||
});
|
||||
|
||||
it("filters by workspace", () => {
|
||||
const lookup = createSidebarSessionWorkspaceLookup(WORKSPACES);
|
||||
|
||||
const visibleIds = AGENTS.filter((agent) =>
|
||||
shouldIncludeSidebarSessionAgent({
|
||||
agent,
|
||||
filter: { type: "workspace", workspaceKey: "server-1:workspace-2" },
|
||||
lookup,
|
||||
}),
|
||||
).map((agent) => agent.id);
|
||||
|
||||
expect(visibleIds).toEqual(["docs"]);
|
||||
});
|
||||
|
||||
it("filters by project", () => {
|
||||
const lookup = createSidebarSessionWorkspaceLookup(WORKSPACES);
|
||||
|
||||
@@ -121,7 +107,6 @@ describe("sidebar session filtering", () => {
|
||||
});
|
||||
|
||||
expect(availability).toEqual({
|
||||
workspaceKeys: ["server-1:workspace-1"],
|
||||
projectKeys: ["project-a"],
|
||||
});
|
||||
const filterProjects = deriveSidebarSessionFilterProjects({
|
||||
@@ -192,11 +177,13 @@ describe("sidebar session filtering", () => {
|
||||
},
|
||||
],
|
||||
availability,
|
||||
workspaceNameByKey: new Map([["server-1:workspace-1", "Main"]]),
|
||||
});
|
||||
|
||||
expect(filterProjects.map(projectWorkspaceKeys)).toEqual([
|
||||
{ projectKey: "project-a", workspaceKeys: ["server-1:workspace-1"] },
|
||||
{
|
||||
projectKey: "project-a",
|
||||
workspaceKeys: ["server-1:workspace-1", "server-1:workspace-3"],
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -8,7 +8,6 @@ export interface SidebarSessionWorkspaceLookup {
|
||||
}
|
||||
|
||||
export interface SidebarSessionFilterAvailability {
|
||||
workspaceKeys: readonly string[];
|
||||
projectKeys: readonly string[];
|
||||
}
|
||||
|
||||
@@ -75,9 +74,6 @@ export function shouldIncludeSidebarSessionAgent(input: {
|
||||
if (input.filter.type === "all") {
|
||||
return true;
|
||||
}
|
||||
if (input.filter.type === "workspace") {
|
||||
return workspace.workspaceKey === input.filter.workspaceKey;
|
||||
}
|
||||
return workspace.projectKey === input.filter.projectKey;
|
||||
}
|
||||
|
||||
@@ -85,7 +81,6 @@ export function deriveSidebarSessionFilterAvailability(input: {
|
||||
agents: readonly SidebarSessionAgent[];
|
||||
lookup: SidebarSessionWorkspaceLookup;
|
||||
}): SidebarSessionFilterAvailability {
|
||||
const workspaceKeys = new Set<string>();
|
||||
const projectKeys = new Set<string>();
|
||||
|
||||
for (const agent of input.agents) {
|
||||
@@ -96,12 +91,10 @@ export function deriveSidebarSessionFilterAvailability(input: {
|
||||
if (!workspace) {
|
||||
continue;
|
||||
}
|
||||
workspaceKeys.add(workspace.workspaceKey);
|
||||
projectKeys.add(workspace.projectKey);
|
||||
}
|
||||
|
||||
return {
|
||||
workspaceKeys: Array.from(workspaceKeys).sort(),
|
||||
projectKeys: Array.from(projectKeys).sort(),
|
||||
};
|
||||
}
|
||||
@@ -109,13 +102,11 @@ export function deriveSidebarSessionFilterAvailability(input: {
|
||||
export function deriveSidebarSessionFilterProjects(input: {
|
||||
projects: readonly SidebarProjectEntry[];
|
||||
availability: SidebarSessionFilterAvailability;
|
||||
workspaceNameByKey: ReadonlyMap<string, string>;
|
||||
}): SidebarProjectEntry[] {
|
||||
if (input.projects.length === 0 || input.availability.workspaceKeys.length === 0) {
|
||||
if (input.projects.length === 0 || input.availability.projectKeys.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const visibleWorkspaceKeys = new Set(input.availability.workspaceKeys);
|
||||
const visibleProjectKeys = new Set(input.availability.projectKeys);
|
||||
const projects: SidebarProjectEntry[] = [];
|
||||
|
||||
@@ -123,16 +114,7 @@ export function deriveSidebarSessionFilterProjects(input: {
|
||||
if (!visibleProjectKeys.has(project.projectKey)) {
|
||||
continue;
|
||||
}
|
||||
const workspaces = project.workspaces
|
||||
.filter((workspace) => visibleWorkspaceKeys.has(workspace.workspaceKey))
|
||||
.map((workspace) => {
|
||||
const name = input.workspaceNameByKey.get(workspace.workspaceKey);
|
||||
return name && name !== workspace.name ? Object.assign({}, workspace, { name }) : workspace;
|
||||
});
|
||||
if (workspaces.length === 0) {
|
||||
continue;
|
||||
}
|
||||
projects.push({ ...project, workspaces });
|
||||
projects.push(project);
|
||||
}
|
||||
|
||||
return projects;
|
||||
|
||||
@@ -128,22 +128,6 @@ function SidebarSessionsFilterMenu({
|
||||
</DropdownMenuItem>
|
||||
{visibleFilterProjects.length > 0 ? (
|
||||
<>
|
||||
<DropdownMenuSeparator />
|
||||
<FilterSectionHeading>Workspace</FilterSectionHeading>
|
||||
{visibleFilterProjects.flatMap((project) =>
|
||||
project.workspaces.map((workspace) => (
|
||||
<WorkspaceFilterItem
|
||||
key={workspace.workspaceKey}
|
||||
selected={
|
||||
filter.type === "workspace" && filter.workspaceKey === workspace.workspaceKey
|
||||
}
|
||||
label={workspace.name}
|
||||
description={project.projectName}
|
||||
workspaceKey={workspace.workspaceKey}
|
||||
onFilterChange={onFilterChange}
|
||||
/>
|
||||
)),
|
||||
)}
|
||||
<DropdownMenuSeparator />
|
||||
<FilterSectionHeading>Project</FilterSectionHeading>
|
||||
{visibleFilterProjects.map((project) => (
|
||||
@@ -225,30 +209,6 @@ function FilterSectionHeading({ children }: { children: string }) {
|
||||
);
|
||||
}
|
||||
|
||||
function WorkspaceFilterItem({
|
||||
selected,
|
||||
label,
|
||||
description,
|
||||
workspaceKey,
|
||||
onFilterChange,
|
||||
}: {
|
||||
selected: boolean;
|
||||
label: string;
|
||||
description: string;
|
||||
workspaceKey: string;
|
||||
onFilterChange: (filter: SidebarSessionFilter) => void;
|
||||
}) {
|
||||
const handleSelect = useCallback(() => {
|
||||
onFilterChange({ type: "workspace", workspaceKey });
|
||||
}, [onFilterChange, workspaceKey]);
|
||||
|
||||
return (
|
||||
<DropdownMenuItem selected={selected} description={description} onSelect={handleSelect}>
|
||||
{label}
|
||||
</DropdownMenuItem>
|
||||
);
|
||||
}
|
||||
|
||||
function ProjectFilterItem({
|
||||
selected,
|
||||
label,
|
||||
|
||||
@@ -2,10 +2,7 @@ import type { AggregatedAgent } from "@/hooks/use-aggregated-agents";
|
||||
|
||||
export type SidebarSessionViewMode = "workspaces" | "sessions";
|
||||
|
||||
export type SidebarSessionFilter =
|
||||
| { type: "all" }
|
||||
| { type: "workspace"; workspaceKey: string }
|
||||
| { type: "project"; projectKey: string };
|
||||
export type SidebarSessionFilter = { type: "all" } | { type: "project"; projectKey: string };
|
||||
|
||||
export interface SidebarSessionWorkspace {
|
||||
serverId: string;
|
||||
|
||||
@@ -97,7 +97,7 @@ afterEach(() => {
|
||||
});
|
||||
|
||||
describe("useVisibleSidebarSessionFilterProjects", () => {
|
||||
it("uses the hydrated workspace branch label for workspace filter options", () => {
|
||||
it("returns projects with mapped active sessions", () => {
|
||||
act(() => {
|
||||
useSessionStore.getState().initializeSession("server-1", {} as unknown as DaemonClient);
|
||||
useSessionStore.getState().setWorkspaces("server-1", new Map([["workspace-1", WORKSPACE]]));
|
||||
@@ -111,8 +111,6 @@ describe("useVisibleSidebarSessionFilterProjects", () => {
|
||||
}),
|
||||
);
|
||||
|
||||
expect(result.current[0]?.workspaces[0]?.name).toBe("feat-foo");
|
||||
expect(result.current[0]?.workspaces[0]?.name).not.toBe("/abs/path/to/repo");
|
||||
expect(result.current[0]?.workspaces[0]?.name).not.toBe("repo");
|
||||
expect(result.current.map((project) => project.projectKey)).toEqual(["project-a"]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
} from "./session-filtering";
|
||||
|
||||
const EMPTY_WORKSPACES: SidebarSessionWorkspace[] = [];
|
||||
const EMPTY_AVAILABILITY = { workspaceKeys: [], projectKeys: [] } as const;
|
||||
const EMPTY_AVAILABILITY = { projectKeys: [] } as const;
|
||||
|
||||
export function useSidebarSessionWorkspaces(input: {
|
||||
serverId: string | null;
|
||||
@@ -108,10 +108,7 @@ export function useVisibleSidebarSessionFilterProjects(input: {
|
||||
deriveSidebarSessionFilterProjects({
|
||||
projects: input.projects,
|
||||
availability,
|
||||
workspaceNameByKey: new Map(
|
||||
workspaces.map((workspace) => [workspace.workspaceKey, workspace.workspaceName]),
|
||||
),
|
||||
}),
|
||||
[availability, input.projects, workspaces],
|
||||
[availability, input.projects],
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user