-
Notifications
You must be signed in to change notification settings - Fork 8.5k
[Logs UI] Refactor query bar state to hooks #52656
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
Changes from 24 commits
ba2c456
f91debd
4e5035d
2759d2f
c16e03c
5798608
57b5b18
ede66d8
968b5a7
273d4de
783f9ab
9c39286
6e5c874
47ffa99
c5e165f
ef00491
8cb525d
c61f5b1
a7fe3ef
43302b3
9063d77
94ae628
9a7e15d
3cbf030
ce3a832
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 |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License; | ||
| * you may not use this file except in compliance with the Elastic License. | ||
| */ | ||
|
|
||
| import { useState, useMemo } from 'react'; | ||
| import createContainer from 'constate'; | ||
| import { IIndexPattern } from 'src/plugins/data/public'; | ||
| import { esKuery } from '../../../../../../../../src/plugins/data/public'; | ||
| import { convertKueryToElasticSearchQuery } from '../../../utils/kuery'; | ||
|
|
||
| export interface KueryFilterQuery { | ||
| kind: 'kuery'; | ||
| expression: string; | ||
| } | ||
|
|
||
| export interface SerializedFilterQuery { | ||
| query: KueryFilterQuery; | ||
| serializedQuery: string; | ||
| } | ||
|
|
||
| interface LogFilterInternalStateParams { | ||
| filterQuery: SerializedFilterQuery | null; | ||
| filterQueryDraft: KueryFilterQuery | null; | ||
| } | ||
|
|
||
| export const logFilterInitialState: LogFilterInternalStateParams = { | ||
| filterQuery: null, | ||
| filterQueryDraft: null, | ||
| }; | ||
|
|
||
| export type LogFilterStateParams = Omit<LogFilterInternalStateParams, 'filterQuery'> & { | ||
| filterQuery: SerializedFilterQuery['serializedQuery'] | null; | ||
| filterQueryAsKuery: SerializedFilterQuery['query'] | null; | ||
| isFilterQueryDraftValid: boolean; | ||
| }; | ||
| export interface LogFilterCallbacks { | ||
| setLogFilterQueryDraft: (expression: string) => void; | ||
| applyLogFilterQuery: (expression: string) => void; | ||
| } | ||
|
|
||
| export const useLogFilterState: (props: { | ||
| indexPattern: IIndexPattern; | ||
| }) => LogFilterStateParams & LogFilterCallbacks = ({ indexPattern }) => { | ||
| const [state, setState] = useState(logFilterInitialState); | ||
| const { filterQuery, filterQueryDraft } = state; | ||
|
|
||
| const setLogFilterQueryDraft = useMemo(() => { | ||
| const setDraft = (payload: KueryFilterQuery) => | ||
| setState(prevState => ({ ...prevState, filterQueryDraft: payload })); | ||
| return (expression: string) => | ||
| setDraft({ | ||
| kind: 'kuery', | ||
| expression, | ||
| }); | ||
| }, []); | ||
| const applyLogFilterQuery = useMemo(() => { | ||
| const applyQuery = (payload: SerializedFilterQuery) => | ||
| setState(prevState => ({ | ||
| ...prevState, | ||
| filterQueryDraft: payload.query, | ||
| filterQuery: payload, | ||
| })); | ||
| return (expression: string) => | ||
| applyQuery({ | ||
| query: { | ||
| kind: 'kuery', | ||
| expression, | ||
| }, | ||
| serializedQuery: convertKueryToElasticSearchQuery(expression, indexPattern), | ||
| }); | ||
| }, [indexPattern]); | ||
|
|
||
| const isFilterQueryDraftValid = useMemo(() => { | ||
| if (filterQueryDraft?.kind === 'kuery') { | ||
| try { | ||
| esKuery.fromKueryExpression(filterQueryDraft.expression); | ||
| } catch (err) { | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| return true; | ||
| }, [filterQueryDraft]); | ||
|
|
||
| const serializedFilterQuery = useMemo(() => (filterQuery ? filterQuery.serializedQuery : null), [ | ||
| filterQuery, | ||
| ]); | ||
|
|
||
| return { | ||
| ...state, | ||
| filterQueryAsKuery: state.filterQuery ? state.filterQuery.query : null, | ||
| filterQuery: serializedFilterQuery, | ||
| isFilterQueryDraftValid, | ||
| setLogFilterQueryDraft, | ||
| applyLogFilterQuery, | ||
| }; | ||
| }; | ||
|
|
||
| export const LogFilterState = createContainer(useLogFilterState); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License; | ||
| * you may not use this file except in compliance with the Elastic License. | ||
| */ | ||
|
|
||
| import React, { useContext } from 'react'; | ||
| import { LogFilterState, LogFilterStateParams } from './log_filter_state'; | ||
| import { replaceStateKeyInQueryString, UrlStateContainer } from '../../../utils/url_state'; | ||
|
|
||
| type LogFilterUrlState = LogFilterStateParams['filterQueryAsKuery']; | ||
|
|
||
| export const WithLogFilterUrlState: React.FC = () => { | ||
Zacqary marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| const { filterQueryAsKuery, applyLogFilterQuery } = useContext(LogFilterState.Context); | ||
| return ( | ||
| <UrlStateContainer | ||
| urlState={filterQueryAsKuery} | ||
| urlStateKey="logFilter" | ||
| mapToUrlState={mapToFilterQuery} | ||
| onChange={urlState => { | ||
| if (urlState) { | ||
| applyLogFilterQuery(urlState.expression); | ||
| } | ||
| }} | ||
| onInitialize={urlState => { | ||
| if (urlState) { | ||
| applyLogFilterQuery(urlState.expression); | ||
| } | ||
| }} | ||
| /> | ||
| ); | ||
| }; | ||
|
|
||
| const mapToFilterQuery = (value: any): LogFilterUrlState | undefined => | ||
| value?.kind === 'kuery' && typeof value.expression === 'string' | ||
| ? { | ||
| kind: value.kind, | ||
| expression: value.expression, | ||
| } | ||
| : undefined; | ||
|
|
||
| export const replaceLogFilterInQueryString = (expression: string) => | ||
| replaceStateKeyInQueryString<LogFilterUrlState>('logFilter', { | ||
| kind: 'kuery', | ||
| expression, | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,7 +7,6 @@ | |
| import React, { useEffect, useContext } from 'react'; | ||
|
|
||
| import { TimeKey } from '../../../../common/time'; | ||
| import { withLogFilter } from '../with_log_filter'; | ||
| import { withLogPosition } from '../with_log_position'; | ||
| import { LogHighlightsState } from './log_highlights'; | ||
|
|
||
|
|
@@ -35,21 +34,8 @@ export const LogHighlightsPositionBridge = withLogPosition( | |
| } | ||
| ); | ||
|
|
||
| export const LogHighlightsFilterQueryBridge = withLogFilter( | ||
| ({ serializedFilterQuery }: { serializedFilterQuery: string | null }) => { | ||
| const { setFilterQuery } = useContext(LogHighlightsState.Context); | ||
|
|
||
| useEffect(() => { | ||
| setFilterQuery(serializedFilterQuery); | ||
| }, [serializedFilterQuery, setFilterQuery]); | ||
|
|
||
| return null; | ||
| } | ||
| ); | ||
|
|
||
| export const LogHighlightsBridge = ({ indexPattern }: { indexPattern: any }) => ( | ||
| export const LogHighlightsBridge = () => ( | ||
|
Contributor
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. I guess we can get rid of this component altogether
Contributor
Author
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. In #50398 we can get rid of it, the log position state still needs the bridge right now though |
||
| <> | ||
| <LogHighlightsPositionBridge /> | ||
| <LogHighlightsFilterQueryBridge indexPattern={indexPattern} /> | ||
| </> | ||
| ); | ||
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.