Skip to content

Commit 929dfea

Browse files
authored
feat(inbox): add "Any" option to Source and Priority filters (#3493)
1 parent afb19ea commit 929dfea

3 files changed

Lines changed: 62 additions & 0 deletions

File tree

packages/ui/src/features/inbox/components/InboxSearchFilterBar.tsx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,14 @@ export function InboxSearchFilterBar({
4040
const toggleSourceProduct = useInboxSignalsFilterStore(
4141
(s) => s.toggleSourceProduct,
4242
);
43+
const clearSourceProductFilter = useInboxSignalsFilterStore(
44+
(s) => s.clearSourceProductFilter,
45+
);
4346
const priorityFilter = useInboxSignalsFilterStore((s) => s.priorityFilter);
4447
const togglePriority = useInboxSignalsFilterStore((s) => s.togglePriority);
48+
const setPriorityFilter = useInboxSignalsFilterStore(
49+
(s) => s.setPriorityFilter,
50+
);
4551

4652
const activeSort = INBOX_SORT_OPTIONS.find(
4753
(option) =>
@@ -73,6 +79,10 @@ export function InboxSearchFilterBar({
7379
active={sourceProductFilter.length > 0}
7480
>
7581
<Flex direction="column" gap="0">
82+
<InboxFilterAnyItem
83+
active={sourceProductFilter.length === 0}
84+
onClick={clearSourceProductFilter}
85+
/>
7686
{INBOX_SOURCE_OPTIONS.map((option) => {
7787
const isActive = sourceProductFilter.includes(option.value);
7888
return (
@@ -132,6 +142,10 @@ export function InboxSearchFilterBar({
132142
active={priorityFilter.length > 0}
133143
>
134144
<Flex direction="column" gap="0">
145+
<InboxFilterAnyItem
146+
active={priorityFilter.length === 0}
147+
onClick={() => setPriorityFilter([])}
148+
/>
135149
{INBOX_PRIORITY_OPTIONS.map((option) => {
136150
const isActive = priorityFilter.includes(option.value);
137151
return (
@@ -160,6 +174,23 @@ export function InboxSearchFilterBar({
160174
);
161175
}
162176

177+
function InboxFilterAnyItem({
178+
active,
179+
onClick,
180+
}: {
181+
active: boolean;
182+
onClick: () => void;
183+
}) {
184+
return (
185+
<button type="button" className={FILTER_ITEM_CLASS} onClick={onClick}>
186+
<span className="truncate">Any</span>
187+
{active ? (
188+
<CheckIcon size={12} className="shrink-0 text-gray-12" />
189+
) : null}
190+
</button>
191+
);
192+
}
193+
163194
function InboxFilterPopover({
164195
label,
165196
value,

packages/ui/src/features/inbox/stores/inboxSignalsFilterStore.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,34 @@ describe("inboxSignalsFilterStore", () => {
7171
]);
7272
});
7373

74+
it("setPriorityFilter resets priorities back to Any (empty)", () => {
75+
useInboxSignalsFilterStore.getState().setPriorityFilter(["P0", "P1"]);
76+
77+
useInboxSignalsFilterStore.getState().setPriorityFilter([]);
78+
79+
expect(useInboxSignalsFilterStore.getState().priorityFilter).toEqual([]);
80+
});
81+
82+
it("clearSourceProductFilter resets sources back to Any (empty)", () => {
83+
useInboxSignalsFilterStore.getState().toggleSourceProduct("github");
84+
useInboxSignalsFilterStore.getState().toggleSourceProduct("linear");
85+
86+
useInboxSignalsFilterStore.getState().clearSourceProductFilter();
87+
88+
expect(useInboxSignalsFilterStore.getState().sourceProductFilter).toEqual(
89+
[],
90+
);
91+
});
92+
93+
it("toggling off the last source is equivalent to Any (empty)", () => {
94+
useInboxSignalsFilterStore.getState().toggleSourceProduct("github");
95+
useInboxSignalsFilterStore.getState().toggleSourceProduct("github");
96+
97+
expect(useInboxSignalsFilterStore.getState().sourceProductFilter).toEqual(
98+
[],
99+
);
100+
});
101+
74102
it("setPriorityFilter de-duplicates priorities", () => {
75103
useInboxSignalsFilterStore.getState().setPriorityFilter(["P0", "P1", "P0"]);
76104

packages/ui/src/features/inbox/stores/inboxSignalsFilterStore.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ interface InboxSignalsFilterActions {
3131
toggleSourceProduct: (source: SourceProduct) => void;
3232
togglePriority: (priority: SignalReportPriority) => void;
3333
setPriorityFilter: (priorities: SignalReportPriority[]) => void;
34+
/** Clear the source filter back to "Any" (empty = all sources). */
35+
clearSourceProductFilter: () => void;
3436
/** Reset all filters when a deep link arrives so the linked report isn't hidden. */
3537
resetFilters: () => void;
3638
}
@@ -74,6 +76,7 @@ export const useInboxSignalsFilterStore = create<InboxSignalsFilterStore>()(
7476
set({
7577
priorityFilter: Array.from(new Set(priorities)),
7678
}),
79+
clearSourceProductFilter: () => set({ sourceProductFilter: [] }),
7780
resetFilters: () =>
7881
set({
7982
searchQuery: "",

0 commit comments

Comments
 (0)