Skip to content

feat: quick filter button#3120

Merged
Ziinc merged 18 commits intoLogflare:mainfrom
msmithstubbs:ui/quick-filter-button
Mar 20, 2026
Merged

feat: quick filter button#3120
Ziinc merged 18 commits intoLogflare:mainfrom
msmithstubbs:ui/quick-filter-button

Conversation

@msmithstubbs
Copy link
Copy Markdown
Contributor

@msmithstubbs msmithstubbs commented Jan 29, 2026

Adds a quick filter button the event viewer.

  • quick filter appends a FilterRule to the LQL query string of the current search.
  • the button is only displayed if the value is less than 500 characters
  • array values will use the list includes search operator
  • timestamp field the search will be +/- 1 of the current chart duration (eg. +1 hour and -1 hour).

The quick filter button is implemented as slot passed to the JSON view component. We could easily add more actions to the UI (even user configurable ones).

CleanShot 2026-01-29 at 16 57 48@2x

Todo

  • let's shrink the icon more
  • let's only show the icon on hover, we can always show icon for the event message and timestamp fields.
  • we should use the same tailing behaviour all the time even if it is a timestamp field,
  • extract the lql manipulation logic to Lql.Rules
  • use lql_schema from parent liveview in QueryComponents
  • source_schema_flat_map in liveview

Demo

CleanShot.2026-02-04.at.15.32.10.mp4

@msmithstubbs msmithstubbs force-pushed the ui/quick-filter-button branch 13 times, most recently from 66fbd43 to 5eed458 Compare February 4, 2026 05:16
@msmithstubbs msmithstubbs changed the title wip: quick filter button feat: quick filter button Feb 4, 2026
@msmithstubbs msmithstubbs marked this pull request as ready for review February 4, 2026 05:37
@msmithstubbs msmithstubbs force-pushed the ui/quick-filter-button branch 2 times, most recently from 6cbfb5d to b7ec690 Compare February 12, 2026 03:41
@msmithstubbs msmithstubbs force-pushed the ui/quick-filter-button branch from b7ec690 to 5fa2074 Compare February 22, 2026 23:51
resolved_path = resolve_lql_path(normalized_key, flat_map)
updated_lql = append_filter(lql, resolved_path, value, source, list_includes?)

is_tailing = if key == "timestamp", do: false, else: is_tailing
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm I'm of the opinion we should use the same tailing behaviour all the time even if it is a timestamp field, since this implies zooming in on historical data

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should use the same tailing behaviour all the time even if it is a timestamp field

I've removed the special case so tailing will be preserved from the current liveview state.
Is that how you wanted it to work?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea only want to trigger tailing on first view of the search page, other flows don't really make sense for the associated cost.

end
end

defp append_filter(lql, path, value, source, list_includes?) do
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can extract the lql manipulation logic to Lql.Rules,not the first time we're doing such rule manipulation

Copy link
Copy Markdown
Contributor Author

@msmithstubbs msmithstubbs Mar 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I switched this to use Rules.upsert_filter_rule_by_path

def upsert_filter_rule_by_path(lql_rules, %FilterRule{path: path} = filter_rule)

This will append the rule if doesn't exist, or replace if it does, which I think is the correct behaviour. I don't think we'd want the quick filter action to create a search with two rules ( m.qty:12 m.qty:11 for example) since that wouldn't return any results.

rules ++ [filter_rule]
end

defp lql_schema(source) do
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parent liveview should have this already

recursively drops the last path segment until it finds an array type.
"""
@spec normalize_array_key(String.t(), [String.t()], map()) :: {String.t(), boolean()} | nil
def normalize_array_key(key, path, flat_map) do
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my recollection, stored source schema flatmaps do not store the array index, could you double check the behaviour?
It would only store the inner types and not an individual key per index.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's correct, the array index key was coming from the JSON viewer component. I used the array index as a key when rendering arrays.

CleanShot 2026-03-17 at 14 36 19@2x

I've updated the JSON component so it doesn't pass the array index as a key anymore.
This means a little more duplicate in the JSON component, but less logic in QueryComponents.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. There could be edge case bugs where stringified numbers are used for field keys and the walk up will skip that level, could you check 🙏
Walk up logic is fine to keep though

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There could be edge case bugs where stringified numbers are used for field keys

It's a good point. I thought I'd handled that but it didn't work if the numeric key was in the middle of the field (metadata.0.info).

I'm sticking with passing the full path through from the view component. This should match the field name used in the schema flat map.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added test coverage, too.

Comment thread lib/logflare_web/components/query_components.ex Outdated
@Ziinc
Copy link
Copy Markdown
Contributor

Ziinc commented Mar 16, 2026

Styling wise:

  • let's shrink the icon more
  • let's only show the icon on hover, we can always show icon for the event message and timestamp fields.

@msmithstubbs msmithstubbs force-pushed the ui/quick-filter-button branch 5 times, most recently from a27bb45 to 0db6b6b Compare March 18, 2026 05:23
@Ziinc Ziinc merged commit c037d07 into Logflare:main Mar 20, 2026
10 checks passed
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.

2 participants