feat(filters): per-row AND/OR (Excel-style chips) + browse-on-click value menus (user report)
- Per-rule connectives: the chip before each rule flips that rule between AND and OR — OR-joined neighbors merge into an invisible OR-block, AND pulls them back out. The tree stays the single source of truth (implicit blocks are a client marker the server ignores), so deep links, saved filters, and the composed engine are untouched. Group-mode pills are gone; explicit groups remain as pure structure (+ group). Compile limit, same as Excel: flat chips express AND-of-OR-groups; a top-level OR of AND-blocks still needs nesting. - Browse-on-click: clicking an empty value box now fetches the field's top values UNDER the other rules (blank typed = browse, not a similarity filter) — 'assign an author, click Publisher, see their publishers' without typing. Server: the composed suggestion engine trims the typed query; client: the >=2-char guard no longer blocks the empty query, browse limit 15 vs 8 while typing. - Tests: the browse case pinned (blank sentinel + rules → the field's values under those rules, zero-match values absent).
This commit is contained in:
1 parent
6f98ca4c22
commit
c747f0a76c
7 files changed
+138
-36
No files matched your search
@@ -863,6 +863,10 @@ func (s *SearchService) ComposedFieldValues(ctx context.Context, p ComposedSugge
|
||||
if p.Limit <= 0 {
|
||||
p.Limit = 50
|
||||
}
|
||||
// A blank typed query means BROWSE (the user clicked the value box
|
||||
// to see what exists under the other rules) — not a similarity
|
||||
// filter for a single space.
|
||||
p.Typed = strings.TrimSpace(p.Typed)
|
||||
|
||||
b := newFilterBuilder(p.UserID)
|
||||
typedBind := b.bind(p.Typed)
|
||||
|
||||
Reference in new issue
Block a user