Skip to content

feat(posts): multi-select label filter on the posts list#34

Merged
paulocastellano merged 2 commits into
mainfrom
feat/posts-label-filter
May 14, 2026
Merged

feat(posts): multi-select label filter on the posts list#34
paulocastellano merged 2 commits into
mainfrom
feat/posts-label-filter

Conversation

@paulocastellano
Copy link
Copy Markdown
Contributor

Context

Posts list (/posts and its /scheduled / /posted / /drafts variants) was already showing labels on each row but had no way to filter by label. Users with many labels had to scroll or use search-by-content as a workaround.

Summary

  • Multi-select combobox in the toolbar (next to the existing search input). Users can pick 1+ labels and the list narrows to posts having any of them (OR semantics).
  • Mirrors the existing Popover + Command idiom used by the brand settings' FontPicker.vue — same UX pattern, no new dependency.
  • Trigger displays selected labels inline as badges (consistent with how each post row already renders its labels). 1-3 labels: shown directly. 4+: first three + +N.
  • Clear-all X button with tooltip and cursor-pointer. Three event stops (click, pointerdown, mousedown) so it doesn't reopen the Popover (the bug we hit during review).
  • Filter combines with search and the existing status tabs; URL is updated with preserveState + replace so back-button history stays clean.

Files

Area Change
app/Http/Controllers/App/PostController.php index() accepts ?labels[]=<id> and applies whereHas + whereIn. Sanitizes blank/empty entries. Exposes labels (workspace labels sorted by name) and filters.labels to the page.
resources/js/components/labels/LabelFilter.vue (new) The combobox component
resources/js/pages/posts/Index.vue Wires the filter — new selectedLabelIds model, watcher shared with search via a single buildFilterUrl helper
lang/{en,pt-BR,es}/posts.php filter_by_label, label_search_placeholder, no_labels, clear_label_filter
tests/Feature/PostControllerTest.php 4 new tests

Test plan

  • php artisan test --compact --parallel1509 passed, 2 skipped, 0 failed (+4 over main)
  • New: posts index exposes workspace labels for filter dropdown
  • New: filter by single label id
  • New: filter by multiple labels (OR semantics)
  • New: blank label query params are ignored
  • Manual: pick 1 label → list narrows; pick 2 → broader OR match; clear via X → list resets; refresh after filtering → state preserved

Adds a combobox-style filter to the posts index toolbar so users can
narrow All / Scheduled / Posted / Drafts views by one or more labels.

- `PostController::index` accepts `?labels[]=<id>` and applies
  `whereHas('labels', whereIn(...))` (OR semantics across selected labels).
  Workspace labels are exposed to the page (sorted by name) and the
  selected set comes back under `filters.labels`.
- New `LabelFilter.vue` component reuses the existing Popover + Command
  pattern (matching `FontPicker` in the Brand settings page). Trigger
  renders the selected `LabelBadge`s inline (mirroring how each post row
  already displays its labels): 1-3 shown directly, 4+ shown as the
  first three plus a "+N" overflow indicator. Clear button has a
  tooltip and `cursor-pointer`, and stops `click`/`pointerdown`/
  `mousedown` so it doesn't reopen the Popover.
- Existing search debounce is shared with the new label watcher via a
  single `buildFilterUrl` helper. URL is updated with `preserveState +
  replace` so the back stack stays clean.
- i18n in en / pt-BR / es: `filter_by_label`, `label_search_placeholder`,
  `no_labels`, `clear_label_filter`.

Tests: 4 new index tests covering the labels prop exposure, single-label
filter, multi-label OR filter, and blank-id sanitization. Full suite:
1509 passed, 2 skipped, 0 failed.
Same semantics, more idiomatic Laravel. Drops the (array) cast,
the array_values+array_filter pair, and the if (!empty(...)) guard
in favor of $request->collect() + Collection pipeline +
$query->when() conditional clause.
@paulocastellano paulocastellano merged commit f966b27 into main May 14, 2026
2 checks passed
@paulocastellano paulocastellano deleted the feat/posts-label-filter branch May 14, 2026 13:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant