Gallery has no filter by stitch count range, by thread count range, by hoop size, or by date range — only text search and favorites-only #223

Closed
opened 2026-10-04 00:06:21 +00:00 by Mark · 0 comments
Owner

Finding

src/pages/Gallery.tsx's filter state includes:

  • searchQuery: string (text search on filename + hoopSize)
  • favoritesOnly: boolean (favorites filter)
  • activeFolder: string (folder filter)

No numeric range filters:

  • Stitch count range (e.g., 100-1000 stitches)
  • Thread count range (e.g., 2-5 colors)
  • Hoop size (e.g., only 4×4 designs)
  • Date range (e.g., designs from the last 7 days)

A user with 50 designs who wants to find all designs that fit in a 4×4 hoop:

  • Can't filter by hoop size
  • Has to read each card's hoop size
  • Or, set the workspace's hoop to 4×4 and try opening each design to see if it fits

A user with 50 designs who wants to find their "small" designs (under 1000 stitches):

  • Can't filter by stitch count
  • Has to scroll through every card

Where

  • Filter state: src/pages/Gallery.tsx (search, favorites, folder)
  • No numeric filter: grep -n 'stitchCount.*>=\|stitchCount.*<=' src/pages/Gallery.tsx returns 0
  • No date range: grep -n 'dateRange\|fromDate' src/pages/Gallery.tsx returns 0
  • Design type: src/components/gallery/types.ts:18 (has stitchCount, threadCount, hoopSize, editedAt)

Suggested fix shape

Add a "Filter" dropdown next to the Sort dropdown:

<DropdownMenu>
  <DropdownMenuTrigger>Filter</DropdownMenuTrigger>
  <DropdownMenuContent>
    <DropdownMenuLabel>Stitch count</DropdownMenuLabel>
    <SliderRow min={0} max={5000} step={100} value={stitchRange} onChange={setStitchRange} />
    <DropdownMenuLabel>Hoop size</DropdownMenuLabel>
    <CheckboxRow label="4×4" checked={hoops.fourByFour} onChange={...} />
    <CheckboxRow label="5×7" checked={hoops.fiveBySeven} onChange={...} />
    ...
  </DropdownMenuContent>
</DropdownMenu>

The filter is applied in the existing useMemo for filteredDesigns:

if (stitchRange) {
  result = result.filter((d) => d.stitchCount >= stitchRange[0] && d.stitchCount <= stitchRange[1]);
}
if (hoopFilter.length > 0) {
  result = result.filter((d) => hoopFilter.includes(d.hoopSize));
}

A "Clear filters" button in the dropdown resets everything.

The text search and folder selection are still the primary filters; the numeric ones are additional.

Severity

Low. The user can scroll. Power users with many designs notice.

Discovered by

Gap analysis (2026-10-02) of gallery filter options.

  • Sort (per #221) is the parallel concern.
  • Search: the text search is the baseline filter; numeric filters are additions.
  • The favorites filter (per #151) is the pattern to mirror for "sticky" filters that survive navigation.
## Finding `src/pages/Gallery.tsx`'s filter state includes: - `searchQuery: string` (text search on filename + hoopSize) - `favoritesOnly: boolean` (favorites filter) - `activeFolder: string` (folder filter) No numeric range filters: - Stitch count range (e.g., 100-1000 stitches) - Thread count range (e.g., 2-5 colors) - Hoop size (e.g., only 4×4 designs) - Date range (e.g., designs from the last 7 days) A user with 50 designs who wants to find all designs that fit in a 4×4 hoop: - Can't filter by hoop size - Has to read each card's hoop size - Or, set the workspace's hoop to 4×4 and try opening each design to see if it fits A user with 50 designs who wants to find their "small" designs (under 1000 stitches): - Can't filter by stitch count - Has to scroll through every card ## Where - Filter state: `src/pages/Gallery.tsx` (search, favorites, folder) - No numeric filter: `grep -n 'stitchCount.*>=\|stitchCount.*<=' src/pages/Gallery.tsx` returns 0 - No date range: `grep -n 'dateRange\|fromDate' src/pages/Gallery.tsx` returns 0 - Design type: `src/components/gallery/types.ts:18` (has stitchCount, threadCount, hoopSize, editedAt) ## Suggested fix shape Add a "Filter" dropdown next to the Sort dropdown: ```tsx <DropdownMenu> <DropdownMenuTrigger>Filter</DropdownMenuTrigger> <DropdownMenuContent> <DropdownMenuLabel>Stitch count</DropdownMenuLabel> <SliderRow min={0} max={5000} step={100} value={stitchRange} onChange={setStitchRange} /> <DropdownMenuLabel>Hoop size</DropdownMenuLabel> <CheckboxRow label="4×4" checked={hoops.fourByFour} onChange={...} /> <CheckboxRow label="5×7" checked={hoops.fiveBySeven} onChange={...} /> ... </DropdownMenuContent> </DropdownMenu> ``` The filter is applied in the existing `useMemo` for `filteredDesigns`: ```ts if (stitchRange) { result = result.filter((d) => d.stitchCount >= stitchRange[0] && d.stitchCount <= stitchRange[1]); } if (hoopFilter.length > 0) { result = result.filter((d) => hoopFilter.includes(d.hoopSize)); } ``` A "Clear filters" button in the dropdown resets everything. The text search and folder selection are still the primary filters; the numeric ones are additional. ## Severity Low. The user can scroll. Power users with many designs notice. ## Discovered by Gap analysis (2026-10-02) of gallery filter options. ## Related - Sort (per #221) is the parallel concern. - Search: the text search is the baseline filter; numeric filters are additions. - The favorites filter (per #151) is the pattern to mirror for "sticky" filters that survive navigation.
Mark 2026-10-04 04:57:00 +00:00
Sign in to join this conversation.
No description provided.