-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Discover] Fix csv export with relative time filter from discover main view #123206
Changes from 4 commits
6f282a7
b1c777d
403132c
b5c36d9
cb16297
5666be9
22c12c4
1199e7d
c914287
0565dd7
762d51c
b2c7fbb
23f21ef
26b0493
25a87bb
2831c1c
2040d86
17927ed
d1a345a
135fb18
4198cb8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,7 +13,7 @@ import type { Filter, ISearchSource, SerializedSearchSourceFields } from 'src/pl | |
import { DOC_HIDE_TIME_COLUMN_SETTING, SORT_DEFAULT_ORDER_SETTING } from '../../common'; | ||
import type { SavedSearch, SortOrder } from '../services/saved_searches'; | ||
import { getSortForSearchSource } from '../components/doc_table'; | ||
import { AppState } from '../application/main/services/discover_state'; | ||
import { AppState, isEqualFilters } from '../application/main/services/discover_state'; | ||
|
||
/** | ||
* Preparing data to share the current state as link or CSV/Report | ||
|
@@ -26,7 +26,7 @@ export async function getSharingData( | |
const { uiSettings: config, data } = services; | ||
const searchSource = currentSearchSource.createCopy(); | ||
const index = searchSource.getField('index')!; | ||
const existingFilter = searchSource.getField('filter'); | ||
let existingFilter = searchSource.getField('filter') as Filter[] | Filter | undefined; | ||
|
||
searchSource.setField( | ||
'sort', | ||
|
@@ -56,10 +56,20 @@ export async function getSharingData( | |
|
||
return { | ||
getSearchSource: (absoluteTime?: boolean): SerializedSearchSourceFields => { | ||
const absoluteFilter = data.query.timefilter.timefilter.createFilter(index); | ||
kertal marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const timeFilter = absoluteTime | ||
? data.query.timefilter.timefilter.createFilter(index) | ||
? absoluteFilter | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, I think I can suggest a way to omit any potential race condition: So I'd suggest moving retrieving absolute and relative time filter to L64
And then depending on
this would prevent the race condition when auto refresh is on and refreshing before |
||
: data.query.timefilter.timefilter.createRelativeFilter(index); | ||
|
||
// remove timeFilter from existing filter | ||
if (Array.isArray(existingFilter)) { | ||
existingFilter = existingFilter.filter( | ||
(current) => !isEqualFilters(current, absoluteFilter) | ||
); | ||
} else if (isEqualFilters(existingFilter, absoluteFilter)) { | ||
existingFilter = undefined; | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. a first thought about this ... now is converted to absolute time when creating a filter, are we sure the generated time here matches to the existing time of the existing filter, which might also be converted, but it was converted before the creation of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @kertal it does look like there could be a race condition. This is quite tricky to reason about -- I agree tests for the different cases would be really useful (even as a way to document all this!). AFAICT there are 2 scenarios we want to handle:
In case 1 we want a search source containing an absolute time range so that we can give the user an accurate picture of their data in that moment. In case 2 we want to give users a "rolling window" so they can get their data over time (unless they've explicitly set an absolute time filter, then RIP relative time filter). A complication is in both cases there could be cascading time range filters, themselves either relative or absolute 🤪 therefore I think this code should try to "only" concern itself with the 2 scenarios AND not overriding existing filters. broadly something like: if (absoluteTime === true) {
// we want to generate a search source that will generate a picture of the data now
// append the absolute time filter
} else {
// we want to generate a search source that will provide a rolling window
// append the relative time filter
} What do you guys think? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, one piece I missed is "extracting" the current time range filter in Discover because we are converting to either relative or absolute, so some overriding is required 🤔 are these perhaps not separated by There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Alright, I think we agree then we should improve code here, but since we also need to backport I'd suggest to keep the scope small, just suggested a way we can be sure that there are no race conditions. If this is fine, it would fix the issue, and we could think about improving stuff in a future PR targeting simplification in this area. How does that sound |
||
if (existingFilter && timeFilter) { | ||
searchSource.setField( | ||
'filter', | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ppisljar we could simplify consumer code by always returning
Filter[]
fromgetField('filter')
instead ofFilter[] | Filter | (() => Filter[] | Filter | undefined)
. WDYT?It may have to be
Filter[] | (() => Filter[])
. Still, currently seems like a lot of things to check 😅