From 6113e98c0f977b73bdd1cb6778f740065929ce82 Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Fri, 23 Dec 2022 08:57:02 +0100 Subject: [PATCH 01/19] wip to bring useStorage to package --- package.json | 1 + tsconfig.base.json | 2 + x-pack/packages/ml/local_storage/README.md | 3 + .../ml/local_storage}/index.ts | 2 +- .../packages/ml/local_storage/jest.config.js | 12 ++ x-pack/packages/ml/local_storage/kibana.jsonc | 5 + x-pack/packages/ml/local_storage/package.json | 9 + .../ml/local_storage/src/is_defined.ts | 10 ++ .../src}/storage_context.test.tsx | 54 +++--- .../ml/local_storage/src/storage_context.tsx | 170 ++++++++++++++++++ .../packages/ml/local_storage/tsconfig.json | 17 ++ x-pack/plugins/ml/common/types/storage.ts | 7 +- x-pack/plugins/ml/public/application/app.tsx | 5 +- .../full_time_range_selector.tsx | 6 +- .../components/job_selector/job_selector.tsx | 2 +- .../contexts/ml/ml_notifications_context.tsx | 2 +- .../contexts/storage/storage_context.tsx | 140 --------------- .../public/application/explorer/explorer.tsx | 2 +- .../components/getting_started_callout.tsx | 2 +- .../series_controls/series_controls.tsx | 2 +- yarn.lock | 4 + 21 files changed, 277 insertions(+), 180 deletions(-) create mode 100644 x-pack/packages/ml/local_storage/README.md rename x-pack/{plugins/ml/public/application/contexts/storage => packages/ml/local_storage}/index.ts (76%) create mode 100644 x-pack/packages/ml/local_storage/jest.config.js create mode 100644 x-pack/packages/ml/local_storage/kibana.jsonc create mode 100644 x-pack/packages/ml/local_storage/package.json create mode 100644 x-pack/packages/ml/local_storage/src/is_defined.ts rename x-pack/{plugins/ml/public/application/contexts/storage => packages/ml/local_storage/src}/storage_context.test.tsx (80%) create mode 100644 x-pack/packages/ml/local_storage/src/storage_context.tsx create mode 100644 x-pack/packages/ml/local_storage/tsconfig.json delete mode 100644 x-pack/plugins/ml/public/application/contexts/storage/storage_context.tsx diff --git a/package.json b/package.json index 237861fe29817..735e50227d7e5 100644 --- a/package.json +++ b/package.json @@ -350,6 +350,7 @@ "@kbn/mapbox-gl": "link:packages/kbn-mapbox-gl", "@kbn/ml-agg-utils": "link:x-pack/packages/ml/agg_utils", "@kbn/ml-is-populated-object": "link:x-pack/packages/ml/is_populated_object", + "@kbn/ml-local-storage": "link:x-pack/packages/ml/local_storage", "@kbn/ml-nested-property": "link:x-pack/packages/ml/nested_property", "@kbn/ml-string-hash": "link:x-pack/packages/ml/string_hash", "@kbn/ml-url-state": "link:x-pack/packages/ml/url_state", diff --git a/tsconfig.base.json b/tsconfig.base.json index a0ac9a862d099..f4504e44f678b 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -816,6 +816,8 @@ "@kbn/ml-agg-utils/*": ["x-pack/packages/ml/agg_utils/*"], "@kbn/ml-is-populated-object": ["x-pack/packages/ml/is_populated_object"], "@kbn/ml-is-populated-object/*": ["x-pack/packages/ml/is_populated_object/*"], + "@kbn/ml-local-storage": ["x-pack/packages/ml/local_storage"], + "@kbn/ml-local-storage/*": ["x-pack/packages/ml/local_storage/*"], "@kbn/ml-nested-property": ["x-pack/packages/ml/nested_property"], "@kbn/ml-nested-property/*": ["x-pack/packages/ml/nested_property/*"], "@kbn/ml-plugin": ["x-pack/plugins/ml"], diff --git a/x-pack/packages/ml/local_storage/README.md b/x-pack/packages/ml/local_storage/README.md new file mode 100644 index 0000000000000..5ff246fddc2e5 --- /dev/null +++ b/x-pack/packages/ml/local_storage/README.md @@ -0,0 +1,3 @@ +# @kbn/ml-local-storage + +Empty package generated by @kbn/generate diff --git a/x-pack/plugins/ml/public/application/contexts/storage/index.ts b/x-pack/packages/ml/local_storage/index.ts similarity index 76% rename from x-pack/plugins/ml/public/application/contexts/storage/index.ts rename to x-pack/packages/ml/local_storage/index.ts index 8b17073d3b099..c84936b4a430c 100644 --- a/x-pack/plugins/ml/public/application/contexts/storage/index.ts +++ b/x-pack/packages/ml/local_storage/index.ts @@ -5,4 +5,4 @@ * 2.0. */ -export { MlStorageContextProvider, useStorage } from './storage_context'; +export { MlStorageContextProvider, useStorage } from './src/storage_context'; diff --git a/x-pack/packages/ml/local_storage/jest.config.js b/x-pack/packages/ml/local_storage/jest.config.js new file mode 100644 index 0000000000000..7de0a696c57ef --- /dev/null +++ b/x-pack/packages/ml/local_storage/jest.config.js @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../..', + roots: ['/x-pack/packages/ml/local_storage'], +}; diff --git a/x-pack/packages/ml/local_storage/kibana.jsonc b/x-pack/packages/ml/local_storage/kibana.jsonc new file mode 100644 index 0000000000000..8afac70248f4f --- /dev/null +++ b/x-pack/packages/ml/local_storage/kibana.jsonc @@ -0,0 +1,5 @@ +{ + "type": "shared-common", + "id": "@kbn/ml-local-storage", + "owner": "@elastic/ml-ui" +} diff --git a/x-pack/packages/ml/local_storage/package.json b/x-pack/packages/ml/local_storage/package.json new file mode 100644 index 0000000000000..af2452a92220b --- /dev/null +++ b/x-pack/packages/ml/local_storage/package.json @@ -0,0 +1,9 @@ +{ + "name": "@kbn/ml-local-storage", + "description": "Utilities to combine url state management with local storage.", + "author": "Machine Learning UI", + "homepage": "https://docs.elastic.dev/kibana-dev-docs/api/kbn-ml-local-storage", + "private": true, + "version": "1.0.0", + "license": "SSPL-1.0 OR Elastic License 2.0" +} diff --git a/x-pack/packages/ml/local_storage/src/is_defined.ts b/x-pack/packages/ml/local_storage/src/is_defined.ts new file mode 100644 index 0000000000000..ead91eafc2d4e --- /dev/null +++ b/x-pack/packages/ml/local_storage/src/is_defined.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export function isDefined(argument: T | undefined | null): argument is T { + return argument !== undefined && argument !== null; +} diff --git a/x-pack/plugins/ml/public/application/contexts/storage/storage_context.test.tsx b/x-pack/packages/ml/local_storage/src/storage_context.test.tsx similarity index 80% rename from x-pack/plugins/ml/public/application/contexts/storage/storage_context.test.tsx rename to x-pack/packages/ml/local_storage/src/storage_context.test.tsx index 6aeeb396f38c3..59d50949d74a3 100644 --- a/x-pack/plugins/ml/public/application/contexts/storage/storage_context.test.tsx +++ b/x-pack/packages/ml/local_storage/src/storage_context.test.tsx @@ -5,33 +5,33 @@ * 2.0. */ +import React, { FC } from 'react'; import { renderHook, act } from '@testing-library/react-hooks'; + +import type { Storage } from '@kbn/kibana-utils-plugin/public'; + import { MlStorageContextProvider, useStorage } from './storage_context'; -import { MlStorageKey } from '../../../../common/types/storage'; const mockSet = jest.fn(); const mockRemove = jest.fn(); - -jest.mock('../kibana', () => ({ - useMlKibana: () => { - return { - services: { - storage: { - set: mockSet, - get: jest.fn((key: MlStorageKey) => { - switch (key) { - case 'ml.gettingStarted.isDismissed': - return true; - default: - return; - } - }), - remove: mockRemove, - }, - }, - }; - }, -})); +const mockStorage: Storage = { + set: mockSet, + get: jest.fn((key: string) => { + switch (key) { + case 'ml.gettingStarted.isDismissed': + return true; + default: + return; + } + }), + remove: mockRemove, + store: jest.fn() as any, + clear: jest.fn(), +}; + +const Provider: FC = ({ children }) => { + return {children}; +}; describe('useStorage', () => { afterEach(() => { @@ -40,7 +40,7 @@ describe('useStorage', () => { test('returns the default value', () => { const { result } = renderHook(() => useStorage('ml.jobSelectorFlyout.applyTimeRange', true), { - wrapper: MlStorageContextProvider, + wrapper: Provider, }); expect(result.current[0]).toBe(true); @@ -48,7 +48,7 @@ describe('useStorage', () => { test('returns the value from storage', () => { const { result } = renderHook(() => useStorage('ml.gettingStarted.isDismissed', false), { - wrapper: MlStorageContextProvider, + wrapper: Provider, }); expect(result.current[0]).toBe(true); @@ -58,7 +58,7 @@ describe('useStorage', () => { const { result, waitForNextUpdate } = renderHook( () => useStorage('ml.gettingStarted.isDismissed'), { - wrapper: MlStorageContextProvider, + wrapper: Provider, } ); @@ -79,7 +79,7 @@ describe('useStorage', () => { const { result, waitForNextUpdate } = renderHook( () => useStorage('ml.gettingStarted.isDismissed'), { - wrapper: MlStorageContextProvider, + wrapper: Provider, } ); @@ -100,7 +100,7 @@ describe('useStorage', () => { const { result, waitForNextUpdate } = renderHook( () => useStorage('ml.gettingStarted.isDismissed'), { - wrapper: MlStorageContextProvider, + wrapper: Provider, } ); diff --git a/x-pack/packages/ml/local_storage/src/storage_context.tsx b/x-pack/packages/ml/local_storage/src/storage_context.tsx new file mode 100644 index 0000000000000..3e0ff17cb51d1 --- /dev/null +++ b/x-pack/packages/ml/local_storage/src/storage_context.tsx @@ -0,0 +1,170 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { + type PropsWithChildren, + useEffect, + useMemo, + useCallback, + useState, + useContext, +} from 'react'; +import { omit } from 'lodash'; + +import type { Storage } from '@kbn/kibana-utils-plugin/public'; + +import { isDefined } from './is_defined'; + +interface StorageDefinition { + [key: string]: unknown; +} + +interface StorageAPI { + value: Partial | null; + setValue: ( + key: Extract, + value: TStorageDefinition[keyof TStorageDefinition] + ) => void; + removeValue: (key: Extract) => void; +} + +export function isStorageKey(key: unknown, storageKeys: T[]): key is T { + return storageKeys.includes(key as T); +} + +export const MlStorageContext = React.createContext>({ + value: null, + setValue() { + throw new Error('MlStorageContext set method is not implemented'); + }, + removeValue() { + throw new Error('MlStorageContext remove method is not implemented'); + }, +}); + +interface MlStorageContextProviderProps< + TStorageDefinition extends StorageDefinition = {}, + TStorage extends Partial | null = null +> { + storage: Storage; + storageKeys: Array>; +} + +export function MlStorageContextProvider({ + children, + storage, + storageKeys, +}: PropsWithChildren>) { + const initialValue = useMemo(() => { + return storageKeys.reduce((acc, curr) => { + acc[curr as keyof TStorageDefinition] = storage.get(curr as string); + return acc; + }, {} as TStorageDefinition); + }, [storage, storageKeys]); + + const [state, setState] = useState>(initialValue); + + const setStorageValue: StorageAPI['setValue'] = useCallback( + (key: keyof TStorageDefinition, value: TStorageDefinition[keyof TStorageDefinition]) => { + storage.set(key as string, value); + + setState( + (prevState) => + ({ + ...prevState, + [key]: value, + } as Partial) + ); + }, + [storage] + ); + + const removeStorageValue: StorageAPI['removeValue'] = useCallback( + (key: keyof TStorageDefinition) => { + storage.remove(key as string); + setState((prevState) => + prevState === null ? prevState : (omit(prevState, key) as TStorageDefinition) + ); + }, + [storage] + ); + + useEffect( + function updateStorageOnExternalChange() { + const eventListener = (event: StorageEvent) => { + if (!isStorageKey(event.key, storageKeys)) return; + + if (isDefined(event.newValue)) { + setState((prev) => { + return { + ...prev, + [event.key as keyof TStorageDefinition]: + typeof event.newValue === 'string' ? JSON.parse(event.newValue) : event.newValue, + }; + }); + } else { + setState((prev) => { + return omit(prev, event.key as keyof TStorageDefinition) as TStorageDefinition; + }); + } + }; + + /** + * This event listener is only invoked when + * the change happens in another browser's tab. + */ + window.addEventListener('storage', eventListener); + + return () => { + window.removeEventListener('storage', eventListener); + }; + }, + [storageKeys] + ); + + const value: StorageAPI = useMemo(() => { + return { + value: state as StorageAPI['value'], + setValue: setStorageValue, + removeValue: removeStorageValue, + }; + }, [state, setStorageValue, removeStorageValue]); + + return {children}; +} + +/** + * Hook for consuming a storage value + * @param key + * @param initValue + */ +export function useStorage( + key: keyof TStorageDefinition, + initValue?: TStorageDefinition[keyof TStorageDefinition] | null +): [ + TStorageDefinition[keyof TStorageDefinition] | null | undefined, + (value: TStorageDefinition[keyof TStorageDefinition]) => void +] { + const { value, setValue, removeValue } = useContext(MlStorageContext); + + const resultValue = useMemo(() => { + return value?.[key] ?? initValue; + }, [value, key, initValue]); + + const setVal = useCallback( + (v: TStorageDefinition[keyof TStorageDefinition]) => { + if (isDefined(v)) { + setValue(key, v as never); + } else { + removeValue(key); + } + }, + [setValue, removeValue, key] + ); + + return [resultValue, setVal]; +} diff --git a/x-pack/packages/ml/local_storage/tsconfig.json b/x-pack/packages/ml/local_storage/tsconfig.json new file mode 100644 index 0000000000000..37f8e83d0d7a6 --- /dev/null +++ b/x-pack/packages/ml/local_storage/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../../../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "types": [ + "jest", + "node", + "react" + ] + }, + "include": [ + "**/*.ts", + "**/*.tsx", + ] +} diff --git a/x-pack/plugins/ml/common/types/storage.ts b/x-pack/plugins/ml/common/types/storage.ts index 34673b7c51059..f3f205f034b0b 100644 --- a/x-pack/plugins/ml/common/types/storage.ts +++ b/x-pack/plugins/ml/common/types/storage.ts @@ -51,14 +51,17 @@ export interface AnomalyExplorerPanelsState { mainPage: { size: number }; } -export type MlStorage = Partial<{ +export interface MlStorageRecord { + [key: string]: unknown; [ML_ENTITY_FIELDS_CONFIG]: PartitionFieldsConfig; [ML_APPLY_TIME_RANGE_CONFIG]: ApplyTimeRangeConfig; [ML_GETTING_STARTED_CALLOUT_DISMISSED]: boolean | undefined; [ML_FROZEN_TIER_PREFERENCE]: 'exclude-frozen' | 'include-frozen'; [ML_ANOMALY_EXPLORER_PANELS]: AnomalyExplorerPanelsState | undefined; [ML_NOTIFICATIONS_LAST_CHECKED_AT]: number | undefined; -}> | null; +} + +export type MlStorage = Partial | null; export type MlStorageKey = keyof Exclude; diff --git a/x-pack/plugins/ml/public/application/app.tsx b/x-pack/plugins/ml/public/application/app.tsx index 98fe9674bb567..dc42f963fd1a8 100644 --- a/x-pack/plugins/ml/public/application/app.tsx +++ b/x-pack/plugins/ml/public/application/app.tsx @@ -15,7 +15,8 @@ import type { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public'; import { Storage } from '@kbn/kibana-utils-plugin/public'; import { KibanaContextProvider, KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; -import { MlStorageContextProvider } from './contexts/storage'; +import { MlStorageContextProvider } from '@kbn/ml-local-storage'; +import { ML_STORAGE_KEYS } from '../../common/types/storage'; import { setDependencyCache, clearCache } from './util/dependency_cache'; import { setLicenseCache } from './license'; import type { MlSetupDependencies, MlStartDependencies } from '../plugin'; @@ -111,7 +112,7 @@ const App: FC = ({ coreStart, deps, appMountParams }) => { mlServices: getMlGlobalServices(coreStart.http, deps.usageCollection), }} > - + diff --git a/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx b/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx index 9b9154eb33660..c229ea869da31 100644 --- a/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx +++ b/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx @@ -22,9 +22,9 @@ import { import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; import { i18n } from '@kbn/i18n'; import type { DataView } from '@kbn/data-views-plugin/public'; +import { useStorage } from '@kbn/ml-local-storage'; import { setFullTimeRange } from './full_time_range_selector_service'; -import { useStorage } from '../../contexts/storage'; -import { ML_FROZEN_TIER_PREFERENCE } from '../../../../common/types/storage'; +import { ML_FROZEN_TIER_PREFERENCE, type MlStorageRecord } from '../../../../common/types/storage'; import { GetTimeFieldRangeResponse } from '../../services/ml_api_service'; interface Props { @@ -53,7 +53,7 @@ export const FullTimeRangeSelector: FC = ({ dataView, query, disabled, ca } const [isPopoverOpen, setPopover] = useState(false); - const [frozenDataPreference, setFrozenDataPreference] = useStorage( + const [frozenDataPreference, setFrozenDataPreference] = useStorage( ML_FROZEN_TIER_PREFERENCE, FROZEN_TIER_PREFERENCE.EXCLUDE ); diff --git a/x-pack/plugins/ml/public/application/components/job_selector/job_selector.tsx b/x-pack/plugins/ml/public/application/components/job_selector/job_selector.tsx index 9c49099c45946..fa2808638cbf5 100644 --- a/x-pack/plugins/ml/public/application/components/job_selector/job_selector.tsx +++ b/x-pack/plugins/ml/public/application/components/job_selector/job_selector.tsx @@ -19,6 +19,7 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { useUrlState } from '@kbn/ml-url-state'; import './_index.scss'; +import { useStorage } from '@kbn/ml-local-storage'; import { Dictionary } from '../../../../common/types/common'; import { IdBadges } from './id_badges'; import { @@ -27,7 +28,6 @@ import { JobSelectorFlyoutProps, } from './job_selector_flyout'; import { MlJobWithTimeRange } from '../../../../common/types/anomaly_detection_jobs'; -import { useStorage } from '../../contexts/storage'; import { ML_APPLY_TIME_RANGE_CONFIG } from '../../../../common/types/storage'; interface GroupObj { diff --git a/x-pack/plugins/ml/public/application/contexts/ml/ml_notifications_context.tsx b/x-pack/plugins/ml/public/application/contexts/ml/ml_notifications_context.tsx index 74b0a1ad54cb8..63e564b54422f 100644 --- a/x-pack/plugins/ml/public/application/contexts/ml/ml_notifications_context.tsx +++ b/x-pack/plugins/ml/public/application/contexts/ml/ml_notifications_context.tsx @@ -10,8 +10,8 @@ import { combineLatest, timer } from 'rxjs'; import { switchMap, map, tap, retry } from 'rxjs/operators'; import moment from 'moment'; import { isPopulatedObject } from '@kbn/ml-is-populated-object'; +import { useStorage } from '@kbn/ml-local-storage'; import { useMlKibana } from '../kibana'; -import { useStorage } from '../storage'; import { ML_NOTIFICATIONS_LAST_CHECKED_AT } from '../../../../common/types/storage'; import { useAsObservable } from '../../hooks'; import type { NotificationsCountResponse } from '../../../../common/types/notifications'; diff --git a/x-pack/plugins/ml/public/application/contexts/storage/storage_context.tsx b/x-pack/plugins/ml/public/application/contexts/storage/storage_context.tsx deleted file mode 100644 index 65e2a64ee3181..0000000000000 --- a/x-pack/plugins/ml/public/application/contexts/storage/storage_context.tsx +++ /dev/null @@ -1,140 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { FC, useEffect, useMemo, useCallback, useState, useContext } from 'react'; -import { omit } from 'lodash'; -import { isDefined } from '../../../../common/types/guards'; -import { useMlKibana } from '../kibana'; -import { MlStorage, ML_STORAGE_KEYS, isMlStorageKey } from '../../../../common/types/storage'; -import { MlStorageKey, TMlStorageMapped } from '../../../../common/types/storage'; - -interface StorageAPI { - value: MlStorage; - setValue: >(key: K, value: T) => void; - removeValue: (key: K) => void; -} - -export const MlStorageContext = React.createContext({ - value: null, - setValue() { - throw new Error('MlStorageContext set method is not implemented'); - }, - removeValue() { - throw new Error('MlStorageContext remove method is not implemented'); - }, -}); - -export const MlStorageContextProvider: FC = ({ children }) => { - const { - services: { storage }, - } = useMlKibana(); - - const initialValue = useMemo(() => { - return ML_STORAGE_KEYS.reduce((acc, curr) => { - acc[curr as MlStorageKey] = storage.get(curr); - return acc; - }, {} as Exclude); - }, [storage]); - - const [state, setState] = useState(initialValue); - - const setStorageValue = useCallback( - >(key: K, value: T) => { - storage.set(key, value); - - setState((prevState) => ({ - ...prevState, - [key]: value, - })); - }, - [storage] - ); - - const removeStorageValue = useCallback( - (key: MlStorageKey) => { - storage.remove(key); - setState((prevState) => omit(prevState, key)); - }, - [storage] - ); - - useEffect(function updateStorageOnExternalChange() { - const eventListener = (event: StorageEvent) => { - if (!isMlStorageKey(event.key)) return; - - if (isDefined(event.newValue)) { - setState((prev) => { - return { - ...prev, - [event.key as MlStorageKey]: - typeof event.newValue === 'string' ? JSON.parse(event.newValue) : event.newValue, - }; - }); - } else { - setState((prev) => { - return omit(prev, event.key as MlStorageKey); - }); - } - }; - - /** - * This event listener is only invoked when - * the change happens in another browser's tab. - */ - window.addEventListener('storage', eventListener); - - return () => { - window.removeEventListener('storage', eventListener); - }; - }, []); - - const value: StorageAPI = useMemo(() => { - return { - value: state, - setValue: setStorageValue, - removeValue: removeStorageValue, - }; - }, [state, setStorageValue, removeStorageValue]); - - return {children}; -}; - -/** - * Hook for consuming a storage value - * @param key - * @param initValue - */ -export function useStorage>( - key: K, - initValue?: T -): [ - typeof initValue extends undefined - ? TMlStorageMapped | undefined - : Exclude, undefined>, - (value: TMlStorageMapped) => void -] { - const { value, setValue, removeValue } = useContext(MlStorageContext); - - const resultValue = useMemo(() => { - return (value?.[key] ?? initValue) as typeof initValue extends undefined - ? TMlStorageMapped | undefined - : Exclude, undefined>; - }, [value, key, initValue]); - - const setVal = useCallback( - (v: TMlStorageMapped) => { - if (isDefined(v)) { - setValue(key, v); - } else { - removeValue(key); - } - }, - [setValue, removeValue, key] - ); - - return [resultValue, setVal]; -} diff --git a/x-pack/plugins/ml/public/application/explorer/explorer.tsx b/x-pack/plugins/ml/public/application/explorer/explorer.tsx index 6e224b25f506f..7c66b55e89271 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer.tsx +++ b/x-pack/plugins/ml/public/application/explorer/explorer.tsx @@ -31,6 +31,7 @@ import { css } from '@emotion/react'; import useObservable from 'react-use/lib/useObservable'; import type { DataView } from '@kbn/data-views-plugin/common'; import type { TimefilterContract } from '@kbn/data-plugin/public'; +import { useStorage } from '@kbn/ml-local-storage'; import { HelpPopover } from '../components/help_popover'; import { AnnotationFlyout } from '../components/annotations/annotation_flyout'; // @ts-ignore @@ -78,7 +79,6 @@ import { useMlKibana, useMlLocator } from '../contexts/kibana'; import { useMlContext } from '../contexts/ml'; import { useAnomalyExplorerContext } from './anomaly_explorer_context'; import { ML_ANOMALY_EXPLORER_PANELS } from '../../../common/types/storage'; -import { useStorage } from '../contexts/storage'; interface ExplorerPageProps { jobSelectorProps: JobSelectorProps; diff --git a/x-pack/plugins/ml/public/application/overview/components/getting_started_callout.tsx b/x-pack/plugins/ml/public/application/overview/components/getting_started_callout.tsx index 7b1f380c90658..d7a0370b4aeac 100644 --- a/x-pack/plugins/ml/public/application/overview/components/getting_started_callout.tsx +++ b/x-pack/plugins/ml/public/application/overview/components/getting_started_callout.tsx @@ -8,8 +8,8 @@ import React, { FC } from 'react'; import { EuiButton, EuiCallOut, EuiLink, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; +import { useStorage } from '@kbn/ml-local-storage'; import { useMlKibana } from '../../contexts/kibana'; -import { useStorage } from '../../contexts/storage'; import { ML_GETTING_STARTED_CALLOUT_DISMISSED } from '../../../../common/types/storage'; const feedbackLink = 'https://www.elastic.co/community/'; diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/series_controls/series_controls.tsx b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/series_controls/series_controls.tsx index 23084c8d8886d..b854efbe85172 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/series_controls/series_controls.tsx +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/series_controls/series_controls.tsx @@ -10,6 +10,7 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { EuiFlexGroup, EuiFlexItem, EuiFormRow, EuiSelect, EuiSelectProps } from '@elastic/eui'; import { debounce } from 'lodash'; import { lastValueFrom } from 'rxjs'; +import { useStorage } from '@kbn/ml-local-storage'; import { EntityControl } from '../entity_control'; import { mlJobService } from '../../../services/job_service'; import { Detector, JobId } from '../../../../../common/types/anomaly_detection_jobs'; @@ -26,7 +27,6 @@ import { PartitionFieldConfig, PartitionFieldsConfig, } from '../../../../../common/types/storage'; -import { useStorage } from '../../../contexts/storage'; import { EntityFieldType } from '../../../../../common/types/anomalies'; import { FieldDefinition } from '../../../services/results_service/result_service_rx'; import { getViewableDetectors } from '../../timeseriesexplorer_utils/get_viewable_detectors'; diff --git a/yarn.lock b/yarn.lock index f97da6163945c..db5c96fa66468 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3745,6 +3745,10 @@ version "0.0.0" uid "" +"@kbn/ml-local-storage@link:x-pack/packages/ml/local_storage": + version "0.0.0" + uid "" + "@kbn/ml-string-hash@link:x-pack/packages/ml/string_hash": version "0.0.0" uid "" From ff7b2ebbab9e92fad94f996f8db0853c0c943a56 Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Fri, 23 Dec 2022 10:31:17 +0100 Subject: [PATCH 02/19] fix package setup --- x-pack/packages/ml/local_storage/tsconfig.json | 12 ++++++++---- x-pack/plugins/ml/tsconfig.json | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/x-pack/packages/ml/local_storage/tsconfig.json b/x-pack/packages/ml/local_storage/tsconfig.json index 37f8e83d0d7a6..f7034734e45a5 100644 --- a/x-pack/packages/ml/local_storage/tsconfig.json +++ b/x-pack/packages/ml/local_storage/tsconfig.json @@ -1,9 +1,7 @@ { - "extends": "../../../../tsconfig.bazel.json", + "extends": "../../../../tsconfig.base.json", "compilerOptions": { - "declaration": true, - "emitDeclarationOnly": true, - "outDir": "target_types", + "outDir": "target/types", "types": [ "jest", "node", @@ -13,5 +11,11 @@ "include": [ "**/*.ts", "**/*.tsx", + ], + "exclude": [ + "target/**/*", + ], + "kbn_references": [ + "@kbn/kibana-utils-plugin", ] } diff --git a/x-pack/plugins/ml/tsconfig.json b/x-pack/plugins/ml/tsconfig.json index d5d42f865e2c0..e16c5a5055ff5 100644 --- a/x-pack/plugins/ml/tsconfig.json +++ b/x-pack/plugins/ml/tsconfig.json @@ -68,6 +68,7 @@ "@kbn/repo-info", "@kbn/ml-url-state", "@kbn/ml-nested-property", + "@kbn/ml-local-storage", ], "exclude": [ "target/**/*", From ade605dab640e90770fb53870b54a480e5ab37a2 Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Fri, 23 Dec 2022 10:50:36 +0100 Subject: [PATCH 03/19] refactor storage context to be based on generics. --- .../ml/local_storage/src/storage_context.tsx | 89 +++++++++---------- x-pack/plugins/ml/common/types/storage.ts | 6 +- .../full_time_range_selector.test.tsx | 2 +- .../full_time_range_selector.tsx | 14 +-- .../ml/ml_notifications_context.test.tsx | 4 +- .../contexts/ml/ml_notifications_context.tsx | 11 ++- .../series_controls/series_controls.tsx | 11 ++- 7 files changed, 71 insertions(+), 66 deletions(-) diff --git a/x-pack/packages/ml/local_storage/src/storage_context.tsx b/x-pack/packages/ml/local_storage/src/storage_context.tsx index 3e0ff17cb51d1..b2c0fc1f3d481 100644 --- a/x-pack/packages/ml/local_storage/src/storage_context.tsx +++ b/x-pack/packages/ml/local_storage/src/storage_context.tsx @@ -23,20 +23,21 @@ interface StorageDefinition { [key: string]: unknown; } -interface StorageAPI { - value: Partial | null; - setValue: ( - key: Extract, - value: TStorageDefinition[keyof TStorageDefinition] - ) => void; - removeValue: (key: Extract) => void; +type TStorage = Partial | null; +type TStorageKey = keyof Exclude; +type TStorageMapped = T extends string ? unknown : null; + +interface StorageAPI { + value: TStorage; + setValue: >(key: K, value: T) => void; + removeValue: (key: K) => void; } -export function isStorageKey(key: unknown, storageKeys: T[]): key is T { +export function isStorageKey(key: unknown, storageKeys: readonly T[]): key is T { return storageKeys.includes(key as T); } -export const MlStorageContext = React.createContext>({ +export const MlStorageContext = React.createContext({ value: null, setValue() { throw new Error('MlStorageContext set method is not implemented'); @@ -46,49 +47,41 @@ export const MlStorageContext = React.createContext | null = null -> { +interface MlStorageContextProviderProps { storage: Storage; - storageKeys: Array>; + storageKeys: readonly K[]; } -export function MlStorageContextProvider({ +export function MlStorageContextProvider({ children, storage, storageKeys, -}: PropsWithChildren>) { +}: PropsWithChildren>) { const initialValue = useMemo(() => { return storageKeys.reduce((acc, curr) => { - acc[curr as keyof TStorageDefinition] = storage.get(curr as string); + acc[curr as K] = storage.get(curr as string); return acc; - }, {} as TStorageDefinition); + }, {} as Exclude); }, [storage, storageKeys]); - const [state, setState] = useState>(initialValue); + const [state, setState] = useState(initialValue); - const setStorageValue: StorageAPI['setValue'] = useCallback( - (key: keyof TStorageDefinition, value: TStorageDefinition[keyof TStorageDefinition]) => { + const setStorageValue = useCallback( + >(key: K, value: TM) => { storage.set(key as string, value); - setState( - (prevState) => - ({ - ...prevState, - [key]: value, - } as Partial) - ); + setState((prevState) => ({ + ...prevState, + [key]: value, + })); }, [storage] ); - const removeStorageValue: StorageAPI['removeValue'] = useCallback( - (key: keyof TStorageDefinition) => { + const removeStorageValue = useCallback( + (key: K) => { storage.remove(key as string); - setState((prevState) => - prevState === null ? prevState : (omit(prevState, key) as TStorageDefinition) - ); + setState((prevState) => omit(prevState, key) as T); }, [storage] ); @@ -102,14 +95,12 @@ export function MlStorageContextProvider { return { ...prev, - [event.key as keyof TStorageDefinition]: + [event.key as K]: typeof event.newValue === 'string' ? JSON.parse(event.newValue) : event.newValue, }; }); } else { - setState((prev) => { - return omit(prev, event.key as keyof TStorageDefinition) as TStorageDefinition; - }); + setState((prev) => omit(prev, event.key as K) as T); } }; @@ -126,12 +117,12 @@ export function MlStorageContextProvider = useMemo(() => { + const value = useMemo(() => { return { - value: state as StorageAPI['value'], + value: state, setValue: setStorageValue, removeValue: removeStorageValue, - }; + } as StorageAPI; }, [state, setStorageValue, removeStorageValue]); return {children}; @@ -142,23 +133,25 @@ export function MlStorageContextProvider( - key: keyof TStorageDefinition, - initValue?: TStorageDefinition[keyof TStorageDefinition] | null +export function useStorage>( + key: K, + initValue?: T ): [ - TStorageDefinition[keyof TStorageDefinition] | null | undefined, - (value: TStorageDefinition[keyof TStorageDefinition]) => void + typeof initValue extends undefined ? T | undefined : Exclude, + (value: T) => void ] { const { value, setValue, removeValue } = useContext(MlStorageContext); const resultValue = useMemo(() => { - return value?.[key] ?? initValue; + return (value?.[key] ?? initValue) as typeof initValue extends undefined + ? T | undefined + : Exclude; }, [value, key, initValue]); const setVal = useCallback( - (v: TStorageDefinition[keyof TStorageDefinition]) => { + (v: T) => { if (isDefined(v)) { - setValue(key, v as never); + setValue(key, v); } else { removeValue(key); } diff --git a/x-pack/plugins/ml/common/types/storage.ts b/x-pack/plugins/ml/common/types/storage.ts index f3f205f034b0b..b11fa87cd44f7 100644 --- a/x-pack/plugins/ml/common/types/storage.ts +++ b/x-pack/plugins/ml/common/types/storage.ts @@ -86,8 +86,4 @@ export const ML_STORAGE_KEYS = [ ML_FROZEN_TIER_PREFERENCE, ML_ANOMALY_EXPLORER_PANELS, ML_NOTIFICATIONS_LAST_CHECKED_AT, -]; - -export function isMlStorageKey(key: unknown): key is MlStorageKey { - return typeof key === 'string' && ML_STORAGE_KEYS.includes(key); -} +] as const; diff --git a/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.test.tsx b/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.test.tsx index 7566d3664af61..442b1407aaf6d 100644 --- a/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.test.tsx +++ b/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.test.tsx @@ -20,7 +20,7 @@ jest.mock('./full_time_range_selector_service', () => ({ mockSetFullTimeRange(indexPattern, query), })); -jest.mock('../../contexts/storage', () => { +jest.mock('@kbn/ml-local-storage', () => { return { useStorage: jest.fn(() => 'exclude-frozen'), }; diff --git a/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx b/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx index c229ea869da31..a221ea05cd23f 100644 --- a/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx +++ b/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx @@ -24,7 +24,11 @@ import { i18n } from '@kbn/i18n'; import type { DataView } from '@kbn/data-views-plugin/public'; import { useStorage } from '@kbn/ml-local-storage'; import { setFullTimeRange } from './full_time_range_selector_service'; -import { ML_FROZEN_TIER_PREFERENCE, type MlStorageRecord } from '../../../../common/types/storage'; +import { + ML_FROZEN_TIER_PREFERENCE, + type MlStorageKey, + type TMlStorageMapped, +} from '../../../../common/types/storage'; import { GetTimeFieldRangeResponse } from '../../services/ml_api_service'; interface Props { @@ -53,10 +57,10 @@ export const FullTimeRangeSelector: FC = ({ dataView, query, disabled, ca } const [isPopoverOpen, setPopover] = useState(false); - const [frozenDataPreference, setFrozenDataPreference] = useStorage( - ML_FROZEN_TIER_PREFERENCE, - FROZEN_TIER_PREFERENCE.EXCLUDE - ); + const [frozenDataPreference, setFrozenDataPreference] = useStorage< + MlStorageKey, + TMlStorageMapped + >(ML_FROZEN_TIER_PREFERENCE, FROZEN_TIER_PREFERENCE.EXCLUDE); const onButtonClick = () => { setPopover(!isPopoverOpen); diff --git a/x-pack/plugins/ml/public/application/contexts/ml/ml_notifications_context.test.tsx b/x-pack/plugins/ml/public/application/contexts/ml/ml_notifications_context.test.tsx index dd24789462cf7..ad6c05d07d4e1 100644 --- a/x-pack/plugins/ml/public/application/contexts/ml/ml_notifications_context.test.tsx +++ b/x-pack/plugins/ml/public/application/contexts/ml/ml_notifications_context.test.tsx @@ -8,7 +8,7 @@ import { renderHook, act } from '@testing-library/react-hooks'; import { of, throwError } from 'rxjs'; import { useMlNotifications, MlNotificationsContextProvider } from './ml_notifications_context'; -import { useStorage } from '../storage'; +import { useStorage } from '@kbn/ml-local-storage'; import { useMlKibana } from '../kibana'; const mockCountMessages = jest.fn(() => { @@ -43,7 +43,7 @@ jest.mock('../kibana', () => ({ })); const mockSetStorageValue = jest.fn(); -jest.mock('../storage', () => ({ +jest.mock('@kbn/ml-local-storage', () => ({ useStorage: jest.fn(() => { return [undefined, mockSetStorageValue]; }), diff --git a/x-pack/plugins/ml/public/application/contexts/ml/ml_notifications_context.tsx b/x-pack/plugins/ml/public/application/contexts/ml/ml_notifications_context.tsx index 63e564b54422f..67e479f1291f5 100644 --- a/x-pack/plugins/ml/public/application/contexts/ml/ml_notifications_context.tsx +++ b/x-pack/plugins/ml/public/application/contexts/ml/ml_notifications_context.tsx @@ -12,7 +12,11 @@ import moment from 'moment'; import { isPopulatedObject } from '@kbn/ml-is-populated-object'; import { useStorage } from '@kbn/ml-local-storage'; import { useMlKibana } from '../kibana'; -import { ML_NOTIFICATIONS_LAST_CHECKED_AT } from '../../../../common/types/storage'; +import { + ML_NOTIFICATIONS_LAST_CHECKED_AT, + type MlStorageKey, + type TMlStorageMapped, +} from '../../../../common/types/storage'; import { useAsObservable } from '../../hooks'; import type { NotificationsCountResponse } from '../../../../common/types/notifications'; @@ -47,7 +51,10 @@ export const MlNotificationsContextProvider: FC = ({ children }) => { const canGetNotifications = canGetJobs && canGetDataFrameAnalytics && canGetTrainedModels; - const [lastCheckedAt, setLastCheckedAt] = useStorage(ML_NOTIFICATIONS_LAST_CHECKED_AT); + const [lastCheckedAt, setLastCheckedAt] = useStorage< + MlStorageKey, + TMlStorageMapped + >(ML_NOTIFICATIONS_LAST_CHECKED_AT); const lastCheckedAt$ = useAsObservable(lastCheckedAt); /** Holds the value used for the actual request */ diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/series_controls/series_controls.tsx b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/series_controls/series_controls.tsx index b854efbe85172..8d79a41b0ab36 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/series_controls/series_controls.tsx +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/series_controls/series_controls.tsx @@ -24,8 +24,10 @@ import { import { getControlsForDetector } from '../../get_controls_for_detector'; import { ML_ENTITY_FIELDS_CONFIG, - PartitionFieldConfig, - PartitionFieldsConfig, + type PartitionFieldConfig, + type PartitionFieldsConfig, + type MlStorageKey, + type TMlStorageMapped, } from '../../../../../common/types/storage'; import { EntityFieldType } from '../../../../../common/types/anomalies'; import { FieldDefinition } from '../../../services/results_service/result_service_rx'; @@ -113,7 +115,10 @@ export const SeriesControls: FC = ({ return getControlsForDetector(selectedDetectorIndex, selectedEntities, selectedJobId); }, [selectedDetectorIndex, selectedEntities, selectedJobId]); - const [storageFieldsConfig, setStorageFieldsConfig] = useStorage(ML_ENTITY_FIELDS_CONFIG); + const [storageFieldsConfig, setStorageFieldsConfig] = useStorage< + MlStorageKey, + TMlStorageMapped + >(ML_ENTITY_FIELDS_CONFIG); // Merge the default config with the one from the local storage const resultFieldsConfig = useMemo(() => { From 20a58e30f4b1c55104c34daedb35cb5bc174b1bb Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Fri, 23 Dec 2022 11:04:45 +0100 Subject: [PATCH 04/19] fix jest tests --- .../ml/common/types/storage.test.tsx} | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) rename x-pack/{packages/ml/local_storage/src/storage_context.test.tsx => plugins/ml/common/types/storage.test.tsx} (92%) diff --git a/x-pack/packages/ml/local_storage/src/storage_context.test.tsx b/x-pack/plugins/ml/common/types/storage.test.tsx similarity index 92% rename from x-pack/packages/ml/local_storage/src/storage_context.test.tsx rename to x-pack/plugins/ml/common/types/storage.test.tsx index 59d50949d74a3..f5773e8ea6933 100644 --- a/x-pack/packages/ml/local_storage/src/storage_context.test.tsx +++ b/x-pack/plugins/ml/common/types/storage.test.tsx @@ -9,8 +9,9 @@ import React, { FC } from 'react'; import { renderHook, act } from '@testing-library/react-hooks'; import type { Storage } from '@kbn/kibana-utils-plugin/public'; +import { MlStorageContextProvider, useStorage } from '@kbn/ml-local-storage'; -import { MlStorageContextProvider, useStorage } from './storage_context'; +import { ML_STORAGE_KEYS } from './storage'; const mockSet = jest.fn(); const mockRemove = jest.fn(); @@ -30,7 +31,11 @@ const mockStorage: Storage = { }; const Provider: FC = ({ children }) => { - return {children}; + return ( + + {children} + + ); }; describe('useStorage', () => { From 6be2cde3e2ddd83f734578e51c3587608c70a17a Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Fri, 23 Dec 2022 11:24:29 +0100 Subject: [PATCH 05/19] use local storage package for data visualizer --- .../full_time_range_selector.tsx | 8 +++- .../index_data_visualizer_view.tsx | 20 ++++---- .../hooks/use_storage.ts | 48 ------------------- .../index_data_visualizer/types/storage.ts | 28 +++++++++++ 4 files changed, 46 insertions(+), 58 deletions(-) delete mode 100644 x-pack/plugins/data_visualizer/public/application/index_data_visualizer/hooks/use_storage.ts create mode 100644 x-pack/plugins/data_visualizer/public/application/index_data_visualizer/types/storage.ts diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/full_time_range_selector/full_time_range_selector.tsx b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/full_time_range_selector/full_time_range_selector.tsx index 1cade1deaa59a..c7764b01762bf 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/full_time_range_selector/full_time_range_selector.tsx +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/full_time_range_selector/full_time_range_selector.tsx @@ -23,9 +23,10 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; +import { useStorage } from '@kbn/ml-local-storage'; import { setFullTimeRange } from './full_time_range_selector_service'; import { useDataVisualizerKibana } from '../../../kibana_context'; -import { DV_FROZEN_TIER_PREFERENCE, useStorage } from '../../hooks/use_storage'; +import { DV_FROZEN_TIER_PREFERENCE, type DVKey, type DVStorageMapped } from '../../types/storage'; export const ML_FROZEN_TIER_PREFERENCE = 'ml.frozenDataTierPreference'; @@ -83,7 +84,10 @@ export const FullTimeRangeSelector: FC = ({ const [isPopoverOpen, setPopover] = useState(false); - const [frozenDataPreference, setFrozenDataPreference] = useStorage( + const [frozenDataPreference, setFrozenDataPreference] = useStorage< + DVKey, + DVStorageMapped + >( DV_FROZEN_TIER_PREFERENCE, // By default we will exclude frozen data tier FROZEN_TIER_PREFERENCE.EXCLUDE diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx index 8e13ce92a5c1e..9ec8b90d84f02 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx @@ -27,8 +27,13 @@ import { generateFilters } from '@kbn/data-plugin/public'; import { DataView, DataViewField } from '@kbn/data-views-plugin/public'; import { usePageUrlState, useUrlState } from '@kbn/ml-url-state'; +import { useStorage } from '@kbn/ml-local-storage'; import { useCurrentEuiTheme } from '../../../common/hooks/use_current_eui_theme'; -import { DV_RANDOM_SAMPLER_PREFERENCE, useStorage } from '../../hooks/use_storage'; +import { + DV_RANDOM_SAMPLER_PREFERENCE, + type DVKey, + type DVStorageMapped, +} from '../../types/storage'; import { FullTimeRangeSelector } from '../full_time_range_selector'; import { DataVisualizerTable, @@ -58,7 +63,7 @@ import { DataVisualizerDataViewManagement } from '../data_view_management'; import { GetAdditionalLinks } from '../../../common/components/results_links'; import { useDataVisualizerGridData } from '../../hooks/use_data_visualizer_grid_data'; import { DataVisualizerGridInput } from '../../embeddables/grid_embeddable/grid_embeddable'; -import { RANDOM_SAMPLER_OPTION, RandomSamplerOption } from '../../constants/random_sampler'; +import { RANDOM_SAMPLER_OPTION } from '../../constants/random_sampler'; interface DataVisualizerPageState { overallStats: OverallStats; @@ -126,18 +131,17 @@ export interface IndexDataVisualizerViewProps { export const IndexDataVisualizerView: FC = (dataVisualizerProps) => { const euiTheme = useCurrentEuiTheme(); - const [savedRandomSamplerPreference, saveRandomSamplerPreference] = - useStorage( - DV_RANDOM_SAMPLER_PREFERENCE, - RANDOM_SAMPLER_OPTION.ON_AUTOMATIC - ); + const [savedRandomSamplerPreference, saveRandomSamplerPreference] = useStorage< + DVKey, + DVStorageMapped + >(DV_RANDOM_SAMPLER_PREFERENCE, RANDOM_SAMPLER_OPTION.ON_AUTOMATIC); const restorableDefaults = useMemo( () => getDefaultDataVisualizerListState({ rndSamplerPref: savedRandomSamplerPreference, }), - // We just need to load the saved preference when the page is first loaded + // We just need to load the saved preference when the page is first loaded // eslint-disable-next-line react-hooks/exhaustive-deps [] ); diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/hooks/use_storage.ts b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/hooks/use_storage.ts deleted file mode 100644 index cd09967a81fa0..0000000000000 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/hooks/use_storage.ts +++ /dev/null @@ -1,48 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { useCallback, useState } from 'react'; -import { useDataVisualizerKibana } from '../../kibana_context'; - -export const DV_FROZEN_TIER_PREFERENCE = 'dataVisualizer.frozenDataTierPreference'; -export const DV_RANDOM_SAMPLER_PREFERENCE = 'dataVisualizer.randomSamplerPreference'; -export const DV_RANDOM_SAMPLER_P_VALUE = 'dataVisualizer.randomSamplerPValue'; - -export type DV = Partial<{ - [DV_FROZEN_TIER_PREFERENCE]: 'exclude_frozen' | 'include_frozen'; - [DV_RANDOM_SAMPLER_PREFERENCE]: 'true' | 'false'; - [DV_RANDOM_SAMPLER_P_VALUE]: number; -}> | null; - -export type DVKey = keyof Exclude; - -/** - * Hook for accessing and changing a value in the storage. - * @param key - Storage key - * @param initValue - */ -export function useStorage(key: DVKey, initValue?: T): [T, (value: T) => void] { - const { - services: { storage }, - } = useDataVisualizerKibana(); - - const [val, setVal] = useState(storage.get(key) ?? initValue); - - const setStorage = useCallback( - (value: T): void => { - try { - storage.set(key, value); - setVal(value); - } catch (e) { - throw new Error('Unable to update storage with provided value'); - } - }, - [key, storage] - ); - - return [val, setStorage]; -} diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/types/storage.ts b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/types/storage.ts new file mode 100644 index 0000000000000..7a0397abb8956 --- /dev/null +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/types/storage.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { RandomSamplerOption } from '../constants/random_sampler'; + +export const DV_FROZEN_TIER_PREFERENCE = 'dataVisualizer.frozenDataTierPreference'; +export const DV_RANDOM_SAMPLER_PREFERENCE = 'dataVisualizer.randomSamplerPreference'; +export const DV_RANDOM_SAMPLER_P_VALUE = 'dataVisualizer.randomSamplerPValue'; + +export type DV = Partial<{ + [DV_FROZEN_TIER_PREFERENCE]: 'exclude_frozen' | 'include_frozen'; + [DV_RANDOM_SAMPLER_PREFERENCE]: RandomSamplerOption; + [DV_RANDOM_SAMPLER_P_VALUE]: number; +}> | null; + +export type DVKey = keyof Exclude; + +export type DVStorageMapped = T extends typeof DV_FROZEN_TIER_PREFERENCE + ? 'exclude-frozen' | 'include-frozen' | undefined + : T extends typeof DV_RANDOM_SAMPLER_PREFERENCE + ? RandomSamplerOption | undefined + : T extends typeof DV_RANDOM_SAMPLER_P_VALUE + ? number | undefined + : null; From ef2454e62d0e6d3fd0ff652d6bf29dea967d0aeb Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Fri, 23 Dec 2022 11:45:09 +0100 Subject: [PATCH 06/19] use local storage package for aiops --- .github/CODEOWNERS | 1 + .../full_time_range_selector.tsx | 21 ++++++---- .../plugins/aiops/public/hooks/use_storage.ts | 42 ------------------- x-pack/plugins/aiops/public/types/storage.ts | 26 ++++++++++++ x-pack/plugins/aiops/tsconfig.json | 1 + x-pack/plugins/data_visualizer/tsconfig.json | 1 + 6 files changed, 41 insertions(+), 51 deletions(-) delete mode 100644 x-pack/plugins/aiops/public/hooks/use_storage.ts create mode 100644 x-pack/plugins/aiops/public/types/storage.ts diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index ab2f3b0a65562..bd404ada0d9c1 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1072,6 +1072,7 @@ x-pack/packages/ml/agg_utils @elastic/ml-ui x-pack/packages/ml/aiops_components @elastic/ml-ui x-pack/packages/ml/aiops_utils @elastic/ml-ui x-pack/packages/ml/is_populated_object @elastic/ml-ui +x-pack/packages/ml/local_storage @elastic/ml-ui x-pack/packages/ml/nested_property @elastic/ml-ui x-pack/packages/ml/string_hash @elastic/ml-ui x-pack/packages/ml/url_state @elastic/ml-ui diff --git a/x-pack/plugins/aiops/public/components/full_time_range_selector/full_time_range_selector.tsx b/x-pack/plugins/aiops/public/components/full_time_range_selector/full_time_range_selector.tsx index 592240675197c..78cf53295cc26 100644 --- a/x-pack/plugins/aiops/public/components/full_time_range_selector/full_time_range_selector.tsx +++ b/x-pack/plugins/aiops/public/components/full_time_range_selector/full_time_range_selector.tsx @@ -25,12 +25,19 @@ import { EuiToolTip, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { useStorage } from '@kbn/ml-local-storage'; import { useAiopsAppContext } from '../../hooks/use_aiops_app_context'; import { type GetTimeFieldRangeResponse, setFullTimeRange, } from './full_time_range_selector_service'; -import { AIOPS_FROZEN_TIER_PREFERENCE, useStorage } from '../../hooks/use_storage'; +import { + AIOPS_FROZEN_TIER_PREFERENCE, + FROZEN_TIER_PREFERENCE, + type AiOpsKey, + type AiOpsStorageMapped, + type FrozenTierPreference, +} from '../../types/storage'; export interface FullTimeRangeSelectorProps { timefilter: TimefilterContract; @@ -40,13 +47,6 @@ export interface FullTimeRangeSelectorProps { callback?: (a: GetTimeFieldRangeResponse) => void; } -const FROZEN_TIER_PREFERENCE = { - EXCLUDE: 'exclude-frozen', - INCLUDE: 'include-frozen', -} as const; - -type FrozenTierPreference = typeof FROZEN_TIER_PREFERENCE[keyof typeof FROZEN_TIER_PREFERENCE]; - export const FullTimeRangeSelector: FC = ({ timefilter, dataView, @@ -90,7 +90,10 @@ export const FullTimeRangeSelector: FC = ({ const [isPopoverOpen, setPopover] = useState(false); - const [frozenDataPreference, setFrozenDataPreference] = useStorage( + const [frozenDataPreference, setFrozenDataPreference] = useStorage< + AiOpsKey, + AiOpsStorageMapped + >( AIOPS_FROZEN_TIER_PREFERENCE, // By default we will exclude frozen data tier FROZEN_TIER_PREFERENCE.EXCLUDE diff --git a/x-pack/plugins/aiops/public/hooks/use_storage.ts b/x-pack/plugins/aiops/public/hooks/use_storage.ts deleted file mode 100644 index c377a85b3e84c..0000000000000 --- a/x-pack/plugins/aiops/public/hooks/use_storage.ts +++ /dev/null @@ -1,42 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { useCallback, useState } from 'react'; -import { useAiopsAppContext } from './use_aiops_app_context'; - -export const AIOPS_FROZEN_TIER_PREFERENCE = 'aiops.frozenDataTierPreference'; - -export type AiOps = Partial<{ - [AIOPS_FROZEN_TIER_PREFERENCE]: 'exclude_frozen' | 'include_frozen'; -}> | null; - -export type AiOpsKey = keyof Exclude; - -/** - * Hook for accessing and changing a value in the storage. - * @param key - Storage key - * @param initValue - */ -export function useStorage(key: AiOpsKey, initValue?: T): [T, (value: T) => void] { - const { storage } = useAiopsAppContext(); - - const [val, setVal] = useState(storage.get(key) ?? initValue); - - const setStorage = useCallback( - (value: T): void => { - try { - storage.set(key, value); - setVal(value); - } catch (e) { - throw new Error('Unable to update storage with provided value'); - } - }, - [key, storage] - ); - - return [val, setStorage]; -} diff --git a/x-pack/plugins/aiops/public/types/storage.ts b/x-pack/plugins/aiops/public/types/storage.ts new file mode 100644 index 0000000000000..049b7cce28139 --- /dev/null +++ b/x-pack/plugins/aiops/public/types/storage.ts @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const AIOPS_FROZEN_TIER_PREFERENCE = 'aiops.frozenDataTierPreference'; + +export const FROZEN_TIER_PREFERENCE = { + EXCLUDE: 'exclude-frozen', + INCLUDE: 'include-frozen', +} as const; + +export type FrozenTierPreference = + typeof FROZEN_TIER_PREFERENCE[keyof typeof FROZEN_TIER_PREFERENCE]; + +export type AiOps = Partial<{ + [AIOPS_FROZEN_TIER_PREFERENCE]: FrozenTierPreference; +}> | null; + +export type AiOpsKey = keyof Exclude; + +export type AiOpsStorageMapped = T extends typeof AIOPS_FROZEN_TIER_PREFERENCE + ? FrozenTierPreference | undefined + : null; diff --git a/x-pack/plugins/aiops/tsconfig.json b/x-pack/plugins/aiops/tsconfig.json index 9f2e110d0af25..9eef408f5a513 100644 --- a/x-pack/plugins/aiops/tsconfig.json +++ b/x-pack/plugins/aiops/tsconfig.json @@ -43,6 +43,7 @@ "@kbn/core-elasticsearch-server", "@kbn/es-types", "@kbn/ml-url-state", + "@kbn/ml-local-storage", ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/data_visualizer/tsconfig.json b/x-pack/plugins/data_visualizer/tsconfig.json index b6c5477266e4c..d0df65b4b8fdb 100644 --- a/x-pack/plugins/data_visualizer/tsconfig.json +++ b/x-pack/plugins/data_visualizer/tsconfig.json @@ -52,6 +52,7 @@ "@kbn/field-types", "@kbn/ml-nested-property", "@kbn/ml-url-state", + "@kbn/ml-local-storage", ], "exclude": [ "target/**/*", From 98c2732878d1451074ccf75884ee4f2d9b1c9555 Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Fri, 23 Dec 2022 12:17:02 +0100 Subject: [PATCH 07/19] types/consts cleanup --- .../full_time_range_selector.tsx | 15 +++++++-------- .../index_data_visualizer/types/storage.ts | 12 ++++++++++-- x-pack/plugins/ml/common/types/storage.ts | 12 ++++++++++-- .../full_time_range_selector.tsx | 9 ++------- 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/full_time_range_selector/full_time_range_selector.tsx b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/full_time_range_selector/full_time_range_selector.tsx index c7764b01762bf..57c9f4fa18a40 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/full_time_range_selector/full_time_range_selector.tsx +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/full_time_range_selector/full_time_range_selector.tsx @@ -26,7 +26,13 @@ import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; import { useStorage } from '@kbn/ml-local-storage'; import { setFullTimeRange } from './full_time_range_selector_service'; import { useDataVisualizerKibana } from '../../../kibana_context'; -import { DV_FROZEN_TIER_PREFERENCE, type DVKey, type DVStorageMapped } from '../../types/storage'; +import { + DV_FROZEN_TIER_PREFERENCE, + FROZEN_TIER_PREFERENCE, + type DVKey, + type DVStorageMapped, + type FrozenTierPreference, +} from '../../types/storage'; export const ML_FROZEN_TIER_PREFERENCE = 'ml.frozenDataTierPreference'; @@ -38,13 +44,6 @@ interface Props { callback?: (a: any) => void; } -const FROZEN_TIER_PREFERENCE = { - EXCLUDE: 'exclude-frozen', - INCLUDE: 'include-frozen', -} as const; - -type FrozenTierPreference = typeof FROZEN_TIER_PREFERENCE[keyof typeof FROZEN_TIER_PREFERENCE]; - // Component for rendering a button which automatically sets the range of the time filter // to the time range of data in the index(es) mapped to the supplied Kibana data view or query. export const FullTimeRangeSelector: FC = ({ diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/types/storage.ts b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/types/storage.ts index 7a0397abb8956..5f3876f2a5d45 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/types/storage.ts +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/types/storage.ts @@ -11,8 +11,16 @@ export const DV_FROZEN_TIER_PREFERENCE = 'dataVisualizer.frozenDataTierPreferenc export const DV_RANDOM_SAMPLER_PREFERENCE = 'dataVisualizer.randomSamplerPreference'; export const DV_RANDOM_SAMPLER_P_VALUE = 'dataVisualizer.randomSamplerPValue'; +export const FROZEN_TIER_PREFERENCE = { + EXCLUDE: 'exclude-frozen', + INCLUDE: 'include-frozen', +} as const; + +export type FrozenTierPreference = + typeof FROZEN_TIER_PREFERENCE[keyof typeof FROZEN_TIER_PREFERENCE]; + export type DV = Partial<{ - [DV_FROZEN_TIER_PREFERENCE]: 'exclude_frozen' | 'include_frozen'; + [DV_FROZEN_TIER_PREFERENCE]: FrozenTierPreference; [DV_RANDOM_SAMPLER_PREFERENCE]: RandomSamplerOption; [DV_RANDOM_SAMPLER_P_VALUE]: number; }> | null; @@ -20,7 +28,7 @@ export type DV = Partial<{ export type DVKey = keyof Exclude; export type DVStorageMapped = T extends typeof DV_FROZEN_TIER_PREFERENCE - ? 'exclude-frozen' | 'include-frozen' | undefined + ? FrozenTierPreference | undefined : T extends typeof DV_RANDOM_SAMPLER_PREFERENCE ? RandomSamplerOption | undefined : T extends typeof DV_RANDOM_SAMPLER_P_VALUE diff --git a/x-pack/plugins/ml/common/types/storage.ts b/x-pack/plugins/ml/common/types/storage.ts index b11fa87cd44f7..7e2e1ba799961 100644 --- a/x-pack/plugins/ml/common/types/storage.ts +++ b/x-pack/plugins/ml/common/types/storage.ts @@ -14,6 +14,14 @@ export const ML_FROZEN_TIER_PREFERENCE = 'ml.frozenDataTierPreference'; export const ML_ANOMALY_EXPLORER_PANELS = 'ml.anomalyExplorerPanels'; export const ML_NOTIFICATIONS_LAST_CHECKED_AT = 'ml.notificationsLastCheckedAt'; +export const FROZEN_TIER_PREFERENCE = { + EXCLUDE: 'exclude-frozen', + INCLUDE: 'include-frozen', +} as const; + +export type FrozenTierPreference = + typeof FROZEN_TIER_PREFERENCE[keyof typeof FROZEN_TIER_PREFERENCE]; + export type PartitionFieldConfig = | { /** @@ -56,7 +64,7 @@ export interface MlStorageRecord { [ML_ENTITY_FIELDS_CONFIG]: PartitionFieldsConfig; [ML_APPLY_TIME_RANGE_CONFIG]: ApplyTimeRangeConfig; [ML_GETTING_STARTED_CALLOUT_DISMISSED]: boolean | undefined; - [ML_FROZEN_TIER_PREFERENCE]: 'exclude-frozen' | 'include-frozen'; + [ML_FROZEN_TIER_PREFERENCE]: FrozenTierPreference; [ML_ANOMALY_EXPLORER_PANELS]: AnomalyExplorerPanelsState | undefined; [ML_NOTIFICATIONS_LAST_CHECKED_AT]: number | undefined; } @@ -72,7 +80,7 @@ export type TMlStorageMapped = T extends typeof ML_ENTIT : T extends typeof ML_GETTING_STARTED_CALLOUT_DISMISSED ? boolean | undefined : T extends typeof ML_FROZEN_TIER_PREFERENCE - ? 'exclude-frozen' | 'include-frozen' | undefined + ? FrozenTierPreference | undefined : T extends typeof ML_ANOMALY_EXPLORER_PANELS ? AnomalyExplorerPanelsState | undefined : T extends typeof ML_NOTIFICATIONS_LAST_CHECKED_AT diff --git a/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx b/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx index a221ea05cd23f..3f4c42bc30ca5 100644 --- a/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx +++ b/x-pack/plugins/ml/public/application/components/full_time_range_selector/full_time_range_selector.tsx @@ -26,8 +26,10 @@ import { useStorage } from '@kbn/ml-local-storage'; import { setFullTimeRange } from './full_time_range_selector_service'; import { ML_FROZEN_TIER_PREFERENCE, + FROZEN_TIER_PREFERENCE, type MlStorageKey, type TMlStorageMapped, + type FrozenTierPreference, } from '../../../../common/types/storage'; import { GetTimeFieldRangeResponse } from '../../services/ml_api_service'; @@ -38,13 +40,6 @@ interface Props { callback?: (a: GetTimeFieldRangeResponse) => void; } -const FROZEN_TIER_PREFERENCE = { - EXCLUDE: 'exclude-frozen', - INCLUDE: 'include-frozen', -} as const; - -type FrozenTierPreference = typeof FROZEN_TIER_PREFERENCE[keyof typeof FROZEN_TIER_PREFERENCE]; - // Component for rendering a button which automatically sets the range of the time filter // to the time range of data in the index(es) mapped to the supplied Kibana index pattern or query. export const FullTimeRangeSelector: FC = ({ dataView, query, disabled, callback }) => { From e3f0d733f832e6e163b2de2c1af618f064cb5337 Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Tue, 27 Dec 2022 13:34:41 +0100 Subject: [PATCH 08/19] fix local storage for data visualizer --- x-pack/plugins/data_visualizer/kibana.json | 1 + .../index_data_visualizer.tsx | 15 +++++++++++---- .../index_data_visualizer/types/storage.ts | 6 ++++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/data_visualizer/kibana.json b/x-pack/plugins/data_visualizer/kibana.json index afc9fe34be640..98d27ba9f0481 100644 --- a/x-pack/plugins/data_visualizer/kibana.json +++ b/x-pack/plugins/data_visualizer/kibana.json @@ -26,6 +26,7 @@ ], "requiredBundles": [ "kibanaReact", + "kibanaUtils", "maps", "esUiShared", "fieldFormats", diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/index_data_visualizer.tsx b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/index_data_visualizer.tsx index 671d410523fdd..829927fe455d3 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/index_data_visualizer.tsx +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/index_data_visualizer.tsx @@ -13,7 +13,9 @@ import { EuiResizeObserver } from '@elastic/eui'; import { encode } from '@kbn/rison'; import { SimpleSavedObject } from '@kbn/core/public'; import { i18n } from '@kbn/i18n'; +import { Storage } from '@kbn/kibana-utils-plugin/public'; import { KibanaContextProvider, KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; +import { MlStorageContextProvider } from '@kbn/ml-local-storage'; import { DataView } from '@kbn/data-views-plugin/public'; import { getNestedProperty } from '@kbn/ml-nested-property'; import { @@ -34,6 +36,9 @@ import { GetAdditionalLinks } from '../common/components/results_links'; import { DATA_VISUALIZER_APP_LOCATOR, IndexDataVisualizerLocatorParams } from './locator'; import { DATA_VISUALIZER_INDEX_VIEWER } from './constants/index_data_visualizer_viewer'; import { INDEX_DATA_VISUALIZER_NAME } from '../common/constants'; +import { DV_STORAGE_KEYS } from './types/storage'; + +const localStorage = new Storage(window.localStorage); export interface DataVisualizerStateContextProviderProps { IndexDataVisualizerComponent: FC; @@ -316,10 +321,12 @@ export const IndexDataVisualizer: FC<{ return ( - + + + ); diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/types/storage.ts b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/types/storage.ts index 5f3876f2a5d45..f2718bc8e803f 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/types/storage.ts +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/types/storage.ts @@ -34,3 +34,9 @@ export type DVStorageMapped = T extends typeof DV_FROZEN_TIER_P : T extends typeof DV_RANDOM_SAMPLER_P_VALUE ? number | undefined : null; + +export const DV_STORAGE_KEYS = [ + DV_FROZEN_TIER_PREFERENCE, + DV_RANDOM_SAMPLER_PREFERENCE, + DV_RANDOM_SAMPLER_P_VALUE, +] as const; From ec91b4cc1593a750693080d80e1e26fe2b32d55f Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Tue, 27 Dec 2022 14:35:19 +0100 Subject: [PATCH 09/19] fix local storage for explain log rate spikes --- x-pack/plugins/aiops/kibana.json | 2 +- .../explain_log_rate_spikes_app_state.tsx | 12 +++++++++--- x-pack/plugins/aiops/public/types/storage.ts | 2 ++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/aiops/kibana.json b/x-pack/plugins/aiops/kibana.json index dba431234ec0a..08cbaf4613464 100755 --- a/x-pack/plugins/aiops/kibana.json +++ b/x-pack/plugins/aiops/kibana.json @@ -16,6 +16,6 @@ "licensing" ], "optionalPlugins": [], - "requiredBundles": ["fieldFormats", "kibanaReact"], + "requiredBundles": ["fieldFormats", "kibanaReact", "kibanaUtils"], "extraPublicDirs": ["common"] } diff --git a/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_app_state.tsx b/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_app_state.tsx index 2e745894cac0a..ba1ee7f1f0504 100644 --- a/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_app_state.tsx +++ b/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_app_state.tsx @@ -11,11 +11,12 @@ import { EuiCallOut } from '@elastic/eui'; import type { Filter, Query } from '@kbn/es-query'; import { i18n } from '@kbn/i18n'; - import type { SavedSearch } from '@kbn/discover-plugin/public'; import type { DataView } from '@kbn/data-views-plugin/public'; - +import { MlStorageContextProvider } from '@kbn/ml-local-storage'; import { UrlStateProvider } from '@kbn/ml-url-state'; +import { Storage } from '@kbn/kibana-utils-plugin/public'; + import { SEARCH_QUERY_LANGUAGE, SearchQueryLanguage, @@ -25,9 +26,12 @@ import type { AiopsAppDependencies } from '../../hooks/use_aiops_app_context'; import { AiopsAppContext } from '../../hooks/use_aiops_app_context'; import { SpikeAnalysisTableRowStateProvider } from '../spike_analysis_table/spike_analysis_table_row_provider'; +import { AIOPS_STORAGE_KEYS } from '../../types/storage'; import { ExplainLogRateSpikesPage } from './explain_log_rate_spikes_page'; +const localStorage = new Storage(window.localStorage); + export interface ExplainLogRateSpikesAppStateProps { /** The data view to analyze. */ dataView: DataView; @@ -95,7 +99,9 @@ export const ExplainLogRateSpikesAppState: FC - + + + diff --git a/x-pack/plugins/aiops/public/types/storage.ts b/x-pack/plugins/aiops/public/types/storage.ts index 049b7cce28139..96eb612d9ca7a 100644 --- a/x-pack/plugins/aiops/public/types/storage.ts +++ b/x-pack/plugins/aiops/public/types/storage.ts @@ -24,3 +24,5 @@ export type AiOpsKey = keyof Exclude; export type AiOpsStorageMapped = T extends typeof AIOPS_FROZEN_TIER_PREFERENCE ? FrozenTierPreference | undefined : null; + +export const AIOPS_STORAGE_KEYS = [AIOPS_FROZEN_TIER_PREFERENCE] as const; From eea98709036c4bf341fb31f6a94a534480c583f6 Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Tue, 27 Dec 2022 14:41:59 +0100 Subject: [PATCH 10/19] fix local storage for aiops section --- .../change_point_detetion_root.tsx | 25 +++++++++++++------ .../explain_log_rate_spikes_app_state.tsx | 2 +- .../log_categorization_app_state.tsx | 13 ++++++++-- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detetion_root.tsx b/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detetion_root.tsx index 44c68c6017588..b28f390e1211c 100644 --- a/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detetion_root.tsx +++ b/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detetion_root.tsx @@ -5,16 +5,25 @@ * 2.0. */ +import React, { FC } from 'react'; + import { DataView } from '@kbn/data-views-plugin/common'; import { SavedSearch } from '@kbn/saved-search-plugin/public'; -import React, { FC } from 'react'; +import { MlStorageContextProvider } from '@kbn/ml-local-storage'; import { UrlStateProvider } from '@kbn/ml-url-state'; -import { PageHeader } from '../page_header'; -import { ChangePointDetectionContextProvider } from './change_point_detection_context'; +import { Storage } from '@kbn/kibana-utils-plugin/public'; + import { DataSourceContext } from '../../hooks/use_data_source'; import { SavedSearchSavedObject } from '../../application/utils/search_utils'; import { AiopsAppContext, AiopsAppDependencies } from '../../hooks/use_aiops_app_context'; +import { AIOPS_STORAGE_KEYS } from '../../types/storage'; + +import { PageHeader } from '../page_header'; + import { ChangePointDetectionPage } from './change_point_detection_page'; +import { ChangePointDetectionContextProvider } from './change_point_detection_context'; + +const localStorage = new Storage(window.localStorage); export interface ChangePointDetectionAppStateProps { dataView: DataView; @@ -31,10 +40,12 @@ export const ChangePointDetectionAppState: FC - - - - + + + + + + {' '} diff --git a/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_app_state.tsx b/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_app_state.tsx index ba1ee7f1f0504..1866dd9782aee 100644 --- a/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_app_state.tsx +++ b/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_app_state.tsx @@ -24,9 +24,9 @@ import { } from '../../application/utils/search_utils'; import type { AiopsAppDependencies } from '../../hooks/use_aiops_app_context'; import { AiopsAppContext } from '../../hooks/use_aiops_app_context'; +import { AIOPS_STORAGE_KEYS } from '../../types/storage'; import { SpikeAnalysisTableRowStateProvider } from '../spike_analysis_table/spike_analysis_table_row_provider'; -import { AIOPS_STORAGE_KEYS } from '../../types/storage'; import { ExplainLogRateSpikesPage } from './explain_log_rate_spikes_page'; diff --git a/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_app_state.tsx b/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_app_state.tsx index 4c0da804f5eb6..c6e7d7c0cc142 100644 --- a/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_app_state.tsx +++ b/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_app_state.tsx @@ -7,12 +7,19 @@ import React, { FC } from 'react'; import type { SavedSearch } from '@kbn/discover-plugin/public'; import type { DataView } from '@kbn/data-views-plugin/public'; +import { MlStorageContextProvider } from '@kbn/ml-local-storage'; import { UrlStateProvider } from '@kbn/ml-url-state'; -import { LogCategorizationPage } from './log_categorization_page'; +import { Storage } from '@kbn/kibana-utils-plugin/public'; + import { SavedSearchSavedObject } from '../../application/utils/search_utils'; import type { AiopsAppDependencies } from '../../hooks/use_aiops_app_context'; +import { AIOPS_STORAGE_KEYS } from '../../types/storage'; import { AiopsAppContext } from '../../hooks/use_aiops_app_context'; +import { LogCategorizationPage } from './log_categorization_page'; + +const localStorage = new Storage(window.localStorage); + export interface LogCategorizationAppStateProps { dataView: DataView; savedSearch: SavedSearch | SavedSearchSavedObject | null; @@ -27,7 +34,9 @@ export const LogCategorizationAppState: FC = ({ return ( - + + + ); From 45bf5fa801eaa30aaed5344b6cfc7933961c99ad Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Tue, 27 Dec 2022 16:33:44 +0100 Subject: [PATCH 11/19] fix space --- .../change_point_detection/change_point_detetion_root.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detetion_root.tsx b/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detetion_root.tsx index b28f390e1211c..031092380512e 100644 --- a/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detetion_root.tsx +++ b/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detetion_root.tsx @@ -45,7 +45,7 @@ export const ChangePointDetectionAppState: FC - {' '} + From 92fb23114e87cac75e31aa6534a80ff0812c50d5 Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Tue, 27 Dec 2022 17:41:50 +0100 Subject: [PATCH 12/19] move isDefined to package --- package.json | 1 + tsconfig.base.json | 2 ++ x-pack/packages/ml/is_defined/README.md | 3 +++ .../ml/is_defined/index.ts} | 4 +--- .../ml/is_defined/jest.config.js} | 8 +++++--- x-pack/packages/ml/is_defined/kibana.jsonc | 5 +++++ x-pack/packages/ml/is_defined/package.json | 6 ++++++ .../src/is_defined.ts | 0 x-pack/packages/ml/is_defined/tsconfig.json | 19 +++++++++++++++++++ .../ml/local_storage/src/storage_context.tsx | 3 +-- .../packages/ml/local_storage/tsconfig.json | 1 + .../document_count_content.tsx | 2 +- .../results_links/results_links.tsx | 2 +- .../application/common/util/example_utils.ts | 2 +- .../actions_panel/actions_panel.tsx | 2 +- .../components/search_panel/search_panel.tsx | 2 +- .../requests/get_document_stats.ts | 2 +- .../requests/get_numeric_field_stats.ts | 2 +- x-pack/plugins/data_visualizer/tsconfig.json | 1 + x-pack/plugins/ml/common/util/alerts.ts | 2 +- x-pack/plugins/ml/common/util/job_utils.ts | 2 +- ...aly_detection_jobs_health_rule_trigger.tsx | 2 +- .../alerting/ml_anomaly_alert_trigger.tsx | 2 +- .../application/explorer/anomalies_map.tsx | 2 +- .../explorer/anomaly_context_menu.tsx | 2 +- .../application/explorer/anomaly_timeline.tsx | 2 +- ...d_anomaly_charts_to_dashboard_controls.tsx | 2 +- .../public/application/explorer/explorer.tsx | 2 +- .../anomaly_explorer_charts_service.ts | 2 +- .../services/ml_api_service/notifications.ts | 2 +- .../models_management/expanded_row.tsx | 2 +- .../public/application/util/string_utils.ts | 2 +- .../ml/server/lib/alerts/alerting_service.ts | 2 +- .../server/lib/alerts/jobs_health_service.ts | 2 +- .../data_frame_analytics/models_provider.ts | 2 +- .../models/data_recognizer/data_recognizer.ts | 2 +- .../models/results_service/anomaly_charts.ts | 2 +- x-pack/plugins/ml/tsconfig.json | 1 + .../plugins/transform/common/types/common.ts | 4 ---- yarn.lock | 12 ++++++++---- 40 files changed, 79 insertions(+), 41 deletions(-) create mode 100644 x-pack/packages/ml/is_defined/README.md rename x-pack/{plugins/data_visualizer/public/application/common/util/is_defined.ts => packages/ml/is_defined/index.ts} (65%) rename x-pack/{plugins/ml/common/types/guards.ts => packages/ml/is_defined/jest.config.js} (65%) create mode 100644 x-pack/packages/ml/is_defined/kibana.jsonc create mode 100644 x-pack/packages/ml/is_defined/package.json rename x-pack/packages/ml/{local_storage => is_defined}/src/is_defined.ts (100%) create mode 100644 x-pack/packages/ml/is_defined/tsconfig.json diff --git a/package.json b/package.json index 735e50227d7e5..e3f11c9fe0e3c 100644 --- a/package.json +++ b/package.json @@ -349,6 +349,7 @@ "@kbn/logging-mocks": "link:packages/kbn-logging-mocks", "@kbn/mapbox-gl": "link:packages/kbn-mapbox-gl", "@kbn/ml-agg-utils": "link:x-pack/packages/ml/agg_utils", + "@kbn/ml-is-defined": "link:x-pack/packages/ml/is_defined", "@kbn/ml-is-populated-object": "link:x-pack/packages/ml/is_populated_object", "@kbn/ml-local-storage": "link:x-pack/packages/ml/local_storage", "@kbn/ml-nested-property": "link:x-pack/packages/ml/nested_property", diff --git a/tsconfig.base.json b/tsconfig.base.json index f4504e44f678b..70b834508d405 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -814,6 +814,8 @@ "@kbn/maps-plugin/*": ["x-pack/plugins/maps/*"], "@kbn/ml-agg-utils": ["x-pack/packages/ml/agg_utils"], "@kbn/ml-agg-utils/*": ["x-pack/packages/ml/agg_utils/*"], + "@kbn/ml-is-defined": ["x-pack/packages/ml/is_defined"], + "@kbn/ml-is-defined/*": ["x-pack/packages/ml/is_defined/*"], "@kbn/ml-is-populated-object": ["x-pack/packages/ml/is_populated_object"], "@kbn/ml-is-populated-object/*": ["x-pack/packages/ml/is_populated_object/*"], "@kbn/ml-local-storage": ["x-pack/packages/ml/local_storage"], diff --git a/x-pack/packages/ml/is_defined/README.md b/x-pack/packages/ml/is_defined/README.md new file mode 100644 index 0000000000000..fc6ed3ab7e554 --- /dev/null +++ b/x-pack/packages/ml/is_defined/README.md @@ -0,0 +1,3 @@ +# @kbn/ml-is-defined + +Empty package generated by @kbn/generate diff --git a/x-pack/plugins/data_visualizer/public/application/common/util/is_defined.ts b/x-pack/packages/ml/is_defined/index.ts similarity index 65% rename from x-pack/plugins/data_visualizer/public/application/common/util/is_defined.ts rename to x-pack/packages/ml/is_defined/index.ts index ead91eafc2d4e..8b04a61a8bdae 100644 --- a/x-pack/plugins/data_visualizer/public/application/common/util/is_defined.ts +++ b/x-pack/packages/ml/is_defined/index.ts @@ -5,6 +5,4 @@ * 2.0. */ -export function isDefined(argument: T | undefined | null): argument is T { - return argument !== undefined && argument !== null; -} +export { isDefined } from './src/is_defined'; diff --git a/x-pack/plugins/ml/common/types/guards.ts b/x-pack/packages/ml/is_defined/jest.config.js similarity index 65% rename from x-pack/plugins/ml/common/types/guards.ts rename to x-pack/packages/ml/is_defined/jest.config.js index ead91eafc2d4e..a4deb4d18ecf8 100644 --- a/x-pack/plugins/ml/common/types/guards.ts +++ b/x-pack/packages/ml/is_defined/jest.config.js @@ -5,6 +5,8 @@ * 2.0. */ -export function isDefined(argument: T | undefined | null): argument is T { - return argument !== undefined && argument !== null; -} +module.exports = { + preset: '@kbn/test', + rootDir: '../../../..', + roots: ['/x-pack/packages/ml/is_defined'], +}; diff --git a/x-pack/packages/ml/is_defined/kibana.jsonc b/x-pack/packages/ml/is_defined/kibana.jsonc new file mode 100644 index 0000000000000..b25718598901b --- /dev/null +++ b/x-pack/packages/ml/is_defined/kibana.jsonc @@ -0,0 +1,5 @@ +{ + "type": "shared-common", + "id": "@kbn/ml-is-defined", + "owner": "@elastic/ml-ui" +} diff --git a/x-pack/packages/ml/is_defined/package.json b/x-pack/packages/ml/is_defined/package.json new file mode 100644 index 0000000000000..2ed8896c22552 --- /dev/null +++ b/x-pack/packages/ml/is_defined/package.json @@ -0,0 +1,6 @@ +{ + "name": "@kbn/ml-is-defined", + "private": true, + "version": "1.0.0", + "license": "SSPL-1.0 OR Elastic License 2.0" +} diff --git a/x-pack/packages/ml/local_storage/src/is_defined.ts b/x-pack/packages/ml/is_defined/src/is_defined.ts similarity index 100% rename from x-pack/packages/ml/local_storage/src/is_defined.ts rename to x-pack/packages/ml/is_defined/src/is_defined.ts diff --git a/x-pack/packages/ml/is_defined/tsconfig.json b/x-pack/packages/ml/is_defined/tsconfig.json new file mode 100644 index 0000000000000..5c989599ec9ad --- /dev/null +++ b/x-pack/packages/ml/is_defined/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "../../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "target/types", + "types": [ + "jest", + "node", + "react" + ] + }, + "include": [ + "**/*.ts", + "**/*.tsx", + ], + "exclude": [ + "target/**/*" + ], + "kbn_references": [] +} diff --git a/x-pack/packages/ml/local_storage/src/storage_context.tsx b/x-pack/packages/ml/local_storage/src/storage_context.tsx index b2c0fc1f3d481..75cbc4fc7c58b 100644 --- a/x-pack/packages/ml/local_storage/src/storage_context.tsx +++ b/x-pack/packages/ml/local_storage/src/storage_context.tsx @@ -16,8 +16,7 @@ import React, { import { omit } from 'lodash'; import type { Storage } from '@kbn/kibana-utils-plugin/public'; - -import { isDefined } from './is_defined'; +import { isDefined } from '@kbn/ml-is-defined'; interface StorageDefinition { [key: string]: unknown; diff --git a/x-pack/packages/ml/local_storage/tsconfig.json b/x-pack/packages/ml/local_storage/tsconfig.json index f7034734e45a5..1f42768195c2b 100644 --- a/x-pack/packages/ml/local_storage/tsconfig.json +++ b/x-pack/packages/ml/local_storage/tsconfig.json @@ -17,5 +17,6 @@ ], "kbn_references": [ "@kbn/kibana-utils-plugin", + "@kbn/ml-is-defined", ] } diff --git a/x-pack/plugins/data_visualizer/public/application/common/components/document_count_content/document_count_content.tsx b/x-pack/plugins/data_visualizer/public/application/common/components/document_count_content/document_count_content.tsx index 09b59cf10abb5..4e3ed74c4470e 100644 --- a/x-pack/plugins/data_visualizer/public/application/common/components/document_count_content/document_count_content.tsx +++ b/x-pack/plugins/data_visualizer/public/application/common/components/document_count_content/document_count_content.tsx @@ -22,7 +22,7 @@ import { import { i18n } from '@kbn/i18n'; import { debounce, sortedIndex } from 'lodash'; import { FormattedMessage } from '@kbn/i18n-react'; -import { isDefined } from '../../util/is_defined'; +import { isDefined } from '@kbn/ml-is-defined'; import type { DocumentCountChartPoint } from './document_count_chart'; import { RANDOM_SAMPLER_STEP, diff --git a/x-pack/plugins/data_visualizer/public/application/common/components/results_links/results_links.tsx b/x-pack/plugins/data_visualizer/public/application/common/components/results_links/results_links.tsx index 387c41f2b44f9..9f84bb6d1debd 100644 --- a/x-pack/plugins/data_visualizer/public/application/common/components/results_links/results_links.tsx +++ b/x-pack/plugins/data_visualizer/public/application/common/components/results_links/results_links.tsx @@ -14,9 +14,9 @@ import { RefreshInterval } from '@kbn/data-plugin/public'; import { FindFileStructureResponse } from '@kbn/file-upload-plugin/common'; import type { FileUploadPluginStart } from '@kbn/file-upload-plugin/public'; import { flatten } from 'lodash'; +import { isDefined } from '@kbn/ml-is-defined'; import { LinkCardProps } from '../link_card/link_card'; import { useDataVisualizerKibana } from '../../../kibana_context'; -import { isDefined } from '../../util/is_defined'; type LinkType = 'file' | 'index'; diff --git a/x-pack/plugins/data_visualizer/public/application/common/util/example_utils.ts b/x-pack/plugins/data_visualizer/public/application/common/util/example_utils.ts index cc4a9a3ca9bfa..e3e97666844c4 100644 --- a/x-pack/plugins/data_visualizer/public/application/common/util/example_utils.ts +++ b/x-pack/plugins/data_visualizer/public/application/common/util/example_utils.ts @@ -6,7 +6,7 @@ */ import { isPopulatedObject } from '@kbn/ml-is-populated-object'; -import { isDefined } from './is_defined'; +import { isDefined } from '@kbn/ml-is-defined'; import { GeoPointExample, LatLongExample } from '../../../../common/types/field_request_config'; export function isGeoPointExample(arg: unknown): arg is GeoPointExample { diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/actions_panel/actions_panel.tsx b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/actions_panel/actions_panel.tsx index fc2efab6610bc..a8f454816e2b6 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/actions_panel/actions_panel.tsx +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/actions_panel/actions_panel.tsx @@ -14,12 +14,12 @@ import { i18n } from '@kbn/i18n'; import { EuiSpacer, EuiTitle } from '@elastic/eui'; import { DataView } from '@kbn/data-views-plugin/public'; import { useUrlState } from '@kbn/ml-url-state'; +import { isDefined } from '@kbn/ml-is-defined'; import { LinkCardProps } from '../../../common/components/link_card/link_card'; import { useDataVisualizerKibana } from '../../../kibana_context'; import { LinkCard } from '../../../common/components/link_card'; import { GetAdditionalLinks } from '../../../common/components/results_links'; -import { isDefined } from '../../../common/util/is_defined'; interface Props { dataView: DataView; diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_panel.tsx b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_panel.tsx index df11ab8dd5cd1..9a81900e5e6a9 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_panel.tsx +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_panel.tsx @@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n'; import { Query, Filter } from '@kbn/es-query'; import type { TimeRange } from '@kbn/es-query'; import { DataView, DataViewField } from '@kbn/data-views-plugin/public'; -import { isDefined } from '../../../common/util/is_defined'; +import { isDefined } from '@kbn/ml-is-defined'; import { DataVisualizerFieldNamesFilter } from './field_name_filter'; import { DataVisualizerFieldTypeFilter } from './field_type_filter'; import { SupportedFieldType } from '../../../../../common/types'; diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/search_strategy/requests/get_document_stats.ts b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/search_strategy/requests/get_document_stats.ts index f74a8800d2bd0..e6fc220ea7f3c 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/search_strategy/requests/get_document_stats.ts +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/search_strategy/requests/get_document_stats.ts @@ -10,7 +10,7 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { isPopulatedObject } from '@kbn/ml-is-populated-object'; import { DataPublicPluginStart, ISearchOptions } from '@kbn/data-plugin/public'; import seedrandom from 'seedrandom'; -import { isDefined } from '../../../common/util/is_defined'; +import { isDefined } from '@kbn/ml-is-defined'; import { RANDOM_SAMPLER_PROBABILITIES } from '../../constants/random_sampler'; import { buildBaseFilterCriteria } from '../../../../../common/utils/query_utils'; import type { diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/search_strategy/requests/get_numeric_field_stats.ts b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/search_strategy/requests/get_numeric_field_stats.ts index 66a7134919760..20143f5fc1581 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/search_strategy/requests/get_numeric_field_stats.ts +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/search_strategy/requests/get_numeric_field_stats.ts @@ -17,8 +17,8 @@ import type { } from '@kbn/data-plugin/common'; import type { ISearchStart } from '@kbn/data-plugin/public'; import { isPopulatedObject } from '@kbn/ml-is-populated-object'; +import { isDefined } from '@kbn/ml-is-defined'; import { processTopValues } from './utils'; -import { isDefined } from '../../../common/util/is_defined'; import { buildAggregationWithSamplingOption } from './build_random_sampler_agg'; import { MAX_PERCENT, PERCENTILE_SPACING, SAMPLER_TOP_TERMS_THRESHOLD } from './constants'; import type { diff --git a/x-pack/plugins/data_visualizer/tsconfig.json b/x-pack/plugins/data_visualizer/tsconfig.json index d0df65b4b8fdb..3098da0f61bc2 100644 --- a/x-pack/plugins/data_visualizer/tsconfig.json +++ b/x-pack/plugins/data_visualizer/tsconfig.json @@ -53,6 +53,7 @@ "@kbn/ml-nested-property", "@kbn/ml-url-state", "@kbn/ml-local-storage", + "@kbn/ml-is-defined", ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/ml/common/util/alerts.ts b/x-pack/plugins/ml/common/util/alerts.ts index 6abc5333a1f73..6c997dfb71566 100644 --- a/x-pack/plugins/ml/common/util/alerts.ts +++ b/x-pack/plugins/ml/common/util/alerts.ts @@ -6,9 +6,9 @@ */ import { pick } from 'lodash'; +import { isDefined } from '@kbn/ml-is-defined'; import { CombinedJobWithStats, Datafeed, Job } from '../types/anomaly_detection_jobs'; import { resolveMaxTimeInterval } from './job_utils'; -import { isDefined } from '../types/guards'; import { parseInterval } from './parse_interval'; import { JobsHealthRuleTestsConfig, JobsHealthTests } from '../types/alerts'; diff --git a/x-pack/plugins/ml/common/util/job_utils.ts b/x-pack/plugins/ml/common/util/job_utils.ts index 4d50af19a8b96..a0cbb5d5762de 100644 --- a/x-pack/plugins/ml/common/util/job_utils.ts +++ b/x-pack/plugins/ml/common/util/job_utils.ts @@ -16,6 +16,7 @@ import { isPopulatedObject } from '@kbn/ml-is-populated-object'; import type { SerializableRecord } from '@kbn/utility-types'; import { FilterStateStore } from '@kbn/es-query'; import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { isDefined } from '@kbn/ml-is-defined'; import { ALLOWED_DATA_UNITS, JOB_ID_MAX_LENGTH } from '../constants/validation'; import { parseInterval } from './parse_interval'; import { maxLengthValidator } from './validators'; @@ -35,7 +36,6 @@ import { MLCATEGORY } from '../constants/field_types'; import { getAggregations, getDatafeedAggregations } from './datafeed_utils'; import { findAggField } from './validation_utils'; import { getFirstKeyInObject } from './object_utils'; -import { isDefined } from '../types/guards'; export interface ValidationResults { valid: boolean; diff --git a/x-pack/plugins/ml/public/alerting/jobs_health_rule/anomaly_detection_jobs_health_rule_trigger.tsx b/x-pack/plugins/ml/public/alerting/jobs_health_rule/anomaly_detection_jobs_health_rule_trigger.tsx index 9fff85c82888f..daab200ff0709 100644 --- a/x-pack/plugins/ml/public/alerting/jobs_health_rule/anomaly_detection_jobs_health_rule_trigger.tsx +++ b/x-pack/plugins/ml/public/alerting/jobs_health_rule/anomaly_detection_jobs_health_rule_trigger.tsx @@ -12,6 +12,7 @@ import { FormattedMessage } from '@kbn/i18n-react'; import useDebounce from 'react-use/lib/useDebounce'; import { RuleTypeParamsExpressionProps } from '@kbn/triggers-actions-ui-plugin/public'; import { isPopulatedObject } from '@kbn/ml-is-populated-object'; +import { isDefined } from '@kbn/ml-is-defined'; import { MlAnomalyDetectionJobsHealthRuleParams } from '../../../common/types/alerts'; import { JobSelectorControl } from '../job_selector'; import { jobsApiProvider } from '../../application/services/ml_api_service/jobs'; @@ -20,7 +21,6 @@ import { useMlKibana } from '../../application/contexts/kibana'; import { TestsSelectionControl } from './tests_selection_control'; import { ALL_JOBS_SELECTION } from '../../../common/constants/alerts'; import { BetaBadge } from '../beta_badge'; -import { isDefined } from '../../../common/types/guards'; export type MlAnomalyAlertTriggerProps = RuleTypeParamsExpressionProps; diff --git a/x-pack/plugins/ml/public/alerting/ml_anomaly_alert_trigger.tsx b/x-pack/plugins/ml/public/alerting/ml_anomaly_alert_trigger.tsx index a5ef1e7943438..980abb23e659d 100644 --- a/x-pack/plugins/ml/public/alerting/ml_anomaly_alert_trigger.tsx +++ b/x-pack/plugins/ml/public/alerting/ml_anomaly_alert_trigger.tsx @@ -10,6 +10,7 @@ import { EuiSpacer, EuiForm } from '@elastic/eui'; import useMount from 'react-use/lib/useMount'; import { i18n } from '@kbn/i18n'; import { RuleTypeParamsExpressionProps } from '@kbn/triggers-actions-ui-plugin/public'; +import { isDefined } from '@kbn/ml-is-defined'; import { JobSelectorControl } from './job_selector'; import { useMlKibana } from '../application/contexts/kibana'; import { jobsApiProvider } from '../application/services/ml_api_service/jobs'; @@ -29,7 +30,6 @@ import { ConfigValidator } from './config_validator'; import { CombinedJobWithStats } from '../../common/types/anomaly_detection_jobs'; import { AdvancedSettings } from './advanced_settings'; import { getLookbackInterval, getTopNBuckets } from '../../common/util/alerts'; -import { isDefined } from '../../common/types/guards'; import { parseInterval } from '../../common/util/parse_interval'; import { BetaBadge } from './beta_badge'; diff --git a/x-pack/plugins/ml/public/application/explorer/anomalies_map.tsx b/x-pack/plugins/ml/public/application/explorer/anomalies_map.tsx index b9a1ef555dbc1..3edfcd9842a18 100644 --- a/x-pack/plugins/ml/public/application/explorer/anomalies_map.tsx +++ b/x-pack/plugins/ml/public/application/explorer/anomalies_map.tsx @@ -25,8 +25,8 @@ import { VectorLayerDescriptor, } from '@kbn/maps-plugin/common'; import { EMSTermJoinConfig } from '@kbn/maps-plugin/public'; +import { isDefined } from '@kbn/ml-is-defined'; import { useMlKibana } from '../contexts/kibana'; -import { isDefined } from '../../../common/types/guards'; import { MlEmbeddedMapComponent } from '../components/ml_embedded_map'; import { AnomaliesTableRecord } from '../../../common/types/anomalies'; diff --git a/x-pack/plugins/ml/public/application/explorer/anomaly_context_menu.tsx b/x-pack/plugins/ml/public/application/explorer/anomaly_context_menu.tsx index 2bfe0c3b2844e..55feffe8ff5c4 100644 --- a/x-pack/plugins/ml/public/application/explorer/anomaly_context_menu.tsx +++ b/x-pack/plugins/ml/public/application/explorer/anomaly_context_menu.tsx @@ -19,7 +19,7 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import useObservable from 'react-use/lib/useObservable'; import type { Query, TimeRange } from '@kbn/es-query'; -import { isDefined } from '../../../common/types/guards'; +import { isDefined } from '@kbn/ml-is-defined'; import { useAnomalyExplorerContext } from './anomaly_explorer_context'; import { escapeKueryForFieldValuePair } from '../util/string_utils'; import { SEARCH_QUERY_LANGUAGE } from '../../../common/constants/search'; diff --git a/x-pack/plugins/ml/public/application/explorer/anomaly_timeline.tsx b/x-pack/plugins/ml/public/application/explorer/anomaly_timeline.tsx index 6b33ba8187d9d..a0ff293a2b203 100644 --- a/x-pack/plugins/ml/public/application/explorer/anomaly_timeline.tsx +++ b/x-pack/plugins/ml/public/application/explorer/anomaly_timeline.tsx @@ -27,6 +27,7 @@ import { FormattedMessage } from '@kbn/i18n-react'; import useDebounce from 'react-use/lib/useDebounce'; import useObservable from 'react-use/lib/useObservable'; import type { Query } from '@kbn/es-query'; +import { isDefined } from '@kbn/ml-is-defined'; import { SEARCH_QUERY_LANGUAGE } from '../../../common/constants/search'; import { useCasesModal } from '../contexts/kibana/use_cases_modal'; import { useTimeRangeUpdates } from '../contexts/kibana/use_timefilter'; @@ -46,7 +47,6 @@ import { AppStateSelectedCells, OverallSwimlaneData, ViewBySwimLaneData } from ' import { NoOverallData } from './components/no_overall_data'; import { SeverityControl } from '../components/severity_control'; import { AnomalyTimelineHelpPopover } from './anomaly_timeline_help_popover'; -import { isDefined } from '../../../common/types/guards'; import { MlTooltipComponent } from '../components/chart_tooltip'; import { SwimlaneAnnotationContainer, Y_AXIS_LABEL_WIDTH } from './swimlane_annotation_container'; import { AnomalyTimelineService } from '../services/anomaly_timeline_service'; diff --git a/x-pack/plugins/ml/public/application/explorer/dashboard_controls/add_anomaly_charts_to_dashboard_controls.tsx b/x-pack/plugins/ml/public/application/explorer/dashboard_controls/add_anomaly_charts_to_dashboard_controls.tsx index 0e928166127fd..cb5d6d2b0201b 100644 --- a/x-pack/plugins/ml/public/application/explorer/dashboard_controls/add_anomaly_charts_to_dashboard_controls.tsx +++ b/x-pack/plugins/ml/public/application/explorer/dashboard_controls/add_anomaly_charts_to_dashboard_controls.tsx @@ -9,8 +9,8 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { EuiFieldNumber, EuiFormRow, htmlIdGenerator } from '@elastic/eui'; import type { Query } from '@kbn/es-query'; import useObservable from 'react-use/lib/useObservable'; +import { isDefined } from '@kbn/ml-is-defined'; import { getSelectionInfluencers } from '../explorer_utils'; -import { isDefined } from '../../../../common/types/guards'; import { useAnomalyExplorerContext } from '../anomaly_explorer_context'; import { escapeKueryForFieldValuePair } from '../../util/string_utils'; import { SEARCH_QUERY_LANGUAGE } from '../../../../common/constants/search'; diff --git a/x-pack/plugins/ml/public/application/explorer/explorer.tsx b/x-pack/plugins/ml/public/application/explorer/explorer.tsx index 7c66b55e89271..f764ede7750c9 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer.tsx +++ b/x-pack/plugins/ml/public/application/explorer/explorer.tsx @@ -32,6 +32,7 @@ import useObservable from 'react-use/lib/useObservable'; import type { DataView } from '@kbn/data-views-plugin/common'; import type { TimefilterContract } from '@kbn/data-plugin/public'; import { useStorage } from '@kbn/ml-local-storage'; +import { isDefined } from '@kbn/ml-is-defined'; import { HelpPopover } from '../components/help_popover'; import { AnnotationFlyout } from '../components/annotations/annotation_flyout'; // @ts-ignore @@ -70,7 +71,6 @@ import { AnomaliesTable } from '../components/anomalies_table/anomalies_table'; import { AnomaliesMap } from './anomalies_map'; import { ANOMALY_DETECTION_DEFAULT_TIME_RANGE } from '../../../common/constants/settings'; import { AnomalyContextMenu } from './anomaly_context_menu'; -import { isDefined } from '../../../common/types/guards'; import type { JobSelectorProps } from '../components/job_selector/job_selector'; import type { ExplorerState } from './reducers'; import type { TimeBuckets } from '../util/time_buckets'; diff --git a/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.ts b/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.ts index 7aa0bb03611e1..6a0f3c8c692b0 100644 --- a/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.ts +++ b/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.ts @@ -10,6 +10,7 @@ import { map as mapObservable } from 'rxjs/operators'; import type { TimeRange } from '@kbn/es-query'; import type { TimefilterContract } from '@kbn/data-plugin/public'; import { isPopulatedObject } from '@kbn/ml-is-populated-object'; +import { isDefined } from '@kbn/ml-is-defined'; import type { RecordForInfluencer } from './results_service/results_service'; import type { EntityField } from '../../../common/util/anomaly_utils'; import type { CombinedJob } from '../../../common/types/anomaly_detection_jobs'; @@ -17,7 +18,6 @@ import type { MlApiServices } from './ml_api_service'; import type { MlResultsService } from './results_service'; import { ExplorerChartsData } from '../explorer/explorer_charts/explorer_charts_container_service'; import type { TimeRangeBounds } from '../util/time_buckets'; -import { isDefined } from '../../../common/types/guards'; import type { AppStateSelectedCells } from '../explorer/explorer_utils'; import type { InfluencersFilterQuery } from '../../../common/types/es_client'; import type { SeriesConfigWithMetadata } from '../../../common/types/results'; diff --git a/x-pack/plugins/ml/public/application/services/ml_api_service/notifications.ts b/x-pack/plugins/ml/public/application/services/ml_api_service/notifications.ts index 653ceebc52cda..fd6f7bd708cd4 100644 --- a/x-pack/plugins/ml/public/application/services/ml_api_service/notifications.ts +++ b/x-pack/plugins/ml/public/application/services/ml_api_service/notifications.ts @@ -6,7 +6,7 @@ */ import { omitBy } from 'lodash'; -import { isDefined } from '../../../../common/types/guards'; +import { isDefined } from '@kbn/ml-is-defined'; import type { NotificationsQueryParams, NotificationsSearchResponse, diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/expanded_row.tsx b/x-pack/plugins/ml/public/application/trained_models/models_management/expanded_row.tsx index 879bed447c864..daa813fe4e1e6 100644 --- a/x-pack/plugins/ml/public/application/trained_models/models_management/expanded_row.tsx +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/expanded_row.tsx @@ -24,8 +24,8 @@ import { import { FormattedMessage } from '@kbn/i18n-react'; import { FIELD_FORMAT_IDS } from '@kbn/field-formats-plugin/common'; import { isPopulatedObject } from '@kbn/ml-is-populated-object'; +import { isDefined } from '@kbn/ml-is-defined'; import type { ModelItemFull } from './models_list'; -import { isDefined } from '../../../../common/types/guards'; import { ModelPipelines } from './pipelines'; import { AllocatedModels } from '../nodes_overview/allocated_models'; import type { AllocatedModel } from '../../../../common/types/trained_models'; diff --git a/x-pack/plugins/ml/public/application/util/string_utils.ts b/x-pack/plugins/ml/public/application/util/string_utils.ts index b870cdff345b5..e1fa570efc20c 100644 --- a/x-pack/plugins/ml/public/application/util/string_utils.ts +++ b/x-pack/plugins/ml/public/application/util/string_utils.ts @@ -12,7 +12,7 @@ import d3 from 'd3'; import he from 'he'; import { escapeKuery } from '@kbn/es-query'; -import { isDefined } from '../../../common/types/guards'; +import { isDefined } from '@kbn/ml-is-defined'; import { CustomUrlAnomalyRecordDoc } from '../../../common/types/custom_urls'; import { Detector } from '../../../common/types/anomaly_detection_jobs'; diff --git a/x-pack/plugins/ml/server/lib/alerts/alerting_service.ts b/x-pack/plugins/ml/server/lib/alerts/alerting_service.ts index 45eef7f63226a..36182956b7388 100644 --- a/x-pack/plugins/ml/server/lib/alerts/alerting_service.ts +++ b/x-pack/plugins/ml/server/lib/alerts/alerting_service.ts @@ -15,6 +15,7 @@ import { IFieldFormat, SerializedFieldFormat, } from '@kbn/field-formats-plugin/common'; +import { isDefined } from '@kbn/ml-is-defined'; import { MlClient } from '../ml_client'; import { MlAnomalyDetectionAlertParams, @@ -32,7 +33,6 @@ import { } from '../../../common/types/alerts'; import { AnomalyDetectionAlertContext } from './register_anomaly_detection_alert_type'; import { resolveMaxTimeInterval } from '../../../common/util/job_utils'; -import { isDefined } from '../../../common/types/guards'; import { getTopNBuckets, resolveLookbackInterval } from '../../../common/util/alerts'; import type { DatafeedsService } from '../../models/job_service/datafeeds'; import { getEntityFieldName, getEntityFieldValue } from '../../../common/util/anomaly_utils'; diff --git a/x-pack/plugins/ml/server/lib/alerts/jobs_health_service.ts b/x-pack/plugins/ml/server/lib/alerts/jobs_health_service.ts index 4c19846794de1..a1ec1931485ac 100644 --- a/x-pack/plugins/ml/server/lib/alerts/jobs_health_service.ts +++ b/x-pack/plugins/ml/server/lib/alerts/jobs_health_service.ts @@ -9,6 +9,7 @@ import { groupBy, keyBy, memoize, partition } from 'lodash'; import { KibanaRequest, Logger, SavedObjectsClientContract } from '@kbn/core/server'; import { i18n } from '@kbn/i18n'; import { MlJob } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { isDefined } from '@kbn/ml-is-defined'; import { MlClient } from '../ml_client'; import { JobSelection } from '../../routes/schemas/alerting_schema'; import { datafeedsProvider, DatafeedsService } from '../../models/job_service/datafeeds'; @@ -30,7 +31,6 @@ import { import { AnnotationService } from '../../models/annotation_service/annotation'; import { annotationServiceProvider } from '../../models/annotation_service'; import { parseInterval } from '../../../common/util/parse_interval'; -import { isDefined } from '../../../common/types/guards'; import { jobAuditMessagesProvider, JobAuditMessagesService, diff --git a/x-pack/plugins/ml/server/models/data_frame_analytics/models_provider.ts b/x-pack/plugins/ml/server/models/data_frame_analytics/models_provider.ts index 1f6bb64fd76f4..ccb60e6379e48 100644 --- a/x-pack/plugins/ml/server/models/data_frame_analytics/models_provider.ts +++ b/x-pack/plugins/ml/server/models/data_frame_analytics/models_provider.ts @@ -11,6 +11,7 @@ import { MlTrainedModelStats, NodesInfoNodeInfo, } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { isDefined } from '@kbn/ml-is-defined'; import type { NodeDeploymentStatsResponse, PipelineDefinition, @@ -21,7 +22,6 @@ import { TrainedModelDeploymentStatsResponse, TrainedModelModelSizeStats, } from '../../../common/types/trained_models'; -import { isDefined } from '../../../common/types/guards'; export type ModelService = ReturnType; diff --git a/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts b/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts index 136722f4ab5b1..e9b92c2f01e6c 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts +++ b/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts @@ -18,6 +18,7 @@ import moment from 'moment'; import { merge } from 'lodash'; import type { DataViewsService } from '@kbn/data-views-plugin/common'; import { isPopulatedObject } from '@kbn/ml-is-populated-object'; +import { isDefined } from '@kbn/ml-is-defined'; import type { AnalysisLimits } from '../../../common/types/anomaly_detection_jobs'; import { getAuthorizationHeader } from '../../lib/request_authorization'; import type { MlClient } from '../../lib/ml_client'; @@ -54,7 +55,6 @@ import { resultsServiceProvider } from '../results_service'; import type { JobExistResult, JobStat } from '../../../common/types/data_recognizer'; import type { Datafeed } from '../../../common/types/anomaly_detection_jobs'; import type { MLSavedObjectService } from '../../saved_objects'; -import { isDefined } from '../../../common/types/guards'; const ML_DIR = 'ml'; const KIBANA_DIR = 'kibana'; diff --git a/x-pack/plugins/ml/server/models/results_service/anomaly_charts.ts b/x-pack/plugins/ml/server/models/results_service/anomaly_charts.ts index dbbf95d4806c2..bcce2455539f7 100644 --- a/x-pack/plugins/ml/server/models/results_service/anomaly_charts.ts +++ b/x-pack/plugins/ml/server/models/results_service/anomaly_charts.ts @@ -11,6 +11,7 @@ import { each, find, get, keyBy, map, reduce, sortBy } from 'lodash'; import type * as estypes from '@elastic/elasticsearch/lib/api/types'; import { extent, max, min } from 'd3'; import { isPopulatedObject } from '@kbn/ml-is-populated-object'; +import { isDefined } from '@kbn/ml-is-defined'; import type { MlClient } from '../../lib/ml_client'; import { isRuntimeMappings } from '../../../common'; import type { @@ -40,7 +41,6 @@ import { isMultiBucketAnomaly, } from '../../../common/util/anomaly_utils'; import { InfluencersFilterQuery } from '../../../common/types/es_client'; -import { isDefined } from '../../../common/types/guards'; import { AnomalyRecordDoc, CombinedJob, Datafeed, RecordForInfluencer } from '../../shared'; import { ES_AGGREGATION, ML_JOB_AGGREGATION } from '../../../common/constants/aggregation_types'; import { parseInterval } from '../../../common/util/parse_interval'; diff --git a/x-pack/plugins/ml/tsconfig.json b/x-pack/plugins/ml/tsconfig.json index e16c5a5055ff5..2b99e5d22616a 100644 --- a/x-pack/plugins/ml/tsconfig.json +++ b/x-pack/plugins/ml/tsconfig.json @@ -69,6 +69,7 @@ "@kbn/ml-url-state", "@kbn/ml-nested-property", "@kbn/ml-local-storage", + "@kbn/ml-is-defined", ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/transform/common/types/common.ts b/x-pack/plugins/transform/common/types/common.ts index 94cb935f52634..1cbb370b0a3ab 100644 --- a/x-pack/plugins/transform/common/types/common.ts +++ b/x-pack/plugins/transform/common/types/common.ts @@ -20,7 +20,3 @@ export function dictionaryToArray(dict: Dictionary): TValue[] { export type DeepPartial = { [P in keyof T]?: DeepPartial; }; - -export function isDefined(argument: T | undefined | null): argument is T { - return argument !== undefined && argument !== null; -} diff --git a/yarn.lock b/yarn.lock index db5c96fa66468..3e0f423b292c0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3741,7 +3741,11 @@ version "0.0.0" uid "" -"@kbn/ml-nested-property@link:x-pack/packages/ml/nested_property": +"@kbn/ml-is-defined@link:x-pack/packages/ml/is_defined": + version "0.0.0" + uid "" + +"@kbn/ml-is-populated-object@link:x-pack/packages/ml/is_populated_object": version "0.0.0" uid "" @@ -3749,15 +3753,15 @@ version "0.0.0" uid "" -"@kbn/ml-string-hash@link:x-pack/packages/ml/string_hash": +"@kbn/ml-nested-property@link:x-pack/packages/ml/nested_property": version "0.0.0" uid "" -"@kbn/ml-url-state@link:x-pack/packages/ml/url_state": +"@kbn/ml-string-hash@link:x-pack/packages/ml/string_hash": version "0.0.0" uid "" -"@kbn/ml-is-populated-object@link:x-pack/packages/ml/is_populated_object": +"@kbn/ml-url-state@link:x-pack/packages/ml/url_state": version "0.0.0" uid "" From 995ae433af8645020b2b555ae379f9e7a357bd14 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 27 Dec 2022 16:47:48 +0000 Subject: [PATCH 13/19] [CI] Auto-commit changed files from 'node scripts/generate codeowners' --- .github/CODEOWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index bd404ada0d9c1..4a6dac89ae710 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1071,6 +1071,7 @@ packages/shared-ux/storybook/mock @elastic/kibana-global-experience x-pack/packages/ml/agg_utils @elastic/ml-ui x-pack/packages/ml/aiops_components @elastic/ml-ui x-pack/packages/ml/aiops_utils @elastic/ml-ui +x-pack/packages/ml/is_defined @elastic/ml-ui x-pack/packages/ml/is_populated_object @elastic/ml-ui x-pack/packages/ml/local_storage @elastic/ml-ui x-pack/packages/ml/nested_property @elastic/ml-ui From 183e884b20db0e9b0e1b7abba7f28f51fb037ecc Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Tue, 27 Dec 2022 21:18:16 +0100 Subject: [PATCH 14/19] fix imports --- .../transform_health_rule_type/transform_selector_control.tsx | 2 +- .../plugins/transform/public/app/hooks/use_get_transforms.ts | 2 +- .../components/step_define/hooks/use_pivot_config.ts | 3 ++- .../components/transform_list/expanded_row.tsx | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/transform/public/alerting/transform_health_rule_type/transform_selector_control.tsx b/x-pack/plugins/transform/public/alerting/transform_health_rule_type/transform_selector_control.tsx index 4300b75cb3fa4..2a44d8fd973f7 100644 --- a/x-pack/plugins/transform/public/alerting/transform_health_rule_type/transform_selector_control.tsx +++ b/x-pack/plugins/transform/public/alerting/transform_health_rule_type/transform_selector_control.tsx @@ -7,8 +7,8 @@ import { EuiComboBox, EuiComboBoxProps, EuiFormRow } from '@elastic/eui'; import React, { FC, useMemo } from 'react'; +import { isDefined } from '@kbn/ml-is-defined'; import { ALL_TRANSFORMS_SELECTION } from '../../../common/constants'; -import { isDefined } from '../../../common/types/common'; export interface TransformSelectorControlProps { label?: string | JSX.Element; diff --git a/x-pack/plugins/transform/public/app/hooks/use_get_transforms.ts b/x-pack/plugins/transform/public/app/hooks/use_get_transforms.ts index c92a7a41da03f..55e3bc40360cf 100644 --- a/x-pack/plugins/transform/public/app/hooks/use_get_transforms.ts +++ b/x-pack/plugins/transform/public/app/hooks/use_get_transforms.ts @@ -6,6 +6,7 @@ */ import type { IHttpFetchError } from '@kbn/core-http-browser'; +import { isDefined } from '@kbn/ml-is-defined'; import { isGetTransformNodesResponseSchema, isGetTransformsResponseSchema, @@ -22,7 +23,6 @@ import { import { useApi } from './use_api'; import { TRANSFORM_ERROR_TYPE } from '../common/transform'; -import { isDefined } from '../../../common/types/common'; export type GetTransforms = (forceRefresh?: boolean) => void; diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/hooks/use_pivot_config.ts b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/hooks/use_pivot_config.ts index 962bc45f3d212..17240497d2057 100644 --- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/hooks/use_pivot_config.ts +++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/hooks/use_pivot_config.ts @@ -9,8 +9,9 @@ import { useCallback, useMemo, useState } from 'react'; import { i18n } from '@kbn/i18n'; import { KBN_FIELD_TYPES } from '@kbn/field-types'; +import { isDefined } from '@kbn/ml-is-defined'; import { AggName } from '../../../../../../../common/types/aggregations'; -import { dictionaryToArray, isDefined } from '../../../../../../../common/types/common'; +import { dictionaryToArray } from '../../../../../../../common/types/common'; import { useToastNotifications } from '../../../../../app_dependencies'; import { diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row.tsx index d96911cfdaa71..6f1d219ce7928 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row.tsx @@ -13,7 +13,7 @@ import { i18n } from '@kbn/i18n'; import { stringHash } from '@kbn/ml-string-hash'; import moment from 'moment-timezone'; -import { isDefined } from '../../../../../../common/types/common'; +import { isDefined } from '@kbn/ml-is-defined'; import { TransformListRow } from '../../../../common'; import { useAppDependencies } from '../../../../app_dependencies'; import { ExpandedRowDetailsPane, SectionConfig, SectionItem } from './expanded_row_details_pane'; From ad5cfc9c255cb77d5ad16885b9576177ad359a9a Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 27 Dec 2022 20:24:51 +0000 Subject: [PATCH 15/19] [CI] Auto-commit changed files from 'node scripts/ts_project_linter --fix' --- x-pack/plugins/transform/tsconfig.json | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugins/transform/tsconfig.json b/x-pack/plugins/transform/tsconfig.json index 2b4b5554ef9d0..8cb77da845d58 100644 --- a/x-pack/plugins/transform/tsconfig.json +++ b/x-pack/plugins/transform/tsconfig.json @@ -45,6 +45,7 @@ "@kbn/ui-theme", "@kbn/field-types", "@kbn/ml-nested-property", + "@kbn/ml-is-defined", ], "exclude": [ "target/**/*", From 40e18a1be872fbc0e7f7b04035fa2e7c23e70de1 Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Tue, 27 Dec 2022 21:47:47 +0100 Subject: [PATCH 16/19] fix imports --- .../advanced_runtime_mappings_settings.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/advanced_runtime_mappings_settings/advanced_runtime_mappings_settings.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/advanced_runtime_mappings_settings/advanced_runtime_mappings_settings.tsx index a07978e12ec0f..db617690efc5f 100644 --- a/x-pack/plugins/transform/public/app/sections/create_transform/components/advanced_runtime_mappings_settings/advanced_runtime_mappings_settings.tsx +++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/advanced_runtime_mappings_settings/advanced_runtime_mappings_settings.tsx @@ -18,7 +18,7 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { isDefined } from '../../../../../../common/types/common'; +import { isDefined } from '@kbn/ml-is-defined'; import { StepDefineFormHook } from '../step_define'; import { AdvancedRuntimeMappingsEditor } from '../advanced_runtime_mappings_editor/advanced_runtime_mappings_editor'; import { AdvancedRuntimeMappingsEditorSwitch } from '../advanced_runtime_mappings_editor_switch'; From c0e5b8763ec3e5b587c059b029530a47d8ff352c Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Fri, 30 Dec 2022 09:28:36 +0100 Subject: [PATCH 17/19] improve READMEs. remove prefix. --- x-pack/packages/ml/is_defined/README.md | 2 +- x-pack/packages/ml/local_storage/README.md | 2 +- x-pack/packages/ml/local_storage/index.ts | 2 +- x-pack/packages/ml/local_storage/src/storage_context.tsx | 6 +++--- .../change_point_detection/change_point_detetion_root.tsx | 6 +++--- .../explain_log_rate_spikes_app_state.tsx | 6 +++--- .../log_categorization/log_categorization_app_state.tsx | 6 +++--- .../index_data_visualizer/index_data_visualizer.tsx | 6 +++--- x-pack/plugins/ml/common/types/storage.test.tsx | 6 +++--- x-pack/plugins/ml/public/application/app.tsx | 6 +++--- 10 files changed, 24 insertions(+), 24 deletions(-) diff --git a/x-pack/packages/ml/is_defined/README.md b/x-pack/packages/ml/is_defined/README.md index fc6ed3ab7e554..c87e487b565a6 100644 --- a/x-pack/packages/ml/is_defined/README.md +++ b/x-pack/packages/ml/is_defined/README.md @@ -1,3 +1,3 @@ # @kbn/ml-is-defined -Empty package generated by @kbn/generate +Utility function to determine if a value is not `undefined` and not `null`. diff --git a/x-pack/packages/ml/local_storage/README.md b/x-pack/packages/ml/local_storage/README.md index 5ff246fddc2e5..d1e7c46957397 100644 --- a/x-pack/packages/ml/local_storage/README.md +++ b/x-pack/packages/ml/local_storage/README.md @@ -1,3 +1,3 @@ # @kbn/ml-local-storage -Empty package generated by @kbn/generate +Utilities to combine url state management with local storage. diff --git a/x-pack/packages/ml/local_storage/index.ts b/x-pack/packages/ml/local_storage/index.ts index c84936b4a430c..f950f8791a341 100644 --- a/x-pack/packages/ml/local_storage/index.ts +++ b/x-pack/packages/ml/local_storage/index.ts @@ -5,4 +5,4 @@ * 2.0. */ -export { MlStorageContextProvider, useStorage } from './src/storage_context'; +export { StorageContextProvider, useStorage } from './src/storage_context'; diff --git a/x-pack/packages/ml/local_storage/src/storage_context.tsx b/x-pack/packages/ml/local_storage/src/storage_context.tsx index 75cbc4fc7c58b..21251e5de7a30 100644 --- a/x-pack/packages/ml/local_storage/src/storage_context.tsx +++ b/x-pack/packages/ml/local_storage/src/storage_context.tsx @@ -46,16 +46,16 @@ export const MlStorageContext = React.createContext({ }, }); -interface MlStorageContextProviderProps { +interface StorageContextProviderProps { storage: Storage; storageKeys: readonly K[]; } -export function MlStorageContextProvider({ +export function StorageContextProvider({ children, storage, storageKeys, -}: PropsWithChildren>) { +}: PropsWithChildren>) { const initialValue = useMemo(() => { return storageKeys.reduce((acc, curr) => { acc[curr as K] = storage.get(curr as string); diff --git a/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detetion_root.tsx b/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detetion_root.tsx index 031092380512e..f7a039c082dee 100644 --- a/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detetion_root.tsx +++ b/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detetion_root.tsx @@ -9,7 +9,7 @@ import React, { FC } from 'react'; import { DataView } from '@kbn/data-views-plugin/common'; import { SavedSearch } from '@kbn/saved-search-plugin/public'; -import { MlStorageContextProvider } from '@kbn/ml-local-storage'; +import { StorageContextProvider } from '@kbn/ml-local-storage'; import { UrlStateProvider } from '@kbn/ml-url-state'; import { Storage } from '@kbn/kibana-utils-plugin/public'; @@ -40,12 +40,12 @@ export const ChangePointDetectionAppState: FC - + - + diff --git a/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_app_state.tsx b/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_app_state.tsx index 1866dd9782aee..6b6b477807d41 100644 --- a/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_app_state.tsx +++ b/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_app_state.tsx @@ -13,7 +13,7 @@ import type { Filter, Query } from '@kbn/es-query'; import { i18n } from '@kbn/i18n'; import type { SavedSearch } from '@kbn/discover-plugin/public'; import type { DataView } from '@kbn/data-views-plugin/public'; -import { MlStorageContextProvider } from '@kbn/ml-local-storage'; +import { StorageContextProvider } from '@kbn/ml-local-storage'; import { UrlStateProvider } from '@kbn/ml-url-state'; import { Storage } from '@kbn/kibana-utils-plugin/public'; @@ -99,9 +99,9 @@ export const ExplainLogRateSpikesAppState: FC - + - + diff --git a/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_app_state.tsx b/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_app_state.tsx index c6e7d7c0cc142..ee571d990c832 100644 --- a/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_app_state.tsx +++ b/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_app_state.tsx @@ -7,7 +7,7 @@ import React, { FC } from 'react'; import type { SavedSearch } from '@kbn/discover-plugin/public'; import type { DataView } from '@kbn/data-views-plugin/public'; -import { MlStorageContextProvider } from '@kbn/ml-local-storage'; +import { StorageContextProvider } from '@kbn/ml-local-storage'; import { UrlStateProvider } from '@kbn/ml-url-state'; import { Storage } from '@kbn/kibana-utils-plugin/public'; @@ -34,9 +34,9 @@ export const LogCategorizationAppState: FC = ({ return ( - + - + ); diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/index_data_visualizer.tsx b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/index_data_visualizer.tsx index 829927fe455d3..156898449ee79 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/index_data_visualizer.tsx +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/index_data_visualizer.tsx @@ -15,7 +15,7 @@ import { SimpleSavedObject } from '@kbn/core/public'; import { i18n } from '@kbn/i18n'; import { Storage } from '@kbn/kibana-utils-plugin/public'; import { KibanaContextProvider, KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; -import { MlStorageContextProvider } from '@kbn/ml-local-storage'; +import { StorageContextProvider } from '@kbn/ml-local-storage'; import { DataView } from '@kbn/data-views-plugin/public'; import { getNestedProperty } from '@kbn/ml-nested-property'; import { @@ -321,12 +321,12 @@ export const IndexDataVisualizer: FC<{ return ( - + - + ); diff --git a/x-pack/plugins/ml/common/types/storage.test.tsx b/x-pack/plugins/ml/common/types/storage.test.tsx index f5773e8ea6933..c27c6e74d9edb 100644 --- a/x-pack/plugins/ml/common/types/storage.test.tsx +++ b/x-pack/plugins/ml/common/types/storage.test.tsx @@ -9,7 +9,7 @@ import React, { FC } from 'react'; import { renderHook, act } from '@testing-library/react-hooks'; import type { Storage } from '@kbn/kibana-utils-plugin/public'; -import { MlStorageContextProvider, useStorage } from '@kbn/ml-local-storage'; +import { StorageContextProvider, useStorage } from '@kbn/ml-local-storage'; import { ML_STORAGE_KEYS } from './storage'; @@ -32,9 +32,9 @@ const mockStorage: Storage = { const Provider: FC = ({ children }) => { return ( - + {children} - + ); }; diff --git a/x-pack/plugins/ml/public/application/app.tsx b/x-pack/plugins/ml/public/application/app.tsx index dc42f963fd1a8..463cb34691144 100644 --- a/x-pack/plugins/ml/public/application/app.tsx +++ b/x-pack/plugins/ml/public/application/app.tsx @@ -15,7 +15,7 @@ import type { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public'; import { Storage } from '@kbn/kibana-utils-plugin/public'; import { KibanaContextProvider, KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; -import { MlStorageContextProvider } from '@kbn/ml-local-storage'; +import { StorageContextProvider } from '@kbn/ml-local-storage'; import { ML_STORAGE_KEYS } from '../../common/types/storage'; import { setDependencyCache, clearCache } from './util/dependency_cache'; import { setLicenseCache } from './license'; @@ -112,9 +112,9 @@ const App: FC = ({ coreStart, deps, appMountParams }) => { mlServices: getMlGlobalServices(coreStart.http, deps.usageCollection), }} > - + - + From 543387f3711bfd720fa8efc399b71890bf648485 Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Wed, 4 Jan 2023 14:41:31 +0100 Subject: [PATCH 18/19] Adds comments to exported code --- x-pack/packages/ml/is_defined/src/is_defined.ts | 6 ++++++ .../ml/local_storage/src/storage_context.tsx | 13 +++++++++++++ 2 files changed, 19 insertions(+) diff --git a/x-pack/packages/ml/is_defined/src/is_defined.ts b/x-pack/packages/ml/is_defined/src/is_defined.ts index ead91eafc2d4e..925be4cfbbcee 100644 --- a/x-pack/packages/ml/is_defined/src/is_defined.ts +++ b/x-pack/packages/ml/is_defined/src/is_defined.ts @@ -5,6 +5,12 @@ * 2.0. */ +/** + * Checks wether the supplied argument is not `undefined` and not `null`. + * + * @param argument + * @returns boolean + */ export function isDefined(argument: T | undefined | null): argument is T { return argument !== undefined && argument !== null; } diff --git a/x-pack/packages/ml/local_storage/src/storage_context.tsx b/x-pack/packages/ml/local_storage/src/storage_context.tsx index 21251e5de7a30..8a79c94aee8a8 100644 --- a/x-pack/packages/ml/local_storage/src/storage_context.tsx +++ b/x-pack/packages/ml/local_storage/src/storage_context.tsx @@ -32,10 +32,20 @@ interface StorageAPI { removeValue: (key: K) => void; } +/** + * Type guard to check if a supplied `key` is in `storageKey`. + * + * @param key + * @param storageKeys + * @returns boolean + */ export function isStorageKey(key: unknown, storageKeys: readonly T[]): key is T { return storageKeys.includes(key as T); } +/** + * React context to hold storage API. + */ export const MlStorageContext = React.createContext({ value: null, setValue() { @@ -51,6 +61,9 @@ interface StorageContextProviderProps { storageKeys: readonly K[]; } +/** + * Provider to manage context for the `useStorage` hook. + */ export function StorageContextProvider({ children, storage, From b41dacf708779ec64185ae49c8af1473d8641238 Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Wed, 4 Jan 2023 17:15:20 +0100 Subject: [PATCH 19/19] more api docs --- .../packages/ml/is_defined/src/is_defined.ts | 2 +- .../ml/local_storage/src/storage_context.tsx | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/x-pack/packages/ml/is_defined/src/is_defined.ts b/x-pack/packages/ml/is_defined/src/is_defined.ts index 925be4cfbbcee..1cf980293277c 100644 --- a/x-pack/packages/ml/is_defined/src/is_defined.ts +++ b/x-pack/packages/ml/is_defined/src/is_defined.ts @@ -6,7 +6,7 @@ */ /** - * Checks wether the supplied argument is not `undefined` and not `null`. + * Checks whether the supplied argument is not `undefined` and not `null`. * * @param argument * @returns boolean diff --git a/x-pack/packages/ml/local_storage/src/storage_context.tsx b/x-pack/packages/ml/local_storage/src/storage_context.tsx index 8a79c94aee8a8..e8cb64d81025e 100644 --- a/x-pack/packages/ml/local_storage/src/storage_context.tsx +++ b/x-pack/packages/ml/local_storage/src/storage_context.tsx @@ -18,14 +18,29 @@ import { omit } from 'lodash'; import type { Storage } from '@kbn/kibana-utils-plugin/public'; import { isDefined } from '@kbn/ml-is-defined'; +/** + * StorageDefinition is a dictionary with `string` based keys. + */ interface StorageDefinition { [key: string]: unknown; } +/** + * TStorage, a partial `StorageDefinition` or `null`. + */ type TStorage = Partial | null; +/** + * TStorageKey, keys of StorageDefintion. + */ type TStorageKey = keyof Exclude; +/** + * TStorageMapped, mapping of TStorage with TStorageKey. + */ type TStorageMapped = T extends string ? unknown : null; +/** + * StorageAPI definition of store TStorage with accessors. + */ interface StorageAPI { value: TStorage; setValue: >(key: K, value: T) => void; @@ -56,6 +71,9 @@ export const MlStorageContext = React.createContext({ }, }); +/** + * Props for StorageContextProvider + */ interface StorageContextProviderProps { storage: Storage; storageKeys: readonly K[];