Repository navigation
feat: filter in / filter out from the detail panel, with tag exclusions that AND correctly - #711
Conversation
An always-applied 'carries none of these labels' conjunct on lorekit_memory_list/_facets/_activity/_pivot, so 'tagged a AND NOT tagged b' is expressible alongside any tags_mode. Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
Both transports (GET query + POST body) decode it into MemoryDimensions and the four handlers forward it as p_exclude_tags. Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
… filter model The tag dimension keeps an include pill and an exclude pill that both hold (exclude_tags on the wire). applyValueFilter is the panel's filter in / filter out: the bar ANDed with the click, simplified exactly for single-valued fields. The policy handoff is withheld when a policy could not express it. Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
FilterableMetaValue's flyout is now two icon buttons (magnifier plus / minus), each explained by its own tooltip; a value already filtered in or out shows that button pressed and the value itself tinted or struck through. Enter / Shift+Enter on the value do the same from the keyboard. The filter menu marks excluded values with a minus instead of a check. Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
…ms.txt Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
|
The dashboard preview for this PR — redeployed on each push that changes the web app.
Preview always points at this PR's latest commit; Deployment is the immutable build of |
…stable A pill keyed by its slot remounted when its operator flipped between include and exclude, leaving the exiting pill in the DOM. Key a field's first pill by the field; only a tag's second pill gets its own key. Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
…ller Magnifiers read as search/zoom; the flyout acts on the filter bar. lucide has no funnel-minus, so it is FunnelPlus without the vertical stroke. Glyphs drop from 14px to 12px; buttons keep the 24px target size. Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
- useUrlState's optimistic value is now shared by key across instances (url-state-optimistic.ts), so a write from one component shows in every reader of the param at once instead of after the navigation lands. - On /lore the detail panel writes ?filters= / ?scope= through that URL state instead of router.push, so the Explorer updates immediately and every other param (sort, retention, the open lesson) is kept. - The flyout stops click propagation at its portal root and its buttons take no focus on mousedown: React bubbles portal events up the component tree, into TagsField's focus-the-input container. Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
🟡 1 non-blocking findingAdds 1 advisory finding below the confidence bar — see Less certain below.
Less certain (1) — advisory, below the confidence bar
Review details
Nothing to report — standards (5 docs), measurability (3 paths classified), integrations (not activated), 0 files skipped.
|
| if (target.kind === 'scope') { | ||
| return { | ||
| filters: filtersParamValue(current.filters, current.legacyTags, current.legacyOwner), | ||
| scope: target.scope, |
There was a problem hiding this comment.
issue (medium): 🟡 Pressed scope filter cannot be removed (non-blocking)
When ?scope= already equals this scope, the button reads pressed and promises removal, but nextMetadataFilterState writes the same scope again, so the click does nothing.
Evidence: packages/web/src/lib/filter-from-metadata.ts:288 (pressed tooltip promises removal) · packages/web/src/components/lore/LessonDetailSheet.tsx:399 (writes next.scope unchanged)
if (target.kind === 'scope') {
return {
filters: filtersParamValue(current.filters, current.legacyTags, current.legacyOwner),
scope: current.scope === target.scope ? null : target.scope,
};
}pr-reviewer · commit 96eaba2
|
Darkplane Automerge did not approve this pull request. It scored 40.56 of 100, and 75 was required.
The other criterion
An AI evaluator produced these scores from the diff, the repository history, and the pull request text. The pull request text is author-controlled, so treat the scores as signals rather than proof. Reviewed for commit 96eaba2. |
Summary
Hovering a value in a memory's detail panel now shows two icons, filter in (funnel +) and filter out (funnel −). Each icon has its own tooltip explaining what it does. Filter out adds a NOT condition, and the result is always the existing bar ANDed with the click. For tags this needed a new API capability: one
tagslist has one mode, so "taggedperfAND NOT taggedflaky" was not expressible. It is now (exclude_tags, migration 00114).Changes
p_exclude_tags text[]appended tolorekit_memory_list/_facets/_activity/_pivot. It is an always-applied "carries none of these" conjunct, reusinglorekit_match_tags(…, 'none'). The tag facet never self-excludes it, so an excluded tag stays listed at count 0. §114 inmigrations.test.sql.exclude_tagson the GET query and POST body forms of list/facets/activity/pivot, decoded by the shareddimensions.ts(edge mirror synced) and forwarded by the four handlers.filters.ts): tags keep an include pill and an exclude pill that both hold. Every other (single-valued) field keeps one pill.applyValueFilteris the panel's in/out:is not A+ filter out X →is not A, X;is A or X+ filter out X →is A;is not A+ filter in X →is X.is X→is not X.exclude_tagsis sent only beside a tag include. A lone exclusion keepstags_mode=none, so existing links and retention policies are unchanged.FilterableMetaValueshows the icon pair, the pressed state, and an in/out cue on the value (accent tint, or struck through). Keyboard:Enter= filter in,Shift+Enter= filter out. The scope offers filter in only, because the API has no "not this scope". The filter menu marks excluded values with a minus.tagscondition. A hand-edited prefill drops the exclusion visibly.tags.mdx,llms.txt(regenerated),docs/decisions.md,docs/key-files.md.Verification
deno check, migration order, and Integration smoke. Its "Migration DB tests" step ranmigrations.test.sql, including the new §114.webunit tests (incl. newfilters-polarity.spec.ts),schemastests, edge-schema parity,tsc./polish+review-looppass. Run/review-loopon this PR before undrafting.