diff --git a/x-pack/packages/ml/url_state/src/url_state.tsx b/x-pack/packages/ml/url_state/src/url_state.tsx index 3e5f2f739016d..d643a22bde6e4 100644 --- a/x-pack/packages/ml/url_state/src/url_state.tsx +++ b/x-pack/packages/ml/url_state/src/url_state.tsx @@ -228,16 +228,21 @@ export class PageUrlStateService { } } +interface PageUrlState { + pageKey: string; + pageUrlState: object; +} + /** * Hook for managing the URL state of the page. */ -export const usePageUrlState = ( - pageKey: string, - defaultState?: PageUrlState +export const usePageUrlState = ( + pageKey: T['pageKey'], + defaultState?: T['pageUrlState'] ): [ - PageUrlState, - (update: Partial, replaceState?: boolean) => void, - PageUrlStateService + T['pageUrlState'], + (update: Partial, replaceState?: boolean) => void, + PageUrlStateService ] => { const [appState, setAppState] = useUrlState('_a'); const pageState = appState?.[pageKey]; @@ -248,9 +253,9 @@ export const usePageUrlState = ( setCallback.current = setAppState; }, [setAppState]); - const prevPageState = useRef(); + const prevPageState = useRef(); - const resultPageState: PageUrlState = useMemo(() => { + const resultPageState: T['pageUrlState'] = useMemo(() => { const result = { ...(defaultState ?? {}), ...(pageState ?? {}), @@ -276,7 +281,7 @@ export const usePageUrlState = ( }, [pageState]); const onStateUpdate = useCallback( - (update: Partial, replaceState?: boolean) => { + (update: Partial, replaceState?: boolean) => { if (!setCallback?.current) { throw new Error('Callback for URL state update has not been initialized.'); } @@ -293,7 +298,7 @@ export const usePageUrlState = ( [pageKey, resultPageState] ); - const pageUrlStateService = useMemo(() => new PageUrlStateService(), []); + const pageUrlStateService = useMemo(() => new PageUrlStateService(), []); useEffect( function updatePageUrlService() { diff --git a/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detection_context.tsx b/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detection_context.tsx index 8e1479f5f132f..600a68ff1a498 100644 --- a/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detection_context.tsx +++ b/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detection_context.tsx @@ -30,6 +30,11 @@ import { type TimeBuckets, TimeBucketsInterval } from '../../../common/time_buck import { useDataSource } from '../../hooks/use_data_source'; import { useTimeBuckets } from '../../hooks/use_time_buckets'; +export interface ChangePointDetectionPageUrlState { + pageKey: 'changePoint'; + pageUrlState: ChangePointDetectionRequestParams; +} + export interface ChangePointDetectionRequestParams { fn: string; splitField: string; @@ -157,7 +162,7 @@ export const ChangePointDetectionContextProvider: FC = ({ children }) => { }, [dataView]); const [requestParamsFromUrl, updateRequestParams] = - usePageUrlState('changePoint'); + usePageUrlState('changePoint'); const resultQuery = useMemo(() => { return ( 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 2f021225bb260..2e745894cac0a 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 @@ -41,6 +41,11 @@ const defaultSearchQuery = { match_all: {}, }; +export interface AiOpsPageUrlState { + pageKey: 'AIOPS_INDEX_VIEWER'; + pageUrlState: AiOpsIndexBasedAppState; +} + export interface AiOpsIndexBasedAppState { searchString?: Query['query']; searchQuery?: Query['query']; diff --git a/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_page.tsx b/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_page.tsx index 819548b216511..98727faeea027 100644 --- a/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_page.tsx +++ b/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_page.tsx @@ -36,7 +36,7 @@ import { DocumentCountContent } from '../document_count_content/document_count_c import { DatePickerWrapper } from '../date_picker_wrapper'; import { SearchPanel } from '../search_panel'; -import { restorableDefaults } from './explain_log_rate_spikes_app_state'; +import { restorableDefaults, type AiOpsPageUrlState } from './explain_log_rate_spikes_app_state'; import { ExplainLogRateSpikesAnalysis } from './explain_log_rate_spikes_analysis'; import type { GroupTableItem } from '../spike_analysis_table/types'; import { useSpikeAnalysisTableRowContext } from '../spike_analysis_table/spike_analysis_table_row_provider'; @@ -79,7 +79,7 @@ export const ExplainLogRateSpikesPage: FC = ({ setSelectedGroup, } = useSpikeAnalysisTableRowContext(); - const [aiopsListState, setAiopsListState] = usePageUrlState( + const [aiopsListState, setAiopsListState] = usePageUrlState( 'AIOPS_INDEX_VIEWER', restorableDefaults ); 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 91049311a0646..8e13ce92a5c1e 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 @@ -39,7 +39,10 @@ import type { TotalFieldsStats } from '../../../common/components/stats_table/co import { OverallStats } from '../../types/overall_stats'; import { IndexBasedDataVisualizerExpandedRow } from '../../../common/components/expanded_row/index_based_expanded_row'; import { DATA_VISUALIZER_INDEX_VIEWER } from '../../constants/index_data_visualizer_viewer'; -import { DataVisualizerIndexBasedAppState } from '../../types/index_data_visualizer_state'; +import { + DataVisualizerIndexBasedAppState, + DataVisualizerIndexBasedPageUrlState, +} from '../../types/index_data_visualizer_state'; import { SEARCH_QUERY_LANGUAGE, SearchQueryLanguage } from '../../types/combined_query'; import { SupportedFieldType, SavedSearchSavedObject } from '../../../../../common/types'; import { useDataVisualizerKibana } from '../../../kibana_context'; @@ -143,10 +146,11 @@ export const IndexDataVisualizerView: FC = (dataVi const { notifications, uiSettings, data } = services; const { toasts } = notifications; - const [dataVisualizerListState, setDataVisualizerListState] = usePageUrlState( - DATA_VISUALIZER_INDEX_VIEWER, - restorableDefaults - ); + const [dataVisualizerListState, setDataVisualizerListState] = + usePageUrlState( + DATA_VISUALIZER_INDEX_VIEWER, + restorableDefaults + ); const [globalState, setGlobalState] = useUrlState('_g'); const [currentSavedSearch, setCurrentSavedSearch] = useState( diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/types/index_data_visualizer_state.ts b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/types/index_data_visualizer_state.ts index 2baba961691fb..5b0bb046f2596 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/types/index_data_visualizer_state.ts +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/types/index_data_visualizer_state.ts @@ -9,6 +9,14 @@ import type { Filter } from '@kbn/es-query'; import type { Query } from '@kbn/data-plugin/common/query'; import type { RandomSamplerOption } from '../constants/random_sampler'; import type { SearchQueryLanguage } from './combined_query'; + +import type { DATA_VISUALIZER_INDEX_VIEWER } from '../constants/index_data_visualizer_viewer'; + +export interface DataVisualizerIndexBasedPageUrlState { + pageKey: typeof DATA_VISUALIZER_INDEX_VIEWER; + pageUrlState: Required; +} + export interface ListingPageUrlState { pageSize: number; pageIndex: number; @@ -16,6 +24,7 @@ export interface ListingPageUrlState { sortDirection: string; queryText?: string; } + export interface DataVisualizerIndexBasedAppState extends Omit { searchString?: Query['query']; searchQuery?: Query['query']; diff --git a/x-pack/plugins/ml/public/application/components/controls/select_interval/select_interval.tsx b/x-pack/plugins/ml/public/application/components/controls/select_interval/select_interval.tsx index 1d34e4e7c516b..fa06273e3dd90 100644 --- a/x-pack/plugins/ml/public/application/components/controls/select_interval/select_interval.tsx +++ b/x-pack/plugins/ml/public/application/components/controls/select_interval/select_interval.tsx @@ -10,6 +10,11 @@ import { EuiIcon, EuiSelect, EuiToolTip } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { usePageUrlState } from '@kbn/ml-url-state'; +interface TableIntervalPageUrlState { + pageKey: 'mlSelectInterval'; + pageUrlState: TableInterval; +} + export interface TableInterval { display: string; val: string; @@ -55,7 +60,7 @@ function optionValueToInterval(value: string) { export const TABLE_INTERVAL_DEFAULT = optionValueToInterval('auto'); export const useTableInterval = (): [TableInterval, (v: TableInterval) => void] => { - const [interval, updateCallback] = usePageUrlState( + const [interval, updateCallback] = usePageUrlState( 'mlSelectInterval', TABLE_INTERVAL_DEFAULT ); diff --git a/x-pack/plugins/ml/public/application/components/controls/select_severity/select_severity.tsx b/x-pack/plugins/ml/public/application/components/controls/select_severity/select_severity.tsx index fc89b95f2db2d..a9375fec0a69e 100644 --- a/x-pack/plugins/ml/public/application/components/controls/select_severity/select_severity.tsx +++ b/x-pack/plugins/ml/public/application/components/controls/select_severity/select_severity.tsx @@ -39,6 +39,11 @@ const optionsMap = { [criticalLabel]: ANOMALY_THRESHOLD.CRITICAL, }; +export interface TableSeverityPageUrlState { + pageKey: 'mlSelectSeverity'; + pageUrlState: TableSeverity; +} + export interface TableSeverity { val: number; display: string; @@ -83,7 +88,7 @@ export function optionValueToThreshold(value: number) { const TABLE_SEVERITY_DEFAULT = SEVERITY_OPTIONS[0]; export const useTableSeverity = () => { - return usePageUrlState('mlSelectSeverity', TABLE_SEVERITY_DEFAULT); + return usePageUrlState('mlSelectSeverity', TABLE_SEVERITY_DEFAULT); }; export const getSeverityOptions = () => diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/hooks/use_exploration_url_state.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/hooks/use_exploration_url_state.ts index 655016a59263f..443b4c2298928 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/hooks/use_exploration_url_state.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/hooks/use_exploration_url_state.ts @@ -28,8 +28,13 @@ export function getDefaultExplorationPageUrlState( }; } +interface UsePageUrlState { + pageKey: typeof ML_PAGES.DATA_FRAME_ANALYTICS_EXPLORATION; + pageUrlState: ExplorationPageUrlState; +} + export function useExplorationUrlState(overrides?: Partial) { - return usePageUrlState( + return usePageUrlState( ML_PAGES.DATA_FRAME_ANALYTICS_EXPLORATION, getDefaultExplorationPageUrlState(overrides) ); diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/page.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/page.tsx index e53812da40a60..c53112c6ddf35 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/page.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/page.tsx @@ -24,6 +24,11 @@ import { useMlKibana } from '../../../contexts/kibana'; import { useRefreshAnalyticsList } from '../../common'; import { MlPageHeader } from '../../../components/page_header'; +interface PageUrlState { + pageKey: typeof ML_PAGES.DATA_FRAME_ANALYTICS_JOBS_MANAGE; + pageUrlState: ListingPageUrlState; +} + export const getDefaultDFAListState = (): ListingPageUrlState => ({ pageIndex: 0, pageSize: 10, @@ -35,7 +40,7 @@ export const Page: FC = () => { const [blockRefresh, setBlockRefresh] = useState(false); const [globalState] = useUrlState('_g'); - const [dfaPageState, setDfaPageState] = usePageUrlState( + const [dfaPageState, setDfaPageState] = usePageUrlState( ML_PAGES.DATA_FRAME_ANALYTICS_JOBS_MANAGE, getDefaultDFAListState() ); diff --git a/x-pack/plugins/ml/public/application/explorer/hooks/use_explorer_url_state.ts b/x-pack/plugins/ml/public/application/explorer/hooks/use_explorer_url_state.ts index 35e7760cd099d..221ac4e624c5b 100644 --- a/x-pack/plugins/ml/public/application/explorer/hooks/use_explorer_url_state.ts +++ b/x-pack/plugins/ml/public/application/explorer/hooks/use_explorer_url_state.ts @@ -11,15 +11,24 @@ import { ML_PAGES } from '../../../../common/constants/locator'; export type AnomalyExplorerUrlStateService = PageUrlStateService; +interface LegacyExplorerPageUrlState { + pageKey: 'mlExplorerSwimlane'; + pageUrlState: ExplorerAppState['mlExplorerSwimlane']; +} + +interface ExplorerPageUrlState { + pageKey: typeof ML_PAGES.ANOMALY_EXPLORER; + pageUrlState: ExplorerAppState; +} + export function useExplorerUrlState() { /** * Originally `mlExplorerSwimlane` resided directly in the app URL state (`_a` URL state key). * With current URL structure it has been moved under the `explorer` key of the app state (_a). */ - const [legacyExplorerState] = - usePageUrlState('mlExplorerSwimlane'); + const [legacyExplorerState] = usePageUrlState('mlExplorerSwimlane'); - return usePageUrlState(ML_PAGES.ANOMALY_EXPLORER, { + return usePageUrlState(ML_PAGES.ANOMALY_EXPLORER, { mlExplorerSwimlane: legacyExplorerState, mlExplorerFilter: {}, }); diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/jobs.tsx b/x-pack/plugins/ml/public/application/jobs/jobs_list/jobs.tsx index cd9bf60edb8cb..f93f1642b10f0 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/jobs.tsx +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/jobs.tsx @@ -7,7 +7,6 @@ import React, { FC } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; -// @ts-ignore import { usePageUrlState } from '@kbn/ml-url-state'; import { JobsListView } from './components/jobs_list_view'; import { ML_PAGES } from '../../../../common/constants/locator'; @@ -18,6 +17,11 @@ import { MlPageHeader } from '../../components/page_header'; import { HeaderMenuPortal } from '../../components/header_menu_portal'; import { JobsActionMenu } from '../components/jobs_action_menu'; +interface PageUrlState { + pageKey: typeof ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE; + pageUrlState: ListingPageUrlState; +} + interface JobsPageProps { isMlEnabledInSpace?: boolean; lastRefresh?: number; @@ -31,7 +35,7 @@ export const getDefaultAnomalyDetectionJobsListState = (): ListingPageUrlState = }); export const JobsPage: FC = ({ isMlEnabledInSpace, lastRefresh }) => { - const [pageState, setPageState] = usePageUrlState( + const [pageState, setPageState] = usePageUrlState( ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE, getDefaultAnomalyDetectionJobsListState() ); diff --git a/x-pack/plugins/ml/public/application/notifications/components/notifications_list.tsx b/x-pack/plugins/ml/public/application/notifications/components/notifications_list.tsx index 86039672cbfd0..83c5f895c9b96 100644 --- a/x-pack/plugins/ml/public/application/notifications/components/notifications_list.tsx +++ b/x-pack/plugins/ml/public/application/notifications/components/notifications_list.tsx @@ -47,6 +47,11 @@ const levelBadgeMap: Record = { [ML_NOTIFICATIONS_MESSAGE_LEVEL.INFO]: 'default', }; +interface PageUrlState { + pageKey: typeof ML_PAGES.NOTIFICATIONS; + pageUrlState: ListingPageUrlState; +} + export const getDefaultNotificationsListState = (): ListingPageUrlState => ({ pageIndex: 0, pageSize: 25, @@ -81,7 +86,7 @@ export const NotificationsList: FC = () => { const dateFormatter = useFieldFormatter(FIELD_FORMAT_IDS.DATE); - const [pageState, updatePageState] = usePageUrlState( + const [pageState, updatePageState] = usePageUrlState( ML_PAGES.NOTIFICATIONS, getDefaultNotificationsListState() ); diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/hooks/use_timeseriesexplorer_url_state.ts b/x-pack/plugins/ml/public/application/timeseriesexplorer/hooks/use_timeseriesexplorer_url_state.ts index 6c473c3d6740d..0ec0851f7be04 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/hooks/use_timeseriesexplorer_url_state.ts +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/hooks/use_timeseriesexplorer_url_state.ts @@ -9,6 +9,11 @@ import { usePageUrlState } from '@kbn/ml-url-state'; import { TimeSeriesExplorerAppState } from '../../../../common/types/locator'; import { ML_PAGES } from '../../../../common/constants/locator'; +interface TimeSeriesExplorerPageUrlState { + pageKey: typeof ML_PAGES.SINGLE_METRIC_VIEWER; + pageUrlState: TimeSeriesExplorerAppState; +} + export function useTimeSeriesExplorerUrlState() { - return usePageUrlState(ML_PAGES.SINGLE_METRIC_VIEWER); + return usePageUrlState(ML_PAGES.SINGLE_METRIC_VIEWER); } diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/models_list.tsx b/x-pack/plugins/ml/public/application/trained_models/models_management/models_list.tsx index c7aafca60f69f..6c665654bc92d 100644 --- a/x-pack/plugins/ml/public/application/trained_models/models_management/models_list.tsx +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/models_list.tsx @@ -59,6 +59,11 @@ export type ModelItem = TrainedModelConfigResponse & { export type ModelItemFull = Required; +interface PageUrlState { + pageKey: typeof ML_PAGES.TRAINED_MODELS_MANAGE; + pageUrlState: ListingPageUrlState; +} + export const getDefaultModelsListState = (): ListingPageUrlState => ({ pageIndex: 0, pageSize: 10, @@ -88,7 +93,7 @@ export const ModelsList: FC = ({ // allow for an internally controlled page state which stores the state in the URL // or an external page state, which is passed in as a prop. // external page state is used on the management page. - const [pageStateInternal, updatePageStateInternal] = usePageUrlState( + const [pageStateInternal, updatePageStateInternal] = usePageUrlState( ML_PAGES.TRAINED_MODELS_MANAGE, getDefaultModelsListState() ); diff --git a/x-pack/plugins/ml/public/application/trained_models/nodes_overview/nodes_list.tsx b/x-pack/plugins/ml/public/application/trained_models/nodes_overview/nodes_list.tsx index 81371345720f8..9ec06645d8e29 100644 --- a/x-pack/plugins/ml/public/application/trained_models/nodes_overview/nodes_list.tsx +++ b/x-pack/plugins/ml/public/application/trained_models/nodes_overview/nodes_list.tsx @@ -32,6 +32,11 @@ import { useRefresh } from '../../routing/use_refresh'; export type NodeItem = NodeDeploymentStatsResponse; +interface PageUrlState { + pageKey: typeof ML_PAGES.TRAINED_MODELS_NODES; + pageUrlState: ListingPageUrlState; +} + export const getDefaultNodesListState = (): ListingPageUrlState => ({ pageIndex: 0, pageSize: 10, @@ -55,7 +60,7 @@ export const NodesList: FC = ({ compactView = false }) => { const [itemIdToExpandedRowMap, setItemIdToExpandedRowMap] = useState>( {} ); - const [pageState, updatePageState] = usePageUrlState( + const [pageState, updatePageState] = usePageUrlState( ML_PAGES.TRAINED_MODELS_NODES, getDefaultNodesListState() );