diff --git a/ui/src/components/IssueFiltersPopover.test.tsx b/ui/src/components/IssueFiltersPopover.test.tsx
index 69eb612fee5..796735a8eb6 100644
--- a/ui/src/components/IssueFiltersPopover.test.tsx
+++ b/ui/src/components/IssueFiltersPopover.test.tsx
@@ -65,7 +65,6 @@ describe("IssueFiltersPopover", () => {
agents={[{ id: "agent-1", name: "Agent One" }]}
projects={[{ id: "project-1", name: "Project One" }]}
labels={[{ id: "label-1", name: "Bug", color: "#ff0000" }]}
- workspaces={[{ id: "workspace-1", name: "Workspace One" }]}
enableRoutineVisibilityFilter
/>,
);
@@ -73,6 +72,8 @@ describe("IssueFiltersPopover", () => {
const popoverContent = container.querySelector("[data-testid='popover-content']");
expect(popoverContent).not.toBeNull();
+ expect(popoverContent?.querySelector('[data-filter-options="workspaces"]')).toBeNull();
+ expect(popoverContent?.textContent).not.toContain("Workspace");
expect(popoverContent?.className).toContain("overflow-y-auto");
expect(popoverContent?.className).toContain("max-h-(--sz-calc-9)");
expect(popoverContent?.querySelectorAll(".overflow-y-auto").length).toBe(0);
@@ -97,7 +98,6 @@ describe("IssueFiltersPopover", () => {
agents={[{ id: "agent-1", name: "Agent One" }]}
projects={[{ id: "project-1", name: "Project One" }]}
labels={[{ id: "label-1", name: "Bug", color: "#ff0000" }]}
- workspaces={[{ id: "workspace-1", name: "Workspace One" }]}
enableRoutineVisibilityFilter
/>,
);
diff --git a/ui/src/components/IssueFiltersPopover.tsx b/ui/src/components/IssueFiltersPopover.tsx
index 05f717493e2..5546054e1f9 100644
--- a/ui/src/components/IssueFiltersPopover.tsx
+++ b/ui/src/components/IssueFiltersPopover.tsx
@@ -4,7 +4,7 @@ import { Badge } from "@/components/ui/badge";
import { Checkbox } from "@/components/ui/checkbox";
import { Input } from "@/components/ui/input";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
-import { Bot, Check, Filter, HardDrive, Search, User, X } from "lucide-react";
+import { Bot, Check, Filter, Search, User, X } from "lucide-react";
import { PriorityIcon } from "./PriorityIcon";
import { SHOW_TASK_PRIORITY_UI } from "../lib/ui-flags";
import { StatusIcon } from "./StatusIcon";
@@ -43,11 +43,6 @@ type LabelOption = {
color: string;
};
-type WorkspaceOption = {
- id: string;
- name: string;
-};
-
type CreatorOption = {
id: string;
label: string;
@@ -116,7 +111,6 @@ export function IssueFiltersPopover({
enableRoutineVisibilityFilter = false,
buttonVariant = "ghost",
iconOnly = false,
- workspaces,
creators,
presentation = "legacy",
inboxScopeFilters,
@@ -132,7 +126,6 @@ export function IssueFiltersPopover({
enableRoutineVisibilityFilter?: boolean;
buttonVariant?: "ghost" | "outline";
iconOnly?: boolean;
- workspaces?: WorkspaceOption[];
creators?: CreatorOption[];
presentation?: "legacy" | "streamlined";
inboxScopeFilters?: InboxScopeFilters;
@@ -142,7 +135,6 @@ export function IssueFiltersPopover({
const [assigneeSearch, setAssigneeSearch] = useState("");
const [projectSearch, setProjectSearch] = useState("");
const [labelSearch, setLabelSearch] = useState("");
- const [workspaceSearch, setWorkspaceSearch] = useState("");
const visibleAgents = useMemo(
() => searchIssueFilterOptions(agents, assigneeSearch, (option) => option.name),
[agents, assigneeSearch],
@@ -155,10 +147,6 @@ export function IssueFiltersPopover({
() => searchIssueFilterOptions(labels, labelSearch, (option) => option.name),
[labels, labelSearch],
);
- const visibleWorkspaces = useMemo(
- () => searchIssueFilterOptions(workspaces, workspaceSearch, (option) => option.name),
- [workspaces, workspaceSearch],
- );
const creatorOptions = creators ?? [];
const creatorOptionById = useMemo(
() => new Map(creatorOptions.map((option) => [option.id, option])),
@@ -490,27 +478,6 @@ export function IssueFiltersPopover({
) : null}
- {workspaces && workspaces.length > 0 ? (
-
-
Workspace
- {streamlined && workspaces.length > SEARCHABLE_FILTER_THRESHOLD ? (
-
- ) : null}
-
- {(streamlined ? visibleWorkspaces : workspaces).map((workspace) => (
-
- ))}
-
-
- ) : null}
-
{enableExternalObjectFilters ? (
External object status
diff --git a/ui/src/components/IssuesList.test.tsx b/ui/src/components/IssuesList.test.tsx
index 72cdcf23ecd..f50a3332c04 100644
--- a/ui/src/components/IssuesList.test.tsx
+++ b/ui/src/components/IssuesList.test.tsx
@@ -1928,6 +1928,56 @@ describe("IssuesList", () => {
});
});
+ it("ignores a saved workspace filter when the page address has no workspace query", async () => {
+ localStorage.setItem(
+ taskCollectionPreferencesStorageKey({
+ companyId: "company-1",
+ collectionKey: "paperclip:test-issues",
+ }),
+ JSON.stringify({
+ version: 1,
+ companyId: "company-1",
+ collectionKey: "paperclip:test-issues",
+ viewState: {
+ workspaces: ["workspace-alpha"],
+ },
+ columns: ["id"],
+ }),
+ );
+ const alphaIssue = createIssue({
+ id: "issue-alpha",
+ identifier: "PAP-40",
+ title: "Alpha issue",
+ executionWorkspaceId: "workspace-alpha",
+ });
+ const betaIssue = createIssue({
+ id: "issue-beta",
+ identifier: "PAP-41",
+ title: "Beta issue",
+ executionWorkspaceId: "workspace-beta",
+ });
+
+ const { root } = renderWithQueryClient(
+
undefined}
+ />,
+ container,
+ );
+
+ await waitForAssertion(() => {
+ expect(container.textContent).toContain("Alpha issue");
+ expect(container.textContent).toContain("Beta issue");
+ });
+
+ act(() => {
+ root.unmount();
+ });
+ });
+
it("applies an initial workspace filter from the issues URL state", async () => {
const alphaIssue = createIssue({
id: "issue-alpha",
diff --git a/ui/src/components/IssuesList.tsx b/ui/src/components/IssuesList.tsx
index da467d40fda..4603c567b9f 100644
--- a/ui/src/components/IssuesList.tsx
+++ b/ui/src/components/IssuesList.tsx
@@ -207,6 +207,9 @@ function normalizeIssueViewState(value: unknown): IssueViewState {
...defaultViewState,
...parsed,
...normalizeIssueFilterState(parsed),
+ // A saved workspace selection has no filter control. Drop it on load.
+ // `initialWorkspaces` from the page address is applied after this.
+ workspaces: [],
sortField: ["status", "priority", "title", "created", "updated", "workflow"].includes(parsed.sortField ?? "")
? parsed.sortField as IssueSortField
: defaultViewState.sortField,
@@ -1043,16 +1046,6 @@ function StreamlinedIssuesList({
return map;
}, [defaultProjectWorkspaceIds, executionWorkspaceById, projectWorkspaceById]);
- const workspaceOptions = useMemo(() => {
- const options = new Map();
- for (const [workspaceId, workspaceName] of workspaceNameMap) {
- options.set(workspaceId, workspaceName);
- }
- return [...options.entries()]
- .sort((a, b) => a[1].localeCompare(b[1]))
- .map(([id, name]) => ({ id, name }));
- }, [workspaceNameMap]);
-
const creatorOptions = useMemo(() => {
const options = new Map();
const knownAgentIds = new Set();
@@ -1920,7 +1913,6 @@ function StreamlinedIssuesList({
enableExternalObjectFilters={externalObjectsEnabled}
enableRoutineVisibilityFilter={enableRoutineVisibilityFilter}
iconOnly
- workspaces={isolatedWorkspacesEnabled ? workspaceOptions : undefined}
presentation={rowPresentation === "task" ? "streamlined" : "legacy"}
/>
diff --git a/ui/src/components/LegacyIssuesList.tsx b/ui/src/components/LegacyIssuesList.tsx
index 55cfbb48f6d..5cd5db5358a 100644
--- a/ui/src/components/LegacyIssuesList.tsx
+++ b/ui/src/components/LegacyIssuesList.tsx
@@ -198,6 +198,7 @@ function getViewState(key: string): IssueViewState {
...defaultViewState,
...parsed,
...normalizeIssueFilterState(parsed),
+ workspaces: [],
boardCardDensity: normalizeBoardCardDensity(parsed.boardCardDensity),
boardColdLaneMode: normalizeBoardColdLaneMode(parsed.boardColdLaneMode),
boardColumnPageSize: normalizeBoardColumnPageSize(parsed.boardColumnPageSize),
@@ -965,16 +966,6 @@ export function IssuesList({
return map;
}, [defaultProjectWorkspaceIds, executionWorkspaceById, projectWorkspaceById]);
- const workspaceOptions = useMemo(() => {
- const options = new Map();
- for (const [workspaceId, workspaceName] of workspaceNameMap) {
- options.set(workspaceId, workspaceName);
- }
- return [...options.entries()]
- .sort((a, b) => a[1].localeCompare(b[1]))
- .map(([id, name]) => ({ id, name }));
- }, [workspaceNameMap]);
-
const creatorOptions = useMemo(() => {
const options = new Map();
const knownAgentIds = new Set();
@@ -1814,7 +1805,6 @@ export function IssuesList({
enableExternalObjectFilters={externalObjectsEnabled}
enableRoutineVisibilityFilter={enableRoutineVisibilityFilter}
iconOnly
- workspaces={isolatedWorkspacesEnabled ? workspaceOptions : undefined}
/>
{/* Sort (list view only) */}
diff --git a/ui/src/lib/inbox.test.ts b/ui/src/lib/inbox.test.ts
index 36b3baf8067..79d0afbf397 100644
--- a/ui/src/lib/inbox.test.ts
+++ b/ui/src/lib/inbox.test.ts
@@ -1159,7 +1159,7 @@ describe("inbox helpers", () => {
creators: ["user:user-1"],
labels: ["label-1"],
projects: ["project-1"],
- workspaces: ["workspace-1"],
+ workspaces: [],
liveOnly: true,
externalObjectStatuses: [],
hideRoutineExecutions: false,
@@ -1210,7 +1210,7 @@ describe("inbox helpers", () => {
creators: ["user:user-1"],
labels: [],
projects: ["project-1"],
- workspaces: ["workspace-1"],
+ workspaces: [],
liveOnly: false,
externalObjectStatuses: [],
hideRoutineExecutions: false,
diff --git a/ui/src/lib/inbox.ts b/ui/src/lib/inbox.ts
index c95b015352c..368cc213a48 100644
--- a/ui/src/lib/inbox.ts
+++ b/ui/src/lib/inbox.ts
@@ -217,7 +217,10 @@ export function loadInboxFilterPreferences(
return {
allCategoryFilter: normalizeInboxCategoryFilter(parsed.allCategoryFilter),
allApprovalFilter: normalizeInboxApprovalFilter(parsed.allApprovalFilter),
- issueFilters: normalizeIssueFilterState(parsed.issueFilters),
+ issueFilters: {
+ ...normalizeIssueFilterState(parsed.issueFilters),
+ workspaces: [],
+ },
};
} catch {
return {
@@ -240,7 +243,10 @@ export function saveInboxFilterPreferences(
JSON.stringify({
allCategoryFilter: normalizeInboxCategoryFilter(preferences.allCategoryFilter),
allApprovalFilter: normalizeInboxApprovalFilter(preferences.allApprovalFilter),
- issueFilters: normalizeIssueFilterState(preferences.issueFilters),
+ issueFilters: {
+ ...normalizeIssueFilterState(preferences.issueFilters),
+ workspaces: [],
+ },
}),
);
} catch {
diff --git a/ui/src/pages/Inbox.tsx b/ui/src/pages/Inbox.tsx
index 37944e25d83..88ae042b349 100644
--- a/ui/src/pages/Inbox.tsx
+++ b/ui/src/pages/Inbox.tsx
@@ -221,7 +221,13 @@ function normalizeInboxCollectionViewState(value: unknown): StreamlinedInboxView
? category
: "everything",
allApprovalFilter: approval === "actionable" || approval === "resolved" ? approval : "all",
- issueFilters: normalizeIssueFilterState(candidate.issueFilters),
+ issueFilters: {
+ ...normalizeIssueFilterState(candidate.issueFilters),
+ // The filter menu no longer offers Workspace. Drop a saved selection so
+ // it cannot keep hiding tasks. A task-link workspace query is applied
+ // by the task list after this load.
+ workspaces: [],
+ },
showDateGroupSeparators: candidate.showDateGroupSeparators !== false,
};
}
@@ -2482,7 +2488,6 @@ function StreamlinedInbox({
enableRoutineVisibilityFilter
buttonVariant="outline"
iconOnly
- workspaces={isolatedWorkspacesEnabled ? executionWorkspaces.filter((w) => w.mode === "isolated_workspace").map((w) => ({ id: w.id, name: w.name })) : undefined}
presentation={streamlinedUiEnabled ? "streamlined" : "legacy"}
/>
@@ -2588,7 +2593,6 @@ function StreamlinedInbox({
enableRoutineVisibilityFilter
buttonVariant="outline"
iconOnly
- workspaces={isolatedWorkspacesEnabled ? executionWorkspaces.filter((w) => w.mode === "isolated_workspace").map((w) => ({ id: w.id, name: w.name })) : undefined}
presentation={streamlinedUiEnabled ? "streamlined" : "legacy"}
inboxScopeFilters={tab === "all" ? {
category: allCategoryFilter,
diff --git a/ui/src/pages/LegacyInbox.tsx b/ui/src/pages/LegacyInbox.tsx
index 35196635373..21d1a885e15 100644
--- a/ui/src/pages/LegacyInbox.tsx
+++ b/ui/src/pages/LegacyInbox.tsx
@@ -2353,7 +2353,6 @@ export function Inbox() {
enableRoutineVisibilityFilter
buttonVariant="outline"
iconOnly
- workspaces={isolatedWorkspacesEnabled ? executionWorkspaces.filter((w) => w.mode === "isolated_workspace").map((w) => ({ id: w.id, name: w.name })) : undefined}
/>
@@ -2452,7 +2451,6 @@ export function Inbox() {
enableRoutineVisibilityFilter
buttonVariant="outline"
iconOnly
- workspaces={isolatedWorkspacesEnabled ? executionWorkspaces.filter((w) => w.mode === "isolated_workspace").map((w) => ({ id: w.id, name: w.name })) : undefined}
/>
diff --git a/ui/storybook/stories/external-objects.stories.tsx b/ui/storybook/stories/external-objects.stories.tsx
index 00108d96e13..e0e91816dae 100644
--- a/ui/storybook/stories/external-objects.stories.tsx
+++ b/ui/storybook/stories/external-objects.stories.tsx
@@ -32,7 +32,6 @@ import {
import type { IssueExternalObjectGroup } from "@/hooks/useIssueExternalObjects";
import {
storybookAgents,
- storybookExecutionWorkspaces,
storybookIssueLabels,
storybookIssues,
storybookProjects,
@@ -650,7 +649,6 @@ function FilterPopoverWithExternalChecked() {
currentUserId="user-board"
enableRoutineVisibilityFilter
buttonVariant="outline"
- workspaces={storybookExecutionWorkspaces.map((workspace) => ({ id: workspace.id, name: workspace.name }))}
creators={[
{ id: "user:user-board", label: "Riley Board", kind: "user", searchText: "board user human" },
]}
diff --git a/ui/storybook/stories/issue-management.stories.tsx b/ui/storybook/stories/issue-management.stories.tsx
index 1939c5b3bfd..e1774d82d92 100644
--- a/ui/storybook/stories/issue-management.stories.tsx
+++ b/ui/storybook/stories/issue-management.stories.tsx
@@ -596,7 +596,6 @@ function OpenFiltersPopover() {
currentUserId="user-board"
enableRoutineVisibilityFilter
buttonVariant="outline"
- workspaces={storybookExecutionWorkspaces.map((workspace) => ({ id: workspace.id, name: workspace.name }))}
creators={[
{ id: "user:user-board", label: "Riley Board", kind: "user", searchText: "board user human" },
...storybookAgents.map((agent) => ({