From c61f5b190b75594c5a699f0b3ce69cc98a96ef88 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Thu, 19 Dec 2019 15:45:59 -0600 Subject: [PATCH] Move URL state to hook --- .../containers/logs/log_filter/index.ts | 2 +- .../log_filter/use_log_filter_url_state.tsx | 44 ++++++++++++++++++ .../log_filter/with_log_filter_url_state.tsx | 46 ------------------- .../pages/logs/stream/page_logs_content.tsx | 5 +- .../pages/logs/stream/page_providers.tsx | 7 +-- .../infra/public/utils/validate_url_rt.ts | 16 +++++++ 6 files changed, 67 insertions(+), 53 deletions(-) create mode 100644 x-pack/legacy/plugins/infra/public/containers/logs/log_filter/use_log_filter_url_state.tsx delete mode 100644 x-pack/legacy/plugins/infra/public/containers/logs/log_filter/with_log_filter_url_state.tsx create mode 100644 x-pack/legacy/plugins/infra/public/utils/validate_url_rt.ts diff --git a/x-pack/legacy/plugins/infra/public/containers/logs/log_filter/index.ts b/x-pack/legacy/plugins/infra/public/containers/logs/log_filter/index.ts index 4c4c317759bb..a2eaf9692b91 100644 --- a/x-pack/legacy/plugins/infra/public/containers/logs/log_filter/index.ts +++ b/x-pack/legacy/plugins/infra/public/containers/logs/log_filter/index.ts @@ -5,4 +5,4 @@ */ export * from './log_filter_state'; -export * from './with_log_filter_url_state'; +export * from './use_log_filter_url_state'; diff --git a/x-pack/legacy/plugins/infra/public/containers/logs/log_filter/use_log_filter_url_state.tsx b/x-pack/legacy/plugins/infra/public/containers/logs/log_filter/use_log_filter_url_state.tsx new file mode 100644 index 000000000000..f5d4dbea05f7 --- /dev/null +++ b/x-pack/legacy/plugins/infra/public/containers/logs/log_filter/use_log_filter_url_state.tsx @@ -0,0 +1,44 @@ +/* + * 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 { useContext, useEffect } from 'react'; +import * as rt from 'io-ts'; +import { LogFilterState } from './log_filter_state'; +import { replaceStateKeyInQueryString } from '../../../utils/url_state'; +import { useUrlState } from '../../../utils/use_url_state'; +import { getEncodeDecodeFromRT } from '../../../utils/validate_url_rt'; + +const logFilterRT = rt.union([ + rt.type({ + kind: rt.literal('kuery'), + expression: rt.string, + }), + rt.undefined, +]); +type LogFilterUrlState = rt.TypeOf; + +const LOG_FILTER_URL_STATE_KEY = 'logFilter'; + +export const useLogFilterUrlState = () => { + const { filterQueryAsKuery, applyLogFilterQuery } = useContext(LogFilterState.Context); + const [logFilterUrlState, setLogFilterUrlState] = useUrlState({ + defaultState: filterQueryAsKuery, + urlStateKey: LOG_FILTER_URL_STATE_KEY, + writeDefaultState: true, + ...getEncodeDecodeFromRT(logFilterRT), + }); + + /* eslint-disable react-hooks/exhaustive-deps */ + useEffect(() => applyLogFilterQuery(logFilterUrlState.expression), [logFilterUrlState]); + useEffect(() => setLogFilterUrlState(filterQueryAsKuery), [filterQueryAsKuery]); + /* eslint-enable react-hooks/exhaustive-deps */ +}; + +export const replaceLogFilterInQueryString = (expression: string) => + replaceStateKeyInQueryString('logFilter', { + kind: 'kuery', + expression, + }); diff --git a/x-pack/legacy/plugins/infra/public/containers/logs/log_filter/with_log_filter_url_state.tsx b/x-pack/legacy/plugins/infra/public/containers/logs/log_filter/with_log_filter_url_state.tsx deleted file mode 100644 index d1da6c715cfc..000000000000 --- a/x-pack/legacy/plugins/infra/public/containers/logs/log_filter/with_log_filter_url_state.tsx +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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 = () => { - const { filterQueryAsKuery, applyLogFilterQuery } = useContext(LogFilterState.Context); - return ( - { - 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('logFilter', { - kind: 'kuery', - expression, - }); diff --git a/x-pack/legacy/plugins/infra/public/pages/logs/stream/page_logs_content.tsx b/x-pack/legacy/plugins/infra/public/pages/logs/stream/page_logs_content.tsx index aff2a3b43106..0681a339efd1 100644 --- a/x-pack/legacy/plugins/infra/public/pages/logs/stream/page_logs_content.tsx +++ b/x-pack/legacy/plugins/infra/public/pages/logs/stream/page_logs_content.tsx @@ -15,7 +15,7 @@ import { PageContent } from '../../../components/page'; import { WithSummary } from '../../../containers/logs/log_summary'; import { LogViewConfiguration } from '../../../containers/logs/log_view_configuration'; -import { LogFilterState } from '../../../containers/logs/log_filter'; +import { LogFilterState, useLogFilterUrlState } from '../../../containers/logs/log_filter'; import { LogFlyout as LogFlyoutState, WithFlyoutOptionsUrlState, @@ -42,6 +42,9 @@ export const LogsPageLogsContent: React.FunctionComponent = () => { flyoutItem, isLoading, } = useContext(LogFlyoutState.Context); + + useLogFilterUrlState(); + const { logSummaryHighlights } = useContext(LogHighlightsState.Context); const { applyLogFilterQuery } = useContext(LogFilterState.Context); return ( diff --git a/x-pack/legacy/plugins/infra/public/pages/logs/stream/page_providers.tsx b/x-pack/legacy/plugins/infra/public/pages/logs/stream/page_providers.tsx index 63425368b040..3d325cfcf8d8 100644 --- a/x-pack/legacy/plugins/infra/public/pages/logs/stream/page_providers.tsx +++ b/x-pack/legacy/plugins/infra/public/pages/logs/stream/page_providers.tsx @@ -10,7 +10,7 @@ import { LogFlyout } from '../../../containers/logs/log_flyout'; import { LogViewConfiguration } from '../../../containers/logs/log_view_configuration'; import { LogHighlightsState } from '../../../containers/logs/log_highlights/log_highlights'; import { LogPositionState } from '../../../containers/logs/log_position'; -import { LogFilterState, WithLogFilterUrlState } from '../../../containers/logs/log_filter'; +import { LogFilterState } from '../../../containers/logs/log_filter'; import { LogEntriesState } from '../../../containers/logs/log_entries'; import { Source } from '../../../containers/source'; @@ -19,10 +19,7 @@ const LogFilterStateProvider: React.FC = ({ children }) => { const { createDerivedIndexPattern } = useContext(Source.Context); const derivedIndexPattern = createDerivedIndexPattern('logs'); return ( - - - {children} - + {children} ); }; diff --git a/x-pack/legacy/plugins/infra/public/utils/validate_url_rt.ts b/x-pack/legacy/plugins/infra/public/utils/validate_url_rt.ts new file mode 100644 index 000000000000..d68cef10f8c5 --- /dev/null +++ b/x-pack/legacy/plugins/infra/public/utils/validate_url_rt.ts @@ -0,0 +1,16 @@ +/* + * 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 { fold } from 'fp-ts/lib/Either'; +import { constant, identity } from 'fp-ts/lib/function'; +import { pipe } from 'fp-ts/lib/pipeable'; +import * as rt from 'io-ts'; + +export const getEncodeDecodeFromRT = (typeRT: rt.Type) => ({ + encodeUrlState: typeRT.encode, + decodeUrlState: (value: unknown) => + pipe(typeRT.decode(value), fold(constant(undefined), identity)), +});