From 3919a8bb049b185912db52e5388ecac75e4c8e28 Mon Sep 17 00:00:00 2001
From: Walter Rafelsberger
Date: Mon, 21 Aug 2023 14:33:45 +0200
Subject: [PATCH 01/53] migrate transform list to use react-query
---
.../common/api_schemas/transforms.ts | 2 +-
x-pack/plugins/transform/common/constants.ts | 5 +
.../transform/public/app/common/index.ts | 7 +-
.../transform/public/app/common/transform.ts | 68 +------
.../public/app/hooks/use_delete_transform.tsx | 5 +-
.../public/app/hooks/use_get_transforms.ts | 139 ++++++-------
.../app/hooks/use_reauthorize_transform.tsx | 5 +-
.../public/app/hooks/use_reset_transform.tsx | 5 +-
.../app/hooks/use_schedule_now_transform.tsx | 5 +-
.../public/app/hooks/use_start_transform.tsx | 5 +-
.../public/app/hooks/use_stop_transform.tsx | 5 +-
.../components/authorization_provider.tsx | 3 +-
.../edit_transform_update_button.tsx | 5 +-
.../transform_list.test.tsx.snap | 96 +++++----
.../expanded_row_messages_pane.tsx | 112 +++++------
.../transform_list/transform_list.test.tsx | 18 +-
.../transform_list/transform_list.tsx | 46 ++++-
.../transform_list/use_actions.test.tsx | 11 +-
.../transform_list/use_columns.test.tsx | 10 +-
.../transform_list/use_refresh_interval.ts | 28 ---
.../transform_management_section.tsx | 183 +++++++-----------
21 files changed, 339 insertions(+), 424 deletions(-)
delete mode 100644 x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_refresh_interval.ts
diff --git a/x-pack/plugins/transform/common/api_schemas/transforms.ts b/x-pack/plugins/transform/common/api_schemas/transforms.ts
index 5b300a613be94..65e0433a81264 100644
--- a/x-pack/plugins/transform/common/api_schemas/transforms.ts
+++ b/x-pack/plugins/transform/common/api_schemas/transforms.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { schema, TypeOf } from '@kbn/config-schema';
+import { schema, type TypeOf } from '@kbn/config-schema';
import type { ES_FIELD_TYPES } from '@kbn/field-types';
diff --git a/x-pack/plugins/transform/common/constants.ts b/x-pack/plugins/transform/common/constants.ts
index 633f0dc7849ac..1076f1d6530d6 100644
--- a/x-pack/plugins/transform/common/constants.ts
+++ b/x-pack/plugins/transform/common/constants.ts
@@ -32,6 +32,11 @@ const EXTERNAL_API_BASE_PATH = '/api/transform/';
export const addInternalBasePath = (uri: string): string => `${INTERNAL_API_BASE_PATH}${uri}`;
export const addExternalBasePath = (uri: string): string => `${EXTERNAL_API_BASE_PATH}${uri}`;
+export const TRANSFORM_REACT_QUERY_KEYS = {
+ PRIVILEGES: 'transform.privileges',
+ TRANSFORMS_LIST: 'transform.transforms_list',
+} as const;
+
// In order to create a transform, the API requires the following privileges:
// - transform_admin (builtin)
// - cluster privileges: manage_transform
diff --git a/x-pack/plugins/transform/public/app/common/index.ts b/x-pack/plugins/transform/public/app/common/index.ts
index c7656974ec569..42701de487adb 100644
--- a/x-pack/plugins/transform/public/app/common/index.ts
+++ b/x-pack/plugins/transform/public/app/common/index.ts
@@ -19,12 +19,7 @@ export {
toggleSelectedField,
} from './fields';
export type { DropDownLabel, DropDownOption, Label } from './dropdown';
-export {
- isTransformIdValid,
- refreshTransformList$,
- useRefreshTransformList,
- REFRESH_TRANSFORM_LIST_STATE,
-} from './transform';
+export { isTransformIdValid, useRefreshTransformList } from './transform';
export type { TransformListAction, TransformListRow } from './transform_list';
export { TRANSFORM_LIST_COLUMN } from './transform_list';
export { getTransformProgress, isCompletedBatchTransform } from './transform_stats';
diff --git a/x-pack/plugins/transform/public/app/common/transform.ts b/x-pack/plugins/transform/public/app/common/transform.ts
index 35ead5691a866..34bbb82805c50 100644
--- a/x-pack/plugins/transform/public/app/common/transform.ts
+++ b/x-pack/plugins/transform/public/app/common/transform.ts
@@ -5,12 +5,12 @@
* 2.0.
*/
-import { useEffect } from 'react';
-import { BehaviorSubject } from 'rxjs';
-import { filter, distinctUntilChanged } from 'rxjs/operators';
-import { Subscription } from 'rxjs';
import { cloneDeep } from 'lodash';
+import { useCallback } from 'react';
+import { useQueryClient } from '@tanstack/react-query';
+
import type { TransformConfigUnion, TransformId } from '../../../common/types/transform';
+import { TRANSFORM_REACT_QUERY_KEYS } from '../../../common/constants';
// Via https://github.com/elastic/elasticsearch/blob/master/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/utils/TransformStrings.java#L24
// Matches a string that contains lowercase characters, digits, hyphens, underscores or dots.
@@ -23,63 +23,13 @@ export function isTransformIdValid(transformId: TransformId) {
export const TRANSFORM_ERROR_TYPE = {
DANGLING_TASK: 'dangling_task',
} as const;
-export enum REFRESH_TRANSFORM_LIST_STATE {
- ERROR = 'error',
- IDLE = 'idle',
- LOADING = 'loading',
- REFRESH = 'refresh',
-}
-export const refreshTransformList$ = new BehaviorSubject(
- REFRESH_TRANSFORM_LIST_STATE.IDLE
-);
-
-export const useRefreshTransformList = (
- callback: {
- isLoading?(d: boolean): void;
- onRefresh?(): void;
- } = {}
-) => {
- useEffect(() => {
- const distinct$ = refreshTransformList$.pipe(distinctUntilChanged());
-
- const subscriptions: Subscription[] = [];
-
- if (typeof callback.onRefresh === 'function') {
- // initial call to refresh
- callback.onRefresh();
-
- subscriptions.push(
- distinct$
- .pipe(filter((state) => state === REFRESH_TRANSFORM_LIST_STATE.REFRESH))
- .subscribe(() => typeof callback.onRefresh === 'function' && callback.onRefresh())
- );
- }
-
- if (typeof callback.isLoading === 'function') {
- subscriptions.push(
- distinct$.subscribe(
- (state) =>
- typeof callback.isLoading === 'function' &&
- callback.isLoading(state === REFRESH_TRANSFORM_LIST_STATE.LOADING)
- )
- );
- }
- return () => {
- subscriptions.map((sub) => sub.unsubscribe());
- };
- // The effect should only be called once.
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, []);
+export const useRefreshTransformList = () => {
+ const queryClient = useQueryClient();
- return {
- refresh: () => {
- // A refresh is followed immediately by setting the state to loading
- // to trigger data fetching and loading indicators in one go.
- refreshTransformList$.next(REFRESH_TRANSFORM_LIST_STATE.REFRESH);
- refreshTransformList$.next(REFRESH_TRANSFORM_LIST_STATE.LOADING);
- },
- };
+ return useCallback(() => {
+ queryClient.invalidateQueries([TRANSFORM_REACT_QUERY_KEYS.TRANSFORMS_LIST]);
+ }, [queryClient]);
};
export const overrideTransformForCloning = (originalConfig: TransformConfigUnion) => {
diff --git a/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx
index 25318fc9e2903..d4e078d285ca9 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx
@@ -16,7 +16,7 @@ import type {
import { isDeleteTransformsResponseSchema } from '../../../common/api_schemas/type_guards';
import { getErrorMessage } from '../../../common/utils/errors';
import { useAppDependencies, useToastNotifications } from '../app_dependencies';
-import { REFRESH_TRANSFORM_LIST_STATE, refreshTransformList$, TransformListRow } from '../common';
+import { useRefreshTransformList, type TransformListRow } from '../common';
import { ToastNotificationText } from '../components';
import { useApi } from './use_api';
import { indexService } from '../services/es_index_service';
@@ -120,6 +120,7 @@ type SuccessCountField = keyof Omit;
export const useDeleteTransforms = () => {
const { overlays, theme } = useAppDependencies();
+ const refreshTransformList = useRefreshTransformList();
const toastNotifications = useToastNotifications();
const api = useApi();
@@ -293,6 +294,6 @@ export const useDeleteTransforms = () => {
}
}
- refreshTransformList$.next(REFRESH_TRANSFORM_LIST_STATE.REFRESH);
+ refreshTransformList();
};
};
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 55e3bc40360cf..e31f30fd790f1 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
@@ -5,75 +5,70 @@
* 2.0.
*/
+import { useQuery } from '@tanstack/react-query';
+
import type { IHttpFetchError } from '@kbn/core-http-browser';
import { isDefined } from '@kbn/ml-is-defined';
+import { isGetTransformsStatsResponseSchema } from '../../../common/api_schemas/type_guards';
+import type {
+ GetTransformNodesResponseSchema,
+ GetTransformsResponseSchema,
+} from '../../../common/api_schemas/transforms';
import {
- isGetTransformNodesResponseSchema,
- isGetTransformsResponseSchema,
- isGetTransformsStatsResponseSchema,
-} from '../../../common/api_schemas/type_guards';
-import { TRANSFORM_MODE } from '../../../common/constants';
+ addInternalBasePath,
+ DEFAULT_REFRESH_INTERVAL_MS,
+ TRANSFORM_REACT_QUERY_KEYS,
+ TRANSFORM_MODE,
+} from '../../../common/constants';
import { isTransformStats } from '../../../common/types/transform_stats';
-import {
- type TransformListRow,
- refreshTransformList$,
- REFRESH_TRANSFORM_LIST_STATE,
-} from '../common';
+import { type TransformListRow } from '../common';
+import { useAppDependencies } from '../app_dependencies';
-import { useApi } from './use_api';
import { TRANSFORM_ERROR_TYPE } from '../common/transform';
export type GetTransforms = (forceRefresh?: boolean) => void;
-export const useGetTransforms = (
- setTransforms: React.Dispatch>,
- setTransformNodes: React.Dispatch>,
- setErrorMessage: React.Dispatch>,
- setTransformIdsWithoutConfig: React.Dispatch>,
- setIsInitialized: React.Dispatch>,
- blockRefresh: boolean
-): GetTransforms => {
- const api = useApi();
-
- let concurrentLoads = 0;
-
- const getTransforms = async (forceRefresh = false) => {
- if (forceRefresh === true || blockRefresh === false) {
- refreshTransformList$.next(REFRESH_TRANSFORM_LIST_STATE.LOADING);
- concurrentLoads++;
-
- if (concurrentLoads > 1) {
- return;
- }
-
- const fetchOptions = { asSystemRequest: true };
- const transformNodes = await api.getTransformNodes();
- const transformConfigs = await api.getTransforms(fetchOptions);
- const transformStats = await api.getTransformsStats(fetchOptions);
-
- if (
- !isGetTransformsResponseSchema(transformConfigs) ||
- !isGetTransformsStatsResponseSchema(transformStats) ||
- !isGetTransformNodesResponseSchema(transformNodes)
- ) {
- // An error is followed immediately by setting the state to idle.
- // This way we're able to treat ERROR as a one-time-event like REFRESH.
- refreshTransformList$.next(REFRESH_TRANSFORM_LIST_STATE.ERROR);
- refreshTransformList$.next(REFRESH_TRANSFORM_LIST_STATE.IDLE);
- setTransformNodes(0);
- setTransforms([]);
-
- setIsInitialized(true);
-
- if (!isGetTransformsResponseSchema(transformConfigs)) {
- setErrorMessage(transformConfigs);
- } else if (!isGetTransformsStatsResponseSchema(transformStats)) {
- setErrorMessage(transformStats);
+interface UseGetTransformsResponse {
+ tableRows: TransformListRow[];
+ transformIdsWithoutConfig?: string[];
+ transformNodes: number;
+}
+
+export const useGetTransforms = () => {
+ const { http } = useAppDependencies();
+
+ return useQuery(
+ [TRANSFORM_REACT_QUERY_KEYS.TRANSFORMS_LIST],
+ async ({ signal }) => {
+ const update: UseGetTransformsResponse = {
+ tableRows: [],
+ transformNodes: 0,
+ };
+
+ const transformNodes = await http.get(
+ addInternalBasePath('transforms/_nodes'),
+ {
+ version: '1',
+ signal,
}
+ );
- return;
- }
+ update.transformNodes = transformNodes.count;
+
+ const transformConfigs = await http.get(
+ addInternalBasePath('transforms'),
+ {
+ version: '1',
+ asSystemRequest: true,
+ signal,
+ }
+ );
+ const transformStats = await http.get(addInternalBasePath(`transforms/_stats`), {
+ version: '1',
+ asSystemRequest: true,
+ signal,
+ });
// There might be some errors with fetching certain transforms
// For example, when task exists and is running but the config is deleted
@@ -87,14 +82,11 @@ export const useGetTransforms = (
})
.filter(isDefined);
- setTransformIdsWithoutConfig(
- danglingTaskIdMatches.length > 0 ? danglingTaskIdMatches : undefined
- );
- } else {
- setTransformIdsWithoutConfig(undefined);
+ update.transformIdsWithoutConfig =
+ danglingTaskIdMatches.length > 0 ? danglingTaskIdMatches : undefined;
}
- const tableRows = transformConfigs.transforms.reduce((reducedtableRows, config) => {
+ update.tableRows = transformConfigs.transforms.reduce((reducedtableRows, config) => {
const stats = isGetTransformsStatsResponseSchema(transformStats)
? transformStats.transforms.find((d) => config.id === d.id)
: undefined;
@@ -117,21 +109,10 @@ export const useGetTransforms = (
return reducedtableRows;
}, [] as TransformListRow[]);
- setTransformNodes(transformNodes.count);
- setTransforms(tableRows);
- setErrorMessage(undefined);
- setIsInitialized(true);
- refreshTransformList$.next(REFRESH_TRANSFORM_LIST_STATE.IDLE);
-
- concurrentLoads--;
-
- if (concurrentLoads > 0) {
- concurrentLoads = 0;
- getTransforms(true);
- return;
- }
+ return update;
+ },
+ {
+ refetchInterval: DEFAULT_REFRESH_INTERVAL_MS,
}
- };
-
- return getTransforms;
+ );
};
diff --git a/x-pack/plugins/transform/public/app/hooks/use_reauthorize_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_reauthorize_transform.tsx
index af6018c35cecc..3b907aa915128 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_reauthorize_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_reauthorize_transform.tsx
@@ -17,13 +17,14 @@ import { isStartTransformsResponseSchema } from '../../../common/api_schemas/typ
import { getErrorMessage } from '../../../common/utils/errors';
import { useAppDependencies, useToastNotifications } from '../app_dependencies';
-import { refreshTransformList$, REFRESH_TRANSFORM_LIST_STATE } from '../common';
+import { useRefreshTransformList } from '../common';
import { ToastNotificationText } from '../components';
import { useApi } from './use_api';
export const useReauthorizeTransforms = () => {
const { overlays, theme } = useAppDependencies();
+ const refreshTransformList = useRefreshTransformList();
const toastNotifications = useToastNotifications();
const api = useApi();
@@ -76,6 +77,6 @@ export const useReauthorizeTransforms = () => {
}
}
- refreshTransformList$.next(REFRESH_TRANSFORM_LIST_STATE.REFRESH);
+ refreshTransformList();
};
};
diff --git a/x-pack/plugins/transform/public/app/hooks/use_reset_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_reset_transform.tsx
index c33cec3f5b93f..d64301ee37522 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_reset_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_reset_transform.tsx
@@ -15,7 +15,7 @@ import type {
import { isResetTransformsResponseSchema } from '../../../common/api_schemas/type_guards';
import { getErrorMessage } from '../../../common/utils/errors';
import { useAppDependencies, useToastNotifications } from '../app_dependencies';
-import { REFRESH_TRANSFORM_LIST_STATE, refreshTransformList$ } from '../common';
+import { useRefreshTransformList } from '../common';
import { ToastNotificationText } from '../components';
import { useApi } from './use_api';
@@ -23,6 +23,7 @@ type SuccessCountField = keyof Omit;
export const useResetTransforms = () => {
const { overlays, theme } = useAppDependencies();
+ const refreshTransformList = useRefreshTransformList();
const toastNotifications = useToastNotifications();
const api = useApi();
@@ -107,6 +108,6 @@ export const useResetTransforms = () => {
}
}
- refreshTransformList$.next(REFRESH_TRANSFORM_LIST_STATE.REFRESH);
+ refreshTransformList();
};
};
diff --git a/x-pack/plugins/transform/public/app/hooks/use_schedule_now_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_schedule_now_transform.tsx
index 8454580867391..b0a15f1635c44 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_schedule_now_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_schedule_now_transform.tsx
@@ -17,13 +17,14 @@ import { isScheduleNowTransformsResponseSchema } from '../../../common/api_schem
import { getErrorMessage } from '../../../common/utils/errors';
import { useAppDependencies, useToastNotifications } from '../app_dependencies';
-import { refreshTransformList$, REFRESH_TRANSFORM_LIST_STATE } from '../common';
+import { useRefreshTransformList } from '../common';
import { ToastNotificationText } from '../components';
import { useApi } from './use_api';
export const useScheduleNowTransforms = () => {
const { overlays, theme } = useAppDependencies();
+ const refreshTransformList = useRefreshTransformList();
const toastNotifications = useToastNotifications();
const api = useApi();
@@ -79,6 +80,6 @@ export const useScheduleNowTransforms = () => {
}
}
- refreshTransformList$.next(REFRESH_TRANSFORM_LIST_STATE.REFRESH);
+ refreshTransformList();
};
};
diff --git a/x-pack/plugins/transform/public/app/hooks/use_start_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_start_transform.tsx
index e4d9bdfe431a9..a3bd5b29d5e57 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_start_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_start_transform.tsx
@@ -17,13 +17,14 @@ import { isStartTransformsResponseSchema } from '../../../common/api_schemas/typ
import { getErrorMessage } from '../../../common/utils/errors';
import { useAppDependencies, useToastNotifications } from '../app_dependencies';
-import { refreshTransformList$, REFRESH_TRANSFORM_LIST_STATE } from '../common';
+import { useRefreshTransformList } from '../common';
import { ToastNotificationText } from '../components';
import { useApi } from './use_api';
export const useStartTransforms = () => {
const { overlays, theme } = useAppDependencies();
+ const refreshTransformList = useRefreshTransformList();
const toastNotifications = useToastNotifications();
const api = useApi();
@@ -73,6 +74,6 @@ export const useStartTransforms = () => {
}
}
- refreshTransformList$.next(REFRESH_TRANSFORM_LIST_STATE.REFRESH);
+ refreshTransformList();
};
};
diff --git a/x-pack/plugins/transform/public/app/hooks/use_stop_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_stop_transform.tsx
index 39d009e471180..d89ee1a0118f1 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_stop_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_stop_transform.tsx
@@ -17,13 +17,14 @@ import { isStopTransformsResponseSchema } from '../../../common/api_schemas/type
import { getErrorMessage } from '../../../common/utils/errors';
import { useAppDependencies, useToastNotifications } from '../app_dependencies';
-import { refreshTransformList$, REFRESH_TRANSFORM_LIST_STATE } from '../common';
+import { useRefreshTransformList } from '../common';
import { ToastNotificationText } from '../components';
import { useApi } from './use_api';
export const useStopTransforms = () => {
const { overlays, theme } = useAppDependencies();
+ const refreshTransformList = useRefreshTransformList();
const toastNotifications = useToastNotifications();
const api = useApi();
@@ -71,6 +72,6 @@ export const useStopTransforms = () => {
}
}
- refreshTransformList$.next(REFRESH_TRANSFORM_LIST_STATE.REFRESH);
+ refreshTransformList();
};
};
diff --git a/x-pack/plugins/transform/public/app/lib/authorization/components/authorization_provider.tsx b/x-pack/plugins/transform/public/app/lib/authorization/components/authorization_provider.tsx
index 02bbe4e40a969..9e73582b13d91 100644
--- a/x-pack/plugins/transform/public/app/lib/authorization/components/authorization_provider.tsx
+++ b/x-pack/plugins/transform/public/app/lib/authorization/components/authorization_provider.tsx
@@ -10,6 +10,7 @@ import { useQuery } from '@tanstack/react-query';
import type { IHttpFetchError } from '@kbn/core-http-browser';
+import { TRANSFORM_REACT_QUERY_KEYS } from '../../../../../common/constants';
import type { Privileges } from '../../../../../common/types/privileges';
import {
@@ -54,7 +55,7 @@ export const AuthorizationProvider = ({ privilegesEndpoint, children }: Props) =
error,
data: privilegesData,
} = useQuery(
- ['transform-privileges-and-capabilities'],
+ [TRANSFORM_REACT_QUERY_KEYS.PRIVILEGES],
async ({ signal }) => {
return await http.fetch(path, {
version,
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/edit_transform_flyout/edit_transform_update_button.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/edit_transform_flyout/edit_transform_update_button.tsx
index 06e30d584de46..59bacf76fd39f 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/edit_transform_flyout/edit_transform_update_button.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/edit_transform_flyout/edit_transform_update_button.tsx
@@ -14,7 +14,7 @@ import { i18n } from '@kbn/i18n';
import { isPostTransformsUpdateResponseSchema } from '../../../../../../common/api_schemas/type_guards';
import { getErrorMessage } from '../../../../../../common/utils/errors';
-import { refreshTransformList$, REFRESH_TRANSFORM_LIST_STATE } from '../../../../common';
+import { useRefreshTransformList } from '../../../../common';
import { useToastNotifications } from '../../../../app_dependencies';
import { useApi } from '../../../../hooks/use_api';
@@ -26,6 +26,7 @@ interface EditTransformUpdateButtonProps {
export const EditTransformUpdateButton: FC = ({ closeFlyout }) => {
const api = useApi();
+ const refreshTransformList = useRefreshTransformList();
const toastNotifications = useToastNotifications();
const requestConfig = useEditTransformFlyout('requestConfig');
@@ -51,7 +52,7 @@ export const EditTransformUpdateButton: FC = ({
})
);
closeFlyout();
- refreshTransformList$.next(REFRESH_TRANSFORM_LIST_STATE.REFRESH);
+ refreshTransformList();
}
return (
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/__snapshots__/transform_list.test.tsx.snap b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/__snapshots__/transform_list.test.tsx.snap
index 2e80f1deb8b2e..a24e252578041 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/__snapshots__/transform_list.test.tsx.snap
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/__snapshots__/transform_list.test.tsx.snap
@@ -1,43 +1,67 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Transform: Transform List Minimal initialization 1`] = `
-
-
-
-
-
- Create your first transform
- ,
- ]
- }
- data-test-subj="transformNoTransformsFound"
- title={
-
- No transforms found
-
- }
- />
-
-
-
+
+
`;
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row_messages_pane.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row_messages_pane.tsx
index 4cf387ad2973b..8178ee43dc809 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row_messages_pane.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row_messages_pane.tsx
@@ -6,6 +6,7 @@
*/
import React, { MouseEvent, useState, type FC } from 'react';
+import { useQuery } from '@tanstack/react-query';
import {
formatDate,
@@ -15,15 +16,21 @@ import {
EuiToolTip,
EuiButtonIcon,
} from '@elastic/eui';
-import { euiLightVars as theme } from '@kbn/ui-theme';
+import type { IHttpFetchError } from '@kbn/core-http-browser';
+import { euiLightVars as theme } from '@kbn/ui-theme';
import { i18n } from '@kbn/i18n';
-import { DEFAULT_MAX_AUDIT_MESSAGE_SIZE, TIME_FORMAT } from '../../../../../../common/constants';
-import { isGetTransformsAuditMessagesResponseSchema } from '../../../../../../common/api_schemas/type_guards';
+import type { GetTransformsAuditMessagesResponseSchema } from '../../../../../../common/api_schemas/audit_messages';
+import {
+ addInternalBasePath,
+ DEFAULT_MAX_AUDIT_MESSAGE_SIZE,
+ TIME_FORMAT,
+ TRANSFORM_REACT_QUERY_KEYS,
+} from '../../../../../../common/constants';
import { TransformMessage } from '../../../../../../common/types/messages';
-import { useApi } from '../../../../hooks/use_api';
+import { useAppDependencies } from '../../../../app_dependencies';
import { JobIcon } from '../../../../components/job_icon';
import { useRefreshTransformList } from '../../../../common';
@@ -37,11 +44,7 @@ interface Sorting {
}
export const ExpandedRowMessagesPane: FC = ({ transformId }) => {
- const [messages, setMessages] = useState([]);
- const [msgCount, setMsgCount] = useState(0);
-
- const [isLoading, setIsLoading] = useState(false);
- const [errorMessage, setErrorMessage] = useState('');
+ const { http } = useAppDependencies();
const [pageIndex, setPageIndex] = useState(0);
const [pageSize, setPageSize] = useState(10);
@@ -52,58 +55,43 @@ export const ExpandedRowMessagesPane: FC = ({ tran
},
});
- const api = useApi();
-
- const getMessagesFactory = (
- sortField: keyof TransformMessage = 'timestamp',
- sortDirection: 'asc' | 'desc' = 'desc'
- ) => {
- let concurrentLoads = 0;
-
- return async function getMessages() {
- concurrentLoads++;
-
- if (concurrentLoads > 1) {
- return;
- }
-
- setIsLoading(true);
- const messagesResp = await api.getTransformAuditMessages(
- transformId,
- sortField,
- sortDirection
- );
-
- if (!isGetTransformsAuditMessagesResponseSchema(messagesResp)) {
- setIsLoading(false);
- setErrorMessage(
- i18n.translate(
- 'xpack.transform.transformList.transformDetails.messagesPane.errorMessage',
- {
- defaultMessage: 'Messages could not be loaded',
- }
- )
- );
- return;
- }
-
- setIsLoading(false);
- setMessages(messagesResp.messages);
- setMsgCount(messagesResp.total);
-
- concurrentLoads--;
-
- if (concurrentLoads > 0) {
- concurrentLoads = 0;
- getMessages();
- }
- };
- };
- const { refresh: refreshMessage } = useRefreshTransformList({ onRefresh: getMessagesFactory() });
+ const { isLoading, error, data } = useQuery<
+ GetTransformsAuditMessagesResponseSchema,
+ IHttpFetchError
+ >(
+ [
+ TRANSFORM_REACT_QUERY_KEYS.TRANSFORMS_LIST,
+ transformId,
+ sorting.sort.field,
+ sorting.sort.direction,
+ ],
+ async ({ signal }) =>
+ await http.get(
+ addInternalBasePath(`transforms/${transformId}/messages`),
+ {
+ query: {
+ sortField: sorting.sort.field,
+ sortDirection: sorting.sort.direction,
+ },
+ version: '1',
+ signal,
+ }
+ )
+ );
+ const messages = data?.messages ?? [];
+ const msgCount = data?.total ?? 0;
+ const errorMessage =
+ error !== null
+ ? i18n.translate('xpack.transform.transformList.transformDetails.messagesPane.errorMessage', {
+ defaultMessage: 'Messages could not be loaded',
+ })
+ : '';
+
+ const refreshTransformList = useRefreshTransformList();
const columns = [
{
- name: refreshMessage ? (
+ name: refreshTransformList ? (
= ({ tran
// TODO: Replace this with ML's blurButtonOnClick when it's moved to a shared package
onClick={(e: MouseEvent) => {
(e.currentTarget as HTMLButtonElement).blur();
- refreshMessage();
+ refreshTransformList();
}}
iconType="refresh"
aria-label={i18n.translate('xpack.transform.transformList.refreshAriaLabel', {
@@ -192,12 +180,6 @@ export const ExpandedRowMessagesPane: FC = ({ tran
setPageSize(size);
if (sort) {
setSorting({ sort });
-
- // Since we only show 500 messages, if user wants oldest messages first
- // we need to make sure we fetch them from elasticsearch
- if (msgCount > DEFAULT_MAX_AUDIT_MESSAGE_SIZE) {
- getMessagesFactory(sort.field, sort.direction)();
- }
}
};
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.test.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.test.tsx
index 430fa9478f60a..c4fc1cbc65c27 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.test.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.test.tsx
@@ -7,6 +7,7 @@
import { shallow } from 'enzyme';
import React from 'react';
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { TransformList } from './transform_list';
@@ -15,13 +16,18 @@ jest.mock('../../../../app_dependencies');
describe('Transform: Transform List ', () => {
test('Minimal initialization', () => {
+ const queryClient = new QueryClient();
const wrapper = shallow(
-
+
+
+
);
expect(wrapper).toMatchSnapshot();
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.tsx
index e6c279e56f3c3..f008cf33ce638 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.tsx
@@ -5,14 +5,16 @@
* 2.0.
*/
-import React, { MouseEventHandler, FC, useContext, useState } from 'react';
+import React, { type MouseEventHandler, type FC, useContext, useState } from 'react';
import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n-react';
import {
EuiButton,
EuiButtonEmpty,
EuiButtonIcon,
+ EuiCallOut,
EuiEmptyPrompt,
EuiFlexGroup,
EuiFlexItem,
@@ -34,7 +36,7 @@ import type { TransformId } from '../../../../../../common/types/transform';
import {
useRefreshTransformList,
- TransformListRow,
+ type TransformListRow,
TRANSFORM_LIST_COLUMN,
} from '../../../../common';
import { AuthorizationContext } from '../../../../lib/authorization';
@@ -74,6 +76,29 @@ import { useAlertRuleFlyout } from '../../../../../alerting/transform_alerting_f
import { TransformHealthAlertRule } from '../../../../../../common/types/alerting';
import { StopActionModal } from '../action_stop/stop_action_modal';
+const ErrorMessage: FC<{ errorMessage: any }> = ({ errorMessage }) => (
+ <>
+
+
+ }
+ color="danger"
+ iconType="error"
+ >
+
+
+ {JSON.stringify(errorMessage)}
+
+
+
+
+ >
+);
+
type ItemIdToExpandedRowMap = Record;
function getItemIdToExpandedRowMap(
@@ -91,6 +116,8 @@ function getItemIdToExpandedRowMap(
}
interface TransformListProps {
+ errorMessage: any;
+ isLoading: boolean;
onCreateTransform: MouseEventHandler;
transformNodes: number;
transforms: TransformListRow[];
@@ -98,13 +125,14 @@ interface TransformListProps {
}
export const TransformList: FC = ({
+ errorMessage,
+ isLoading,
onCreateTransform,
transformNodes,
transforms,
transformsLoading,
}) => {
- const [isLoading, setIsLoading] = useState(false);
- const { refresh } = useRefreshTransformList({ isLoading: setIsLoading });
+ const refreshTransformList = useRefreshTransformList();
const { setEditAlertRule } = useAlertRuleFlyout();
const [query, setQuery] = useState>[0]>();
@@ -142,11 +170,10 @@ export const TransformList: FC = ({
const filteredTransforms =
clauses.length > 0 ? filterTransforms(transforms, clauses) : transforms;
- if (transforms.length === 0 && transformNodes === 0) {
- return null;
- }
+ const errorMessageInsert =
+ errorMessage !== null ? : null;
- if (transforms.length === 0) {
+ if (transforms.length === 0 && errorMessage === null) {
return (
@@ -319,7 +346,7 @@ export const TransformList: FC = ({
const toolsRight = (
-
+
@@ -355,6 +382,7 @@ export const TransformList: FC = ({
{/* Single Action Modals */}
{singleActionModals}
+ {errorMessage !== null && errorMessageInsert}
{
test('useActions()', async () => {
- const { result, waitForNextUpdate } = renderHook(() =>
- useActions({ forceDisable: false, transformNodes: 1 })
+ const queryClient = new QueryClient();
+ const wrapper: FC = ({ children }) => (
+ {children}
+ );
+ const { result, waitForNextUpdate } = renderHook(
+ () => useActions({ forceDisable: false, transformNodes: 1 }),
+ { wrapper }
);
await waitForNextUpdate();
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_columns.test.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_columns.test.tsx
index 521bd745e8692..87f550e433bc2 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_columns.test.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_columns.test.tsx
@@ -5,6 +5,8 @@
* 2.0.
*/
+import React, { type FC } from 'react';
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { renderHook } from '@testing-library/react-hooks';
import { useColumns } from './use_columns';
@@ -14,7 +16,13 @@ jest.mock('../../../../app_dependencies');
describe('Transform: Job List Columns', () => {
test('useColumns()', async () => {
- const { result, waitForNextUpdate } = renderHook(() => useColumns([], () => {}, 1, []));
+ const queryClient = new QueryClient();
+ const wrapper: FC = ({ children }) => (
+ {children}
+ );
+ const { result, waitForNextUpdate } = renderHook(() => useColumns([], () => {}, 1, []), {
+ wrapper,
+ });
await waitForNextUpdate();
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_refresh_interval.ts b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_refresh_interval.ts
deleted file mode 100644
index c1f4c3d4f7d5c..0000000000000
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_refresh_interval.ts
+++ /dev/null
@@ -1,28 +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, { useEffect } from 'react';
-
-import { DEFAULT_REFRESH_INTERVAL_MS } from '../../../../../../common/constants';
-
-import { useRefreshTransformList } from '../../../../common';
-
-export const useRefreshInterval = (
- setBlockRefresh: React.Dispatch>
-) => {
- const { refresh } = useRefreshTransformList();
- useEffect(() => {
- const interval = setInterval(refresh, DEFAULT_REFRESH_INTERVAL_MS);
-
- // useEffect cleanup
- return () => {
- clearInterval(interval);
- };
- // custom comparison
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, []); // [] as comparator makes sure this only runs once
-};
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/transform_management_section.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/transform_management_section.tsx
index 3c74cf450b4b9..829233680a2f9 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/transform_management_section.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/transform_management_section.tsx
@@ -11,12 +11,8 @@ import { FormattedMessage } from '@kbn/i18n-react';
import {
EuiButtonEmpty,
- EuiEmptyPrompt,
- EuiFlexGroup,
- EuiFlexItem,
EuiSkeletonText,
EuiModal,
- EuiPageContent_Deprecated as EuiPageContent,
EuiPageContentBody_Deprecated as EuiPageContentBody,
EuiPageHeader,
EuiSpacer,
@@ -30,14 +26,12 @@ import {
TRANSFORM_STATE,
} from '../../../../common/constants';
-import { useRefreshTransformList, TransformListRow } from '../../common';
import { useDocumentationLinks } from '../../hooks/use_documentation_links';
import { useDeleteTransforms, useGetTransforms } from '../../hooks';
import { RedirectToCreateTransform } from '../../common/navigation';
import { AuthorizationContext, PrivilegesWrapper } from '../../lib/authorization';
import { breadcrumbService, docTitleService, BREADCRUMB_SECTION } from '../../services/navigation';
-import { useRefreshInterval } from './components/transform_list/use_refresh_interval';
import { SearchSelection } from './components/search_selection';
import { TransformList } from './components/transform_list';
import { TransformStatsBar } from './components/transform_list/transforms_stats_bar';
@@ -50,34 +44,18 @@ import {
export const TransformManagement: FC = () => {
const { esTransform } = useDocumentationLinks();
- const [transformsLoading, setTransformsLoading] = useState(false);
- const [isInitialized, setIsInitialized] = useState(false);
- const [blockRefresh, setBlockRefresh] = useState(false);
- const [transforms, setTransforms] = useState([]);
- const [transformNodes, setTransformNodes] = useState(0);
- const [errorMessage, setErrorMessage] = useState(undefined);
- const [transformIdsWithoutConfig, setTransformIdsWithoutConfig] = useState<
- string[] | undefined
- >();
-
const deleteTransforms = useDeleteTransforms();
- const getTransforms = useGetTransforms(
- setTransforms,
- setTransformNodes,
- setErrorMessage,
- setTransformIdsWithoutConfig,
- setIsInitialized,
- blockRefresh
- );
-
- // Subscribe to the refresh observable to trigger reloading the transform list.
- useRefreshTransformList({
- isLoading: setTransformsLoading,
- onRefresh: () => getTransforms(true),
- });
- // Call useRefreshInterval() after the subscription above is set up.
- useRefreshInterval(setBlockRefresh);
+ const {
+ isInitialLoading,
+ isLoading: transformsLoading,
+ error: errorMessage,
+ data,
+ } = useGetTransforms();
+ const isInitialized = !isInitialLoading;
+ const transforms = useMemo(() => data?.tableRows ?? [], [data]);
+ const transformNodes = data?.transformNodes ?? 0;
+ const transformIdsWithoutConfig = data?.transformIdsWithoutConfig;
const { canStartStopTransform } = useContext(AuthorizationContext).capabilities;
@@ -180,92 +158,63 @@ export const TransformManagement: FC = () => {
- {typeof errorMessage !== 'undefined' && (
-
-
-
-
-
-
-
- }
- body={
-
-
{JSON.stringify(errorMessage)}
-
- }
- actions={[]}
- />
-
-
-
- )}
- {typeof errorMessage === 'undefined' && (
-
- {transformIdsWithoutConfig ? (
- <>
-
-
-
-
- {
- await deleteTransforms(
- // If transform task doesn't have any corresponding config
- // we won't know what the destination index or data view would be
- // and should be force deleted
- {
- transformsInfo: transformIdsWithoutConfig.map((id) => ({
- id,
- state: TRANSFORM_STATE.FAILED,
- })),
- deleteDestIndex: false,
- deleteDestDataView: false,
- forceDelete: true,
- }
- );
+
+
+ {transformIdsWithoutConfig ? (
+ <>
+
+
+
+
+ {
+ await deleteTransforms(
+ // If transform task doesn't have any corresponding config
+ // we won't know what the destination index or data view would be
+ // and should be force deleted
+ {
+ transformsInfo: transformIdsWithoutConfig.map((id) => ({
+ id,
+ state: TRANSFORM_STATE.FAILED,
+ })),
+ deleteDestIndex: false,
+ deleteDestDataView: false,
+ forceDelete: true,
+ }
+ );
+ }}
+ >
+
-
-
-
-
- >
- ) : null}
-
-
-
- )}
+ />
+
+
+
+ >
+ ) : null}
+
+
+
>
)}
From ec2bd1c264c50417cf3fad3f370be18c2c28328b Mon Sep 17 00:00:00 2001
From: Walter Rafelsberger
Date: Mon, 21 Aug 2023 16:12:18 +0200
Subject: [PATCH 02/53] refactor inline useQuery to custom hook. cleanup
useApi.
---
.../transform_health_rule_trigger.tsx | 50 ++++++-----------
.../public/app/hooks/__mocks__/use_api.ts | 13 -----
.../transform/public/app/hooks/index.ts | 2 +
.../transform/public/app/hooks/use_api.ts | 56 -------------------
.../hooks/use_get_transform_audit_messages.ts | 39 +++++++++++++
.../public/app/hooks/use_get_transforms.ts | 2 -
.../step_details/step_details_form.tsx | 44 +++++++--------
.../expanded_row_messages_pane.tsx | 40 ++-----------
.../transform_management_section.tsx | 2 +-
9 files changed, 88 insertions(+), 160 deletions(-)
create mode 100644 x-pack/plugins/transform/public/app/hooks/use_get_transform_audit_messages.ts
diff --git a/x-pack/plugins/transform/public/alerting/transform_health_rule_type/transform_health_rule_trigger.tsx b/x-pack/plugins/transform/public/alerting/transform_health_rule_type/transform_health_rule_trigger.tsx
index 56bd9a2db877e..f691c6a986020 100644
--- a/x-pack/plugins/transform/public/alerting/transform_health_rule_type/transform_health_rule_trigger.tsx
+++ b/x-pack/plugins/transform/public/alerting/transform_health_rule_type/transform_health_rule_trigger.tsx
@@ -6,16 +6,15 @@
*/
import { EuiForm, EuiSpacer } from '@elastic/eui';
-import React, { FC, useCallback, useEffect, useMemo, useState } from 'react';
+import React, { FC, useCallback, useEffect, useMemo } from 'react';
import { FormattedMessage } from '@kbn/i18n-react';
import { i18n } from '@kbn/i18n';
import type { RuleTypeParamsExpressionProps } from '@kbn/triggers-actions-ui-plugin/public';
import type { TransformHealthRuleParams } from '../../../common/types/alerting';
import { TestsSelectionControl } from './tests_selection_control';
import { TransformSelectorControl } from './transform_selector_control';
-import { useApi } from '../../app/hooks';
+import { useGetTransforms } from '../../app/hooks';
import { useToastNotifications } from '../../app/app_dependencies';
-import { GetTransformsResponseSchema } from '../../../common/api_schemas/transforms';
import { ALL_TRANSFORMS_SELECTION } from '../../../common/constants';
export type TransformHealthRuleTriggerProps =
@@ -29,9 +28,12 @@ const TransformHealthRuleTrigger: FC = ({
const formErrors = Object.values(errors).flat();
const isFormInvalid = formErrors.length > 0;
- const api = useApi();
const toast = useToastNotifications();
- const [transformOptions, setTransformOptions] = useState([]);
+ const { error, data } = useGetTransforms();
+ const transformOptions = useMemo(
+ () => data?.tableRows.filter((v) => v.config.sync).map((v) => v.id) ?? [],
+ [data]
+ );
const onAlertParamChange = useCallback(
(param: T) =>
@@ -41,34 +43,18 @@ const TransformHealthRuleTrigger: FC = ({
[setRuleParams]
);
- useEffect(
- function fetchTransforms() {
- let unmounted = false;
- api
- .getTransforms()
- .then((r) => {
- if (!unmounted) {
- setTransformOptions(
- (r as GetTransformsResponseSchema).transforms.filter((v) => v.sync).map((v) => v.id)
- );
+ useEffect(() => {
+ if (error !== null) {
+ toast.addError(error, {
+ title: i18n.translate(
+ 'xpack.transform.alertingRuleTypes.transformHealth.fetchErrorMessage',
+ {
+ defaultMessage: 'Unable to fetch transforms',
}
- })
- .catch((e) => {
- toast.addError(e, {
- title: i18n.translate(
- 'xpack.transform.alertingRuleTypes.transformHealth.fetchErrorMessage',
- {
- defaultMessage: 'Unable to fetch transforms',
- }
- ),
- });
- });
- return () => {
- unmounted = true;
- };
- },
- [api, toast]
- );
+ ),
+ });
+ }
+ }, [error, toast]);
const excludeTransformOptions = useMemo(() => {
if (ruleParams.includeTransforms?.some((v) => v === ALL_TRANSFORMS_SELECTION)) {
diff --git a/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts b/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
index 2e0407b0ac974..a2f30a6c256b9 100644
--- a/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
+++ b/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
@@ -12,7 +12,6 @@ import { DEFAULT_SAMPLER_SHARD_SIZE } from '@kbn/ml-agg-utils';
import type { TransformId } from '../../../../common/types/transform';
import type { FieldHistogramsResponseSchema } from '../../../../common/api_schemas/field_histograms';
-import type { GetTransformsAuditMessagesResponseSchema } from '../../../../common/api_schemas/audit_messages';
import type {
DeleteTransformsRequestSchema,
DeleteTransformsResponseSchema,
@@ -53,17 +52,11 @@ const apiFactory = () => ({
): Promise {
return Promise.resolve({ count: 0, transforms: [] });
},
- async getTransforms(): Promise {
- return Promise.resolve({ count: 0, transforms: [] });
- },
async getTransformStats(
transformId: TransformId
): Promise {
return Promise.resolve({ count: 0, transforms: [] });
},
- async getTransformsStats(): Promise {
- return Promise.resolve({ count: 0, transforms: [] });
- },
async createTransform(
transformId: TransformId,
transformConfig: PutTransformsRequestSchema
@@ -126,12 +119,6 @@ const apiFactory = () => ({
): Promise {
return Promise.resolve({});
},
- async getTransformAuditMessages(
- transformId: TransformId
- ): Promise {
- return Promise.resolve({ messages: [], total: 0 });
- },
-
async getEsIndices(): Promise {
return Promise.resolve([]);
},
diff --git a/x-pack/plugins/transform/public/app/hooks/index.ts b/x-pack/plugins/transform/public/app/hooks/index.ts
index f6a4c72b39a44..91730ec067aeb 100644
--- a/x-pack/plugins/transform/public/app/hooks/index.ts
+++ b/x-pack/plugins/transform/public/app/hooks/index.ts
@@ -6,6 +6,8 @@
*/
export { useApi } from './use_api';
+export { useDocumentationLinks } from './use_documentation_links';
+export { useGetTransformAuditMessages } from './use_get_transform_audit_messages';
export { useGetTransforms } from './use_get_transforms';
export { useDeleteTransforms, useDeleteIndexAndTargetIndex } from './use_delete_transform';
export { useResetTransforms } from './use_reset_transform';
diff --git a/x-pack/plugins/transform/public/app/hooks/use_api.ts b/x-pack/plugins/transform/public/app/hooks/use_api.ts
index 066977fb841df..a72e249d7b944 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_api.ts
+++ b/x-pack/plugins/transform/public/app/hooks/use_api.ts
@@ -16,7 +16,6 @@ import {
ReauthorizeTransformsRequestSchema,
ReauthorizeTransformsResponseSchema,
} from '../../../common/api_schemas/reauthorize_transforms';
-import type { GetTransformsAuditMessagesResponseSchema } from '../../../common/api_schemas/audit_messages';
import type {
DeleteTransformsRequestSchema,
DeleteTransformsResponseSchema,
@@ -42,7 +41,6 @@ import type {
ScheduleNowTransformsResponseSchema,
} from '../../../common/api_schemas/schedule_now_transforms';
import type {
- GetTransformNodesResponseSchema,
GetTransformsResponseSchema,
PostTransformsPreviewRequestSchema,
PostTransformsPreviewResponseSchema,
@@ -68,22 +66,11 @@ export interface FieldHistogramRequestConfig {
type?: KBN_FIELD_TYPES;
}
-interface FetchOptions {
- asSystemRequest?: boolean;
-}
-
export const useApi = () => {
const { http } = useAppDependencies();
return useMemo(
() => ({
- async getTransformNodes(): Promise {
- try {
- return await http.get(addInternalBasePath(`transforms/_nodes`), { version: '1' });
- } catch (e) {
- return e;
- }
- },
async getTransform(
transformId: TransformId
): Promise {
@@ -95,18 +82,6 @@ export const useApi = () => {
return e;
}
},
- async getTransforms(
- fetchOptions: FetchOptions = {}
- ): Promise {
- try {
- return await http.get(addInternalBasePath(`transforms`), {
- ...fetchOptions,
- version: '1',
- });
- } catch (e) {
- return e;
- }
- },
async getTransformStats(
transformId: TransformId
): Promise {
@@ -118,18 +93,6 @@ export const useApi = () => {
return e;
}
},
- async getTransformsStats(
- fetchOptions: FetchOptions = {}
- ): Promise {
- try {
- return await http.get(addInternalBasePath(`transforms/_stats`), {
- ...fetchOptions,
- version: '1',
- });
- } catch (e) {
- return e;
- }
- },
async createTransform(
transformId: TransformId,
transformConfig: PutTransformsRequestSchema
@@ -241,25 +204,6 @@ export const useApi = () => {
return e;
}
},
- async getTransformAuditMessages(
- transformId: TransformId,
- sortField: string,
- sortDirection: 'asc' | 'desc'
- ): Promise<
- { messages: GetTransformsAuditMessagesResponseSchema; total: number } | IHttpFetchError
- > {
- try {
- return await http.get(addInternalBasePath(`transforms/${transformId}/messages`), {
- query: {
- sortField,
- sortDirection,
- },
- version: '1',
- });
- } catch (e) {
- return e;
- }
- },
async getEsIndices(): Promise {
try {
return await http.get(`/api/index_management/indices`, { version: '1' });
diff --git a/x-pack/plugins/transform/public/app/hooks/use_get_transform_audit_messages.ts b/x-pack/plugins/transform/public/app/hooks/use_get_transform_audit_messages.ts
new file mode 100644
index 0000000000000..09e0bdf23571d
--- /dev/null
+++ b/x-pack/plugins/transform/public/app/hooks/use_get_transform_audit_messages.ts
@@ -0,0 +1,39 @@
+/*
+ * 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 { useQuery } from '@tanstack/react-query';
+
+import type { IHttpFetchError } from '@kbn/core-http-browser';
+
+import type { GetTransformsAuditMessagesResponseSchema } from '../../../common/api_schemas/audit_messages';
+import { addInternalBasePath, TRANSFORM_REACT_QUERY_KEYS } from '../../../common/constants';
+import { TransformMessage } from '../../../common/types/messages';
+
+import { useAppDependencies } from '../app_dependencies';
+
+export const useGetTransformAuditMessages = (
+ transformId: string,
+ sortField: keyof TransformMessage,
+ sortDirection: 'asc' | 'desc'
+) => {
+ const { http } = useAppDependencies();
+
+ const query = { sortField, sortDirection };
+
+ return useQuery(
+ [TRANSFORM_REACT_QUERY_KEYS.TRANSFORMS_LIST, transformId, query],
+ async ({ signal }) =>
+ await http.get(
+ addInternalBasePath(`transforms/${transformId}/messages`),
+ {
+ query,
+ version: '1',
+ signal,
+ }
+ )
+ );
+};
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 e31f30fd790f1..ee644f9dd8d32 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
@@ -27,8 +27,6 @@ import { useAppDependencies } from '../app_dependencies';
import { TRANSFORM_ERROR_TYPE } from '../common/transform';
-export type GetTransforms = (forceRefresh?: boolean) => void;
-
interface UseGetTransformsResponse {
tableRows: TransformListRow[];
transformIdsWithoutConfig?: string[];
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx
index 4e8104a7645ee..f2c6a448943e5 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx
@@ -42,7 +42,7 @@ import { getErrorMessage } from '../../../../../../common/utils/errors';
import { useAppDependencies, useToastNotifications } from '../../../../app_dependencies';
import { ToastNotificationText } from '../../../../components';
-import { useDocumentationLinks } from '../../../../hooks/use_documentation_links';
+import { useDocumentationLinks, useGetTransforms } from '../../../../hooks';
import { SearchItems } from '../../../../hooks/use_search_items';
import { useApi } from '../../../../hooks/use_api';
import { StepDetailsTimeField } from './step_details_time_field';
@@ -90,7 +90,6 @@ export const StepDetailsForm: FC = React.memo(
const [destinationIngestPipeline, setDestinationIngestPipeline] = useState(
defaults.destinationIngestPipeline
);
- const [transformIds, setTransformIds] = useState([]);
const [indexNames, setIndexNames] = useState([]);
const [ingestPipelineNames, setIngestPipelineNames] = useState([]);
@@ -128,6 +127,27 @@ export const StepDetailsForm: FC = React.memo(
const { overlays, theme } = useAppDependencies();
const api = useApi();
+ const { error, data } = useGetTransforms();
+ const transformIds = data?.tableRows.map((d) => d.id) ?? [];
+
+ useEffect(() => {
+ if (isHttpFetchError(error)) {
+ toastNotifications.addDanger({
+ title: i18n.translate('xpack.transform.stepDetailsForm.errorGettingTransformList', {
+ defaultMessage: 'An error occurred getting the existing transform IDs:',
+ }),
+ text: toMountPoint(
+ ,
+ { theme$: theme.theme$ }
+ ),
+ });
+ }
+ }, [error, overlays, theme, toastNotifications]);
+
// fetch existing transform IDs and indices once for form validation
useEffect(() => {
// use an IIFE to avoid returning a Promise to useEffect.
@@ -167,26 +187,6 @@ export const StepDetailsForm: FC = React.memo(
});
}
- const resp = await api.getTransforms();
-
- if (isHttpFetchError(resp)) {
- toastNotifications.addDanger({
- title: i18n.translate('xpack.transform.stepDetailsForm.errorGettingTransformList', {
- defaultMessage: 'An error occurred getting the existing transform IDs:',
- }),
- text: toMountPoint(
- ,
- { theme$: theme.theme$ }
- ),
- });
- } else {
- setTransformIds(resp.transforms.map((transform) => transform.id));
- }
-
const [indices, ingestPipelines] = await Promise.all([
api.getEsIndices(),
api.getEsIngestPipelines(),
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row_messages_pane.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row_messages_pane.tsx
index 8178ee43dc809..fb435679d2185 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row_messages_pane.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row_messages_pane.tsx
@@ -6,7 +6,6 @@
*/
import React, { MouseEvent, useState, type FC } from 'react';
-import { useQuery } from '@tanstack/react-query';
import {
formatDate,
@@ -17,22 +16,15 @@ import {
EuiButtonIcon,
} from '@elastic/eui';
-import type { IHttpFetchError } from '@kbn/core-http-browser';
import { euiLightVars as theme } from '@kbn/ui-theme';
import { i18n } from '@kbn/i18n';
-import type { GetTransformsAuditMessagesResponseSchema } from '../../../../../../common/api_schemas/audit_messages';
-import {
- addInternalBasePath,
- DEFAULT_MAX_AUDIT_MESSAGE_SIZE,
- TIME_FORMAT,
- TRANSFORM_REACT_QUERY_KEYS,
-} from '../../../../../../common/constants';
+import { DEFAULT_MAX_AUDIT_MESSAGE_SIZE, TIME_FORMAT } from '../../../../../../common/constants';
import { TransformMessage } from '../../../../../../common/types/messages';
-import { useAppDependencies } from '../../../../app_dependencies';
import { JobIcon } from '../../../../components/job_icon';
import { useRefreshTransformList } from '../../../../common';
+import { useGetTransformAuditMessages } from '../../../../hooks';
interface ExpandedRowMessagesPaneProps {
transformId: string;
@@ -44,8 +36,6 @@ interface Sorting {
}
export const ExpandedRowMessagesPane: FC = ({ transformId }) => {
- const { http } = useAppDependencies();
-
const [pageIndex, setPageIndex] = useState(0);
const [pageSize, setPageSize] = useState(10);
const [sorting, setSorting] = useState<{ sort: Sorting }>({
@@ -55,28 +45,10 @@ export const ExpandedRowMessagesPane: FC = ({ tran
},
});
- const { isLoading, error, data } = useQuery<
- GetTransformsAuditMessagesResponseSchema,
- IHttpFetchError
- >(
- [
- TRANSFORM_REACT_QUERY_KEYS.TRANSFORMS_LIST,
- transformId,
- sorting.sort.field,
- sorting.sort.direction,
- ],
- async ({ signal }) =>
- await http.get(
- addInternalBasePath(`transforms/${transformId}/messages`),
- {
- query: {
- sortField: sorting.sort.field,
- sortDirection: sorting.sort.direction,
- },
- version: '1',
- signal,
- }
- )
+ const { isLoading, error, data } = useGetTransformAuditMessages(
+ transformId,
+ sorting.sort.field,
+ sorting.sort.direction
);
const messages = data?.messages ?? [];
const msgCount = data?.total ?? 0;
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/transform_management_section.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/transform_management_section.tsx
index 829233680a2f9..045f1bdbc38e0 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/transform_management_section.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/transform_management_section.tsx
@@ -26,7 +26,7 @@ import {
TRANSFORM_STATE,
} from '../../../../common/constants';
-import { useDocumentationLinks } from '../../hooks/use_documentation_links';
+import { useDocumentationLinks } from '../../hooks';
import { useDeleteTransforms, useGetTransforms } from '../../hooks';
import { RedirectToCreateTransform } from '../../common/navigation';
import { AuthorizationContext, PrivilegesWrapper } from '../../lib/authorization';
From 04ae3c043f981b0ff1a2bf836c08b41dbf97db17 Mon Sep 17 00:00:00 2001
From: Walter Rafelsberger
Date: Tue, 22 Aug 2023 14:02:51 +0200
Subject: [PATCH 03/53] migrate wizard to use react-query
---
.../common/api_schemas/transforms_stats.ts | 2 +-
x-pack/plugins/transform/common/constants.ts | 1 +
.../public/app/hooks/__mocks__/use_api.ts | 26 --
.../transform/public/app/hooks/index.ts | 2 +
.../transform/public/app/hooks/use_api.ts | 47 ---
.../public/app/hooks/use_create_transform.tsx | 84 +++++
.../public/app/hooks/use_delete_transform.tsx | 296 +++++++++---------
.../app/hooks/use_get_transform_stats.ts | 37 +++
.../public/app/hooks/use_start_transform.tsx | 86 ++---
.../step_create/step_create_form.test.tsx | 8 +-
.../step_create/step_create_form.tsx | 234 ++++++--------
.../action_start/use_start_action.tsx | 2 +-
.../transform_management_section.tsx | 8 +-
13 files changed, 427 insertions(+), 406 deletions(-)
create mode 100644 x-pack/plugins/transform/public/app/hooks/use_create_transform.tsx
create mode 100644 x-pack/plugins/transform/public/app/hooks/use_get_transform_stats.ts
diff --git a/x-pack/plugins/transform/common/api_schemas/transforms_stats.ts b/x-pack/plugins/transform/common/api_schemas/transforms_stats.ts
index 459d37414e244..a9d177a341e21 100644
--- a/x-pack/plugins/transform/common/api_schemas/transforms_stats.ts
+++ b/x-pack/plugins/transform/common/api_schemas/transforms_stats.ts
@@ -13,7 +13,7 @@ import { getTransformsRequestSchema } from './transforms';
export const getTransformsStatsRequestSchema = getTransformsRequestSchema;
-export type GetTransformsRequestSchema = TypeOf;
+export type GetTransformsStatsRequestSchema = TypeOf;
export interface GetTransformsStatsResponseSchema {
node_failures?: object;
diff --git a/x-pack/plugins/transform/common/constants.ts b/x-pack/plugins/transform/common/constants.ts
index 1076f1d6530d6..eb4943f2e6706 100644
--- a/x-pack/plugins/transform/common/constants.ts
+++ b/x-pack/plugins/transform/common/constants.ts
@@ -35,6 +35,7 @@ export const addExternalBasePath = (uri: string): string => `${EXTERNAL_API_BASE
export const TRANSFORM_REACT_QUERY_KEYS = {
PRIVILEGES: 'transform.privileges',
TRANSFORMS_LIST: 'transform.transforms_list',
+ TRANSFORM_STATS: 'transform.transform_stats',
} as const;
// In order to create a transform, the API requires the following privileges:
diff --git a/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts b/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
index a2f30a6c256b9..f76de90a1259a 100644
--- a/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
+++ b/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
@@ -12,14 +12,6 @@ import { DEFAULT_SAMPLER_SHARD_SIZE } from '@kbn/ml-agg-utils';
import type { TransformId } from '../../../../common/types/transform';
import type { FieldHistogramsResponseSchema } from '../../../../common/api_schemas/field_histograms';
-import type {
- DeleteTransformsRequestSchema,
- DeleteTransformsResponseSchema,
-} from '../../../../common/api_schemas/delete_transforms';
-import type {
- StartTransformsRequestSchema,
- StartTransformsResponseSchema,
-} from '../../../../common/api_schemas/start_transforms';
import type {
StopTransformsRequestSchema,
StopTransformsResponseSchema,
@@ -28,8 +20,6 @@ import type {
GetTransformsResponseSchema,
PostTransformsPreviewRequestSchema,
PostTransformsPreviewResponseSchema,
- PutTransformsRequestSchema,
- PutTransformsResponseSchema,
} from '../../../../common/api_schemas/transforms';
import type { GetTransformsStatsResponseSchema } from '../../../../common/api_schemas/transforms_stats';
import type {
@@ -57,12 +47,6 @@ const apiFactory = () => ({
): Promise {
return Promise.resolve({ count: 0, transforms: [] });
},
- async createTransform(
- transformId: TransformId,
- transformConfig: PutTransformsRequestSchema
- ): Promise {
- return Promise.resolve({ transformsCreated: [], errors: [] });
- },
async updateTransform(
transformId: TransformId,
transformConfig: PostTransformsUpdateRequestSchema
@@ -82,11 +66,6 @@ const apiFactory = () => ({
create_time: 1598860879097,
});
},
- async deleteTransforms(
- reqBody: DeleteTransformsRequestSchema
- ): Promise {
- return Promise.resolve({});
- },
async getTransformsPreview(
obj: PostTransformsPreviewRequestSchema
): Promise {
@@ -109,11 +88,6 @@ const apiFactory = () => ({
preview: [],
});
},
- async startTransforms(
- reqBody: StartTransformsRequestSchema
- ): Promise {
- return Promise.resolve({});
- },
async stopTransforms(
transformsInfo: StopTransformsRequestSchema
): Promise {
diff --git a/x-pack/plugins/transform/public/app/hooks/index.ts b/x-pack/plugins/transform/public/app/hooks/index.ts
index 91730ec067aeb..d77f60439609b 100644
--- a/x-pack/plugins/transform/public/app/hooks/index.ts
+++ b/x-pack/plugins/transform/public/app/hooks/index.ts
@@ -6,9 +6,11 @@
*/
export { useApi } from './use_api';
+export { useCreateTransform } from './use_create_transform';
export { useDocumentationLinks } from './use_documentation_links';
export { useGetTransformAuditMessages } from './use_get_transform_audit_messages';
export { useGetTransforms } from './use_get_transforms';
+export { useGetTransformStats } from './use_get_transform_stats';
export { useDeleteTransforms, useDeleteIndexAndTargetIndex } from './use_delete_transform';
export { useResetTransforms } from './use_reset_transform';
export { useScheduleNowTransforms } from './use_schedule_now_transform';
diff --git a/x-pack/plugins/transform/public/app/hooks/use_api.ts b/x-pack/plugins/transform/public/app/hooks/use_api.ts
index a72e249d7b944..14547f0dd834a 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_api.ts
+++ b/x-pack/plugins/transform/public/app/hooks/use_api.ts
@@ -16,10 +16,6 @@ import {
ReauthorizeTransformsRequestSchema,
ReauthorizeTransformsResponseSchema,
} from '../../../common/api_schemas/reauthorize_transforms';
-import type {
- DeleteTransformsRequestSchema,
- DeleteTransformsResponseSchema,
-} from '../../../common/api_schemas/delete_transforms';
import type {
FieldHistogramsRequestSchema,
FieldHistogramsResponseSchema,
@@ -28,10 +24,6 @@ import type {
ResetTransformsRequestSchema,
ResetTransformsResponseSchema,
} from '../../../common/api_schemas/reset_transforms';
-import type {
- StartTransformsRequestSchema,
- StartTransformsResponseSchema,
-} from '../../../common/api_schemas/start_transforms';
import type {
StopTransformsRequestSchema,
StopTransformsResponseSchema,
@@ -44,8 +36,6 @@ import type {
GetTransformsResponseSchema,
PostTransformsPreviewRequestSchema,
PostTransformsPreviewResponseSchema,
- PutTransformsRequestSchema,
- PutTransformsResponseSchema,
} from '../../../common/api_schemas/transforms';
import type {
PostTransformsUpdateRequestSchema,
@@ -93,19 +83,6 @@ export const useApi = () => {
return e;
}
},
- async createTransform(
- transformId: TransformId,
- transformConfig: PutTransformsRequestSchema
- ): Promise {
- try {
- return await http.put(addInternalBasePath(`transforms/${transformId}`), {
- body: JSON.stringify(transformConfig),
- version: '1',
- });
- } catch (e) {
- return e;
- }
- },
async updateTransform(
transformId: TransformId,
transformConfig: PostTransformsUpdateRequestSchema
@@ -119,18 +96,6 @@ export const useApi = () => {
return e;
}
},
- async deleteTransforms(
- reqBody: DeleteTransformsRequestSchema
- ): Promise {
- try {
- return await http.post(addInternalBasePath(`delete_transforms`), {
- body: JSON.stringify(reqBody),
- version: '1',
- });
- } catch (e) {
- return e;
- }
- },
async getTransformsPreview(
obj: PostTransformsPreviewRequestSchema
): Promise {
@@ -168,18 +133,6 @@ export const useApi = () => {
return e;
}
},
- async startTransforms(
- reqBody: StartTransformsRequestSchema
- ): Promise {
- try {
- return await http.post(addInternalBasePath(`start_transforms`), {
- body: JSON.stringify(reqBody),
- version: '1',
- });
- } catch (e) {
- return e;
- }
- },
async stopTransforms(
transformsInfo: StopTransformsRequestSchema
): Promise {
diff --git a/x-pack/plugins/transform/public/app/hooks/use_create_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_create_transform.tsx
new file mode 100644
index 0000000000000..f44f0f234559f
--- /dev/null
+++ b/x-pack/plugins/transform/public/app/hooks/use_create_transform.tsx
@@ -0,0 +1,84 @@
+/*
+ * 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 from 'react';
+import { useMutation } from '@tanstack/react-query';
+
+import { i18n } from '@kbn/i18n';
+import { toMountPoint } from '@kbn/kibana-react-plugin/public';
+
+import type {
+ PutTransformsRequestSchema,
+ PutTransformsResponseSchema,
+} from '../../../common/api_schemas/transforms';
+import { isPutTransformsResponseSchema } from '../../../common/api_schemas/type_guards';
+import { addInternalBasePath } from '../../../common/constants';
+import type { TransformId } from '../../../common/types/transform';
+import { getErrorMessage } from '../../../common/utils/errors';
+
+import { useAppDependencies, useToastNotifications } from '../app_dependencies';
+import { useRefreshTransformList } from '../common';
+import { ToastNotificationText } from '../components';
+
+export const useCreateTransform = (
+ transformId: TransformId,
+ transformConfig: PutTransformsRequestSchema
+) => {
+ const { http, overlays, theme } = useAppDependencies();
+ const refreshTransformList = useRefreshTransformList();
+ const toastNotifications = useToastNotifications();
+
+ const mutation = useMutation({
+ mutationFn: () => {
+ return http.put(
+ addInternalBasePath(`transforms/${transformId}`),
+ {
+ body: JSON.stringify(transformConfig),
+ version: '1',
+ }
+ );
+ },
+ onError: (resp) => {
+ if (!isPutTransformsResponseSchema(resp) || resp.errors.length > 0) {
+ let respErrors:
+ | PutTransformsResponseSchema['errors']
+ | PutTransformsResponseSchema['errors'][number]
+ | undefined;
+
+ if (isPutTransformsResponseSchema(resp) && resp.errors.length > 0) {
+ respErrors = resp.errors.length === 1 ? resp.errors[0] : resp.errors;
+ }
+
+ toastNotifications.addDanger({
+ title: i18n.translate('xpack.transform.stepCreateForm.createTransformErrorMessage', {
+ defaultMessage: 'An error occurred creating the transform {transformId}:',
+ values: { transformId },
+ }),
+ text: toMountPoint(
+ ,
+ { theme$: theme.theme$ }
+ ),
+ });
+ }
+ },
+ onSuccess: (results) => {
+ toastNotifications.addSuccess(
+ i18n.translate('xpack.transform.stepCreateForm.createTransformSuccessMessage', {
+ defaultMessage: 'Request to create transform {transformId} acknowledged.',
+ values: { transformId },
+ })
+ );
+ refreshTransformList();
+ },
+ });
+
+ return mutation;
+};
diff --git a/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx
index d4e078d285ca9..453a9bd912c07 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx
@@ -6,19 +6,22 @@
*/
import React, { useCallback, useEffect, useState } from 'react';
+import { useMutation } from '@tanstack/react-query';
+
import { i18n } from '@kbn/i18n';
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
import { extractErrorMessage } from '@kbn/ml-error-utils';
+
+import { addInternalBasePath } from '../../../common/constants';
import type {
DeleteTransformStatus,
DeleteTransformsRequestSchema,
+ DeleteTransformsResponseSchema,
} from '../../../common/api_schemas/delete_transforms';
-import { isDeleteTransformsResponseSchema } from '../../../common/api_schemas/type_guards';
import { getErrorMessage } from '../../../common/utils/errors';
import { useAppDependencies, useToastNotifications } from '../app_dependencies';
import { useRefreshTransformList, type TransformListRow } from '../common';
import { ToastNotificationText } from '../components';
-import { useApi } from './use_api';
import { indexService } from '../services/es_index_service';
export const useDeleteIndexAndTargetIndex = (items: TransformListRow[]) => {
@@ -119,15 +122,18 @@ export const useDeleteIndexAndTargetIndex = (items: TransformListRow[]) => {
type SuccessCountField = keyof Omit;
export const useDeleteTransforms = () => {
- const { overlays, theme } = useAppDependencies();
+ const { http, overlays, theme } = useAppDependencies();
const refreshTransformList = useRefreshTransformList();
const toastNotifications = useToastNotifications();
- const api = useApi();
- return async (reqBody: DeleteTransformsRequestSchema) => {
- const results = await api.deleteTransforms(reqBody);
-
- if (!isDeleteTransformsResponseSchema(results)) {
+ const mutation = useMutation({
+ mutationFn: (reqBody: DeleteTransformsRequestSchema) => {
+ return http.post(addInternalBasePath('delete_transforms'), {
+ body: JSON.stringify(reqBody),
+ version: '1',
+ });
+ },
+ onError: (error) => {
toastNotifications.addDanger({
title: i18n.translate('xpack.transform.transformList.deleteTransformGenericErrorMessage', {
defaultMessage: 'An error occurred calling the API endpoint to delete transforms.',
@@ -137,163 +143,165 @@ export const useDeleteTransforms = () => {
previewTextLength={50}
overlays={overlays}
theme={theme}
- text={getErrorMessage(results)}
+ text={getErrorMessage(error)}
/>,
{ theme$: theme.theme$ }
),
});
- return;
- }
-
- const isBulk = Object.keys(results).length > 1;
- const successCount: Record = {
- transformDeleted: 0,
- destIndexDeleted: 0,
- destDataViewDeleted: 0,
- };
- for (const transformId in results) {
- // hasOwnProperty check to ensure only properties on object itself, and not its prototypes
- if (results.hasOwnProperty(transformId)) {
- const status = results[transformId];
- const destinationIndex = status.destinationIndex;
+ },
+ onSuccess: (results) => {
+ const isBulk = Object.keys(results).length > 1;
+ const successCount: Record = {
+ transformDeleted: 0,
+ destIndexDeleted: 0,
+ destDataViewDeleted: 0,
+ };
+ for (const transformId in results) {
+ // hasOwnProperty check to ensure only properties on object itself, and not its prototypes
+ if (results.hasOwnProperty(transformId)) {
+ const status = results[transformId];
+ const destinationIndex = status.destinationIndex;
- // if we are only deleting one transform, show the success toast messages
- if (!isBulk && status.transformDeleted) {
- if (status.transformDeleted?.success) {
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.transformList.deleteTransformSuccessMessage', {
- defaultMessage: 'Request to delete transform {transformId} acknowledged.',
+ // if we are only deleting one transform, show the success toast messages
+ if (!isBulk && status.transformDeleted) {
+ if (status.transformDeleted?.success) {
+ toastNotifications.addSuccess(
+ i18n.translate('xpack.transform.transformList.deleteTransformSuccessMessage', {
+ defaultMessage: 'Request to delete transform {transformId} acknowledged.',
+ values: { transformId },
+ })
+ );
+ }
+ if (status.destIndexDeleted?.success) {
+ toastNotifications.addSuccess(
+ i18n.translate(
+ 'xpack.transform.deleteTransform.deleteAnalyticsWithIndexSuccessMessage',
+ {
+ defaultMessage:
+ 'Request to delete destination index {destinationIndex} acknowledged.',
+ values: { destinationIndex },
+ }
+ )
+ );
+ }
+ if (status.destDataViewDeleted?.success) {
+ toastNotifications.addSuccess(
+ i18n.translate(
+ 'xpack.transform.deleteTransform.deleteAnalyticsWithDataViewSuccessMessage',
+ {
+ defaultMessage: 'Request to delete data view {destinationIndex} acknowledged.',
+ values: { destinationIndex },
+ }
+ )
+ );
+ }
+ } else {
+ (Object.keys(successCount) as SuccessCountField[]).forEach((key) => {
+ if (status[key]?.success) {
+ successCount[key] = successCount[key] + 1;
+ }
+ });
+ }
+ if (status.transformDeleted?.error) {
+ const error = status.transformDeleted.error.reason;
+ toastNotifications.addDanger({
+ title: i18n.translate('xpack.transform.transformList.deleteTransformErrorMessage', {
+ defaultMessage: 'An error occurred deleting the transform {transformId}',
values: { transformId },
- })
- );
+ }),
+ text: toMountPoint(
+ ,
+ { theme$: theme.theme$ }
+ ),
+ });
}
- if (status.destIndexDeleted?.success) {
- toastNotifications.addSuccess(
- i18n.translate(
- 'xpack.transform.deleteTransform.deleteAnalyticsWithIndexSuccessMessage',
+
+ if (status.destIndexDeleted?.error) {
+ const error = status.destIndexDeleted.error.reason;
+ toastNotifications.addDanger({
+ title: i18n.translate(
+ 'xpack.transform.deleteTransform.deleteAnalyticsWithIndexErrorMessage',
{
- defaultMessage:
- 'Request to delete destination index {destinationIndex} acknowledged.',
+ defaultMessage: 'An error occurred deleting destination index {destinationIndex}',
values: { destinationIndex },
}
- )
- );
+ ),
+ text: toMountPoint(
+ ,
+ { theme$: theme.theme$ }
+ ),
+ });
}
- if (status.destDataViewDeleted?.success) {
- toastNotifications.addSuccess(
- i18n.translate(
- 'xpack.transform.deleteTransform.deleteAnalyticsWithDataViewSuccessMessage',
+
+ if (status.destDataViewDeleted?.error) {
+ const error = status.destDataViewDeleted.error.reason;
+ toastNotifications.addDanger({
+ title: i18n.translate(
+ 'xpack.transform.deleteTransform.deleteAnalyticsWithDataViewErrorMessage',
{
- defaultMessage: 'Request to delete data view {destinationIndex} acknowledged.',
+ defaultMessage: 'An error occurred deleting data view {destinationIndex}',
values: { destinationIndex },
}
- )
- );
+ ),
+ text: toMountPoint(
+ ,
+ { theme$: theme.theme$ }
+ ),
+ });
}
- } else {
- (Object.keys(successCount) as SuccessCountField[]).forEach((key) => {
- if (status[key]?.success) {
- successCount[key] = successCount[key] + 1;
- }
- });
- }
- if (status.transformDeleted?.error) {
- const error = status.transformDeleted.error.reason;
- toastNotifications.addDanger({
- title: i18n.translate('xpack.transform.transformList.deleteTransformErrorMessage', {
- defaultMessage: 'An error occurred deleting the transform {transformId}',
- values: { transformId },
- }),
- text: toMountPoint(
- ,
- { theme$: theme.theme$ }
- ),
- });
}
+ }
- if (status.destIndexDeleted?.error) {
- const error = status.destIndexDeleted.error.reason;
- toastNotifications.addDanger({
- title: i18n.translate(
- 'xpack.transform.deleteTransform.deleteAnalyticsWithIndexErrorMessage',
- {
- defaultMessage: 'An error occurred deleting destination index {destinationIndex}',
- values: { destinationIndex },
- }
- ),
- text: toMountPoint(
- ,
- { theme$: theme.theme$ }
- ),
- });
+ // if we are deleting multiple transforms, combine the success messages
+ if (isBulk) {
+ if (successCount.transformDeleted > 0) {
+ toastNotifications.addSuccess(
+ i18n.translate('xpack.transform.transformList.bulkDeleteTransformSuccessMessage', {
+ defaultMessage:
+ 'Successfully deleted {count} {count, plural, one {transform} other {transforms}}.',
+ values: { count: successCount.transformDeleted },
+ })
+ );
}
- if (status.destDataViewDeleted?.error) {
- const error = status.destDataViewDeleted.error.reason;
- toastNotifications.addDanger({
- title: i18n.translate(
- 'xpack.transform.deleteTransform.deleteAnalyticsWithDataViewErrorMessage',
- {
- defaultMessage: 'An error occurred deleting data view {destinationIndex}',
- values: { destinationIndex },
- }
- ),
- text: toMountPoint(
- ,
- { theme$: theme.theme$ }
- ),
- });
+ if (successCount.destIndexDeleted > 0) {
+ toastNotifications.addSuccess(
+ i18n.translate('xpack.transform.transformList.bulkDeleteDestIndexSuccessMessage', {
+ defaultMessage:
+ 'Successfully deleted {count} destination {count, plural, one {index} other {indices}}.',
+ values: { count: successCount.destIndexDeleted },
+ })
+ );
+ }
+ if (successCount.destDataViewDeleted > 0) {
+ toastNotifications.addSuccess(
+ i18n.translate('xpack.transform.transformList.bulkDeleteDestDataViewSuccessMessage', {
+ defaultMessage:
+ 'Successfully deleted {count} destination data {count, plural, one {view} other {views}}.',
+ values: { count: successCount.destDataViewDeleted },
+ })
+ );
}
- }
- }
-
- // if we are deleting multiple transforms, combine the success messages
- if (isBulk) {
- if (successCount.transformDeleted > 0) {
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.transformList.bulkDeleteTransformSuccessMessage', {
- defaultMessage:
- 'Successfully deleted {count} {count, plural, one {transform} other {transforms}}.',
- values: { count: successCount.transformDeleted },
- })
- );
}
- if (successCount.destIndexDeleted > 0) {
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.transformList.bulkDeleteDestIndexSuccessMessage', {
- defaultMessage:
- 'Successfully deleted {count} destination {count, plural, one {index} other {indices}}.',
- values: { count: successCount.destIndexDeleted },
- })
- );
- }
- if (successCount.destDataViewDeleted > 0) {
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.transformList.bulkDeleteDestDataViewSuccessMessage', {
- defaultMessage:
- 'Successfully deleted {count} destination data {count, plural, one {view} other {views}}.',
- values: { count: successCount.destDataViewDeleted },
- })
- );
- }
- }
+ refreshTransformList();
+ },
+ });
- refreshTransformList();
- };
+ return (reqBody: DeleteTransformsRequestSchema) => mutation.mutate(reqBody);
};
diff --git a/x-pack/plugins/transform/public/app/hooks/use_get_transform_stats.ts b/x-pack/plugins/transform/public/app/hooks/use_get_transform_stats.ts
new file mode 100644
index 0000000000000..a5df06f2ece59
--- /dev/null
+++ b/x-pack/plugins/transform/public/app/hooks/use_get_transform_stats.ts
@@ -0,0 +1,37 @@
+/*
+ * 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 { useQuery } from '@tanstack/react-query';
+
+import type { IHttpFetchError } from '@kbn/core-http-browser';
+
+import type { GetTransformsStatsResponseSchema } from '../../../common/api_schemas/transforms_stats';
+import { addInternalBasePath, TRANSFORM_REACT_QUERY_KEYS } from '../../../common/constants';
+import type { TransformId } from '../../../common/types/transform';
+
+import { useAppDependencies } from '../app_dependencies';
+
+export const useGetTransformStats = (
+ transformId: TransformId,
+ enabled?: boolean,
+ refetchInterval?: number | false
+) => {
+ const { http } = useAppDependencies();
+
+ return useQuery(
+ [TRANSFORM_REACT_QUERY_KEYS.TRANSFORM_STATS, transformId],
+ async ({ signal }) =>
+ await http.get(
+ addInternalBasePath(`transforms/${transformId}/_stats`),
+ {
+ version: '1',
+ signal,
+ }
+ ),
+ { enabled, refetchInterval }
+ );
+};
diff --git a/x-pack/plugins/transform/public/app/hooks/use_start_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_start_transform.tsx
index a3bd5b29d5e57..84dc80ef64e47 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_start_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_start_transform.tsx
@@ -6,13 +6,17 @@
*/
import React from 'react';
+import { useMutation } from '@tanstack/react-query';
import { i18n } from '@kbn/i18n';
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
-import type { StartTransformsRequestSchema } from '../../../common/api_schemas/start_transforms';
-import { isStartTransformsResponseSchema } from '../../../common/api_schemas/type_guards';
+import { addInternalBasePath } from '../../../common/constants';
+import type {
+ StartTransformsRequestSchema,
+ StartTransformsResponseSchema,
+} from '../../../common/api_schemas/start_transforms';
import { getErrorMessage } from '../../../common/utils/errors';
@@ -20,18 +24,19 @@ import { useAppDependencies, useToastNotifications } from '../app_dependencies';
import { useRefreshTransformList } from '../common';
import { ToastNotificationText } from '../components';
-import { useApi } from './use_api';
-
export const useStartTransforms = () => {
- const { overlays, theme } = useAppDependencies();
+ const { http, overlays, theme } = useAppDependencies();
const refreshTransformList = useRefreshTransformList();
const toastNotifications = useToastNotifications();
- const api = useApi();
-
- return async (transformsInfo: StartTransformsRequestSchema) => {
- const results = await api.startTransforms(transformsInfo);
- if (!isStartTransformsResponseSchema(results)) {
+ const mutation = useMutation({
+ mutationFn: (reqBody: StartTransformsRequestSchema) => {
+ return http.post(addInternalBasePath(`start_transforms`), {
+ body: JSON.stringify(reqBody),
+ version: '1',
+ });
+ },
+ onError: (error) => {
toastNotifications.addDanger({
title: i18n.translate(
'xpack.transform.stepCreateForm.startTransformResponseSchemaErrorMessage',
@@ -40,40 +45,41 @@ export const useStartTransforms = () => {
}
),
text: toMountPoint(
- ,
+ ,
{ theme$: theme.theme$ }
),
});
- return;
- }
-
- for (const transformId in results) {
- // hasOwnProperty check to ensure only properties on object itself, and not its prototypes
- if (results.hasOwnProperty(transformId)) {
- const result = results[transformId];
- if (result.success === true) {
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.transformList.startTransformSuccessMessage', {
- defaultMessage: 'Request to start transform {transformId} acknowledged.',
- values: { transformId },
- })
- );
- } else {
- toastNotifications.addError(new Error(JSON.stringify(result.error!.caused_by, null, 2)), {
- title: i18n.translate('xpack.transform.transformList.startTransformErrorMessage', {
- defaultMessage: 'An error occurred starting the transform {transformId}',
- values: { transformId },
- }),
- toastMessage: result.error!.reason,
- });
+ },
+ onSuccess: (results) => {
+ for (const transformId in results) {
+ // hasOwnProperty check to ensure only properties on object itself, and not its prototypes
+ if (results.hasOwnProperty(transformId)) {
+ const result = results[transformId];
+ if (result.success === true) {
+ toastNotifications.addSuccess(
+ i18n.translate('xpack.transform.transformList.startTransformSuccessMessage', {
+ defaultMessage: 'Request to start transform {transformId} acknowledged.',
+ values: { transformId },
+ })
+ );
+ } else {
+ toastNotifications.addError(
+ new Error(JSON.stringify(result.error!.caused_by, null, 2)),
+ {
+ title: i18n.translate('xpack.transform.transformList.startTransformErrorMessage', {
+ defaultMessage: 'An error occurred starting the transform {transformId}',
+ values: { transformId },
+ }),
+ toastMessage: result.error!.reason,
+ }
+ );
+ }
}
}
- }
- refreshTransformList();
- };
+ refreshTransformList();
+ },
+ });
+
+ return mutation;
};
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.test.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.test.tsx
index 2e785c2d6680b..e2fa8912fc932 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.test.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.test.tsx
@@ -7,6 +7,7 @@
import React from 'react';
import { render } from '@testing-library/react';
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { StepCreateForm, StepCreateFormProps } from './step_create_form';
@@ -16,6 +17,7 @@ jest.mock('../../../../app_dependencies');
describe('Transform: ', () => {
test('Minimal initialization', () => {
// Arrange
+ const queryClient = new QueryClient();
const props: StepCreateFormProps = {
createDataView: false,
transformId: 'the-transform-id',
@@ -35,7 +37,11 @@ describe('Transform: ', () => {
onChange() {},
};
- const { getByText } = render();
+ const { getByText } = render(
+
+
+
+ );
// Act
// Assert
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.tsx
index d61b18632cef4..b0391c85c1146 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.tsx
@@ -31,10 +31,8 @@ import { DISCOVER_APP_LOCATOR } from '@kbn/discover-plugin/common';
import { DuplicateDataViewError } from '@kbn/data-plugin/public';
import type { RuntimeField } from '@kbn/data-views-plugin/common';
import { isPopulatedObject } from '@kbn/ml-is-populated-object';
-import type { PutTransformsResponseSchema } from '../../../../../../common/api_schemas/transforms';
import {
isGetTransformsStatsResponseSchema,
- isPutTransformsResponseSchema,
isStartTransformsResponseSchema,
} from '../../../../../../common/api_schemas/type_guards';
import { PROGRESS_REFRESH_INTERVAL_MS } from '../../../../../../common/constants';
@@ -42,7 +40,7 @@ import { PROGRESS_REFRESH_INTERVAL_MS } from '../../../../../../common/constants
import { getErrorMessage } from '../../../../../../common/utils/errors';
import { getTransformProgress } from '../../../../common';
-import { useApi } from '../../../../hooks/use_api';
+import { useCreateTransform, useGetTransformStats, useStartTransforms } from '../../../../hooks';
import { useAppDependencies, useToastNotifications } from '../../../../app_dependencies';
import { RedirectToTransformManagement } from '../../../../common/navigation';
import { ToastNotificationText } from '../../../../components';
@@ -129,103 +127,45 @@ export const StepCreateForm: FC = React.memo(
}, [created, started, dataViewId]);
const { overlays, theme } = useAppDependencies();
- const api = useApi();
+ const { mutate: startTransforms } = useStartTransforms();
+ const { mutate: createTransform } = useCreateTransform(transformId, transformConfig);
- async function createTransform() {
+ function createTransformHandler(startAfterCreation = false) {
setLoading(true);
- const resp = await api.createTransform(transformId, transformConfig);
-
- if (!isPutTransformsResponseSchema(resp) || resp.errors.length > 0) {
- let respErrors:
- | PutTransformsResponseSchema['errors']
- | PutTransformsResponseSchema['errors'][number]
- | undefined;
-
- if (isPutTransformsResponseSchema(resp) && resp.errors.length > 0) {
- respErrors = resp.errors.length === 1 ? resp.errors[0] : resp.errors;
- }
-
- toastNotifications.addDanger({
- title: i18n.translate('xpack.transform.stepCreateForm.createTransformErrorMessage', {
- defaultMessage: 'An error occurred creating the transform {transformId}:',
- values: { transformId },
- }),
- text: toMountPoint(
- ,
- { theme$: theme.theme$ }
- ),
- });
- setCreated(false);
- setLoading(false);
- return false;
- }
-
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.stepCreateForm.createTransformSuccessMessage', {
- defaultMessage: 'Request to create transform {transformId} acknowledged.',
- values: { transformId },
- })
- );
- setCreated(true);
- setLoading(false);
-
- if (createDataView) {
- createKibanaDataView();
- }
-
- return true;
+ createTransform(undefined, {
+ onError: () => {
+ setCreated(false);
+ },
+ onSuccess: () => {
+ setCreated(true);
+ if (createDataView) {
+ createKibanaDataView();
+ }
+ if (startAfterCreation) {
+ startTransform();
+ }
+ },
+ onSettled: () => {
+ setLoading(false);
+ },
+ });
}
- async function startTransform() {
+ function startTransform() {
setLoading(true);
- const resp = await api.startTransforms([{ id: transformId }]);
-
- if (isStartTransformsResponseSchema(resp) && resp[transformId]?.success === true) {
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.stepCreateForm.startTransformSuccessMessage', {
- defaultMessage: 'Request to start transform {transformId} acknowledged.',
- values: { transformId },
- })
- );
- setStarted(true);
- setLoading(false);
- return;
- }
-
- const errorMessage =
- isStartTransformsResponseSchema(resp) && resp[transformId]?.success === false
- ? resp[transformId].error
- : resp;
-
- toastNotifications.addDanger({
- title: i18n.translate('xpack.transform.stepCreateForm.startTransformErrorMessage', {
- defaultMessage: 'An error occurred starting the transform {transformId}:',
- values: { transformId },
- }),
- text: toMountPoint(
- ,
- { theme$: theme.theme$ }
- ),
+ startTransforms([{ id: transformId }], {
+ onError: () => {
+ setStarted(false);
+ },
+ onSuccess: (resp) => {
+ setStarted(isStartTransformsResponseSchema(resp) && resp[transformId]?.success === true);
+ },
+ onSettled: () => {
+ setLoading(false);
+ },
});
- setStarted(false);
- setLoading(false);
- }
-
- async function createAndStartTransform() {
- const acknowledged = await createTransform();
- if (acknowledged) {
- await startTransform();
- }
}
const createKibanaDataView = async () => {
@@ -288,57 +228,67 @@ export const StepCreateForm: FC = React.memo(
const isBatchTransform = typeof transformConfig.sync === 'undefined';
- if (
- loading === false &&
- started === true &&
- progressPercentComplete === undefined &&
- isBatchTransform
- ) {
- // wrapping in function so we can keep the interval id in local scope
- function startProgressBar() {
- const interval = setInterval(async () => {
- const stats = await api.getTransformStats(transformId);
-
- if (
- isGetTransformsStatsResponseSchema(stats) &&
- Array.isArray(stats.transforms) &&
- stats.transforms.length > 0
- ) {
- const percent =
- getTransformProgress({
- id: transformId,
- config: {
- ...transformConfig,
- id: transformId,
- },
- stats: stats.transforms[0],
- }) || 0;
- setProgressPercentComplete(percent);
- if (percent >= 100) {
- clearInterval(interval);
- }
- } else {
- toastNotifications.addDanger({
- title: i18n.translate('xpack.transform.stepCreateForm.progressErrorMessage', {
- defaultMessage: 'An error occurred getting the progress percentage:',
- }),
- text: toMountPoint(
- ,
- { theme$: theme.theme$ }
- ),
- });
- clearInterval(interval);
- }
- }, PROGRESS_REFRESH_INTERVAL_MS);
+ useEffect(() => {
+ if (
+ loading === false &&
+ started === true &&
+ progressPercentComplete === undefined &&
+ isBatchTransform
+ ) {
setProgressPercentComplete(0);
}
+ }, [loading, started, progressPercentComplete, isBatchTransform]);
+
+ const progressBarRefetchEnabled =
+ isBatchTransform &&
+ typeof progressPercentComplete === 'number' &&
+ progressPercentComplete < 100;
+ const progressBarRefetchInterval = progressBarRefetchEnabled
+ ? PROGRESS_REFRESH_INTERVAL_MS
+ : false;
+
+ const { data: stats } = useGetTransformStats(
+ transformId,
+ progressBarRefetchEnabled,
+ progressBarRefetchInterval
+ );
- startProgressBar();
- }
+ useEffect(() => {
+ if (stats === undefined) {
+ return;
+ }
+
+ if (
+ isGetTransformsStatsResponseSchema(stats) &&
+ Array.isArray(stats.transforms) &&
+ stats.transforms.length > 0
+ ) {
+ const percent =
+ getTransformProgress({
+ id: transformId,
+ config: {
+ ...transformConfig,
+ id: transformId,
+ },
+ stats: stats.transforms[0],
+ }) || 0;
+ setProgressPercentComplete(percent);
+ } else {
+ toastNotifications.addDanger({
+ title: i18n.translate('xpack.transform.stepCreateForm.progressErrorMessage', {
+ defaultMessage: 'An error occurred getting the progress percentage:',
+ }),
+ text: toMountPoint(
+ ,
+ { theme$: theme.theme$ }
+ ),
+ });
+ }
+ }, [overlays, stats, theme, toastNotifications, transformConfig, transformId]);
function getTransformConfigDevConsoleStatement() {
return `PUT _transform/${transformId}\n${JSON.stringify(transformConfig, null, 2)}\n\n`;
@@ -362,7 +312,7 @@ export const StepCreateForm: FC = React.memo(
createTransformHandler(true)}
data-test-subj="transformWizardCreateAndStartButton"
>
{i18n.translate('xpack.transform.stepCreateForm.createAndStartTransformButton', {
@@ -436,7 +386,7 @@ export const StepCreateForm: FC = React.memo(
createTransformHandler()}
data-test-subj="transformWizardCreateButton"
>
{i18n.translate('xpack.transform.stepCreateForm.createTransformButton', {
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/use_start_action.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/use_start_action.tsx
index 20910cf5fa0a5..b033cb514cbf2 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/use_start_action.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/use_start_action.tsx
@@ -19,7 +19,7 @@ export type StartAction = ReturnType;
export const useStartAction = (forceDisable: boolean, transformNodes: number) => {
const { canStartStopTransform } = useContext(AuthorizationContext).capabilities;
- const startTransforms = useStartTransforms();
+ const { mutate: startTransforms } = useStartTransforms();
const [isModalVisible, setModalVisible] = useState(false);
const [items, setItems] = useState([]);
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/transform_management_section.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/transform_management_section.tsx
index 045f1bdbc38e0..1a8db994e0fec 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/transform_management_section.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/transform_management_section.tsx
@@ -176,8 +176,8 @@ export const TransformManagement: FC = () => {
{
- await deleteTransforms(
+ onClick={() =>
+ deleteTransforms(
// If transform task doesn't have any corresponding config
// we won't know what the destination index or data view would be
// and should be force deleted
@@ -190,8 +190,8 @@ export const TransformManagement: FC = () => {
deleteDestDataView: false,
forceDelete: true,
}
- );
- }}
+ )
+ }
>
Date: Tue, 22 Aug 2023 14:37:31 +0200
Subject: [PATCH 04/53] fix i18n
---
x-pack/plugins/translations/translations/fr-FR.json | 2 --
x-pack/plugins/translations/translations/ja-JP.json | 2 --
x-pack/plugins/translations/translations/zh-CN.json | 2 --
3 files changed, 6 deletions(-)
diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json
index 147738ec2eda0..9f0b2ff73b908 100644
--- a/x-pack/plugins/translations/translations/fr-FR.json
+++ b/x-pack/plugins/translations/translations/fr-FR.json
@@ -37794,8 +37794,6 @@
"xpack.transform.stepCreateForm.createTransformErrorMessage": "Une erreur s'est produite lors de la création de la transformation {transformId} :",
"xpack.transform.stepCreateForm.createTransformSuccessMessage": "La requête pour créer la transformation {transformId} a été reconnue.",
"xpack.transform.stepCreateForm.duplicateDataViewErrorMessage": "Une erreur est survenue lors de la création de la vue de données Kibana {dataViewName} : La vue de données existe déjà.",
- "xpack.transform.stepCreateForm.startTransformErrorMessage": "Une erreur s'est produite lors du démarrage de la transformation {transformId} :",
- "xpack.transform.stepCreateForm.startTransformSuccessMessage": "La requête pour démarrer la transformation {transformId} a été reconnue.",
"xpack.transform.stepDefineForm.invalidKuerySyntaxErrorMessageQueryBar": "Requête non valide : {queryErrorMessage}",
"xpack.transform.stepDefineForm.queryPlaceholderKql": "Par exemple, {example}",
"xpack.transform.stepDefineForm.queryPlaceholderLucene": "Par exemple, {example}",
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index ba3c415751725..e1129d3faa9d1 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -37793,8 +37793,6 @@
"xpack.transform.stepCreateForm.createTransformErrorMessage": "変換 {transformId} の取得中にエラーが発生しました。",
"xpack.transform.stepCreateForm.createTransformSuccessMessage": "変換 {transformId} の作成リクエストが受け付けられました。",
"xpack.transform.stepCreateForm.duplicateDataViewErrorMessage": "Kibanaデータビュー{dataViewName}の作成中にエラーが発生しました:データビューはすでに存在します。",
- "xpack.transform.stepCreateForm.startTransformErrorMessage": "変換 {transformId} の開始中にエラーが発生しました。",
- "xpack.transform.stepCreateForm.startTransformSuccessMessage": "変換 {transformId} の開始リクエストが受け付けられました。",
"xpack.transform.stepDefineForm.invalidKuerySyntaxErrorMessageQueryBar": "無効なクエリ:{queryErrorMessage}",
"xpack.transform.stepDefineForm.queryPlaceholderKql": "例: {example}.",
"xpack.transform.stepDefineForm.queryPlaceholderLucene": "例: {example}.",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index be39a446a11a8..a7195f24d0c46 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -37787,8 +37787,6 @@
"xpack.transform.stepCreateForm.createTransformErrorMessage": "创建转换 {transformId} 时出错:",
"xpack.transform.stepCreateForm.createTransformSuccessMessage": "创建转换 {transformId} 的请求已确认。",
"xpack.transform.stepCreateForm.duplicateDataViewErrorMessage": "创建 Kibana 数据视图 {dataViewName} 时发生错误:数据视图已存在。",
- "xpack.transform.stepCreateForm.startTransformErrorMessage": "启动转换 {transformId} 时发生错误:",
- "xpack.transform.stepCreateForm.startTransformSuccessMessage": "启动转换 {transformId} 的请求已确认。",
"xpack.transform.stepDefineForm.invalidKuerySyntaxErrorMessageQueryBar": "无效查询:{queryErrorMessage}",
"xpack.transform.stepDefineForm.queryPlaceholderKql": "例如,{example}",
"xpack.transform.stepDefineForm.queryPlaceholderLucene": "例如,{example}",
From c23dc685d68b26b031d688b140aa968efad9e5e9 Mon Sep 17 00:00:00 2001
From: Walter Rafelsberger
Date: Tue, 22 Aug 2023 14:48:44 +0200
Subject: [PATCH 05/53] migrate cloning to use react-query
---
x-pack/plugins/transform/common/constants.ts | 6 +-
.../transform/public/app/common/transform.ts | 3 +-
.../public/app/hooks/__mocks__/use_api.ts | 6 --
.../transform/public/app/hooks/index.ts | 1 +
.../transform/public/app/hooks/use_api.ts | 12 ---
.../public/app/hooks/use_get_transform.tsx | 40 ++++++++++
.../hooks/use_get_transform_audit_messages.ts | 2 +-
.../app/hooks/use_get_transform_stats.ts | 2 +-
.../public/app/hooks/use_get_transforms.ts | 2 +-
.../clone_transform_section.tsx | 73 ++++++++++---------
10 files changed, 87 insertions(+), 60 deletions(-)
create mode 100644 x-pack/plugins/transform/public/app/hooks/use_get_transform.tsx
diff --git a/x-pack/plugins/transform/common/constants.ts b/x-pack/plugins/transform/common/constants.ts
index eb4943f2e6706..b6518c1fa241d 100644
--- a/x-pack/plugins/transform/common/constants.ts
+++ b/x-pack/plugins/transform/common/constants.ts
@@ -34,8 +34,10 @@ export const addExternalBasePath = (uri: string): string => `${EXTERNAL_API_BASE
export const TRANSFORM_REACT_QUERY_KEYS = {
PRIVILEGES: 'transform.privileges',
- TRANSFORMS_LIST: 'transform.transforms_list',
- TRANSFORM_STATS: 'transform.transform_stats',
+ GET_TRANSFORM: 'transform.get_transform',
+ GET_TRANSFORM_AUDIT_MESSAGES: 'transform.get_transform_audit_messages',
+ GET_TRANSFORM_STATS: 'transform.get_transform_stats',
+ GET_TRANSFORMS: 'transform.get_transforms',
} as const;
// In order to create a transform, the API requires the following privileges:
diff --git a/x-pack/plugins/transform/public/app/common/transform.ts b/x-pack/plugins/transform/public/app/common/transform.ts
index 34bbb82805c50..6339917a41db3 100644
--- a/x-pack/plugins/transform/public/app/common/transform.ts
+++ b/x-pack/plugins/transform/public/app/common/transform.ts
@@ -28,7 +28,8 @@ export const useRefreshTransformList = () => {
const queryClient = useQueryClient();
return useCallback(() => {
- queryClient.invalidateQueries([TRANSFORM_REACT_QUERY_KEYS.TRANSFORMS_LIST]);
+ queryClient.invalidateQueries([TRANSFORM_REACT_QUERY_KEYS.GET_TRANSFORMS]);
+ queryClient.invalidateQueries([TRANSFORM_REACT_QUERY_KEYS.GET_TRANSFORM_AUDIT_MESSAGES]);
}, [queryClient]);
};
diff --git a/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts b/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
index f76de90a1259a..763e754bc4aa8 100644
--- a/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
+++ b/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
@@ -17,7 +17,6 @@ import type {
StopTransformsResponseSchema,
} from '../../../../common/api_schemas/stop_transforms';
import type {
- GetTransformsResponseSchema,
PostTransformsPreviewRequestSchema,
PostTransformsPreviewResponseSchema,
} from '../../../../common/api_schemas/transforms';
@@ -37,11 +36,6 @@ export interface FieldHistogramRequestConfig {
}
const apiFactory = () => ({
- async getTransform(
- transformId: TransformId
- ): Promise {
- return Promise.resolve({ count: 0, transforms: [] });
- },
async getTransformStats(
transformId: TransformId
): Promise {
diff --git a/x-pack/plugins/transform/public/app/hooks/index.ts b/x-pack/plugins/transform/public/app/hooks/index.ts
index d77f60439609b..b3283da96a65a 100644
--- a/x-pack/plugins/transform/public/app/hooks/index.ts
+++ b/x-pack/plugins/transform/public/app/hooks/index.ts
@@ -9,6 +9,7 @@ export { useApi } from './use_api';
export { useCreateTransform } from './use_create_transform';
export { useDocumentationLinks } from './use_documentation_links';
export { useGetTransformAuditMessages } from './use_get_transform_audit_messages';
+export { useGetTransform } from './use_get_transform';
export { useGetTransforms } from './use_get_transforms';
export { useGetTransformStats } from './use_get_transform_stats';
export { useDeleteTransforms, useDeleteIndexAndTargetIndex } from './use_delete_transform';
diff --git a/x-pack/plugins/transform/public/app/hooks/use_api.ts b/x-pack/plugins/transform/public/app/hooks/use_api.ts
index 14547f0dd834a..edd839b447805 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_api.ts
+++ b/x-pack/plugins/transform/public/app/hooks/use_api.ts
@@ -33,7 +33,6 @@ import type {
ScheduleNowTransformsResponseSchema,
} from '../../../common/api_schemas/schedule_now_transforms';
import type {
- GetTransformsResponseSchema,
PostTransformsPreviewRequestSchema,
PostTransformsPreviewResponseSchema,
} from '../../../common/api_schemas/transforms';
@@ -61,17 +60,6 @@ export const useApi = () => {
return useMemo(
() => ({
- async getTransform(
- transformId: TransformId
- ): Promise {
- try {
- return await http.get(addInternalBasePath(`transforms/${transformId}`), {
- version: '1',
- });
- } catch (e) {
- return e;
- }
- },
async getTransformStats(
transformId: TransformId
): Promise {
diff --git a/x-pack/plugins/transform/public/app/hooks/use_get_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_get_transform.tsx
new file mode 100644
index 0000000000000..e3038706758a4
--- /dev/null
+++ b/x-pack/plugins/transform/public/app/hooks/use_get_transform.tsx
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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 { useQuery } from '@tanstack/react-query';
+
+import type { IHttpFetchError } from '@kbn/core-http-browser';
+
+import type { GetTransformsResponseSchema } from '../../../common/api_schemas/transforms';
+import { addInternalBasePath, TRANSFORM_REACT_QUERY_KEYS } from '../../../common/constants';
+import type { TransformId } from '../../../common/types/transform';
+
+import { useAppDependencies } from '../app_dependencies';
+
+export const useGetTransform = (transformId: TransformId, enabled?: boolean) => {
+ const { http } = useAppDependencies();
+
+ return useQuery(
+ [TRANSFORM_REACT_QUERY_KEYS.GET_TRANSFORM, transformId],
+ async ({ signal }) =>
+ await http.get(
+ addInternalBasePath(`transforms/${transformId}`),
+ {
+ version: '1',
+ signal,
+ }
+ ),
+ { enabled }
+ );
+};
diff --git a/x-pack/plugins/transform/public/app/hooks/use_get_transform_audit_messages.ts b/x-pack/plugins/transform/public/app/hooks/use_get_transform_audit_messages.ts
index 09e0bdf23571d..fec306f455417 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_get_transform_audit_messages.ts
+++ b/x-pack/plugins/transform/public/app/hooks/use_get_transform_audit_messages.ts
@@ -25,7 +25,7 @@ export const useGetTransformAuditMessages = (
const query = { sortField, sortDirection };
return useQuery(
- [TRANSFORM_REACT_QUERY_KEYS.TRANSFORMS_LIST, transformId, query],
+ [TRANSFORM_REACT_QUERY_KEYS.GET_TRANSFORM_AUDIT_MESSAGES, transformId, query],
async ({ signal }) =>
await http.get(
addInternalBasePath(`transforms/${transformId}/messages`),
diff --git a/x-pack/plugins/transform/public/app/hooks/use_get_transform_stats.ts b/x-pack/plugins/transform/public/app/hooks/use_get_transform_stats.ts
index a5df06f2ece59..c6f1951b85819 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_get_transform_stats.ts
+++ b/x-pack/plugins/transform/public/app/hooks/use_get_transform_stats.ts
@@ -23,7 +23,7 @@ export const useGetTransformStats = (
const { http } = useAppDependencies();
return useQuery(
- [TRANSFORM_REACT_QUERY_KEYS.TRANSFORM_STATS, transformId],
+ [TRANSFORM_REACT_QUERY_KEYS.GET_TRANSFORM_STATS, transformId],
async ({ signal }) =>
await http.get(
addInternalBasePath(`transforms/${transformId}/_stats`),
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 ee644f9dd8d32..f97eaf671fb97 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
@@ -37,7 +37,7 @@ export const useGetTransforms = () => {
const { http } = useAppDependencies();
return useQuery(
- [TRANSFORM_REACT_QUERY_KEYS.TRANSFORMS_LIST],
+ [TRANSFORM_REACT_QUERY_KEYS.GET_TRANSFORMS],
async ({ signal }) => {
const update: UseGetTransformsResponse = {
tableRows: [],
diff --git a/x-pack/plugins/transform/public/app/sections/clone_transform/clone_transform_section.tsx b/x-pack/plugins/transform/public/app/sections/clone_transform/clone_transform_section.tsx
index 2131ae616553d..04e04f4e47b81 100644
--- a/x-pack/plugins/transform/public/app/sections/clone_transform/clone_transform_section.tsx
+++ b/x-pack/plugins/transform/public/app/sections/clone_transform/clone_transform_section.tsx
@@ -23,7 +23,7 @@ import { isHttpFetchError } from '@kbn/core-http-browser';
import { APP_CREATE_TRANSFORM_CLUSTER_PRIVILEGES } from '../../../../common/constants';
import { TransformConfigUnion } from '../../../../common/types/transform';
-import { useApi } from '../../hooks/use_api';
+import { useGetTransform } from '../../hooks';
import { useDocumentationLinks } from '../../hooks/use_documentation_links';
import { useSearchItems } from '../../hooks/use_search_items';
@@ -45,8 +45,6 @@ export const CloneTransformSection: FC = ({ match, location }) => {
docTitleService.setTitle('createTransform');
}, []);
- const api = useApi();
-
const { esTransform } = useDocumentationLinks();
const transformId = match.params.transformId;
@@ -56,52 +54,55 @@ export const CloneTransformSection: FC = ({ match, location }) => {
const [isInitialized, setIsInitialized] = useState(false);
const { error: searchItemsError, searchItems, setSavedObjectId } = useSearchItems(undefined);
- const fetchTransformConfig = async () => {
+ useEffect(() => {
+ if (dataViewId === undefined) {
+ setErrorMessage(
+ i18n.translate('xpack.transform.clone.fetchErrorPromptText', {
+ defaultMessage: 'Could not fetch the Kibana data view ID.',
+ })
+ );
+ } else {
+ setSavedObjectId(dataViewId);
+ }
+ }, [dataViewId, setSavedObjectId]);
+
+ useEffect(() => {
if (searchItemsError !== undefined) {
setTransformConfig(undefined);
setErrorMessage(searchItemsError);
setIsInitialized(true);
- return;
}
+ }, [searchItemsError]);
+
+ const { data: transformConfigs, error } = useGetTransform(
+ transformId,
+ searchItemsError === undefined
+ );
- const transformConfigs = await api.getTransform(transformId);
- if (isHttpFetchError(transformConfigs)) {
+ useEffect(() => {
+ if (isHttpFetchError(error) && error.message !== errorMessage) {
setTransformConfig(undefined);
- setErrorMessage(transformConfigs.message);
+ setErrorMessage(error.message);
setIsInitialized(true);
return;
}
- try {
- if (dataViewId === undefined) {
- throw new Error(
- i18n.translate('xpack.transform.clone.fetchErrorPromptText', {
- defaultMessage: 'Could not fetch the Kibana data view ID.',
- })
- );
- }
-
- setSavedObjectId(dataViewId);
-
- setTransformConfig(overrideTransformForCloning(transformConfigs.transforms[0]));
- setErrorMessage(undefined);
- setIsInitialized(true);
- } catch (e) {
- setTransformConfig(undefined);
- if (e.message !== undefined) {
- setErrorMessage(e.message);
- } else {
- setErrorMessage(JSON.stringify(e, null, 2));
+ if (transformConfigs !== undefined) {
+ try {
+ setTransformConfig(overrideTransformForCloning(transformConfigs.transforms[0]));
+ setErrorMessage(undefined);
+ setIsInitialized(true);
+ } catch (e) {
+ setTransformConfig(undefined);
+ if (e.message !== undefined) {
+ setErrorMessage(e.message);
+ } else {
+ setErrorMessage(JSON.stringify(e, null, 2));
+ }
+ setIsInitialized(true);
}
- setIsInitialized(true);
}
- };
-
- useEffect(() => {
- fetchTransformConfig();
- // The effect should only be called once.
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, []);
+ }, [error, errorMessage, transformConfigs]);
const docsLink = (
Date: Tue, 22 Aug 2023 14:52:24 +0200
Subject: [PATCH 06/53] remove getTransformStats from useApi
---
.../transform/public/app/hooks/__mocks__/use_api.ts | 6 ------
x-pack/plugins/transform/public/app/hooks/use_api.ts | 12 ------------
2 files changed, 18 deletions(-)
diff --git a/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts b/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
index 763e754bc4aa8..f278460c637b9 100644
--- a/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
+++ b/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
@@ -20,7 +20,6 @@ import type {
PostTransformsPreviewRequestSchema,
PostTransformsPreviewResponseSchema,
} from '../../../../common/api_schemas/transforms';
-import type { GetTransformsStatsResponseSchema } from '../../../../common/api_schemas/transforms_stats';
import type {
PostTransformsUpdateRequestSchema,
PostTransformsUpdateResponseSchema,
@@ -36,11 +35,6 @@ export interface FieldHistogramRequestConfig {
}
const apiFactory = () => ({
- async getTransformStats(
- transformId: TransformId
- ): Promise {
- return Promise.resolve({ count: 0, transforms: [] });
- },
async updateTransform(
transformId: TransformId,
transformConfig: PostTransformsUpdateRequestSchema
diff --git a/x-pack/plugins/transform/public/app/hooks/use_api.ts b/x-pack/plugins/transform/public/app/hooks/use_api.ts
index edd839b447805..fab00296f73f9 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_api.ts
+++ b/x-pack/plugins/transform/public/app/hooks/use_api.ts
@@ -40,7 +40,6 @@ import type {
PostTransformsUpdateRequestSchema,
PostTransformsUpdateResponseSchema,
} from '../../../common/api_schemas/update_transforms';
-import type { GetTransformsStatsResponseSchema } from '../../../common/api_schemas/transforms_stats';
import type { TransformId } from '../../../common/types/transform';
import { addInternalBasePath } from '../../../common/constants';
import type { EsIndex } from '../../../common/types/es_index';
@@ -60,17 +59,6 @@ export const useApi = () => {
return useMemo(
() => ({
- async getTransformStats(
- transformId: TransformId
- ): Promise {
- try {
- return await http.get(addInternalBasePath(`transforms/${transformId}/_stats`), {
- version: '1',
- });
- } catch (e) {
- return e;
- }
- },
async updateTransform(
transformId: TransformId,
transformConfig: PostTransformsUpdateRequestSchema
From a2978b2ad7eab64d41b86e6ccb3e087facc5656d Mon Sep 17 00:00:00 2001
From: Walter Rafelsberger
Date: Tue, 22 Aug 2023 15:11:40 +0200
Subject: [PATCH 07/53] migrate update to use react-query
---
.../public/app/hooks/__mocks__/use_api.ts | 24 ---------
.../transform/public/app/hooks/index.ts | 1 +
.../transform/public/app/hooks/use_api.ts | 18 -------
.../public/app/hooks/use_update_transform.ts | 52 +++++++++++++++++++
.../edit_transform_update_button.tsx | 35 ++++---------
5 files changed, 64 insertions(+), 66 deletions(-)
create mode 100644 x-pack/plugins/transform/public/app/hooks/use_update_transform.ts
diff --git a/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts b/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
index f278460c637b9..4e3035ea7da6f 100644
--- a/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
+++ b/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
@@ -10,7 +10,6 @@ import type { IHttpFetchError } from '@kbn/core-http-browser';
import { KBN_FIELD_TYPES } from '@kbn/field-types';
import { DEFAULT_SAMPLER_SHARD_SIZE } from '@kbn/ml-agg-utils';
-import type { TransformId } from '../../../../common/types/transform';
import type { FieldHistogramsResponseSchema } from '../../../../common/api_schemas/field_histograms';
import type {
StopTransformsRequestSchema,
@@ -20,10 +19,6 @@ import type {
PostTransformsPreviewRequestSchema,
PostTransformsPreviewResponseSchema,
} from '../../../../common/api_schemas/transforms';
-import type {
- PostTransformsUpdateRequestSchema,
- PostTransformsUpdateResponseSchema,
-} from '../../../../common/api_schemas/update_transforms';
import type { EsIndex } from '../../../../common/types/es_index';
@@ -35,25 +30,6 @@ export interface FieldHistogramRequestConfig {
}
const apiFactory = () => ({
- async updateTransform(
- transformId: TransformId,
- transformConfig: PostTransformsUpdateRequestSchema
- ): Promise {
- return Promise.resolve({
- id: 'the-test-id',
- source: { index: ['the-index-name'], query: { match_all: {} } },
- dest: { index: 'user-the-destination-index-name' },
- frequency: '10m',
- pivot: {
- group_by: { the_group: { terms: { field: 'the-group-by-field' } } },
- aggregations: { the_agg: { value_count: { field: 'the-agg-field' } } },
- },
- description: 'the-description',
- settings: { docs_per_second: null },
- version: '8.0.0',
- create_time: 1598860879097,
- });
- },
async getTransformsPreview(
obj: PostTransformsPreviewRequestSchema
): Promise {
diff --git a/x-pack/plugins/transform/public/app/hooks/index.ts b/x-pack/plugins/transform/public/app/hooks/index.ts
index b3283da96a65a..5d44385247434 100644
--- a/x-pack/plugins/transform/public/app/hooks/index.ts
+++ b/x-pack/plugins/transform/public/app/hooks/index.ts
@@ -17,3 +17,4 @@ export { useResetTransforms } from './use_reset_transform';
export { useScheduleNowTransforms } from './use_schedule_now_transform';
export { useStartTransforms } from './use_start_transform';
export { useStopTransforms } from './use_stop_transform';
+export { useUpdateTransform } from './use_update_transform';
diff --git a/x-pack/plugins/transform/public/app/hooks/use_api.ts b/x-pack/plugins/transform/public/app/hooks/use_api.ts
index fab00296f73f9..45a2579078e7f 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_api.ts
+++ b/x-pack/plugins/transform/public/app/hooks/use_api.ts
@@ -36,11 +36,6 @@ import type {
PostTransformsPreviewRequestSchema,
PostTransformsPreviewResponseSchema,
} from '../../../common/api_schemas/transforms';
-import type {
- PostTransformsUpdateRequestSchema,
- PostTransformsUpdateResponseSchema,
-} from '../../../common/api_schemas/update_transforms';
-import type { TransformId } from '../../../common/types/transform';
import { addInternalBasePath } from '../../../common/constants';
import type { EsIndex } from '../../../common/types/es_index';
import type { EsIngestPipeline } from '../../../common/types/es_ingest_pipeline';
@@ -59,19 +54,6 @@ export const useApi = () => {
return useMemo(
() => ({
- async updateTransform(
- transformId: TransformId,
- transformConfig: PostTransformsUpdateRequestSchema
- ): Promise {
- try {
- return await http.post(addInternalBasePath(`transforms/${transformId}/_update`), {
- body: JSON.stringify(transformConfig),
- version: '1',
- });
- } catch (e) {
- return e;
- }
- },
async getTransformsPreview(
obj: PostTransformsPreviewRequestSchema
): Promise {
diff --git a/x-pack/plugins/transform/public/app/hooks/use_update_transform.ts b/x-pack/plugins/transform/public/app/hooks/use_update_transform.ts
new file mode 100644
index 0000000000000..ec1c572a66b86
--- /dev/null
+++ b/x-pack/plugins/transform/public/app/hooks/use_update_transform.ts
@@ -0,0 +1,52 @@
+/*
+ * 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 { useMutation } from '@tanstack/react-query';
+
+import { i18n } from '@kbn/i18n';
+
+import type {
+ PostTransformsUpdateRequestSchema,
+ PostTransformsUpdateResponseSchema,
+} from '../../../common/api_schemas/update_transforms';
+import { addInternalBasePath } from '../../../common/constants';
+import type { TransformId } from '../../../common/types/transform';
+
+import { useAppDependencies, useToastNotifications } from '../app_dependencies';
+import { useRefreshTransformList } from '../common';
+
+export const useUpdateTransform = (
+ transformId: TransformId,
+ transformConfig: PostTransformsUpdateRequestSchema
+) => {
+ const { http } = useAppDependencies();
+ const refreshTransformList = useRefreshTransformList();
+ const toastNotifications = useToastNotifications();
+
+ const mutation = useMutation({
+ mutationFn: () => {
+ return http.post(
+ addInternalBasePath(`transforms/${transformId}/_update`),
+ {
+ body: JSON.stringify(transformConfig),
+ version: '1',
+ }
+ );
+ },
+ onSuccess: () => {
+ toastNotifications.addSuccess(
+ i18n.translate('xpack.transform.transformList.editTransformSuccessMessage', {
+ defaultMessage: 'Transform {transformId} updated.',
+ values: { transformId },
+ })
+ );
+ refreshTransformList();
+ },
+ });
+
+ return mutation;
+};
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/edit_transform_flyout/edit_transform_update_button.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/edit_transform_flyout/edit_transform_update_button.tsx
index 59bacf76fd39f..7b00ce29bf8f3 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/edit_transform_flyout/edit_transform_update_button.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/edit_transform_flyout/edit_transform_update_button.tsx
@@ -11,12 +11,9 @@ import { EuiButton } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { isPostTransformsUpdateResponseSchema } from '../../../../../../common/api_schemas/type_guards';
import { getErrorMessage } from '../../../../../../common/utils/errors';
-import { useRefreshTransformList } from '../../../../common';
-import { useToastNotifications } from '../../../../app_dependencies';
-import { useApi } from '../../../../hooks/use_api';
+import { useUpdateTransform } from '../../../../hooks';
import { useEditTransformFlyout } from './use_edit_transform_flyout';
@@ -25,34 +22,24 @@ interface EditTransformUpdateButtonProps {
}
export const EditTransformUpdateButton: FC = ({ closeFlyout }) => {
- const api = useApi();
- const refreshTransformList = useRefreshTransformList();
- const toastNotifications = useToastNotifications();
-
const requestConfig = useEditTransformFlyout('requestConfig');
const isUpdateButtonDisabled = useEditTransformFlyout('isUpdateButtonDisabled');
const config = useEditTransformFlyout('config');
const { apiError } = useEditTransformFlyout('actions');
+ const { mutate: updateTransfrom } = useUpdateTransform(config.id, requestConfig);
+
async function submitFormHandler() {
apiError(undefined);
- const transformId = config.id;
-
- const resp = await api.updateTransform(transformId, requestConfig);
-
- if (!isPostTransformsUpdateResponseSchema(resp)) {
- apiError(getErrorMessage(resp));
- return;
- }
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.transformList.editTransformSuccessMessage', {
- defaultMessage: 'Transform {transformId} updated.',
- values: { transformId },
- })
- );
- closeFlyout();
- refreshTransformList();
+ updateTransfrom(undefined, {
+ onError: (error) => {
+ apiError(getErrorMessage(error));
+ },
+ onSuccess: () => {
+ closeFlyout();
+ },
+ });
}
return (
From 1f55030b999ac354afd16c1dec9884f96c5c9d77 Mon Sep 17 00:00:00 2001
From: Walter Rafelsberger
Date: Tue, 22 Aug 2023 16:43:54 +0200
Subject: [PATCH 08/53] migrate preview to use react-query
---
x-pack/plugins/transform/common/constants.ts | 1 +
.../public/app/hooks/__mocks__/use_api.ts | 26 ---
.../transform/public/app/hooks/index.ts | 1 +
.../transform/public/app/hooks/use_api.ts | 16 --
.../public/app/hooks/use_get_transform.tsx | 7 -
.../app/hooks/use_get_transforms_preview.ts | 39 ++++
.../app/hooks/use_transform_config_data.ts | 167 +++++++++---------
.../step_define/step_define_form.test.tsx | 18 +-
.../step_define/step_define_summary.test.tsx | 10 +-
.../step_details/step_details_form.tsx | 92 +++++-----
10 files changed, 194 insertions(+), 183 deletions(-)
create mode 100644 x-pack/plugins/transform/public/app/hooks/use_get_transforms_preview.ts
diff --git a/x-pack/plugins/transform/common/constants.ts b/x-pack/plugins/transform/common/constants.ts
index b6518c1fa241d..367459e566019 100644
--- a/x-pack/plugins/transform/common/constants.ts
+++ b/x-pack/plugins/transform/common/constants.ts
@@ -38,6 +38,7 @@ export const TRANSFORM_REACT_QUERY_KEYS = {
GET_TRANSFORM_AUDIT_MESSAGES: 'transform.get_transform_audit_messages',
GET_TRANSFORM_STATS: 'transform.get_transform_stats',
GET_TRANSFORMS: 'transform.get_transforms',
+ GET_TRANSFORMS_PREVIEW: 'transform.get_transforms_preview',
} as const;
// In order to create a transform, the API requires the following privileges:
diff --git a/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts b/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
index 4e3035ea7da6f..249198b2e600f 100644
--- a/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
+++ b/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
@@ -15,10 +15,6 @@ import type {
StopTransformsRequestSchema,
StopTransformsResponseSchema,
} from '../../../../common/api_schemas/stop_transforms';
-import type {
- PostTransformsPreviewRequestSchema,
- PostTransformsPreviewResponseSchema,
-} from '../../../../common/api_schemas/transforms';
import type { EsIndex } from '../../../../common/types/es_index';
@@ -30,28 +26,6 @@ export interface FieldHistogramRequestConfig {
}
const apiFactory = () => ({
- async getTransformsPreview(
- obj: PostTransformsPreviewRequestSchema
- ): Promise {
- return Promise.resolve({
- generated_dest_index: {
- mappings: {
- _meta: {
- _transform: {
- transform: 'the-transform',
- version: { create: 'the-version' },
- creation_date_in_millis: 0,
- },
- created_by: 'mock',
- },
- properties: {},
- },
- settings: { index: { number_of_shards: '1', auto_expand_replicas: '0-1' } },
- aliases: {},
- },
- preview: [],
- });
- },
async stopTransforms(
transformsInfo: StopTransformsRequestSchema
): Promise {
diff --git a/x-pack/plugins/transform/public/app/hooks/index.ts b/x-pack/plugins/transform/public/app/hooks/index.ts
index 5d44385247434..71789989ba5ff 100644
--- a/x-pack/plugins/transform/public/app/hooks/index.ts
+++ b/x-pack/plugins/transform/public/app/hooks/index.ts
@@ -11,6 +11,7 @@ export { useDocumentationLinks } from './use_documentation_links';
export { useGetTransformAuditMessages } from './use_get_transform_audit_messages';
export { useGetTransform } from './use_get_transform';
export { useGetTransforms } from './use_get_transforms';
+export { useGetTransformsPreview } from './use_get_transforms_preview';
export { useGetTransformStats } from './use_get_transform_stats';
export { useDeleteTransforms, useDeleteIndexAndTargetIndex } from './use_delete_transform';
export { useResetTransforms } from './use_reset_transform';
diff --git a/x-pack/plugins/transform/public/app/hooks/use_api.ts b/x-pack/plugins/transform/public/app/hooks/use_api.ts
index 45a2579078e7f..e6fd8542f9ba6 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_api.ts
+++ b/x-pack/plugins/transform/public/app/hooks/use_api.ts
@@ -32,10 +32,6 @@ import type {
ScheduleNowTransformsRequestSchema,
ScheduleNowTransformsResponseSchema,
} from '../../../common/api_schemas/schedule_now_transforms';
-import type {
- PostTransformsPreviewRequestSchema,
- PostTransformsPreviewResponseSchema,
-} from '../../../common/api_schemas/transforms';
import { addInternalBasePath } from '../../../common/constants';
import type { EsIndex } from '../../../common/types/es_index';
import type { EsIngestPipeline } from '../../../common/types/es_ingest_pipeline';
@@ -54,18 +50,6 @@ export const useApi = () => {
return useMemo(
() => ({
- async getTransformsPreview(
- obj: PostTransformsPreviewRequestSchema
- ): Promise {
- try {
- return await http.post(addInternalBasePath(`transforms/_preview`), {
- body: JSON.stringify(obj),
- version: '1',
- });
- } catch (e) {
- return e;
- }
- },
async reauthorizeTransforms(
reqBody: ReauthorizeTransformsRequestSchema
): Promise {
diff --git a/x-pack/plugins/transform/public/app/hooks/use_get_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_get_transform.tsx
index e3038706758a4..4cccc76295d52 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_get_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_get_transform.tsx
@@ -5,13 +5,6 @@
* 2.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 { useQuery } from '@tanstack/react-query';
import type { IHttpFetchError } from '@kbn/core-http-browser';
diff --git a/x-pack/plugins/transform/public/app/hooks/use_get_transforms_preview.ts b/x-pack/plugins/transform/public/app/hooks/use_get_transforms_preview.ts
new file mode 100644
index 0000000000000..096c966e53311
--- /dev/null
+++ b/x-pack/plugins/transform/public/app/hooks/use_get_transforms_preview.ts
@@ -0,0 +1,39 @@
+/*
+ * 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 { useQuery } from '@tanstack/react-query';
+
+import type { IHttpFetchError } from '@kbn/core-http-browser';
+
+import type {
+ PostTransformsPreviewRequestSchema,
+ PostTransformsPreviewResponseSchema,
+} from '../../../common/api_schemas/transforms';
+import { addInternalBasePath, TRANSFORM_REACT_QUERY_KEYS } from '../../../common/constants';
+
+import { useAppDependencies } from '../app_dependencies';
+
+export const useGetTransformsPreview = (
+ obj: PostTransformsPreviewRequestSchema,
+ enabled?: boolean
+) => {
+ const { http } = useAppDependencies();
+
+ return useQuery(
+ [TRANSFORM_REACT_QUERY_KEYS.GET_TRANSFORMS_PREVIEW, obj],
+ async ({ signal }) =>
+ await http.post(
+ addInternalBasePath('transforms/_preview'),
+ {
+ body: JSON.stringify(obj),
+ version: '1',
+ signal,
+ }
+ ),
+ { enabled }
+ );
+};
diff --git a/x-pack/plugins/transform/public/app/hooks/use_transform_config_data.ts b/x-pack/plugins/transform/public/app/hooks/use_transform_config_data.ts
index f96a0f72194c6..0871dd7877c14 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_transform_config_data.ts
+++ b/x-pack/plugins/transform/public/app/hooks/use_transform_config_data.ts
@@ -29,14 +29,13 @@ import {
} from '@kbn/ml-data-grid';
import type { PreviewMappingsProperties } from '../../../common/api_schemas/transforms';
-import { isPostTransformsPreviewResponseSchema } from '../../../common/api_schemas/type_guards';
import { getErrorMessage } from '../../../common/utils/errors';
import { getPreviewTransformRequestBody, type TransformConfigQuery } from '../common';
import { SearchItems } from './use_search_items';
-import { useApi } from './use_api';
+import { useGetTransformsPreview } from './use_get_transforms_preview';
import { StepDefineExposedState } from '../sections/create_transform/components/step_define';
import {
isLatestPartialRequest,
@@ -111,7 +110,6 @@ export const useTransformConfigData = (
): UseIndexDataReturnType => {
const [previewMappingsProperties, setPreviewMappingsProperties] =
useState({});
- const api = useApi();
// Filters mapping properties of type `object`, which get returned for nested field parents.
const columnKeys = Object.keys(previewMappingsProperties).filter(
@@ -147,84 +145,100 @@ export const useTransformConfigData = (
tableItems,
} = dataGrid;
- const getPreviewData = async () => {
- if (!validationStatus.isValid) {
+ const previewRequest = useMemo(
+ () =>
+ getPreviewTransformRequestBody(
+ dataView,
+ query,
+ requestPayload,
+ combinedRuntimeMappings,
+ timeRangeMs
+ ),
+ [dataView, query, requestPayload, combinedRuntimeMappings, timeRangeMs]
+ );
+
+ const {
+ error: previewError,
+ data: previewData,
+ isError,
+ isLoading,
+ } = useGetTransformsPreview(previewRequest, validationStatus.isValid);
+
+ useEffect(() => {
+ if (isLoading) {
+ setErrorMessage('');
+ setNoDataMessage('');
+ setStatus(INDEX_STATUS.LOADING);
+ } else if (isError) {
+ setErrorMessage(getErrorMessage(previewError));
setTableItems([]);
setRowCountInfo({
rowCount: 0,
rowCountRelation: ES_CLIENT_TOTAL_HITS_RELATION.EQ,
});
- setNoDataMessage(validationStatus.errorMessage!);
- return;
+ setPreviewMappingsProperties({});
+ setStatus(INDEX_STATUS.ERROR);
+ } else if (!isLoading && !isError && previewData !== undefined) {
+ // To improve UI performance with a latest configuration for indices with a large number
+ // of fields, we reduce the number of available columns to those populated with values.
+
+ // 1. Flatten the returned object structure object documents to match mapping properties
+ const docs = previewData.preview.map(getFlattenedObject);
+
+ // 2. Get all field names for each returned doc and flatten it
+ // to a list of unique field names used across all docs.
+ const populatedFields = [...new Set(docs.map(Object.keys).flat(1))];
+
+ // 3. Filter mapping properties by populated fields
+ let populatedProperties: PreviewMappingsProperties = Object.entries(
+ previewData.generated_dest_index.mappings.properties
+ )
+ .filter(([key]) => populatedFields.includes(key))
+ .reduce(
+ (p, [key, value]) => ({
+ ...p,
+ [key]: value,
+ }),
+ {}
+ );
+
+ populatedProperties = getCombinedProperties(populatedProperties, docs);
+
+ setTableItems(docs);
+ setRowCountInfo({
+ rowCount: docs.length,
+ rowCountRelation: ES_CLIENT_TOTAL_HITS_RELATION.EQ,
+ });
+ setPreviewMappingsProperties(populatedProperties);
+ setStatus(INDEX_STATUS.LOADED);
+
+ if (docs.length === 0) {
+ setNoDataMessage(
+ i18n.translate('xpack.transform.pivotPreview.PivotPreviewNoDataCalloutBody', {
+ defaultMessage:
+ 'The preview request did not return any data. Please ensure the optional query returns data and that values exist for the field used by group-by and aggregation fields.',
+ })
+ );
+ } else {
+ setNoDataMessage('');
+ }
}
+ // custom comparison
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [isError, isLoading, previewData]);
- setErrorMessage('');
- setNoDataMessage('');
- setStatus(INDEX_STATUS.LOADING);
-
- const previewRequest = getPreviewTransformRequestBody(
- dataView,
- query,
- requestPayload,
- combinedRuntimeMappings,
- timeRangeMs
- );
- const resp = await api.getTransformsPreview(previewRequest);
-
- if (!isPostTransformsPreviewResponseSchema(resp)) {
- setErrorMessage(getErrorMessage(resp));
+ useEffect(() => {
+ if (!validationStatus.isValid) {
setTableItems([]);
setRowCountInfo({
rowCount: 0,
rowCountRelation: ES_CLIENT_TOTAL_HITS_RELATION.EQ,
});
- setPreviewMappingsProperties({});
- setStatus(INDEX_STATUS.ERROR);
- return;
- }
-
- // To improve UI performance with a latest configuration for indices with a large number
- // of fields, we reduce the number of available columns to those populated with values.
-
- // 1. Flatten the returned object structure object documents to match mapping properties
- const docs = resp.preview.map(getFlattenedObject);
-
- // 2. Get all field names for each returned doc and flatten it
- // to a list of unique field names used across all docs.
- const populatedFields = [...new Set(docs.map(Object.keys).flat(1))];
-
- // 3. Filter mapping properties by populated fields
- let populatedProperties: PreviewMappingsProperties = Object.entries(
- resp.generated_dest_index.mappings.properties
- )
- .filter(([key]) => populatedFields.includes(key))
- .reduce(
- (p, [key, value]) => ({
- ...p,
- [key]: value,
- }),
- {}
- );
-
- populatedProperties = getCombinedProperties(populatedProperties, docs);
-
- setTableItems(docs);
- setRowCountInfo({
- rowCount: docs.length,
- rowCountRelation: ES_CLIENT_TOTAL_HITS_RELATION.EQ,
- });
- setPreviewMappingsProperties(populatedProperties);
- setStatus(INDEX_STATUS.LOADED);
-
- if (docs.length === 0) {
- setNoDataMessage(
- i18n.translate('xpack.transform.pivotPreview.PivotPreviewNoDataCalloutBody', {
- defaultMessage:
- 'The preview request did not return any data. Please ensure the optional query returns data and that values exist for the field used by group-by and aggregation fields.',
- })
- );
+ setNoDataMessage(validationStatus.errorMessage!);
}
- };
+ // custom comparison
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [validationStatus.isValid]);
useEffect(() => {
resetPagination();
@@ -232,15 +246,6 @@ export const useTransformConfigData = (
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [JSON.stringify(query)]);
- useEffect(() => {
- getPreviewData();
- // custom comparison
- /* eslint-disable react-hooks/exhaustive-deps */
- }, [
- dataView.getIndexPattern(),
- JSON.stringify([requestPayload, query, combinedRuntimeMappings, timeRangeMs]),
- ]);
-
if (sortingColumns.length > 0) {
const sortingColumnsWithTypes = sortingColumns.map((c) => {
// Since items might contain undefined/null values, we want to accurate find the data type
@@ -291,13 +296,7 @@ export const useTransformConfigData = (
return cellValue;
};
- }, [
- pageData,
- pagination.pageIndex,
- pagination.pageSize,
- previewMappingsProperties,
- formatHumanReadableDateTimeSeconds,
- ]);
+ }, [pageData, pagination.pageIndex, pagination.pageSize, previewMappingsProperties]);
return {
...dataGrid,
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_form.test.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_form.test.tsx
index 6d5d6d0ea6fc9..3470cf5706a2e 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_form.test.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_form.test.tsx
@@ -7,6 +7,7 @@
import React from 'react';
import { render, waitFor } from '@testing-library/react';
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { I18nProvider } from '@kbn/i18n-react';
import { DatePickerContextProvider, type DatePickerDependencies } from '@kbn/ml-date-picker';
@@ -66,6 +67,7 @@ const createMockStorage = () => ({
describe('Transform: ', () => {
test('Minimal initialization', async () => {
// Arrange
+ const queryClient = new QueryClient();
const mlSharedImports = await getMlSharedImports();
const searchItems = {
@@ -87,13 +89,15 @@ describe('Transform: ', () => {
const { getByText } = render(
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
);
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_summary.test.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_summary.test.tsx
index 85cef1fb2958e..4f378d4394da0 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_summary.test.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_summary.test.tsx
@@ -7,6 +7,7 @@
import React from 'react';
import { render, waitFor } from '@testing-library/react';
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { PIVOT_SUPPORTED_AGGS } from '../../../../../../common/types/pivot_aggs';
@@ -30,6 +31,7 @@ describe('Transform: ', () => {
// Using the async/await wait()/done() pattern to avoid act() errors.
test('Minimal initialization', async () => {
// Arrange
+ const queryClient = new QueryClient();
const mlSharedImports = await getMlSharedImports();
const searchItems = {
@@ -78,9 +80,11 @@ describe('Transform: ', () => {
};
const { queryByText } = render(
-
-
-
+
+
+
+
+
);
// Act
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx
index f2c6a448943e5..9c7f20197c33b 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx
@@ -42,7 +42,11 @@ import { getErrorMessage } from '../../../../../../common/utils/errors';
import { useAppDependencies, useToastNotifications } from '../../../../app_dependencies';
import { ToastNotificationText } from '../../../../components';
-import { useDocumentationLinks, useGetTransforms } from '../../../../hooks';
+import {
+ useDocumentationLinks,
+ useGetTransforms,
+ useGetTransformsPreview,
+} from '../../../../hooks';
import { SearchItems } from '../../../../hooks/use_search_items';
import { useApi } from '../../../../hooks/use_api';
import { StepDetailsTimeField } from './step_details_time_field';
@@ -127,11 +131,11 @@ export const StepDetailsForm: FC = React.memo(
const { overlays, theme } = useAppDependencies();
const api = useApi();
- const { error, data } = useGetTransforms();
- const transformIds = data?.tableRows.map((d) => d.id) ?? [];
+ const { error: transformsError, data: transforms } = useGetTransforms();
+ const transformIds = transforms?.tableRows.map((d) => d.id) ?? [];
useEffect(() => {
- if (isHttpFetchError(error)) {
+ if (isHttpFetchError(transformsError)) {
toastNotifications.addDanger({
title: i18n.translate('xpack.transform.stepDetailsForm.errorGettingTransformList', {
defaultMessage: 'An error occurred getting the existing transform IDs:',
@@ -140,53 +144,61 @@ export const StepDetailsForm: FC = React.memo(
,
{ theme$: theme.theme$ }
),
});
}
- }, [error, overlays, theme, toastNotifications]);
+ }, [transformsError, overlays, theme, toastNotifications]);
+
+ const previewRequest = useMemo(() => {
+ const { searchQuery, previewRequest: partialPreviewRequest } = stepDefineState;
+ const transformConfigQuery = getTransformConfigQuery(searchQuery);
+ return getPreviewTransformRequestBody(
+ searchItems.dataView,
+ transformConfigQuery,
+ partialPreviewRequest,
+ stepDefineState.runtimeMappings
+ );
+ }, [searchItems.dataView, stepDefineState]);
+ const { error: transformsPreviewError, data: transformPreview } =
+ useGetTransformsPreview(previewRequest);
- // fetch existing transform IDs and indices once for form validation
useEffect(() => {
- // use an IIFE to avoid returning a Promise to useEffect.
- (async function () {
- const { searchQuery, previewRequest: partialPreviewRequest } = stepDefineState;
- const transformConfigQuery = getTransformConfigQuery(searchQuery);
- const previewRequest = getPreviewTransformRequestBody(
- searchItems.dataView,
- transformConfigQuery,
- partialPreviewRequest,
- stepDefineState.runtimeMappings
+ if (isPostTransformsPreviewResponseSchema(transformPreview)) {
+ const properties = transformPreview.generated_dest_index.mappings.properties;
+ const timeFields: string[] = Object.keys(properties).filter(
+ (col) => properties[col].type === 'date'
);
- const transformPreview = await api.getTransformsPreview(previewRequest);
-
- if (isPostTransformsPreviewResponseSchema(transformPreview)) {
- const properties = transformPreview.generated_dest_index.mappings.properties;
- const timeFields: string[] = Object.keys(properties).filter(
- (col) => properties[col].type === 'date'
- );
+ setDataViewAvailableTimeFields(timeFields);
+ setDataViewTimeField(timeFields[0]);
+ }
+ }, [transformPreview]);
- setDataViewAvailableTimeFields(timeFields);
- setDataViewTimeField(timeFields[0]);
- } else {
- toastNotifications.addDanger({
- title: i18n.translate('xpack.transform.stepDetailsForm.errorGettingTransformPreview', {
- defaultMessage: 'An error occurred fetching the transform preview',
- }),
- text: toMountPoint(
- ,
- { theme$: theme.theme$ }
- ),
- });
- }
+ useEffect(() => {
+ if (transformsPreviewError !== null) {
+ toastNotifications.addDanger({
+ title: i18n.translate('xpack.transform.stepDetailsForm.errorGettingTransformPreview', {
+ defaultMessage: 'An error occurred fetching the transform preview',
+ }),
+ text: toMountPoint(
+ ,
+ { theme$: theme.theme$ }
+ ),
+ });
+ }
+ }, [overlays, theme, toastNotifications, transformsPreviewError]);
+ // fetch existing transform IDs and indices once for form validation
+ useEffect(() => {
+ // use an IIFE to avoid returning a Promise to useEffect.
+ (async function () {
const [indices, ingestPipelines] = await Promise.all([
api.getEsIndices(),
api.getEsIngestPipelines(),
From 7d5107b2aff53dcabea8747ff89818cb5378a5cb Mon Sep 17 00:00:00 2001
From: Walter Rafelsberger
Date: Tue, 22 Aug 2023 16:52:47 +0200
Subject: [PATCH 09/53] migrate reauthorize to use react-query
---
.../transform/public/app/hooks/use_api.ts | 17 ----
.../app/hooks/use_reauthorize_transform.tsx | 92 ++++++++++---------
.../use_reauthorize_action.tsx | 2 +-
3 files changed, 51 insertions(+), 60 deletions(-)
diff --git a/x-pack/plugins/transform/public/app/hooks/use_api.ts b/x-pack/plugins/transform/public/app/hooks/use_api.ts
index e6fd8542f9ba6..b6a766ceb0752 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_api.ts
+++ b/x-pack/plugins/transform/public/app/hooks/use_api.ts
@@ -12,10 +12,6 @@ import type { IHttpFetchError } from '@kbn/core-http-browser';
import { KBN_FIELD_TYPES } from '@kbn/field-types';
import { DEFAULT_SAMPLER_SHARD_SIZE } from '@kbn/ml-agg-utils';
-import {
- ReauthorizeTransformsRequestSchema,
- ReauthorizeTransformsResponseSchema,
-} from '../../../common/api_schemas/reauthorize_transforms';
import type {
FieldHistogramsRequestSchema,
FieldHistogramsResponseSchema,
@@ -50,19 +46,6 @@ export const useApi = () => {
return useMemo(
() => ({
- async reauthorizeTransforms(
- reqBody: ReauthorizeTransformsRequestSchema
- ): Promise {
- try {
- return await http.post(addInternalBasePath(`reauthorize_transforms`), {
- body: JSON.stringify(reqBody),
- version: '1',
- });
- } catch (e) {
- return e;
- }
- },
-
async resetTransforms(
reqBody: ResetTransformsRequestSchema
): Promise {
diff --git a/x-pack/plugins/transform/public/app/hooks/use_reauthorize_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_reauthorize_transform.tsx
index 3b907aa915128..34a18acfaafe9 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_reauthorize_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_reauthorize_transform.tsx
@@ -6,32 +6,39 @@
*/
import React from 'react';
+import { useMutation } from '@tanstack/react-query';
import { i18n } from '@kbn/i18n';
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
-import type { StartTransformsRequestSchema } from '../../../common/api_schemas/start_transforms';
-import { isStartTransformsResponseSchema } from '../../../common/api_schemas/type_guards';
-
+import { addInternalBasePath } from '../../../common/constants';
import { getErrorMessage } from '../../../common/utils/errors';
+import {
+ ReauthorizeTransformsRequestSchema,
+ ReauthorizeTransformsResponseSchema,
+} from '../../../common/api_schemas/reauthorize_transforms';
import { useAppDependencies, useToastNotifications } from '../app_dependencies';
import { useRefreshTransformList } from '../common';
import { ToastNotificationText } from '../components';
-import { useApi } from './use_api';
-
export const useReauthorizeTransforms = () => {
- const { overlays, theme } = useAppDependencies();
+ const { http, overlays, theme } = useAppDependencies();
const refreshTransformList = useRefreshTransformList();
const toastNotifications = useToastNotifications();
- const api = useApi();
-
- return async (transformsInfo: StartTransformsRequestSchema) => {
- const results = await api.reauthorizeTransforms(transformsInfo);
- if (!isStartTransformsResponseSchema(results)) {
+ const mutation = useMutation({
+ mutationFn: (reqBody: ReauthorizeTransformsRequestSchema) => {
+ return http.post(
+ addInternalBasePath('reauthorize_transforms'),
+ {
+ body: JSON.stringify(reqBody),
+ version: '1',
+ }
+ );
+ },
+ onError: (error) => {
toastNotifications.addDanger({
title: i18n.translate(
'xpack.transform.stepCreateForm.reauthorizeTransformResponseSchemaErrorMessage',
@@ -40,43 +47,44 @@ export const useReauthorizeTransforms = () => {
}
),
text: toMountPoint(
- ,
+ ,
{ theme$: theme.theme$ }
),
});
- return;
- }
-
- for (const transformId in results) {
- // hasOwnProperty check to ensure only properties on object itself, and not its prototypes
- if (results.hasOwnProperty(transformId)) {
- const result = results[transformId];
- if (result.success === true) {
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.transformList.reauthorizeTransformSuccessMessage', {
- defaultMessage: 'Request to reauthorize transform {transformId} acknowledged.',
- values: { transformId },
- })
- );
- } else {
- toastNotifications.addError(new Error(JSON.stringify(result.error!.caused_by, null, 2)), {
- title: i18n.translate(
- 'xpack.transform.transformList.reauthorizeTransformErrorMessage',
- {
- defaultMessage: 'An error occurred reauthorizing the transform {transformId}',
+ },
+ onSuccess: (results) => {
+ for (const transformId in results) {
+ // hasOwnProperty check to ensure only properties on object itself, and not its prototypes
+ if (results.hasOwnProperty(transformId)) {
+ const result = results[transformId];
+ if (result.success === true) {
+ toastNotifications.addSuccess(
+ i18n.translate('xpack.transform.transformList.reauthorizeTransformSuccessMessage', {
+ defaultMessage: 'Request to reauthorize transform {transformId} acknowledged.',
values: { transformId },
+ })
+ );
+ } else {
+ toastNotifications.addError(
+ new Error(JSON.stringify(result.error!.caused_by, null, 2)),
+ {
+ title: i18n.translate(
+ 'xpack.transform.transformList.reauthorizeTransformErrorMessage',
+ {
+ defaultMessage: 'An error occurred reauthorizing the transform {transformId}',
+ values: { transformId },
+ }
+ ),
+ toastMessage: result.error!.reason,
}
- ),
- toastMessage: result.error!.reason,
- });
+ );
+ }
}
}
- }
- refreshTransformList();
- };
+ refreshTransformList();
+ },
+ });
+
+ return mutation;
};
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reauthorize/use_reauthorize_action.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reauthorize/use_reauthorize_action.tsx
index 086f5451d53be..b3c11971fb750 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reauthorize/use_reauthorize_action.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reauthorize/use_reauthorize_action.tsx
@@ -23,7 +23,7 @@ export type ReauthorizeAction = ReturnType;
export const useReauthorizeAction = (forceDisable: boolean, transformNodes: number) => {
const { canStartStopTransform } = useContext(AuthorizationContext).capabilities;
- const reauthorizeTransforms = useReauthorizeTransforms();
+ const { mutate: reauthorizeTransforms } = useReauthorizeTransforms();
const [isModalVisible, setModalVisible] = useState(false);
const [items, setItems] = useState([]);
From e7d1c0e880bbaa7be48014446e38be948b6f66d0 Mon Sep 17 00:00:00 2001
From: Walter Rafelsberger
Date: Tue, 22 Aug 2023 17:11:42 +0200
Subject: [PATCH 10/53] migrate reset to use react-query
---
.../transform/public/app/hooks/use_api.ts | 16 --
.../public/app/hooks/use_reset_transform.tsx | 140 +++++++++---------
.../action_reset/use_reset_action.tsx | 2 +-
3 files changed, 75 insertions(+), 83 deletions(-)
diff --git a/x-pack/plugins/transform/public/app/hooks/use_api.ts b/x-pack/plugins/transform/public/app/hooks/use_api.ts
index b6a766ceb0752..e64240893a7d7 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_api.ts
+++ b/x-pack/plugins/transform/public/app/hooks/use_api.ts
@@ -16,10 +16,6 @@ import type {
FieldHistogramsRequestSchema,
FieldHistogramsResponseSchema,
} from '../../../common/api_schemas/field_histograms';
-import type {
- ResetTransformsRequestSchema,
- ResetTransformsResponseSchema,
-} from '../../../common/api_schemas/reset_transforms';
import type {
StopTransformsRequestSchema,
StopTransformsResponseSchema,
@@ -46,18 +42,6 @@ export const useApi = () => {
return useMemo(
() => ({
- async resetTransforms(
- reqBody: ResetTransformsRequestSchema
- ): Promise {
- try {
- return await http.post(addInternalBasePath(`reset_transforms`), {
- body: JSON.stringify(reqBody),
- version: '1',
- });
- } catch (e) {
- return e;
- }
- },
async stopTransforms(
transformsInfo: StopTransformsRequestSchema
): Promise {
diff --git a/x-pack/plugins/transform/public/app/hooks/use_reset_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_reset_transform.tsx
index d64301ee37522..d91ddaf142306 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_reset_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_reset_transform.tsx
@@ -6,31 +6,37 @@
*/
import React from 'react';
+import { useMutation } from '@tanstack/react-query';
+
import { i18n } from '@kbn/i18n';
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
+
import type {
ResetTransformStatus,
ResetTransformsRequestSchema,
+ ResetTransformsResponseSchema,
} from '../../../common/api_schemas/reset_transforms';
-import { isResetTransformsResponseSchema } from '../../../common/api_schemas/type_guards';
+import { addInternalBasePath } from '../../../common/constants';
import { getErrorMessage } from '../../../common/utils/errors';
import { useAppDependencies, useToastNotifications } from '../app_dependencies';
import { useRefreshTransformList } from '../common';
import { ToastNotificationText } from '../components';
-import { useApi } from './use_api';
type SuccessCountField = keyof Omit;
export const useResetTransforms = () => {
- const { overlays, theme } = useAppDependencies();
+ const { http, overlays, theme } = useAppDependencies();
const refreshTransformList = useRefreshTransformList();
const toastNotifications = useToastNotifications();
- const api = useApi();
-
- return async (reqBody: ResetTransformsRequestSchema) => {
- const results = await api.resetTransforms(reqBody);
- if (!isResetTransformsResponseSchema(results)) {
+ const mutation = useMutation({
+ mutationFn: (reqBody: ResetTransformsRequestSchema) => {
+ return http.post(addInternalBasePath('reset_transforms'), {
+ body: JSON.stringify(reqBody),
+ version: '1',
+ });
+ },
+ onError: (error) => {
toastNotifications.addDanger({
title: i18n.translate('xpack.transform.transformList.resetTransformGenericErrorMessage', {
defaultMessage: 'An error occurred calling the API endpoint to reset transforms.',
@@ -40,74 +46,76 @@ export const useResetTransforms = () => {
previewTextLength={50}
overlays={overlays}
theme={theme}
- text={getErrorMessage(results)}
+ text={getErrorMessage(error)}
/>,
{ theme$: theme.theme$ }
),
});
- return;
- }
-
- const isBulk = Object.keys(results).length > 1;
- const successCount: Record = {
- transformReset: 0,
- };
- for (const transformId in results) {
- // hasOwnProperty check to ensure only properties on object itself, and not its prototypes
- if (results.hasOwnProperty(transformId)) {
- const status = results[transformId];
+ },
+ onSuccess: (results) => {
+ const isBulk = Object.keys(results).length > 1;
+ const successCount: Record = {
+ transformReset: 0,
+ };
+ for (const transformId in results) {
+ // hasOwnProperty check to ensure only properties on object itself, and not its prototypes
+ if (results.hasOwnProperty(transformId)) {
+ const status = results[transformId];
- // if we are only resetting one transform, show the success toast messages
- if (!isBulk && status.transformReset) {
- if (status.transformReset?.success) {
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.transformList.resetTransformSuccessMessage', {
- defaultMessage: 'Request to reset transform {transformId} acknowledged.',
+ // if we are only resetting one transform, show the success toast messages
+ if (!isBulk && status.transformReset) {
+ if (status.transformReset?.success) {
+ toastNotifications.addSuccess(
+ i18n.translate('xpack.transform.transformList.resetTransformSuccessMessage', {
+ defaultMessage: 'Request to reset transform {transformId} acknowledged.',
+ values: { transformId },
+ })
+ );
+ }
+ } else {
+ (Object.keys(successCount) as SuccessCountField[]).forEach((key) => {
+ if (status[key]?.success) {
+ successCount[key] = successCount[key] + 1;
+ }
+ });
+ }
+ if (status.transformReset?.error) {
+ const error = status.transformReset.error.reason;
+ toastNotifications.addDanger({
+ title: i18n.translate('xpack.transform.transformList.resetTransformErrorMessage', {
+ defaultMessage: 'An error occurred resetting the transform {transformId}',
values: { transformId },
- })
- );
+ }),
+ text: toMountPoint(
+ ,
+ { theme$: theme.theme$ }
+ ),
+ });
}
- } else {
- (Object.keys(successCount) as SuccessCountField[]).forEach((key) => {
- if (status[key]?.success) {
- successCount[key] = successCount[key] + 1;
- }
- });
- }
- if (status.transformReset?.error) {
- const error = status.transformReset.error.reason;
- toastNotifications.addDanger({
- title: i18n.translate('xpack.transform.transformList.resetTransformErrorMessage', {
- defaultMessage: 'An error occurred resetting the transform {transformId}',
- values: { transformId },
- }),
- text: toMountPoint(
- ,
- { theme$: theme.theme$ }
- ),
- });
}
}
- }
- // if we are deleting multiple transforms, combine the success messages
- if (isBulk) {
- if (successCount.transformReset > 0) {
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.transformList.bulkResetTransformSuccessMessage', {
- defaultMessage:
- 'Successfully reset {count} {count, plural, one {transform} other {transforms}}.',
- values: { count: successCount.transformReset },
- })
- );
+ // if we are deleting multiple transforms, combine the success messages
+ if (isBulk) {
+ if (successCount.transformReset > 0) {
+ toastNotifications.addSuccess(
+ i18n.translate('xpack.transform.transformList.bulkResetTransformSuccessMessage', {
+ defaultMessage:
+ 'Successfully reset {count} {count, plural, one {transform} other {transforms}}.',
+ values: { count: successCount.transformReset },
+ })
+ );
+ }
}
- }
- refreshTransformList();
- };
+ refreshTransformList();
+ },
+ });
+
+ return mutation;
};
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reset/use_reset_action.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reset/use_reset_action.tsx
index 70164bc22a63c..45dcf5b4ba3da 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reset/use_reset_action.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reset/use_reset_action.tsx
@@ -19,7 +19,7 @@ export type ResetAction = ReturnType;
export const useResetAction = (forceDisable: boolean) => {
const { canResetTransform } = useContext(AuthorizationContext).capabilities;
- const resetTransforms = useResetTransforms();
+ const { mutate: resetTransforms } = useResetTransforms();
const [isModalVisible, setModalVisible] = useState(false);
const [items, setItems] = useState([]);
From 9c47fe6ffdc8ee2c731013175eb664b39273e794 Mon Sep 17 00:00:00 2001
From: Walter Rafelsberger
Date: Tue, 22 Aug 2023 17:18:15 +0200
Subject: [PATCH 11/53] migrate stop to use react-query
---
.../public/app/hooks/__mocks__/use_api.ts | 9 ---
.../transform/public/app/hooks/use_api.ts | 16 ----
.../public/app/hooks/use_start_transform.tsx | 2 +-
.../public/app/hooks/use_stop_transform.tsx | 80 ++++++++++---------
.../action_stop/use_stop_action.tsx | 2 +-
5 files changed, 43 insertions(+), 66 deletions(-)
diff --git a/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts b/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
index 249198b2e600f..69e056ffdfb6c 100644
--- a/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
+++ b/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
@@ -11,10 +11,6 @@ import { KBN_FIELD_TYPES } from '@kbn/field-types';
import { DEFAULT_SAMPLER_SHARD_SIZE } from '@kbn/ml-agg-utils';
import type { FieldHistogramsResponseSchema } from '../../../../common/api_schemas/field_histograms';
-import type {
- StopTransformsRequestSchema,
- StopTransformsResponseSchema,
-} from '../../../../common/api_schemas/stop_transforms';
import type { EsIndex } from '../../../../common/types/es_index';
@@ -26,11 +22,6 @@ export interface FieldHistogramRequestConfig {
}
const apiFactory = () => ({
- async stopTransforms(
- transformsInfo: StopTransformsRequestSchema
- ): Promise {
- return Promise.resolve({});
- },
async getEsIndices(): Promise {
return Promise.resolve([]);
},
diff --git a/x-pack/plugins/transform/public/app/hooks/use_api.ts b/x-pack/plugins/transform/public/app/hooks/use_api.ts
index e64240893a7d7..5b741e50b39e5 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_api.ts
+++ b/x-pack/plugins/transform/public/app/hooks/use_api.ts
@@ -16,10 +16,6 @@ import type {
FieldHistogramsRequestSchema,
FieldHistogramsResponseSchema,
} from '../../../common/api_schemas/field_histograms';
-import type {
- StopTransformsRequestSchema,
- StopTransformsResponseSchema,
-} from '../../../common/api_schemas/stop_transforms';
import type {
ScheduleNowTransformsRequestSchema,
ScheduleNowTransformsResponseSchema,
@@ -42,18 +38,6 @@ export const useApi = () => {
return useMemo(
() => ({
- async stopTransforms(
- transformsInfo: StopTransformsRequestSchema
- ): Promise {
- try {
- return await http.post(addInternalBasePath(`stop_transforms`), {
- body: JSON.stringify(transformsInfo),
- version: '1',
- });
- } catch (e) {
- return e;
- }
- },
async scheduleNowTransforms(
transformsInfo: ScheduleNowTransformsRequestSchema
): Promise {
diff --git a/x-pack/plugins/transform/public/app/hooks/use_start_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_start_transform.tsx
index 84dc80ef64e47..2f0e7a28e1e28 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_start_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_start_transform.tsx
@@ -31,7 +31,7 @@ export const useStartTransforms = () => {
const mutation = useMutation({
mutationFn: (reqBody: StartTransformsRequestSchema) => {
- return http.post(addInternalBasePath(`start_transforms`), {
+ return http.post(addInternalBasePath('start_transforms'), {
body: JSON.stringify(reqBody),
version: '1',
});
diff --git a/x-pack/plugins/transform/public/app/hooks/use_stop_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_stop_transform.tsx
index d89ee1a0118f1..004ee40389200 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_stop_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_stop_transform.tsx
@@ -6,32 +6,36 @@
*/
import React from 'react';
+import { useMutation } from '@tanstack/react-query';
import { i18n } from '@kbn/i18n';
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
-import type { StopTransformsRequestSchema } from '../../../common/api_schemas/stop_transforms';
-import { isStopTransformsResponseSchema } from '../../../common/api_schemas/type_guards';
-
+import { addInternalBasePath } from '../../../common/constants';
+import type {
+ StopTransformsRequestSchema,
+ StopTransformsResponseSchema,
+} from '../../../common/api_schemas/stop_transforms';
import { getErrorMessage } from '../../../common/utils/errors';
import { useAppDependencies, useToastNotifications } from '../app_dependencies';
import { useRefreshTransformList } from '../common';
import { ToastNotificationText } from '../components';
-import { useApi } from './use_api';
-
export const useStopTransforms = () => {
- const { overlays, theme } = useAppDependencies();
+ const { http, overlays, theme } = useAppDependencies();
const refreshTransformList = useRefreshTransformList();
const toastNotifications = useToastNotifications();
- const api = useApi();
- return async (transformsInfo: StopTransformsRequestSchema) => {
- const results = await api.stopTransforms(transformsInfo);
-
- if (!isStopTransformsResponseSchema(results)) {
+ const mutation = useMutation({
+ mutationFn: (reqBody: StopTransformsRequestSchema) => {
+ return http.post(addInternalBasePath('stop_transforms'), {
+ body: JSON.stringify(reqBody),
+ version: '1',
+ });
+ },
+ onError: (error) => {
toastNotifications.addDanger({
title: i18n.translate(
'xpack.transform.transformList.stopTransformResponseSchemaErrorMessage',
@@ -40,38 +44,36 @@ export const useStopTransforms = () => {
}
),
text: toMountPoint(
- ,
+ ,
{ theme$: theme.theme$ }
),
});
- return;
- }
-
- for (const transformId in results) {
- // hasOwnProperty check to ensure only properties on object itself, and not its prototypes
- if (results.hasOwnProperty(transformId)) {
- if (results[transformId].success === true) {
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.transformList.stopTransformSuccessMessage', {
- defaultMessage: 'Request to stop data frame transform {transformId} acknowledged.',
- values: { transformId },
- })
- );
- } else {
- toastNotifications.addDanger(
- i18n.translate('xpack.transform.transformList.stopTransformErrorMessage', {
- defaultMessage: 'An error occurred stopping the data frame transform {transformId}',
- values: { transformId },
- })
- );
+ },
+ onSuccess: (results) => {
+ for (const transformId in results) {
+ // hasOwnProperty check to ensure only properties on object itself, and not its prototypes
+ if (results.hasOwnProperty(transformId)) {
+ if (results[transformId].success === true) {
+ toastNotifications.addSuccess(
+ i18n.translate('xpack.transform.transformList.stopTransformSuccessMessage', {
+ defaultMessage: 'Request to stop data frame transform {transformId} acknowledged.',
+ values: { transformId },
+ })
+ );
+ } else {
+ toastNotifications.addDanger(
+ i18n.translate('xpack.transform.transformList.stopTransformErrorMessage', {
+ defaultMessage: 'An error occurred stopping the data frame transform {transformId}',
+ values: { transformId },
+ })
+ );
+ }
}
}
- }
- refreshTransformList();
- };
+ refreshTransformList();
+ },
+ });
+
+ return mutation;
};
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/use_stop_action.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/use_stop_action.tsx
index ac53ee83f6f65..e09d5cc4888d0 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/use_stop_action.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/use_stop_action.tsx
@@ -18,7 +18,7 @@ export type StopAction = ReturnType;
export const useStopAction = (forceDisable: boolean) => {
const { canStartStopTransform } = useContext(AuthorizationContext).capabilities;
- const stopTransforms = useStopTransforms();
+ const { mutate: stopTransforms } = useStopTransforms();
const [isModalVisible, setModalVisible] = useState(false);
const [items, setItems] = useState([]);
From cb904c056f9c73b8c1e7a05eb047a4284b3c6687 Mon Sep 17 00:00:00 2001
From: Walter Rafelsberger
Date: Tue, 22 Aug 2023 17:23:58 +0200
Subject: [PATCH 12/53] migrate schedule now to use react-query
---
.../transform/public/app/hooks/use_api.ts | 16 ----
.../app/hooks/use_schedule_now_transform.tsx | 95 ++++++++++---------
.../public/app/hooks/use_start_transform.tsx | 2 -
.../use_schedule_now_action.tsx | 2 +-
4 files changed, 52 insertions(+), 63 deletions(-)
diff --git a/x-pack/plugins/transform/public/app/hooks/use_api.ts b/x-pack/plugins/transform/public/app/hooks/use_api.ts
index 5b741e50b39e5..6956d7fa7b084 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_api.ts
+++ b/x-pack/plugins/transform/public/app/hooks/use_api.ts
@@ -16,10 +16,6 @@ import type {
FieldHistogramsRequestSchema,
FieldHistogramsResponseSchema,
} from '../../../common/api_schemas/field_histograms';
-import type {
- ScheduleNowTransformsRequestSchema,
- ScheduleNowTransformsResponseSchema,
-} from '../../../common/api_schemas/schedule_now_transforms';
import { addInternalBasePath } from '../../../common/constants';
import type { EsIndex } from '../../../common/types/es_index';
import type { EsIngestPipeline } from '../../../common/types/es_ingest_pipeline';
@@ -38,18 +34,6 @@ export const useApi = () => {
return useMemo(
() => ({
- async scheduleNowTransforms(
- transformsInfo: ScheduleNowTransformsRequestSchema
- ): Promise {
- try {
- return await http.post(addInternalBasePath(`schedule_now_transforms`), {
- body: JSON.stringify(transformsInfo),
- version: '1',
- });
- } catch (e) {
- return e;
- }
- },
async getEsIndices(): Promise {
try {
return await http.get(`/api/index_management/indices`, { version: '1' });
diff --git a/x-pack/plugins/transform/public/app/hooks/use_schedule_now_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_schedule_now_transform.tsx
index b0a15f1635c44..398bd42629167 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_schedule_now_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_schedule_now_transform.tsx
@@ -6,32 +6,38 @@
*/
import React from 'react';
+import { useMutation } from '@tanstack/react-query';
import { i18n } from '@kbn/i18n';
-
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
-import type { ScheduleNowTransformsRequestSchema } from '../../../common/api_schemas/schedule_now_transforms';
-import { isScheduleNowTransformsResponseSchema } from '../../../common/api_schemas/type_guards';
-
+import { addInternalBasePath } from '../../../common/constants';
+import type {
+ ScheduleNowTransformsRequestSchema,
+ ScheduleNowTransformsResponseSchema,
+} from '../../../common/api_schemas/schedule_now_transforms';
import { getErrorMessage } from '../../../common/utils/errors';
import { useAppDependencies, useToastNotifications } from '../app_dependencies';
import { useRefreshTransformList } from '../common';
import { ToastNotificationText } from '../components';
-import { useApi } from './use_api';
-
export const useScheduleNowTransforms = () => {
- const { overlays, theme } = useAppDependencies();
+ const { http, overlays, theme } = useAppDependencies();
const refreshTransformList = useRefreshTransformList();
const toastNotifications = useToastNotifications();
- const api = useApi();
- return async (transformsInfo: ScheduleNowTransformsRequestSchema) => {
- const results = await api.scheduleNowTransforms(transformsInfo);
-
- if (!isScheduleNowTransformsResponseSchema(results)) {
+ const mutation = useMutation({
+ mutationFn: (reqBody: ScheduleNowTransformsRequestSchema) => {
+ return http.post(
+ addInternalBasePath('schedule_now_transforms'),
+ {
+ body: JSON.stringify(reqBody),
+ version: '1',
+ }
+ );
+ },
+ onError: (error) => {
toastNotifications.addDanger({
title: i18n.translate(
'xpack.transform.stepCreateForm.scheduleNowTransformResponseSchemaErrorMessage',
@@ -41,45 +47,46 @@ export const useScheduleNowTransforms = () => {
}
),
text: toMountPoint(
- ,
+ ,
{ theme$: theme.theme$ }
),
});
- return;
- }
-
- for (const transformId in results) {
- // hasOwnProperty check to ensure only properties on object itself, and not its prototypes
- if (results.hasOwnProperty(transformId)) {
- const result = results[transformId];
- if (result.success === true) {
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.transformList.scheduleNowTransformSuccessMessage', {
- defaultMessage:
- 'Request to schedule transform {transformId} to process data instantly acknowledged.',
- values: { transformId },
- })
- );
- } else {
- toastNotifications.addError(new Error(JSON.stringify(result.error!.caused_by, null, 2)), {
- title: i18n.translate(
- 'xpack.transform.transformList.scheduleNowTransformErrorMessage',
- {
+ },
+ onSuccess: (results) => {
+ for (const transformId in results) {
+ // hasOwnProperty check to ensure only properties on object itself, and not its prototypes
+ if (results.hasOwnProperty(transformId)) {
+ const result = results[transformId];
+ if (result.success === true) {
+ toastNotifications.addSuccess(
+ i18n.translate('xpack.transform.transformList.scheduleNowTransformSuccessMessage', {
defaultMessage:
- 'An error occurred scheduling transform {transformId} to process data instantly.',
+ 'Request to schedule transform {transformId} to process data instantly acknowledged.',
values: { transformId },
+ })
+ );
+ } else {
+ toastNotifications.addError(
+ new Error(JSON.stringify(result.error!.caused_by, null, 2)),
+ {
+ title: i18n.translate(
+ 'xpack.transform.transformList.scheduleNowTransformErrorMessage',
+ {
+ defaultMessage:
+ 'An error occurred scheduling transform {transformId} to process data instantly.',
+ values: { transformId },
+ }
+ ),
+ toastMessage: result.error!.reason,
}
- ),
- toastMessage: result.error!.reason,
- });
+ );
+ }
}
}
- }
- refreshTransformList();
- };
+ refreshTransformList();
+ },
+ });
+
+ return mutation;
};
diff --git a/x-pack/plugins/transform/public/app/hooks/use_start_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_start_transform.tsx
index 2f0e7a28e1e28..65defb8a5dbee 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_start_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_start_transform.tsx
@@ -9,7 +9,6 @@ import React from 'react';
import { useMutation } from '@tanstack/react-query';
import { i18n } from '@kbn/i18n';
-
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
import { addInternalBasePath } from '../../../common/constants';
@@ -17,7 +16,6 @@ import type {
StartTransformsRequestSchema,
StartTransformsResponseSchema,
} from '../../../common/api_schemas/start_transforms';
-
import { getErrorMessage } from '../../../common/utils/errors';
import { useAppDependencies, useToastNotifications } from '../app_dependencies';
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_schedule_now/use_schedule_now_action.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_schedule_now/use_schedule_now_action.tsx
index dda70deb225a6..1d9fb7417dc04 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_schedule_now/use_schedule_now_action.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_schedule_now/use_schedule_now_action.tsx
@@ -23,7 +23,7 @@ export type ScheduleNowAction = ReturnType;
export const useScheduleNowAction = (forceDisable: boolean, transformNodes: number) => {
const { canScheduleNowTransform } = useContext(AuthorizationContext).capabilities;
- const scheduleNowTransforms = useScheduleNowTransforms();
+ const { mutate: scheduleNowTransforms } = useScheduleNowTransforms();
const action: TransformListAction = useMemo(
() => ({
From 1526d624ea73433d7c5abb0caeedbf848742c408 Mon Sep 17 00:00:00 2001
From: Walter Rafelsberger
Date: Tue, 22 Aug 2023 18:29:16 +0200
Subject: [PATCH 13/53] migrate more to react-query
---
x-pack/plugins/transform/common/constants.ts | 5 +-
.../public/app/hooks/__mocks__/use_api.ts | 5 -
.../transform/public/app/hooks/index.ts | 3 +
.../transform/public/app/hooks/use_api.ts | 16 --
.../app/hooks/use_get_data_view_titles.ts | 23 +++
.../public/app/hooks/use_get_es_indices.ts | 28 ++++
.../app/hooks/use_get_es_ingest_pipelines.ts | 28 ++++
.../public/app/hooks/use_get_transform.tsx | 13 +-
.../hooks/use_get_transform_audit_messages.ts | 4 +-
.../app/hooks/use_get_transform_stats.ts | 4 +-
.../app/hooks/use_get_transforms_preview.ts | 15 +-
.../components/authorization_provider.tsx | 9 +-
.../step_details/step_details_form.tsx | 141 +++++++++---------
.../edit_transform_ingest_pipeline.tsx | 37 +----
14 files changed, 178 insertions(+), 153 deletions(-)
create mode 100644 x-pack/plugins/transform/public/app/hooks/use_get_data_view_titles.ts
create mode 100644 x-pack/plugins/transform/public/app/hooks/use_get_es_indices.ts
create mode 100644 x-pack/plugins/transform/public/app/hooks/use_get_es_ingest_pipelines.ts
diff --git a/x-pack/plugins/transform/common/constants.ts b/x-pack/plugins/transform/common/constants.ts
index 367459e566019..19bf3512d40d7 100644
--- a/x-pack/plugins/transform/common/constants.ts
+++ b/x-pack/plugins/transform/common/constants.ts
@@ -33,7 +33,10 @@ export const addInternalBasePath = (uri: string): string => `${INTERNAL_API_BASE
export const addExternalBasePath = (uri: string): string => `${EXTERNAL_API_BASE_PATH}${uri}`;
export const TRANSFORM_REACT_QUERY_KEYS = {
- PRIVILEGES: 'transform.privileges',
+ GET_DATA_VIEW_TITLES: 'transform.get_data_view_titles',
+ GET_ES_INDICES: 'transform.get_es_indices',
+ GET_ES_INGEST_PIPELINES: 'transform.get_es_ingest_pipelines',
+ GET_PRIVILEGES: 'transform.get_privileges',
GET_TRANSFORM: 'transform.get_transform',
GET_TRANSFORM_AUDIT_MESSAGES: 'transform.get_transform_audit_messages',
GET_TRANSFORM_STATS: 'transform.get_transform_stats',
diff --git a/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts b/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
index 69e056ffdfb6c..1bcd2e8cd0506 100644
--- a/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
+++ b/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
@@ -12,8 +12,6 @@ import { DEFAULT_SAMPLER_SHARD_SIZE } from '@kbn/ml-agg-utils';
import type { FieldHistogramsResponseSchema } from '../../../../common/api_schemas/field_histograms';
-import type { EsIndex } from '../../../../common/types/es_index';
-
import type { SavedSearchQuery } from '../use_search_items';
export interface FieldHistogramRequestConfig {
@@ -22,9 +20,6 @@ export interface FieldHistogramRequestConfig {
}
const apiFactory = () => ({
- async getEsIndices(): Promise {
- return Promise.resolve([]);
- },
async getHistogramsForFields(
dataViewTitle: string,
fields: FieldHistogramRequestConfig[],
diff --git a/x-pack/plugins/transform/public/app/hooks/index.ts b/x-pack/plugins/transform/public/app/hooks/index.ts
index 71789989ba5ff..03a90d3b89042 100644
--- a/x-pack/plugins/transform/public/app/hooks/index.ts
+++ b/x-pack/plugins/transform/public/app/hooks/index.ts
@@ -8,6 +8,9 @@
export { useApi } from './use_api';
export { useCreateTransform } from './use_create_transform';
export { useDocumentationLinks } from './use_documentation_links';
+export { useGetDataViewTitles } from './use_get_data_view_titles';
+export { useGetEsIndices } from './use_get_es_indices';
+export { useGetEsIngestPipelines } from './use_get_es_ingest_pipelines';
export { useGetTransformAuditMessages } from './use_get_transform_audit_messages';
export { useGetTransform } from './use_get_transform';
export { useGetTransforms } from './use_get_transforms';
diff --git a/x-pack/plugins/transform/public/app/hooks/use_api.ts b/x-pack/plugins/transform/public/app/hooks/use_api.ts
index 6956d7fa7b084..f50af871368f1 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_api.ts
+++ b/x-pack/plugins/transform/public/app/hooks/use_api.ts
@@ -17,8 +17,6 @@ import type {
FieldHistogramsResponseSchema,
} from '../../../common/api_schemas/field_histograms';
import { addInternalBasePath } from '../../../common/constants';
-import type { EsIndex } from '../../../common/types/es_index';
-import type { EsIngestPipeline } from '../../../common/types/es_ingest_pipeline';
import { useAppDependencies } from '../app_dependencies';
@@ -34,20 +32,6 @@ export const useApi = () => {
return useMemo(
() => ({
- async getEsIndices(): Promise {
- try {
- return await http.get(`/api/index_management/indices`, { version: '1' });
- } catch (e) {
- return e;
- }
- },
- async getEsIngestPipelines(): Promise {
- try {
- return await http.get('/api/ingest_pipelines', { version: '1' });
- } catch (e) {
- return e;
- }
- },
async getHistogramsForFields(
dataViewTitle: string,
fields: FieldHistogramRequestConfig[],
diff --git a/x-pack/plugins/transform/public/app/hooks/use_get_data_view_titles.ts b/x-pack/plugins/transform/public/app/hooks/use_get_data_view_titles.ts
new file mode 100644
index 0000000000000..449ac30b9f513
--- /dev/null
+++ b/x-pack/plugins/transform/public/app/hooks/use_get_data_view_titles.ts
@@ -0,0 +1,23 @@
+/*
+ * 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 { useQuery } from '@tanstack/react-query';
+
+import type { IHttpFetchError } from '@kbn/core-http-browser';
+
+import { TRANSFORM_REACT_QUERY_KEYS } from '../../../common/constants';
+
+import { useAppDependencies } from '../app_dependencies';
+
+export const useGetDataViewTitles = () => {
+ const { data } = useAppDependencies();
+
+ return useQuery(
+ [TRANSFORM_REACT_QUERY_KEYS.GET_DATA_VIEW_TITLES],
+ () => data.dataViews.getTitles()
+ );
+};
diff --git a/x-pack/plugins/transform/public/app/hooks/use_get_es_indices.ts b/x-pack/plugins/transform/public/app/hooks/use_get_es_indices.ts
new file mode 100644
index 0000000000000..7da50c155d1be
--- /dev/null
+++ b/x-pack/plugins/transform/public/app/hooks/use_get_es_indices.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 { useQuery } from '@tanstack/react-query';
+
+import type { IHttpFetchError } from '@kbn/core-http-browser';
+
+import { TRANSFORM_REACT_QUERY_KEYS } from '../../../common/constants';
+import type { EsIndex } from '../../../common/types/es_index';
+
+import { useAppDependencies } from '../app_dependencies';
+
+export const useGetEsIndices = () => {
+ const { http } = useAppDependencies();
+
+ return useQuery(
+ [TRANSFORM_REACT_QUERY_KEYS.GET_ES_INDICES],
+ ({ signal }) =>
+ http.get('/api/index_management/indices', {
+ version: '1',
+ signal,
+ })
+ );
+};
diff --git a/x-pack/plugins/transform/public/app/hooks/use_get_es_ingest_pipelines.ts b/x-pack/plugins/transform/public/app/hooks/use_get_es_ingest_pipelines.ts
new file mode 100644
index 0000000000000..3f9784c64b652
--- /dev/null
+++ b/x-pack/plugins/transform/public/app/hooks/use_get_es_ingest_pipelines.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 { useQuery } from '@tanstack/react-query';
+
+import type { IHttpFetchError } from '@kbn/core-http-browser';
+
+import { TRANSFORM_REACT_QUERY_KEYS } from '../../../common/constants';
+import type { EsIngestPipeline } from '../../../common/types/es_ingest_pipeline';
+
+import { useAppDependencies } from '../app_dependencies';
+
+export const useGetEsIngestPipelines = () => {
+ const { http } = useAppDependencies();
+
+ return useQuery(
+ [TRANSFORM_REACT_QUERY_KEYS.GET_ES_INGEST_PIPELINES],
+ ({ signal }) =>
+ http.get('/api/ingest_pipelines', {
+ version: '1',
+ signal,
+ })
+ );
+};
diff --git a/x-pack/plugins/transform/public/app/hooks/use_get_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_get_transform.tsx
index 4cccc76295d52..b9e3d977c71bd 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_get_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_get_transform.tsx
@@ -20,14 +20,11 @@ export const useGetTransform = (transformId: TransformId, enabled?: boolean) =>
return useQuery(
[TRANSFORM_REACT_QUERY_KEYS.GET_TRANSFORM, transformId],
- async ({ signal }) =>
- await http.get(
- addInternalBasePath(`transforms/${transformId}`),
- {
- version: '1',
- signal,
- }
- ),
+ ({ signal }) =>
+ http.get(addInternalBasePath(`transforms/${transformId}`), {
+ version: '1',
+ signal,
+ }),
{ enabled }
);
};
diff --git a/x-pack/plugins/transform/public/app/hooks/use_get_transform_audit_messages.ts b/x-pack/plugins/transform/public/app/hooks/use_get_transform_audit_messages.ts
index fec306f455417..3f7559a251275 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_get_transform_audit_messages.ts
+++ b/x-pack/plugins/transform/public/app/hooks/use_get_transform_audit_messages.ts
@@ -26,8 +26,8 @@ export const useGetTransformAuditMessages = (
return useQuery(
[TRANSFORM_REACT_QUERY_KEYS.GET_TRANSFORM_AUDIT_MESSAGES, transformId, query],
- async ({ signal }) =>
- await http.get(
+ ({ signal }) =>
+ http.get(
addInternalBasePath(`transforms/${transformId}/messages`),
{
query,
diff --git a/x-pack/plugins/transform/public/app/hooks/use_get_transform_stats.ts b/x-pack/plugins/transform/public/app/hooks/use_get_transform_stats.ts
index c6f1951b85819..d2b9d32f25853 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_get_transform_stats.ts
+++ b/x-pack/plugins/transform/public/app/hooks/use_get_transform_stats.ts
@@ -24,8 +24,8 @@ export const useGetTransformStats = (
return useQuery(
[TRANSFORM_REACT_QUERY_KEYS.GET_TRANSFORM_STATS, transformId],
- async ({ signal }) =>
- await http.get(
+ ({ signal }) =>
+ http.get(
addInternalBasePath(`transforms/${transformId}/_stats`),
{
version: '1',
diff --git a/x-pack/plugins/transform/public/app/hooks/use_get_transforms_preview.ts b/x-pack/plugins/transform/public/app/hooks/use_get_transforms_preview.ts
index 096c966e53311..ae671912b9267 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_get_transforms_preview.ts
+++ b/x-pack/plugins/transform/public/app/hooks/use_get_transforms_preview.ts
@@ -25,15 +25,12 @@ export const useGetTransformsPreview = (
return useQuery(
[TRANSFORM_REACT_QUERY_KEYS.GET_TRANSFORMS_PREVIEW, obj],
- async ({ signal }) =>
- await http.post(
- addInternalBasePath('transforms/_preview'),
- {
- body: JSON.stringify(obj),
- version: '1',
- signal,
- }
- ),
+ ({ signal }) =>
+ http.post(addInternalBasePath('transforms/_preview'), {
+ body: JSON.stringify(obj),
+ version: '1',
+ signal,
+ }),
{ enabled }
);
};
diff --git a/x-pack/plugins/transform/public/app/lib/authorization/components/authorization_provider.tsx b/x-pack/plugins/transform/public/app/lib/authorization/components/authorization_provider.tsx
index 9e73582b13d91..34760269772d1 100644
--- a/x-pack/plugins/transform/public/app/lib/authorization/components/authorization_provider.tsx
+++ b/x-pack/plugins/transform/public/app/lib/authorization/components/authorization_provider.tsx
@@ -55,14 +55,13 @@ export const AuthorizationProvider = ({ privilegesEndpoint, children }: Props) =
error,
data: privilegesData,
} = useQuery(
- [TRANSFORM_REACT_QUERY_KEYS.PRIVILEGES],
- async ({ signal }) => {
- return await http.fetch(path, {
+ [TRANSFORM_REACT_QUERY_KEYS.GET_PRIVILEGES],
+ ({ signal }) =>
+ http.fetch(path, {
version,
method: 'GET',
signal,
- });
- }
+ })
);
const value = {
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx
index 9c7f20197c33b..bb10abbeb8c3b 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx
@@ -29,11 +29,7 @@ import { toMountPoint } from '@kbn/kibana-react-plugin/public';
import { isHttpFetchError } from '@kbn/core-http-browser';
import { retentionPolicyMaxAgeInvalidErrorMessage } from '../../../../common/constants/validation_messages';
-import {
- isEsIndices,
- isEsIngestPipelines,
- isPostTransformsPreviewResponseSchema,
-} from '../../../../../../common/api_schemas/type_guards';
+import { isPostTransformsPreviewResponseSchema } from '../../../../../../common/api_schemas/type_guards';
import { DEFAULT_TRANSFORM_FREQUENCY } from '../../../../../../common/constants';
import { TransformId } from '../../../../../../common/types/transform';
import { isValidIndexName } from '../../../../../../common/utils/es_utils';
@@ -44,18 +40,20 @@ import { useAppDependencies, useToastNotifications } from '../../../../app_depen
import { ToastNotificationText } from '../../../../components';
import {
useDocumentationLinks,
+ useGetDataViewTitles,
+ useGetEsIndices,
+ useGetEsIngestPipelines,
useGetTransforms,
useGetTransformsPreview,
} from '../../../../hooks';
import { SearchItems } from '../../../../hooks/use_search_items';
-import { useApi } from '../../../../hooks/use_api';
import { StepDetailsTimeField } from './step_details_time_field';
import {
getTransformConfigQuery,
getPreviewTransformRequestBody,
isTransformIdValid,
} from '../../../../common';
-import { EsIndexName, DataViewTitle } from './common';
+import { EsIndexName } from './common';
import {
continuousModeDelayValidator,
integerRangeMinus1To100Validator,
@@ -94,8 +92,6 @@ export const StepDetailsForm: FC = React.memo(
const [destinationIngestPipeline, setDestinationIngestPipeline] = useState(
defaults.destinationIngestPipeline
);
- const [indexNames, setIndexNames] = useState([]);
- const [ingestPipelineNames, setIngestPipelineNames] = useState([]);
const canCreateDataView = useMemo(
() =>
@@ -105,7 +101,6 @@ export const StepDetailsForm: FC = React.memo(
);
// Index pattern state
- const [dataViewTitles, setDataViewTitles] = useState([]);
const [createDataView, setCreateDataView] = useState(
canCreateDataView === false ? false : defaults.createDataView
);
@@ -129,7 +124,6 @@ export const StepDetailsForm: FC = React.memo(
);
const { overlays, theme } = useAppDependencies();
- const api = useApi();
const { error: transformsError, data: transforms } = useGetTransforms();
const transformIds = transforms?.tableRows.map((d) => d.id) ?? [];
@@ -195,68 +189,72 @@ export const StepDetailsForm: FC = React.memo(
}
}, [overlays, theme, toastNotifications, transformsPreviewError]);
- // fetch existing transform IDs and indices once for form validation
+ const { error: esIndicesError, data: esIndicesData } = useGetEsIndices();
+ const indexNames = esIndicesData?.map((index) => index.name) ?? [];
+
useEffect(() => {
- // use an IIFE to avoid returning a Promise to useEffect.
- (async function () {
- const [indices, ingestPipelines] = await Promise.all([
- api.getEsIndices(),
- api.getEsIngestPipelines(),
- ]);
-
- if (isEsIndices(indices)) {
- setIndexNames(indices.map((index) => index.name));
- } else {
- toastNotifications.addDanger({
- title: i18n.translate('xpack.transform.stepDetailsForm.errorGettingIndexNames', {
- defaultMessage: 'An error occurred getting the existing index names:',
- }),
- text: toMountPoint(
- ,
- { theme$: theme.theme$ }
- ),
- });
- }
+ if (esIndicesError !== null) {
+ toastNotifications.addDanger({
+ title: i18n.translate('xpack.transform.stepDetailsForm.errorGettingIndexNames', {
+ defaultMessage: 'An error occurred getting the existing index names:',
+ }),
+ text: toMountPoint(
+ ,
+ { theme$: theme.theme$ }
+ ),
+ });
+ }
+ // custom comparison
+ /* eslint-disable react-hooks/exhaustive-deps */
+ }, [esIndicesError]);
- if (isEsIngestPipelines(ingestPipelines)) {
- setIngestPipelineNames(ingestPipelines.map(({ name }) => name));
- } else {
- toastNotifications.addDanger({
- title: i18n.translate('xpack.transform.stepDetailsForm.errorGettingIngestPipelines', {
- defaultMessage: 'An error occurred getting the existing ingest pipeline names:',
- }),
- text: toMountPoint(
- ,
- { theme$: theme.theme$ }
- ),
- });
- }
+ const { error: esIngestPipelinesError, data: esIngestPipelinesData } =
+ useGetEsIngestPipelines();
+ const ingestPipelineNames = esIngestPipelinesData?.map(({ name }) => name) ?? [];
- try {
- setDataViewTitles(await deps.data.dataViews.getTitles());
- } catch (e) {
- toastNotifications.addDanger({
- title: i18n.translate('xpack.transform.stepDetailsForm.errorGettingDataViewTitles', {
- defaultMessage: 'An error occurred getting the existing data view titles:',
- }),
- text: toMountPoint(
- ,
- { theme$: theme.theme$ }
- ),
- });
- }
- })();
- // run once
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, []);
+ useEffect(() => {
+ if (esIngestPipelinesError !== null) {
+ toastNotifications.addDanger({
+ title: i18n.translate('xpack.transform.stepDetailsForm.errorGettingIngestPipelines', {
+ defaultMessage: 'An error occurred getting the existing ingest pipeline names:',
+ }),
+ text: toMountPoint(
+ ,
+ { theme$: theme.theme$ }
+ ),
+ });
+ }
+ // custom comparison
+ /* eslint-disable react-hooks/exhaustive-deps */
+ }, [esIngestPipelinesError]);
+
+ const { error: dataViewTitlesError, data: dataViewTitles } = useGetDataViewTitles();
+
+ useEffect(() => {
+ if (dataViewTitlesError !== null) {
+ toastNotifications.addDanger({
+ title: i18n.translate('xpack.transform.stepDetailsForm.errorGettingDataViewTitles', {
+ defaultMessage: 'An error occurred getting the existing data view titles:',
+ }),
+ text: toMountPoint(
+ ,
+ { theme$: theme.theme$ }
+ ),
+ });
+ }
+ }, [dataViewTitlesError]);
const dateFieldNames = searchItems.dataView.fields
.filter((f) => f.type === KBN_FIELD_TYPES.DATE)
@@ -296,7 +294,6 @@ export const StepDetailsForm: FC = React.memo(
);
setRetentionPolicyMaxAge('');
}
- // eslint-disable-next-line react-hooks/exhaustive-deps
}, [isRetentionPolicyEnabled]);
const transformIdExists = transformIds.some((id) => transformId === id);
@@ -306,7 +303,7 @@ export const StepDetailsForm: FC = React.memo(
const indexNameExists = indexNames.some((name) => destinationIndex === name);
const indexNameEmpty = destinationIndex === '';
const indexNameValid = isValidIndexName(destinationIndex);
- const dataViewTitleExists = dataViewTitles.some((name) => destinationIndex === name);
+ const dataViewTitleExists = dataViewTitles?.some((name) => destinationIndex === name) ?? false;
const [transformFrequency, setTransformFrequency] = useState(defaults.transformFrequency);
const isTransformFrequencyValid = transformFrequencyValidator(transformFrequency);
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/edit_transform_flyout/edit_transform_ingest_pipeline.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/edit_transform_flyout/edit_transform_ingest_pipeline.tsx
index b5bb7f3fb258f..519bdc94011e1 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/edit_transform_flyout/edit_transform_ingest_pipeline.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/edit_transform_flyout/edit_transform_ingest_pipeline.tsx
@@ -5,15 +5,13 @@
* 2.0.
*/
-import React, { useEffect, useState, type FC } from 'react';
+import React, { type FC } from 'react';
import { useEuiTheme, EuiComboBox, EuiFormRow, EuiSkeletonRectangle } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { isEsIngestPipelines } from '../../../../../../common/api_schemas/type_guards';
-
-import { useApi } from '../../../../hooks/use_api';
+import { useGetEsIngestPipelines } from '../../../../hooks';
import { EditTransformFlyoutFormTextInput } from './edit_transform_flyout_form_text_input';
import { useEditTransformFlyout } from './use_edit_transform_flyout';
@@ -30,35 +28,8 @@ export const EditTransformIngestPipeline: FC = () => {
const { errorMessages, value } = useEditTransformFlyout('destinationIngestPipeline');
const { formField } = useEditTransformFlyout('actions');
- const api = useApi();
-
- const [ingestPipelineNames, setIngestPipelineNames] = useState([]);
- const [isLoading, setIsLoading] = useState(true);
-
- useEffect(function fetchPipelinesOnMount() {
- let unmounted = false;
-
- async function getIngestPipelineNames() {
- try {
- const ingestPipelines = await api.getEsIngestPipelines();
-
- if (!unmounted && isEsIngestPipelines(ingestPipelines)) {
- setIngestPipelineNames(ingestPipelines.map(({ name }) => name));
- }
- } finally {
- if (!unmounted) {
- setIsLoading(false);
- }
- }
- }
-
- getIngestPipelineNames();
-
- return () => {
- unmounted = true;
- };
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, []);
+ const { data: esIngestPipelinesData, isLoading } = useGetEsIngestPipelines();
+ const ingestPipelineNames = esIngestPipelinesData?.map(({ name }) => name) ?? [];
return (
<>
From 8cade10233ad0da793133a380ef8394e9aee750a Mon Sep 17 00:00:00 2001
From: Walter Rafelsberger
Date: Tue, 22 Aug 2023 19:18:32 +0200
Subject: [PATCH 14/53] migrate rest of useApi to react-query
---
x-pack/plugins/transform/common/constants.ts | 1 +
.../public/app/hooks/__mocks__/use_api.ts | 35 --------
.../transform/public/app/hooks/index.ts | 1 -
.../transform/public/app/hooks/use_api.ts | 59 -------------
.../hooks/use_get_histograms_for_fields.ts | 66 +++++++++++++++
.../public/app/hooks/use_index_data.test.tsx | 39 +++++----
.../public/app/hooks/use_index_data.ts | 82 +++++++++----------
7 files changed, 127 insertions(+), 156 deletions(-)
delete mode 100644 x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
delete mode 100644 x-pack/plugins/transform/public/app/hooks/use_api.ts
create mode 100644 x-pack/plugins/transform/public/app/hooks/use_get_histograms_for_fields.ts
diff --git a/x-pack/plugins/transform/common/constants.ts b/x-pack/plugins/transform/common/constants.ts
index 19bf3512d40d7..2c7adcaaae1ec 100644
--- a/x-pack/plugins/transform/common/constants.ts
+++ b/x-pack/plugins/transform/common/constants.ts
@@ -36,6 +36,7 @@ export const TRANSFORM_REACT_QUERY_KEYS = {
GET_DATA_VIEW_TITLES: 'transform.get_data_view_titles',
GET_ES_INDICES: 'transform.get_es_indices',
GET_ES_INGEST_PIPELINES: 'transform.get_es_ingest_pipelines',
+ GET_HISTOGRAMS_FOR_FIELDS: 'transform.get_histograms_for_fields',
GET_PRIVILEGES: 'transform.get_privileges',
GET_TRANSFORM: 'transform.get_transform',
GET_TRANSFORM_AUDIT_MESSAGES: 'transform.get_transform_audit_messages',
diff --git a/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts b/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
deleted file mode 100644
index 1bcd2e8cd0506..0000000000000
--- a/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts
+++ /dev/null
@@ -1,35 +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 type { IHttpFetchError } from '@kbn/core-http-browser';
-
-import { KBN_FIELD_TYPES } from '@kbn/field-types';
-import { DEFAULT_SAMPLER_SHARD_SIZE } from '@kbn/ml-agg-utils';
-
-import type { FieldHistogramsResponseSchema } from '../../../../common/api_schemas/field_histograms';
-
-import type { SavedSearchQuery } from '../use_search_items';
-
-export interface FieldHistogramRequestConfig {
- fieldName: string;
- type?: KBN_FIELD_TYPES;
-}
-
-const apiFactory = () => ({
- async getHistogramsForFields(
- dataViewTitle: string,
- fields: FieldHistogramRequestConfig[],
- query: string | SavedSearchQuery,
- samplerShardSize = DEFAULT_SAMPLER_SHARD_SIZE
- ): Promise {
- return Promise.resolve([]);
- },
-});
-
-export const useApi = () => {
- return apiFactory();
-};
diff --git a/x-pack/plugins/transform/public/app/hooks/index.ts b/x-pack/plugins/transform/public/app/hooks/index.ts
index 03a90d3b89042..f3e619e2364ce 100644
--- a/x-pack/plugins/transform/public/app/hooks/index.ts
+++ b/x-pack/plugins/transform/public/app/hooks/index.ts
@@ -5,7 +5,6 @@
* 2.0.
*/
-export { useApi } from './use_api';
export { useCreateTransform } from './use_create_transform';
export { useDocumentationLinks } from './use_documentation_links';
export { useGetDataViewTitles } from './use_get_data_view_titles';
diff --git a/x-pack/plugins/transform/public/app/hooks/use_api.ts b/x-pack/plugins/transform/public/app/hooks/use_api.ts
deleted file mode 100644
index f50af871368f1..0000000000000
--- a/x-pack/plugins/transform/public/app/hooks/use_api.ts
+++ /dev/null
@@ -1,59 +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 { useMemo } from 'react';
-
-import type { IHttpFetchError } from '@kbn/core-http-browser';
-
-import { KBN_FIELD_TYPES } from '@kbn/field-types';
-import { DEFAULT_SAMPLER_SHARD_SIZE } from '@kbn/ml-agg-utils';
-
-import type {
- FieldHistogramsRequestSchema,
- FieldHistogramsResponseSchema,
-} from '../../../common/api_schemas/field_histograms';
-import { addInternalBasePath } from '../../../common/constants';
-
-import { useAppDependencies } from '../app_dependencies';
-
-import type { SavedSearchQuery } from './use_search_items';
-
-export interface FieldHistogramRequestConfig {
- fieldName: string;
- type?: KBN_FIELD_TYPES;
-}
-
-export const useApi = () => {
- const { http } = useAppDependencies();
-
- return useMemo(
- () => ({
- async getHistogramsForFields(
- dataViewTitle: string,
- fields: FieldHistogramRequestConfig[],
- query: string | SavedSearchQuery,
- runtimeMappings?: FieldHistogramsRequestSchema['runtimeMappings'],
- samplerShardSize = DEFAULT_SAMPLER_SHARD_SIZE
- ): Promise {
- try {
- return await http.post(addInternalBasePath(`field_histograms/${dataViewTitle}`), {
- body: JSON.stringify({
- query,
- fields,
- samplerShardSize,
- ...(runtimeMappings !== undefined ? { runtimeMappings } : {}),
- }),
- version: '1',
- });
- } catch (e) {
- return e;
- }
- },
- }),
- [http]
- );
-};
diff --git a/x-pack/plugins/transform/public/app/hooks/use_get_histograms_for_fields.ts b/x-pack/plugins/transform/public/app/hooks/use_get_histograms_for_fields.ts
new file mode 100644
index 0000000000000..63ce23dba6214
--- /dev/null
+++ b/x-pack/plugins/transform/public/app/hooks/use_get_histograms_for_fields.ts
@@ -0,0 +1,66 @@
+/*
+ * 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 { useQuery } from '@tanstack/react-query';
+
+import type { IHttpFetchError } from '@kbn/core-http-browser';
+import { KBN_FIELD_TYPES } from '@kbn/field-types';
+import { DEFAULT_SAMPLER_SHARD_SIZE } from '@kbn/ml-agg-utils';
+
+import { addInternalBasePath, TRANSFORM_REACT_QUERY_KEYS } from '../../../common/constants';
+import type {
+ FieldHistogramsRequestSchema,
+ FieldHistogramsResponseSchema,
+} from '../../../common/api_schemas/field_histograms';
+
+import { useAppDependencies } from '../app_dependencies';
+
+import type { SavedSearchQuery } from './use_search_items';
+
+export interface FieldHistogramRequestConfig {
+ fieldName: string;
+ type?: KBN_FIELD_TYPES;
+}
+
+export const useGetHistogramsForFields = (
+ dataViewTitle: string,
+ fields: FieldHistogramRequestConfig[],
+ query: string | SavedSearchQuery,
+ runtimeMappings?: FieldHistogramsRequestSchema['runtimeMappings'],
+ enabled?: boolean,
+ samplerShardSize = DEFAULT_SAMPLER_SHARD_SIZE
+) => {
+ const { http } = useAppDependencies();
+
+ return useQuery(
+ [
+ TRANSFORM_REACT_QUERY_KEYS.GET_HISTOGRAMS_FOR_FIELDS,
+ {
+ dataViewTitle,
+ fields,
+ query,
+ runtimeMappings,
+ samplerShardSize,
+ },
+ ],
+ ({ signal }) =>
+ http.post(
+ addInternalBasePath(`field_histograms/${dataViewTitle}`),
+ {
+ body: JSON.stringify({
+ query,
+ fields,
+ samplerShardSize,
+ ...(runtimeMappings !== undefined ? { runtimeMappings } : {}),
+ }),
+ version: '1',
+ signal,
+ }
+ ),
+ { enabled }
+ );
+};
diff --git a/x-pack/plugins/transform/public/app/hooks/use_index_data.test.tsx b/x-pack/plugins/transform/public/app/hooks/use_index_data.test.tsx
index 9da9fa8e5e782..c64d2eb09ee54 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_index_data.test.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_index_data.test.tsx
@@ -6,12 +6,12 @@
*/
import React, { FC } from 'react';
-import { __IntlProvider as IntlProvider } from '@kbn/i18n-react';
-
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import '@testing-library/jest-dom/extend-expect';
import { render, screen, waitFor } from '@testing-library/react';
import { renderHook } from '@testing-library/react-hooks';
+import { __IntlProvider as IntlProvider } from '@kbn/i18n-react';
import { CoreSetup } from '@kbn/core/public';
import { DataGrid, type UseIndexDataReturnType } from '@kbn/ml-data-grid';
import type { RuntimeMappings } from '@kbn/ml-runtime-field-utils';
@@ -25,7 +25,6 @@ import { useIndexData } from './use_index_data';
jest.mock('../../shared_imports');
jest.mock('../app_dependencies');
-jest.mock('./use_api');
import { MlSharedContext } from '../__mocks__/shared_context';
@@ -45,13 +44,17 @@ const runtimeMappings: RuntimeMappings = {
},
};
+const queryClient = new QueryClient();
+
describe('Transform: useIndexData()', () => {
test('dataView set triggers loading', async () => {
const mlShared = await getMlSharedImports();
const wrapper: FC = ({ children }) => (
-
- {children}
-
+
+
+ {children}
+
+
);
const { result, waitForNextUpdate } = renderHook(
@@ -102,11 +105,13 @@ describe('Transform: with useIndexData()', () => {
};
render(
-
-
-
-
-
+
+
+
+
+
+
+
);
// Act
@@ -142,11 +147,13 @@ describe('Transform: with useIndexData()', () => {
};
render(
-
-
-
-
-
+
+
+
+
+
+
+
);
// Act
diff --git a/x-pack/plugins/transform/public/app/hooks/use_index_data.ts b/x-pack/plugins/transform/public/app/hooks/use_index_data.ts
index 7b6911636c600..1f42394fb0fdb 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_index_data.ts
+++ b/x-pack/plugins/transform/public/app/hooks/use_index_data.ts
@@ -28,10 +28,7 @@ import {
} from '@kbn/ml-data-grid';
import type { TimeRange as TimeRangeMs } from '@kbn/ml-date-picker';
-import {
- isEsSearchResponse,
- isFieldHistogramsResponseSchema,
-} from '../../../common/api_schemas/type_guards';
+import { isEsSearchResponse } from '../../../common/api_schemas/type_guards';
import {
hasKeywordDuplicate,
isKeywordDuplicate,
@@ -44,7 +41,7 @@ import { useToastNotifications, useAppDependencies } from '../app_dependencies';
import type { StepDefineExposedState } from '../sections/create_transform/components/step_define/common';
import { SearchItems } from './use_search_items';
-import { useApi } from './use_api';
+import { useGetHistogramsForFields } from './use_get_histograms_for_fields';
import { useDataSearch } from './use_data_search';
export const useIndexData = (
@@ -61,7 +58,6 @@ export const useIndexData = (
const indexPattern = useMemo(() => dataView.getIndexPattern(), [dataView]);
- const api = useApi();
const dataSearch = useDataSearch();
const toastNotifications = useToastNotifications();
@@ -273,58 +269,54 @@ export const useIndexData = (
]),
]);
- useEffect(() => {
- const fetchColumnChartsData = async function () {
- const allDataViewFieldNames = new Set(dataView.fields.map((f) => f.name));
- const columnChartsData = await api.getHistogramsForFields(
- indexPattern,
- columns
- .filter((cT) => dataGrid.visibleColumns.includes(cT.id))
- .map((cT) => {
- // If a column field name has a corresponding keyword field,
- // fetch the keyword field instead to be able to do aggregations.
- const fieldName = cT.id;
- return hasKeywordDuplicate(fieldName, allDataViewFieldNames)
- ? {
- fieldName: `${fieldName}.keyword`,
- type: getFieldType(undefined),
- }
- : {
- fieldName,
- type: getFieldType(cT.schema),
- };
- }),
- isDefaultQuery(query) ? defaultQuery : queryWithBaseFilterCriteria,
- combinedRuntimeMappings
- );
+ const allDataViewFieldNames = new Set(dataView.fields.map((f) => f.name));
+ const { error: histogramsForFieldsError, data: histogramsForFieldsData } =
+ useGetHistogramsForFields(
+ indexPattern,
+ columns
+ .filter((cT) => dataGrid.visibleColumns.includes(cT.id))
+ .map((cT) => {
+ // If a column field name has a corresponding keyword field,
+ // fetch the keyword field instead to be able to do aggregations.
+ const fieldName = cT.id;
+ return hasKeywordDuplicate(fieldName, allDataViewFieldNames)
+ ? {
+ fieldName: `${fieldName}.keyword`,
+ type: getFieldType(undefined),
+ }
+ : {
+ fieldName,
+ type: getFieldType(cT.schema),
+ };
+ }),
+ isDefaultQuery(query) ? defaultQuery : queryWithBaseFilterCriteria,
+ combinedRuntimeMappings,
+ chartsVisible
+ );
- if (!isFieldHistogramsResponseSchema(columnChartsData)) {
- showDataGridColumnChartErrorMessageToast(columnChartsData, toastNotifications);
- return;
- }
+ useEffect(() => {
+ if (histogramsForFieldsError !== null) {
+ showDataGridColumnChartErrorMessageToast(histogramsForFieldsError, toastNotifications);
+ }
+ // custom comparison
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [histogramsForFieldsError]);
+ useEffect(() => {
+ if (histogramsForFieldsData) {
setColumnCharts(
// revert field names with `.keyword` used to do aggregations to their original column name
- columnChartsData.map((d) => ({
+ histogramsForFieldsData.map((d) => ({
...d,
...(isKeywordDuplicate(d.id, allDataViewFieldNames)
? { id: removeKeywordPostfix(d.id) }
: {}),
}))
);
- };
-
- if (chartsVisible) {
- fetchColumnChartsData();
}
// custom comparison
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [
- chartsVisible,
- indexPattern,
- // eslint-disable-next-line react-hooks/exhaustive-deps
- JSON.stringify([query, dataGrid.visibleColumns, combinedRuntimeMappings, timeRangeMs]),
- ]);
+ }, [histogramsForFieldsData]);
const renderCellValue = useRenderCellValue(dataView, pagination, tableItems);
From 0614d002266a3259b061038ab764430c87e7ec84 Mon Sep 17 00:00:00 2001
From: Walter Rafelsberger
Date: Tue, 22 Aug 2023 19:35:26 +0200
Subject: [PATCH 15/53] remove unnecessary type guards
---
.../common/api_schemas/type_guards.ts | 125 ------------------
.../public/app/hooks/use_create_transform.tsx | 59 ++++-----
.../public/app/hooks/use_get_transforms.ts | 21 +--
.../step_create/step_create_form.tsx | 22 +--
.../step_details/step_details_form.tsx | 3 +-
5 files changed, 42 insertions(+), 188 deletions(-)
diff --git a/x-pack/plugins/transform/common/api_schemas/type_guards.ts b/x-pack/plugins/transform/common/api_schemas/type_guards.ts
index d5dbad0056c35..08b12144aec35 100644
--- a/x-pack/plugins/transform/common/api_schemas/type_guards.ts
+++ b/x-pack/plugins/transform/common/api_schemas/type_guards.ts
@@ -9,74 +9,6 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import { isPopulatedObject } from '@kbn/ml-is-populated-object';
-import type { EsIndex } from '../types/es_index';
-import type { EsIngestPipeline } from '../types/es_ingest_pipeline';
-
-// To be able to use the type guards on the client side, we need to make sure we don't import
-// the code of '@kbn/config-schema' but just its types, otherwise the client side code will
-// fail to build.
-import type { FieldHistogramsResponseSchema } from './field_histograms';
-import type { GetTransformsAuditMessagesResponseSchema } from './audit_messages';
-import type { DeleteTransformsResponseSchema } from './delete_transforms';
-import type { ResetTransformsResponseSchema } from './reset_transforms';
-import type { StartTransformsResponseSchema } from './start_transforms';
-import type { StopTransformsResponseSchema } from './stop_transforms';
-import type { ScheduleNowTransformsResponseSchema } from './schedule_now_transforms';
-import type {
- GetTransformNodesResponseSchema,
- GetTransformsResponseSchema,
- PostTransformsPreviewResponseSchema,
- PutTransformsResponseSchema,
-} from './transforms';
-import type { GetTransformsStatsResponseSchema } from './transforms_stats';
-import type { PostTransformsUpdateResponseSchema } from './update_transforms';
-
-const isGenericResponseSchema = (arg: any): arg is T => {
- return isPopulatedObject(arg, ['count', 'transforms']) && Array.isArray(arg.transforms);
-};
-
-export const isGetTransformNodesResponseSchema = (
- arg: unknown
-): arg is GetTransformNodesResponseSchema => {
- return isPopulatedObject(arg, ['count']) && typeof arg.count === 'number';
-};
-
-export const isGetTransformsResponseSchema = (arg: unknown): arg is GetTransformsResponseSchema => {
- return isGenericResponseSchema(arg);
-};
-
-export const isGetTransformsStatsResponseSchema = (
- arg: unknown
-): arg is GetTransformsStatsResponseSchema => {
- return isGenericResponseSchema(arg);
-};
-
-export const isDeleteTransformsResponseSchema = (
- arg: unknown
-): arg is DeleteTransformsResponseSchema => {
- return (
- isPopulatedObject(arg) &&
- Object.values(arg).every((d) => isPopulatedObject(d, ['transformDeleted']))
- );
-};
-
-export const isResetTransformsResponseSchema = (
- arg: unknown
-): arg is ResetTransformsResponseSchema => {
- return (
- isPopulatedObject(arg) &&
- Object.values(arg).every((d) => isPopulatedObject(d, ['transformReset']))
- );
-};
-
-export const isEsIndices = (arg: unknown): arg is EsIndex[] => {
- return Array.isArray(arg);
-};
-
-export const isEsIngestPipelines = (arg: unknown): arg is EsIngestPipeline[] => {
- return Array.isArray(arg) && arg.every((d) => isPopulatedObject(d, ['name']));
-};
-
export const isEsSearchResponse = (arg: unknown): arg is estypes.SearchResponse => {
return isPopulatedObject(arg, ['hits']);
};
@@ -88,60 +20,3 @@ export const isEsSearchResponseWithAggregations = (
): arg is SearchResponseWithAggregations => {
return isEsSearchResponse(arg) && {}.hasOwnProperty.call(arg, 'aggregations');
};
-
-export const isFieldHistogramsResponseSchema = (
- arg: unknown
-): arg is FieldHistogramsResponseSchema => {
- return Array.isArray(arg);
-};
-
-export const isGetTransformsAuditMessagesResponseSchema = (
- arg: unknown
-): arg is GetTransformsAuditMessagesResponseSchema => {
- return isPopulatedObject(arg, ['messages', 'total']);
-};
-
-export const isPostTransformsPreviewResponseSchema = (
- arg: unknown
-): arg is PostTransformsPreviewResponseSchema => {
- return (
- isPopulatedObject(arg, ['generated_dest_index', 'preview']) &&
- typeof arg.generated_dest_index !== undefined &&
- Array.isArray(arg.preview)
- );
-};
-
-export const isPostTransformsUpdateResponseSchema = (
- arg: unknown
-): arg is PostTransformsUpdateResponseSchema => {
- return isPopulatedObject(arg, ['id']) && typeof arg.id === 'string';
-};
-
-export const isPutTransformsResponseSchema = (arg: unknown): arg is PutTransformsResponseSchema => {
- return (
- isPopulatedObject(arg, ['transformsCreated', 'errors']) &&
- Array.isArray(arg.transformsCreated) &&
- Array.isArray(arg.errors)
- );
-};
-
-const isGenericSuccessResponseSchema = (arg: unknown) =>
- isPopulatedObject(arg) && Object.values(arg).every((d) => isPopulatedObject(d, ['success']));
-
-export const isStartTransformsResponseSchema = (
- arg: unknown
-): arg is StartTransformsResponseSchema => {
- return isGenericSuccessResponseSchema(arg);
-};
-
-export const isStopTransformsResponseSchema = (
- arg: unknown
-): arg is StopTransformsResponseSchema => {
- return isGenericSuccessResponseSchema(arg);
-};
-
-export const isScheduleNowTransformsResponseSchema = (
- arg: unknown
-): arg is ScheduleNowTransformsResponseSchema => {
- return isGenericSuccessResponseSchema(arg);
-};
diff --git a/x-pack/plugins/transform/public/app/hooks/use_create_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_create_transform.tsx
index f44f0f234559f..d97508ed3a009 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_create_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_create_transform.tsx
@@ -15,7 +15,6 @@ import type {
PutTransformsRequestSchema,
PutTransformsResponseSchema,
} from '../../../common/api_schemas/transforms';
-import { isPutTransformsResponseSchema } from '../../../common/api_schemas/type_guards';
import { addInternalBasePath } from '../../../common/constants';
import type { TransformId } from '../../../common/types/transform';
import { getErrorMessage } from '../../../common/utils/errors';
@@ -32,6 +31,19 @@ export const useCreateTransform = (
const refreshTransformList = useRefreshTransformList();
const toastNotifications = useToastNotifications();
+ function errorToast(error: unknown) {
+ toastNotifications.addDanger({
+ title: i18n.translate('xpack.transform.stepCreateForm.createTransformErrorMessage', {
+ defaultMessage: 'An error occurred creating the transform {transformId}:',
+ values: { transformId },
+ }),
+ text: toMountPoint(
+ ,
+ { theme$: theme.theme$ }
+ ),
+ });
+ }
+
const mutation = useMutation({
mutationFn: () => {
return http.put(
@@ -42,40 +54,21 @@ export const useCreateTransform = (
}
);
},
- onError: (resp) => {
- if (!isPutTransformsResponseSchema(resp) || resp.errors.length > 0) {
- let respErrors:
- | PutTransformsResponseSchema['errors']
- | PutTransformsResponseSchema['errors'][number]
- | undefined;
-
- if (isPutTransformsResponseSchema(resp) && resp.errors.length > 0) {
- respErrors = resp.errors.length === 1 ? resp.errors[0] : resp.errors;
- }
-
- toastNotifications.addDanger({
- title: i18n.translate('xpack.transform.stepCreateForm.createTransformErrorMessage', {
- defaultMessage: 'An error occurred creating the transform {transformId}:',
+ onError: (error) => {
+ errorToast(error);
+ },
+ onSuccess: (resp) => {
+ if (resp.errors.length > 0) {
+ errorToast(resp.errors.length === 1 ? resp.errors[0] : resp.errors);
+ } else {
+ toastNotifications.addSuccess(
+ i18n.translate('xpack.transform.stepCreateForm.createTransformSuccessMessage', {
+ defaultMessage: 'Request to create transform {transformId} acknowledged.',
values: { transformId },
- }),
- text: toMountPoint(
- ,
- { theme$: theme.theme$ }
- ),
- });
+ })
+ );
}
- },
- onSuccess: (results) => {
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.stepCreateForm.createTransformSuccessMessage', {
- defaultMessage: 'Request to create transform {transformId} acknowledged.',
- values: { transformId },
- })
- );
+
refreshTransformList();
},
});
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 f97eaf671fb97..04a0d09219095 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
@@ -9,11 +9,12 @@ import { useQuery } from '@tanstack/react-query';
import type { IHttpFetchError } from '@kbn/core-http-browser';
import { isDefined } from '@kbn/ml-is-defined';
-import { isGetTransformsStatsResponseSchema } from '../../../common/api_schemas/type_guards';
+
import type {
GetTransformNodesResponseSchema,
GetTransformsResponseSchema,
} from '../../../common/api_schemas/transforms';
+import type { GetTransformsStatsResponseSchema } from '../../../common/api_schemas/transforms_stats';
import {
addInternalBasePath,
DEFAULT_REFRESH_INTERVAL_MS,
@@ -24,7 +25,6 @@ import { isTransformStats } from '../../../common/types/transform_stats';
import { type TransformListRow } from '../common';
import { useAppDependencies } from '../app_dependencies';
-
import { TRANSFORM_ERROR_TYPE } from '../common/transform';
interface UseGetTransformsResponse {
@@ -62,11 +62,14 @@ export const useGetTransforms = () => {
signal,
}
);
- const transformStats = await http.get(addInternalBasePath(`transforms/_stats`), {
- version: '1',
- asSystemRequest: true,
- signal,
- });
+ const transformStats = await http.get(
+ addInternalBasePath(`transforms/_stats`),
+ {
+ version: '1',
+ asSystemRequest: true,
+ signal,
+ }
+ );
// There might be some errors with fetching certain transforms
// For example, when task exists and is running but the config is deleted
@@ -85,9 +88,7 @@ export const useGetTransforms = () => {
}
update.tableRows = transformConfigs.transforms.reduce((reducedtableRows, config) => {
- const stats = isGetTransformsStatsResponseSchema(transformStats)
- ? transformStats.transforms.find((d) => config.id === d.id)
- : undefined;
+ const stats = transformStats.transforms.find((d) => config.id === d.id);
// A newly created transform might not have corresponding stats yet.
// If that's the case we just skip the transform and don't add it to the transform list yet.
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.tsx
index b0391c85c1146..2bca8ec8072e1 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.tsx
@@ -31,10 +31,6 @@ import { DISCOVER_APP_LOCATOR } from '@kbn/discover-plugin/common';
import { DuplicateDataViewError } from '@kbn/data-plugin/public';
import type { RuntimeField } from '@kbn/data-views-plugin/common';
import { isPopulatedObject } from '@kbn/ml-is-populated-object';
-import {
- isGetTransformsStatsResponseSchema,
- isStartTransformsResponseSchema,
-} from '../../../../../../common/api_schemas/type_guards';
import { PROGRESS_REFRESH_INTERVAL_MS } from '../../../../../../common/constants';
import { getErrorMessage } from '../../../../../../common/utils/errors';
@@ -156,15 +152,9 @@ export const StepCreateForm: FC = React.memo(
setLoading(true);
startTransforms([{ id: transformId }], {
- onError: () => {
- setStarted(false);
- },
- onSuccess: (resp) => {
- setStarted(isStartTransformsResponseSchema(resp) && resp[transformId]?.success === true);
- },
- onSettled: () => {
- setLoading(false);
- },
+ onError: () => setStarted(false),
+ onSuccess: (resp) => setStarted(resp[transformId]?.success === true),
+ onSettled: () => setLoading(false),
});
}
@@ -258,11 +248,7 @@ export const StepCreateForm: FC = React.memo(
return;
}
- if (
- isGetTransformsStatsResponseSchema(stats) &&
- Array.isArray(stats.transforms) &&
- stats.transforms.length > 0
- ) {
+ if (stats && Array.isArray(stats.transforms) && stats.transforms.length > 0) {
const percent =
getTransformProgress({
id: transformId,
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx
index bb10abbeb8c3b..a234795ebe788 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx
@@ -29,7 +29,6 @@ import { toMountPoint } from '@kbn/kibana-react-plugin/public';
import { isHttpFetchError } from '@kbn/core-http-browser';
import { retentionPolicyMaxAgeInvalidErrorMessage } from '../../../../common/constants/validation_messages';
-import { isPostTransformsPreviewResponseSchema } from '../../../../../../common/api_schemas/type_guards';
import { DEFAULT_TRANSFORM_FREQUENCY } from '../../../../../../common/constants';
import { TransformId } from '../../../../../../common/types/transform';
import { isValidIndexName } from '../../../../../../common/utils/es_utils';
@@ -160,7 +159,7 @@ export const StepDetailsForm: FC = React.memo(
useGetTransformsPreview(previewRequest);
useEffect(() => {
- if (isPostTransformsPreviewResponseSchema(transformPreview)) {
+ if (transformPreview) {
const properties = transformPreview.generated_dest_index.mappings.properties;
const timeFields: string[] = Object.keys(properties).filter(
(col) => properties[col].type === 'date'
From 5f04ab7e38da32338ef5932257da9efe9e6c9ca8 Mon Sep 17 00:00:00 2001
From: Walter Rafelsberger
Date: Tue, 22 Aug 2023 22:56:40 +0200
Subject: [PATCH 16/53] remove unnecessary type guards
---
.../common/api_schemas/type_guards.ts | 22 --
x-pack/plugins/transform/common/constants.ts | 1 +
.../public/app/hooks/use_data_search.ts | 46 ++--
.../public/app/hooks/use_index_data.ts | 212 ++++++++----------
.../components/filter_term_form.tsx | 128 +++++------
5 files changed, 174 insertions(+), 235 deletions(-)
delete mode 100644 x-pack/plugins/transform/common/api_schemas/type_guards.ts
diff --git a/x-pack/plugins/transform/common/api_schemas/type_guards.ts b/x-pack/plugins/transform/common/api_schemas/type_guards.ts
deleted file mode 100644
index 08b12144aec35..0000000000000
--- a/x-pack/plugins/transform/common/api_schemas/type_guards.ts
+++ /dev/null
@@ -1,22 +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 type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
-
-import { isPopulatedObject } from '@kbn/ml-is-populated-object';
-
-export const isEsSearchResponse = (arg: unknown): arg is estypes.SearchResponse => {
- return isPopulatedObject(arg, ['hits']);
-};
-
-type SearchResponseWithAggregations = Required> &
- estypes.SearchResponse;
-export const isEsSearchResponseWithAggregations = (
- arg: unknown
-): arg is SearchResponseWithAggregations => {
- return isEsSearchResponse(arg) && {}.hasOwnProperty.call(arg, 'aggregations');
-};
diff --git a/x-pack/plugins/transform/common/constants.ts b/x-pack/plugins/transform/common/constants.ts
index 2c7adcaaae1ec..1584811c0df6b 100644
--- a/x-pack/plugins/transform/common/constants.ts
+++ b/x-pack/plugins/transform/common/constants.ts
@@ -33,6 +33,7 @@ export const addInternalBasePath = (uri: string): string => `${INTERNAL_API_BASE
export const addExternalBasePath = (uri: string): string => `${EXTERNAL_API_BASE_PATH}${uri}`;
export const TRANSFORM_REACT_QUERY_KEYS = {
+ DATA_SEARCH: 'transform.data_search',
GET_DATA_VIEW_TITLES: 'transform.get_data_view_titles',
GET_ES_INDICES: 'transform.get_es_indices',
GET_ES_INGEST_PIPELINES: 'transform.get_es_ingest_pipelines',
diff --git a/x-pack/plugins/transform/public/app/hooks/use_data_search.ts b/x-pack/plugins/transform/public/app/hooks/use_data_search.ts
index af4bb440f9e24..f691cb7a0d8b6 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_data_search.ts
+++ b/x-pack/plugins/transform/public/app/hooks/use_data_search.ts
@@ -5,37 +5,37 @@
* 2.0.
*/
-import { useCallback } from 'react';
+import { useQuery } from '@tanstack/react-query';
import { lastValueFrom } from 'rxjs';
+import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
+
import type { IKibanaSearchRequest } from '@kbn/data-plugin/common';
+import { TRANSFORM_REACT_QUERY_KEYS } from '../../../common/constants';
+
import { useAppDependencies } from '../app_dependencies';
-export const useDataSearch = () => {
+export const useDataSearch = (
+ esSearchRequestParams: IKibanaSearchRequest['params'],
+ enabled?: boolean
+) => {
const { data } = useAppDependencies();
- return useCallback(
- async (esSearchRequestParams: IKibanaSearchRequest['params'], abortSignal?: AbortSignal) => {
- try {
- const { rawResponse: resp } = await lastValueFrom(
- data.search.search(
- {
- params: esSearchRequestParams,
- },
- { abortSignal }
- )
- );
-
- return resp;
- } catch (error) {
- if (error.name === 'AbortError') {
- // ignore abort errors
- } else {
- return error;
- }
- }
+ return useQuery(
+ [TRANSFORM_REACT_QUERY_KEYS.DATA_SEARCH, esSearchRequestParams],
+ async ({ signal }) => {
+ const { rawResponse: resp } = await lastValueFrom(
+ data.search.search(
+ {
+ params: esSearchRequestParams,
+ },
+ { abortSignal: signal }
+ )
+ );
+
+ return resp;
},
- [data]
+ { enabled }
);
};
diff --git a/x-pack/plugins/transform/public/app/hooks/use_index_data.ts b/x-pack/plugins/transform/public/app/hooks/use_index_data.ts
index 1f42394fb0fdb..5fca52ae9c6f8 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_index_data.ts
+++ b/x-pack/plugins/transform/public/app/hooks/use_index_data.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { useEffect, useMemo, useRef, useState } from 'react';
+import { useEffect, useMemo, useRef } from 'react';
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import type { EuiDataGridColumn } from '@elastic/eui';
@@ -28,7 +28,6 @@ import {
} from '@kbn/ml-data-grid';
import type { TimeRange as TimeRangeMs } from '@kbn/ml-date-picker';
-import { isEsSearchResponse } from '../../../common/api_schemas/type_guards';
import {
hasKeywordDuplicate,
isKeywordDuplicate,
@@ -57,12 +56,8 @@ export const useIndexData = (
const loadIndexDataStartTime = useRef(window.performance.now());
const indexPattern = useMemo(() => dataView.getIndexPattern(), [dataView]);
-
- const dataSearch = useDataSearch();
const toastNotifications = useToastNotifications();
- const [dataViewFields, setDataViewFields] = useState();
-
const baseFilterCriteria = buildBaseFilterCriteria(
dataView.timeFieldName,
timeRangeMs?.from,
@@ -81,67 +76,69 @@ export const useIndexData = (
},
};
- useEffect(() => {
- if (dataView.timeFieldName !== undefined && timeRangeMs === undefined) {
- return;
- }
- const abortController = new AbortController();
-
- // Fetch 500 random documents to determine populated fields.
- // This is a workaround to avoid passing potentially thousands of unpopulated fields
- // (for example, as part of filebeat/metricbeat/ECS based indices)
- // to the data grid component which would significantly slow down the page.
- const fetchDataGridSampleDocuments = async function () {
- setErrorMessage('');
- setStatus(INDEX_STATUS.LOADING);
-
- const esSearchRequest = {
- index: indexPattern,
- body: {
- fields: ['*'],
- _source: false,
- query: {
- function_score: {
- query: defaultQuery,
- random_score: {},
- },
+ // Fetch 500 random documents to determine populated fields.
+ // This is a workaround to avoid passing potentially thousands of unpopulated fields
+ // (for example, as part of filebeat/metricbeat/ECS based indices)
+ // to the data grid component which would significantly slow down the page.
+ const {
+ error: dataViewFieldsError,
+ data: dataViewFieldsData,
+ isError: dataViewFieldsIsError,
+ isLoading: dataViewFieldsIsLoading,
+ } = useDataSearch(
+ {
+ index: indexPattern,
+ body: {
+ fields: ['*'],
+ _source: false,
+ query: {
+ function_score: {
+ query: defaultQuery,
+ random_score: {},
},
- size: 500,
},
- };
-
- const resp = await dataSearch(esSearchRequest, abortController.signal);
-
- if (!isEsSearchResponse(resp)) {
- setErrorMessage(getErrorMessage(resp));
- setStatus(INDEX_STATUS.ERROR);
- return;
- }
+ size: 500,
+ },
+ },
+ // Check whether fetching should be enabled
+ !(dataView.timeFieldName !== undefined && timeRangeMs === undefined)
+ );
+ useEffect(() => {
+ if (dataViewFieldsIsLoading && !dataViewFieldsIsError) {
+ setErrorMessage('');
+ setStatus(INDEX_STATUS.LOADING);
+ } else if (dataViewFieldsError !== null) {
+ setErrorMessage(getErrorMessage(dataViewFieldsError));
+ setStatus(INDEX_STATUS.ERROR);
+ } else if (
+ !dataViewFieldsIsLoading &&
+ !dataViewFieldsIsError &&
+ dataViewFieldsData !== undefined
+ ) {
const isCrossClusterSearch = indexPattern.includes(':');
- const isMissingFields = resp.hits.hits.every((d) => typeof d.fields === 'undefined');
+ const isMissingFields = dataViewFieldsData.hits.hits.every(
+ (d) => typeof d.fields === 'undefined'
+ );
+
+ setCcsWarning(isCrossClusterSearch && isMissingFields);
+ setStatus(INDEX_STATUS.LOADED);
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [dataViewFieldsData, dataViewFieldsError, dataViewFieldsIsError, dataViewFieldsIsLoading]);
- const docs = resp.hits.hits.map((d) => getProcessedFields(d.fields ?? {}));
+ const dataViewFields = useMemo(() => {
+ if (dataViewFieldsData) {
+ const docs = dataViewFieldsData.hits.hits.map((d) => getProcessedFields(d.fields ?? {}));
// Get all field names for each returned doc and flatten it
// to a list of unique field names used across all docs.
const allDataViewFields = getFieldsFromKibanaIndexPattern(dataView);
- const populatedFields = [...new Set(docs.map(Object.keys).flat(1))]
+ return [...new Set(docs.map(Object.keys).flat(1))]
.filter((d) => allDataViewFields.includes(d))
.sort();
-
- setCcsWarning(isCrossClusterSearch && isMissingFields);
- setStatus(INDEX_STATUS.LOADED);
- setDataViewFields(populatedFields);
- };
-
- fetchDataGridSampleDocuments();
-
- return () => {
- abortController.abort();
- };
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [timeRangeMs]);
+ }
+ }, [dataView, dataViewFieldsData]);
const columns: EuiDataGridColumn[] = useMemo(() => {
if (typeof dataViewFields === 'undefined') {
@@ -195,79 +192,64 @@ export const useIndexData = (
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [JSON.stringify([query, timeRangeMs])]);
- useEffect(() => {
- if (typeof dataViewFields === 'undefined') {
- return;
- }
- const abortController = new AbortController();
+ const sort: EsSorting = sortingColumns.reduce((s, column) => {
+ s[column.id] = { order: column.direction };
+ return s;
+ }, {} as EsSorting);
+
+ const {
+ error: dataGridDataError,
+ data: dataGridData,
+ isError: dataGridDataIsError,
+ isLoading: dataGridDataIsLoading,
+ } = useDataSearch(
+ {
+ index: indexPattern,
+ body: {
+ fields: ['*'],
+ _source: false,
+ query: isDefaultQuery(query) ? defaultQuery : queryWithBaseFilterCriteria,
+ from: pagination.pageIndex * pagination.pageSize,
+ size: pagination.pageSize,
+ ...(Object.keys(sort).length > 0 ? { sort } : {}),
+ ...(isRuntimeMappings(combinedRuntimeMappings)
+ ? { runtime_mappings: combinedRuntimeMappings }
+ : {}),
+ },
+ },
+ // Check whether fetching should be enabled
+ dataViewFields !== undefined
+ );
- const fetchDataGridData = async function () {
+ useEffect(() => {
+ if (dataGridDataIsLoading && !dataGridDataIsError) {
setErrorMessage('');
setStatus(INDEX_STATUS.LOADING);
-
- const sort: EsSorting = sortingColumns.reduce((s, column) => {
- s[column.id] = { order: column.direction };
- return s;
- }, {} as EsSorting);
-
- const esSearchRequest = {
- index: indexPattern,
- body: {
- fields: ['*'],
- _source: false,
- query: isDefaultQuery(query) ? defaultQuery : queryWithBaseFilterCriteria,
- from: pagination.pageIndex * pagination.pageSize,
- size: pagination.pageSize,
- ...(Object.keys(sort).length > 0 ? { sort } : {}),
- ...(isRuntimeMappings(combinedRuntimeMappings)
- ? { runtime_mappings: combinedRuntimeMappings }
- : {}),
- },
- };
- const resp = await dataSearch(esSearchRequest, abortController.signal);
-
- if (!isEsSearchResponse(resp)) {
- setErrorMessage(getErrorMessage(resp));
- setStatus(INDEX_STATUS.ERROR);
- return;
- }
-
+ } else if (dataGridDataError !== null) {
+ setErrorMessage(getErrorMessage(dataGridDataError));
+ setStatus(INDEX_STATUS.ERROR);
+ } else if (!dataGridDataIsLoading && !dataGridDataIsError && dataGridData !== undefined) {
const isCrossClusterSearch = indexPattern.includes(':');
- const isMissingFields = resp.hits.hits.every((d) => typeof d.fields === 'undefined');
+ const isMissingFields = dataGridData.hits.hits.every((d) => typeof d.fields === 'undefined');
- const docs = resp.hits.hits.map((d) => getProcessedFields(d.fields ?? {}));
+ const docs = dataGridData.hits.hits.map((d) => getProcessedFields(d.fields ?? {}));
setCcsWarning(isCrossClusterSearch && isMissingFields);
setRowCountInfo({
- rowCount: typeof resp.hits.total === 'number' ? resp.hits.total : resp.hits.total!.value,
+ rowCount:
+ typeof dataGridData.hits.total === 'number'
+ ? dataGridData.hits.total
+ : dataGridData.hits.total!.value,
rowCountRelation:
- typeof resp.hits.total === 'number'
+ typeof dataGridData.hits.total === 'number'
? ('eq' as estypes.SearchTotalHitsRelation)
- : resp.hits.total!.relation,
+ : dataGridData.hits.total!.relation,
});
setTableItems(docs);
setStatus(INDEX_STATUS.LOADED);
- };
-
- fetchDataGridData();
-
- return () => {
- abortController.abort();
- };
- // custom comparison
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [
- indexPattern,
+ }
// eslint-disable-next-line react-hooks/exhaustive-deps
- JSON.stringify([
- query,
- pagination,
- sortingColumns,
- dataViewFields,
- combinedRuntimeMappings,
- timeRangeMs,
- ]),
- ]);
+ }, [dataGridDataError, dataGridDataIsError, dataGridDataIsLoading]);
const allDataViewFieldNames = new Set(dataView.fields.map((f) => f.name));
const { error: histogramsForFieldsError, data: histogramsForFieldsData } =
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/common/filter_agg/components/filter_term_form.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/common/filter_agg/components/filter_term_form.tsx
index 0c6fae30fd1f0..c35cca74c72ac 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/common/filter_agg/components/filter_term_form.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/common/filter_agg/components/filter_term_form.tsx
@@ -6,7 +6,7 @@
*/
import { debounce } from 'lodash';
-import React, { useCallback, useContext, useEffect, useState } from 'react';
+import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react';
import useUpdateEffect from 'react-use/lib/useUpdateEffect';
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
@@ -18,7 +18,6 @@ import { i18n } from '@kbn/i18n';
import { isMultiBucketAggregate } from '@kbn/ml-agg-utils';
import { useDataSearch } from '../../../../../../../hooks/use_data_search';
-import { isEsSearchResponseWithAggregations } from '../../../../../../../../../common/api_schemas/type_guards';
import { CreateTransformWizardContext } from '../../../../wizard/wizard';
import { useToastNotifications } from '../../../../../../../app_dependencies';
@@ -33,16 +32,22 @@ export const FilterTermForm: FilterAggConfigTerm['aggTypeConfig']['FilterAggForm
selectedField,
}) => {
const { dataView, runtimeMappings } = useContext(CreateTransformWizardContext);
- const dataSearch = useDataSearch();
const toastNotifications = useToastNotifications();
- const [options, setOptions] = useState([]);
- const [isLoading, setIsLoading] = useState(true);
const [searchValue, setSearchValue] = useState('');
+ const debouncedOnSearchChange = useMemo(
+ () => debounce((d: string) => setSearchValue(d), 600),
+ []
+ );
- const onSearchChange = (newSearchValue: string) => {
- setSearchValue(newSearchValue);
- };
+ useEffect(() => {
+ // Simulate initial load.
+ debouncedOnSearchChange('');
+ // Cancel debouncing when unmounting
+ return () => debouncedOnSearchChange.cancel();
+ // Only call on mount
+ /* eslint-disable-next-line react-hooks/exhaustive-deps */
+ }, []);
const updateConfig = useCallback(
(update) => {
@@ -56,80 +61,53 @@ export const FilterTermForm: FilterAggConfigTerm['aggTypeConfig']['FilterAggForm
[config, onChange]
);
- useEffect(() => {
- const abortController = new AbortController();
-
- const fetchOptions = debounce(async () => {
- if (selectedField === undefined) return;
-
- setIsLoading(true);
- setOptions([]);
-
- const esSearchRequest = {
- index: dataView!.title,
- body: {
- ...(runtimeMappings !== undefined ? { runtime_mappings: runtimeMappings } : {}),
- query: {
- wildcard: {
- [selectedField!]: {
- value: `*${searchValue}*`,
- },
+ const { data, isError, isLoading } = useDataSearch(
+ {
+ index: dataView!.title,
+ body: {
+ ...(runtimeMappings !== undefined ? { runtime_mappings: runtimeMappings } : {}),
+ query: {
+ wildcard: {
+ [selectedField!]: {
+ value: `*${searchValue}*`,
},
},
- aggs: {
- field_values: {
- terms: {
- field: selectedField,
- size: 10,
- },
+ },
+ aggs: {
+ field_values: {
+ terms: {
+ field: selectedField,
+ size: 10,
},
},
- size: 0,
},
- };
-
- const response = await dataSearch(esSearchRequest, abortController.signal);
-
- setIsLoading(false);
-
- if (
- !(
- isEsSearchResponseWithAggregations(response) &&
- isMultiBucketAggregate(
- response.aggregations.field_values
- )
- )
- ) {
- toastNotifications.addWarning(
- i18n.translate('xpack.transform.agg.popoverForm.filerAgg.term.errorFetchSuggestions', {
- defaultMessage: 'Unable to fetch suggestions',
- })
- );
- return;
- }
+ size: 0,
+ },
+ },
+ // Check whether fetching should be enabled
+ selectedField !== undefined
+ );
- setOptions(
- (
- response.aggregations.field_values
- .buckets as estypes.AggregationsSignificantLongTermsBucket[]
- ).map((value) => ({ label: value.key + '' }))
+ useEffect(() => {
+ if (isError) {
+ toastNotifications.addWarning(
+ i18n.translate('xpack.transform.agg.popoverForm.filerAgg.term.errorFetchSuggestions', {
+ defaultMessage: 'Unable to fetch suggestions',
+ })
);
- }, 600);
-
- fetchOptions();
-
- return () => {
- // make sure the ongoing request is canceled
- fetchOptions.cancel();
- abortController.abort();
- };
+ }
/* eslint-disable-next-line react-hooks/exhaustive-deps */
- }, [selectedField]);
-
- useEffect(() => {
- // Simulate initial load.
- onSearchChange('');
- }, []);
+ }, [isError]);
+
+ const options: EuiComboBoxOptionOption[] =
+ isMultiBucketAggregate(
+ data?.aggregations?.field_values
+ )
+ ? (
+ data?.aggregations?.field_values
+ .buckets as estypes.AggregationsSignificantLongTermsBucket[]
+ ).map((value) => ({ label: value.key + '' }))
+ : [];
useUpdateEffect(() => {
// Reset value control on field change
@@ -168,7 +146,7 @@ export const FilterTermForm: FilterAggConfigTerm['aggTypeConfig']['FilterAggForm
onCreateOption={(value) => {
updateConfig({ value });
}}
- onSearchChange={onSearchChange}
+ onSearchChange={debouncedOnSearchChange}
data-test-subj="transformFilterTermValueSelector"
/>
From c4b4d53cb0465bacef1fd74883fcdaf98eb00dfd Mon Sep 17 00:00:00 2001
From: Walter Rafelsberger
Date: Tue, 22 Aug 2023 23:08:14 +0200
Subject: [PATCH 17/53] cleanup
---
.../public/app/hooks/use_create_transform.tsx | 18 ++++++------------
.../public/app/hooks/use_delete_transform.tsx | 14 ++++++--------
.../app/hooks/use_reauthorize_transform.tsx | 12 +++++-------
.../public/app/hooks/use_reset_transform.tsx | 12 +++++-------
.../app/hooks/use_schedule_now_transform.tsx | 12 +++++-------
.../public/app/hooks/use_start_transform.tsx | 12 +++++-------
.../public/app/hooks/use_stop_transform.tsx | 12 +++++-------
.../public/app/hooks/use_update_transform.ts | 7 +++----
.../transform_management_section.tsx | 2 +-
9 files changed, 41 insertions(+), 60 deletions(-)
diff --git a/x-pack/plugins/transform/public/app/hooks/use_create_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_create_transform.tsx
index d97508ed3a009..7f7d397d0baee 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_create_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_create_transform.tsx
@@ -45,18 +45,12 @@ export const useCreateTransform = (
}
const mutation = useMutation({
- mutationFn: () => {
- return http.put(
- addInternalBasePath(`transforms/${transformId}`),
- {
- body: JSON.stringify(transformConfig),
- version: '1',
- }
- );
- },
- onError: (error) => {
- errorToast(error);
- },
+ mutationFn: () =>
+ http.put(addInternalBasePath(`transforms/${transformId}`), {
+ body: JSON.stringify(transformConfig),
+ version: '1',
+ }),
+ onError: (error) => errorToast(error),
onSuccess: (resp) => {
if (resp.errors.length > 0) {
errorToast(resp.errors.length === 1 ? resp.errors[0] : resp.errors);
diff --git a/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx
index 453a9bd912c07..99fb593b4d165 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx
@@ -127,13 +127,12 @@ export const useDeleteTransforms = () => {
const toastNotifications = useToastNotifications();
const mutation = useMutation({
- mutationFn: (reqBody: DeleteTransformsRequestSchema) => {
- return http.post(addInternalBasePath('delete_transforms'), {
+ mutationFn: (reqBody: DeleteTransformsRequestSchema) =>
+ http.post(addInternalBasePath('delete_transforms'), {
body: JSON.stringify(reqBody),
version: '1',
- });
- },
- onError: (error) => {
+ }),
+ onError: (error) =>
toastNotifications.addDanger({
title: i18n.translate('xpack.transform.transformList.deleteTransformGenericErrorMessage', {
defaultMessage: 'An error occurred calling the API endpoint to delete transforms.',
@@ -147,8 +146,7 @@ export const useDeleteTransforms = () => {
/>,
{ theme$: theme.theme$ }
),
- });
- },
+ }),
onSuccess: (results) => {
const isBulk = Object.keys(results).length > 1;
const successCount: Record = {
@@ -303,5 +301,5 @@ export const useDeleteTransforms = () => {
},
});
- return (reqBody: DeleteTransformsRequestSchema) => mutation.mutate(reqBody);
+ return mutation;
};
diff --git a/x-pack/plugins/transform/public/app/hooks/use_reauthorize_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_reauthorize_transform.tsx
index 34a18acfaafe9..c226d82fc0410 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_reauthorize_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_reauthorize_transform.tsx
@@ -29,16 +29,15 @@ export const useReauthorizeTransforms = () => {
const toastNotifications = useToastNotifications();
const mutation = useMutation({
- mutationFn: (reqBody: ReauthorizeTransformsRequestSchema) => {
- return http.post(
+ mutationFn: (reqBody: ReauthorizeTransformsRequestSchema) =>
+ http.post(
addInternalBasePath('reauthorize_transforms'),
{
body: JSON.stringify(reqBody),
version: '1',
}
- );
- },
- onError: (error) => {
+ ),
+ onError: (error) =>
toastNotifications.addDanger({
title: i18n.translate(
'xpack.transform.stepCreateForm.reauthorizeTransformResponseSchemaErrorMessage',
@@ -50,8 +49,7 @@ export const useReauthorizeTransforms = () => {
,
{ theme$: theme.theme$ }
),
- });
- },
+ }),
onSuccess: (results) => {
for (const transformId in results) {
// hasOwnProperty check to ensure only properties on object itself, and not its prototypes
diff --git a/x-pack/plugins/transform/public/app/hooks/use_reset_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_reset_transform.tsx
index d91ddaf142306..e3147f0578ea5 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_reset_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_reset_transform.tsx
@@ -30,13 +30,12 @@ export const useResetTransforms = () => {
const toastNotifications = useToastNotifications();
const mutation = useMutation({
- mutationFn: (reqBody: ResetTransformsRequestSchema) => {
- return http.post(addInternalBasePath('reset_transforms'), {
+ mutationFn: (reqBody: ResetTransformsRequestSchema) =>
+ http.post(addInternalBasePath('reset_transforms'), {
body: JSON.stringify(reqBody),
version: '1',
- });
- },
- onError: (error) => {
+ }),
+ onError: (error) =>
toastNotifications.addDanger({
title: i18n.translate('xpack.transform.transformList.resetTransformGenericErrorMessage', {
defaultMessage: 'An error occurred calling the API endpoint to reset transforms.',
@@ -50,8 +49,7 @@ export const useResetTransforms = () => {
/>,
{ theme$: theme.theme$ }
),
- });
- },
+ }),
onSuccess: (results) => {
const isBulk = Object.keys(results).length > 1;
const successCount: Record = {
diff --git a/x-pack/plugins/transform/public/app/hooks/use_schedule_now_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_schedule_now_transform.tsx
index 398bd42629167..ac37b25c9478b 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_schedule_now_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_schedule_now_transform.tsx
@@ -28,16 +28,15 @@ export const useScheduleNowTransforms = () => {
const toastNotifications = useToastNotifications();
const mutation = useMutation({
- mutationFn: (reqBody: ScheduleNowTransformsRequestSchema) => {
- return http.post(
+ mutationFn: (reqBody: ScheduleNowTransformsRequestSchema) =>
+ http.post(
addInternalBasePath('schedule_now_transforms'),
{
body: JSON.stringify(reqBody),
version: '1',
}
- );
- },
- onError: (error) => {
+ ),
+ onError: (error) =>
toastNotifications.addDanger({
title: i18n.translate(
'xpack.transform.stepCreateForm.scheduleNowTransformResponseSchemaErrorMessage',
@@ -50,8 +49,7 @@ export const useScheduleNowTransforms = () => {
,
{ theme$: theme.theme$ }
),
- });
- },
+ }),
onSuccess: (results) => {
for (const transformId in results) {
// hasOwnProperty check to ensure only properties on object itself, and not its prototypes
diff --git a/x-pack/plugins/transform/public/app/hooks/use_start_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_start_transform.tsx
index 65defb8a5dbee..ddb3b1a0e0ef3 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_start_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_start_transform.tsx
@@ -28,13 +28,12 @@ export const useStartTransforms = () => {
const toastNotifications = useToastNotifications();
const mutation = useMutation({
- mutationFn: (reqBody: StartTransformsRequestSchema) => {
- return http.post(addInternalBasePath('start_transforms'), {
+ mutationFn: (reqBody: StartTransformsRequestSchema) =>
+ http.post(addInternalBasePath('start_transforms'), {
body: JSON.stringify(reqBody),
version: '1',
- });
- },
- onError: (error) => {
+ }),
+ onError: (error) =>
toastNotifications.addDanger({
title: i18n.translate(
'xpack.transform.stepCreateForm.startTransformResponseSchemaErrorMessage',
@@ -46,8 +45,7 @@ export const useStartTransforms = () => {
,
{ theme$: theme.theme$ }
),
- });
- },
+ }),
onSuccess: (results) => {
for (const transformId in results) {
// hasOwnProperty check to ensure only properties on object itself, and not its prototypes
diff --git a/x-pack/plugins/transform/public/app/hooks/use_stop_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_stop_transform.tsx
index 004ee40389200..35f58302a256d 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_stop_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_stop_transform.tsx
@@ -29,13 +29,12 @@ export const useStopTransforms = () => {
const toastNotifications = useToastNotifications();
const mutation = useMutation({
- mutationFn: (reqBody: StopTransformsRequestSchema) => {
- return http.post(addInternalBasePath('stop_transforms'), {
+ mutationFn: (reqBody: StopTransformsRequestSchema) =>
+ http.post(addInternalBasePath('stop_transforms'), {
body: JSON.stringify(reqBody),
version: '1',
- });
- },
- onError: (error) => {
+ }),
+ onError: (error) =>
toastNotifications.addDanger({
title: i18n.translate(
'xpack.transform.transformList.stopTransformResponseSchemaErrorMessage',
@@ -47,8 +46,7 @@ export const useStopTransforms = () => {
,
{ theme$: theme.theme$ }
),
- });
- },
+ }),
onSuccess: (results) => {
for (const transformId in results) {
// hasOwnProperty check to ensure only properties on object itself, and not its prototypes
diff --git a/x-pack/plugins/transform/public/app/hooks/use_update_transform.ts b/x-pack/plugins/transform/public/app/hooks/use_update_transform.ts
index ec1c572a66b86..23c295d7c7be9 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_update_transform.ts
+++ b/x-pack/plugins/transform/public/app/hooks/use_update_transform.ts
@@ -28,15 +28,14 @@ export const useUpdateTransform = (
const toastNotifications = useToastNotifications();
const mutation = useMutation({
- mutationFn: () => {
- return http.post(
+ mutationFn: () =>
+ http.post(
addInternalBasePath(`transforms/${transformId}/_update`),
{
body: JSON.stringify(transformConfig),
version: '1',
}
- );
- },
+ ),
onSuccess: () => {
toastNotifications.addSuccess(
i18n.translate('xpack.transform.transformList.editTransformSuccessMessage', {
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/transform_management_section.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/transform_management_section.tsx
index 1a8db994e0fec..12e85a9232b84 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/transform_management_section.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/transform_management_section.tsx
@@ -44,7 +44,7 @@ import {
export const TransformManagement: FC = () => {
const { esTransform } = useDocumentationLinks();
- const deleteTransforms = useDeleteTransforms();
+ const { mutate: deleteTransforms } = useDeleteTransforms();
const {
isInitialLoading,
From be3e0fcda240f583e0e80a6c279084e19e29520d Mon Sep 17 00:00:00 2001
From: Walter Rafelsberger
Date: Tue, 22 Aug 2023 23:18:24 +0200
Subject: [PATCH 18/53] cleanup
---
.../transform/public/app/hooks/use_create_transform.tsx | 2 +-
.../app/sections/clone_transform/clone_transform_section.tsx | 4 ++--
.../components/step_details/step_details_form.tsx | 3 +--
3 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/x-pack/plugins/transform/public/app/hooks/use_create_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_create_transform.tsx
index 7f7d397d0baee..7d404ef2c66bb 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_create_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_create_transform.tsx
@@ -50,7 +50,7 @@ export const useCreateTransform = (
body: JSON.stringify(transformConfig),
version: '1',
}),
- onError: (error) => errorToast(error),
+ onError: errorToast,
onSuccess: (resp) => {
if (resp.errors.length > 0) {
errorToast(resp.errors.length === 1 ? resp.errors[0] : resp.errors);
diff --git a/x-pack/plugins/transform/public/app/sections/clone_transform/clone_transform_section.tsx b/x-pack/plugins/transform/public/app/sections/clone_transform/clone_transform_section.tsx
index 04e04f4e47b81..269adfd3eb266 100644
--- a/x-pack/plugins/transform/public/app/sections/clone_transform/clone_transform_section.tsx
+++ b/x-pack/plugins/transform/public/app/sections/clone_transform/clone_transform_section.tsx
@@ -19,7 +19,7 @@ import {
EuiPageHeader,
EuiSpacer,
} from '@elastic/eui';
-import { isHttpFetchError } from '@kbn/core-http-browser';
+
import { APP_CREATE_TRANSFORM_CLUSTER_PRIVILEGES } from '../../../../common/constants';
import { TransformConfigUnion } from '../../../../common/types/transform';
@@ -80,7 +80,7 @@ export const CloneTransformSection: FC = ({ match, location }) => {
);
useEffect(() => {
- if (isHttpFetchError(error) && error.message !== errorMessage) {
+ if (error !== null && error.message !== errorMessage) {
setTransformConfig(undefined);
setErrorMessage(error.message);
setIsInitialized(true);
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx
index a234795ebe788..9fda641d16f65 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx
@@ -27,7 +27,6 @@ import {
import { KBN_FIELD_TYPES } from '@kbn/field-types';
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
-import { isHttpFetchError } from '@kbn/core-http-browser';
import { retentionPolicyMaxAgeInvalidErrorMessage } from '../../../../common/constants/validation_messages';
import { DEFAULT_TRANSFORM_FREQUENCY } from '../../../../../../common/constants';
import { TransformId } from '../../../../../../common/types/transform';
@@ -128,7 +127,7 @@ export const StepDetailsForm: FC = React.memo(
const transformIds = transforms?.tableRows.map((d) => d.id) ?? [];
useEffect(() => {
- if (isHttpFetchError(transformsError)) {
+ if (transformsError !== null) {
toastNotifications.addDanger({
title: i18n.translate('xpack.transform.stepDetailsForm.errorGettingTransformList', {
defaultMessage: 'An error occurred getting the existing transform IDs:',
From 30801503d07cf35e44c823c2a850d7d6683249ff Mon Sep 17 00:00:00 2001
From: Walter Rafelsberger
Date: Wed, 23 Aug 2023 00:40:17 +0200
Subject: [PATCH 19/53] refactor IndexService into custom hooks using
react-query
---
x-pack/plugins/transform/common/constants.ts | 2 +
.../public/app/hooks/use_can_delete_index.ts | 33 ++++++
.../public/app/hooks/use_data_view_exists.ts | 32 ++++++
.../public/app/hooks/use_delete_transform.tsx | 108 ++++++++----------
.../action_delete/use_delete_action.tsx | 2 +-
.../public/app/services/es_index_service.ts | 29 -----
6 files changed, 117 insertions(+), 89 deletions(-)
create mode 100644 x-pack/plugins/transform/public/app/hooks/use_can_delete_index.ts
create mode 100644 x-pack/plugins/transform/public/app/hooks/use_data_view_exists.ts
delete mode 100644 x-pack/plugins/transform/public/app/services/es_index_service.ts
diff --git a/x-pack/plugins/transform/common/constants.ts b/x-pack/plugins/transform/common/constants.ts
index 1584811c0df6b..1bf6a81167124 100644
--- a/x-pack/plugins/transform/common/constants.ts
+++ b/x-pack/plugins/transform/common/constants.ts
@@ -33,7 +33,9 @@ export const addInternalBasePath = (uri: string): string => `${INTERNAL_API_BASE
export const addExternalBasePath = (uri: string): string => `${EXTERNAL_API_BASE_PATH}${uri}`;
export const TRANSFORM_REACT_QUERY_KEYS = {
+ CAN_DELETE_INDEX: 'transform.can_delete_index',
DATA_SEARCH: 'transform.data_search',
+ DATA_VIEW_EXISTS: 'transform.data_view_exists',
GET_DATA_VIEW_TITLES: 'transform.get_data_view_titles',
GET_ES_INDICES: 'transform.get_es_indices',
GET_ES_INGEST_PIPELINES: 'transform.get_es_ingest_pipelines',
diff --git a/x-pack/plugins/transform/public/app/hooks/use_can_delete_index.ts b/x-pack/plugins/transform/public/app/hooks/use_can_delete_index.ts
new file mode 100644
index 0000000000000..d198daa9ab26f
--- /dev/null
+++ b/x-pack/plugins/transform/public/app/hooks/use_can_delete_index.ts
@@ -0,0 +1,33 @@
+/*
+ * 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 { useQuery } from '@tanstack/react-query';
+
+import type { IHttpFetchError } from '@kbn/core-http-browser';
+
+import type { PrivilegesAndCapabilities } from '../../../common/privilege/has_privilege_factory';
+import { addInternalBasePath, TRANSFORM_REACT_QUERY_KEYS } from '../../../common/constants';
+
+import { useAppDependencies } from '../app_dependencies';
+
+export const useCanDeleteIndex = () => {
+ const { http } = useAppDependencies();
+
+ return useQuery(
+ [TRANSFORM_REACT_QUERY_KEYS.CAN_DELETE_INDEX],
+ async ({ signal }) => {
+ const resp = await http.get(addInternalBasePath('privileges'), {
+ version: '1',
+ signal,
+ });
+ if (!resp) {
+ return false;
+ }
+ return resp.privileges.hasAllPrivileges;
+ }
+ );
+};
diff --git a/x-pack/plugins/transform/public/app/hooks/use_data_view_exists.ts b/x-pack/plugins/transform/public/app/hooks/use_data_view_exists.ts
new file mode 100644
index 0000000000000..7f2a2b48af1c1
--- /dev/null
+++ b/x-pack/plugins/transform/public/app/hooks/use_data_view_exists.ts
@@ -0,0 +1,32 @@
+/*
+ * 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 { useQuery } from '@tanstack/react-query';
+
+import type { ErrorType } from '@kbn/ml-error-utils';
+
+import { TRANSFORM_REACT_QUERY_KEYS } from '../../../common/constants';
+
+import { useAppDependencies } from '../app_dependencies';
+
+export const useDataViewExists = (indexName?: string, enabled?: boolean, initialData?: boolean) => {
+ const {
+ data: { dataViews: dataViewsContract },
+ } = useAppDependencies();
+
+ return useQuery(
+ [TRANSFORM_REACT_QUERY_KEYS.DATA_VIEW_EXISTS, indexName],
+ async () => {
+ if (indexName === undefined) {
+ return false;
+ }
+
+ return (await dataViewsContract.find(indexName)).some(({ title }) => title === indexName);
+ },
+ { enabled, initialData }
+ );
+};
diff --git a/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx
index 99fb593b4d165..58e3db4e7cd22 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx
@@ -5,7 +5,7 @@
* 2.0.
*/
-import React, { useCallback, useEffect, useState } from 'react';
+import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useMutation } from '@tanstack/react-query';
import { i18n } from '@kbn/i18n';
@@ -19,24 +19,42 @@ import type {
DeleteTransformsResponseSchema,
} from '../../../common/api_schemas/delete_transforms';
import { getErrorMessage } from '../../../common/utils/errors';
+
import { useAppDependencies, useToastNotifications } from '../app_dependencies';
+import { useCanDeleteIndex } from './use_can_delete_index';
+import { useDataViewExists } from './use_data_view_exists';
import { useRefreshTransformList, type TransformListRow } from '../common';
import { ToastNotificationText } from '../components';
-import { indexService } from '../services/es_index_service';
export const useDeleteIndexAndTargetIndex = (items: TransformListRow[]) => {
const {
- http,
- data: { dataViews: dataViewsContract },
application: { capabilities },
} = useAppDependencies();
const toastNotifications = useToastNotifications();
+ const userCanDeleteDataView =
+ capabilities.savedObjectsManagement.delete === true || capabilities.indexPatterns.save === true;
+
const [deleteDestIndex, setDeleteDestIndex] = useState(true);
- const [deleteDataView, setDeleteDataView] = useState(true);
- const [userCanDeleteIndex, setUserCanDeleteIndex] = useState(false);
- const [dataViewExists, setDataViewExists] = useState(false);
- const [userCanDeleteDataView, setUserCanDeleteDataView] = useState(false);
+ const [deleteDataView, setDeleteDataView] = useState(userCanDeleteDataView);
+
+ const { error: canDeleteIndexError, data: canDeleteIndex } = useCanDeleteIndex();
+ const userCanDeleteIndex = canDeleteIndex === true;
+
+ useEffect(() => {
+ if (canDeleteIndexError !== null) {
+ toastNotifications.addDanger(
+ i18n.translate(
+ 'xpack.transform.transformList.errorWithCheckingIfUserCanDeleteIndexNotificationErrorMessage',
+ {
+ defaultMessage: 'An error occurred checking if user can delete destination index',
+ }
+ )
+ );
+ }
+ // custom comparison
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [canDeleteIndexError]);
const toggleDeleteIndex = useCallback(
() => setDeleteDestIndex(!deleteDestIndex),
@@ -46,67 +64,39 @@ export const useDeleteIndexAndTargetIndex = (items: TransformListRow[]) => {
() => setDeleteDataView(!deleteDataView),
[deleteDataView]
);
- const checkDataViewExists = useCallback(
- async (indexName: string) => {
- try {
- const dvExists = await indexService.dataViewExists(dataViewsContract, indexName);
- setDataViewExists(dvExists);
- } catch (e) {
- const error = extractErrorMessage(e);
- toastNotifications.addDanger(
- i18n.translate(
- 'xpack.transform.deleteTransform.errorWithCheckingIfDataViewExistsNotificationErrorMessage',
- {
- defaultMessage: 'An error occurred checking if data view {dataView} exists: {error}',
- values: { dataView: indexName, error },
- }
- )
- );
- }
- },
- [dataViewsContract, toastNotifications]
+ const indexName = useMemo(() => {
+ // if user only deleting one transform
+ if (items.length === 1) {
+ const config = items[0].config;
+ return Array.isArray(config.dest.index) ? config.dest.index[0] : config.dest.index;
+ }
+ }, [items]);
+
+ const { error: dataViewExistsError, data: dataViewExists } = useDataViewExists(
+ indexName,
+ items.length === 1,
+ items.length !== 1
);
- const checkUserIndexPermission = useCallback(async () => {
- try {
- const userCanDelete = await indexService.canDeleteIndex(http);
- if (userCanDelete) {
- setUserCanDeleteIndex(true);
- }
- const canDeleteDataView =
- capabilities.savedObjectsManagement.delete === true ||
- capabilities.indexPatterns.save === true;
- setUserCanDeleteDataView(canDeleteDataView);
- if (canDeleteDataView === false) {
- setDeleteDataView(false);
- }
- } catch (e) {
+ useEffect(() => {
+ if (dataViewExistsError !== null) {
toastNotifications.addDanger(
i18n.translate(
- 'xpack.transform.transformList.errorWithCheckingIfUserCanDeleteIndexNotificationErrorMessage',
+ 'xpack.transform.deleteTransform.errorWithCheckingIfDataViewExistsNotificationErrorMessage',
{
- defaultMessage: 'An error occurred checking if user can delete destination index',
+ defaultMessage: 'An error occurred checking if data view {dataView} exists: {error}',
+ values: {
+ dataView: indexName,
+ error: extractErrorMessage(dataViewExistsError),
+ },
}
)
);
}
- }, [http, toastNotifications, capabilities]);
-
- useEffect(() => {
- checkUserIndexPermission();
-
- // if user only deleting one transform
- if (items.length === 1) {
- const config = items[0].config;
- const destinationIndex = Array.isArray(config.dest.index)
- ? config.dest.index[0]
- : config.dest.index;
- checkDataViewExists(destinationIndex);
- } else {
- setDataViewExists(true);
- }
- }, [checkDataViewExists, checkUserIndexPermission, items]);
+ // custom comparison
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [dataViewExistsError]);
return {
userCanDeleteIndex,
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/use_delete_action.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/use_delete_action.tsx
index 357809b54746b..e81612fe77bac 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/use_delete_action.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/use_delete_action.tsx
@@ -23,7 +23,7 @@ export type DeleteAction = ReturnType;
export const useDeleteAction = (forceDisable: boolean) => {
const { canDeleteTransform } = useContext(AuthorizationContext).capabilities;
- const deleteTransforms = useDeleteTransforms();
+ const { mutate: deleteTransforms } = useDeleteTransforms();
const [isModalVisible, setModalVisible] = useState(false);
const [items, setItems] = useState([]);
diff --git a/x-pack/plugins/transform/public/app/services/es_index_service.ts b/x-pack/plugins/transform/public/app/services/es_index_service.ts
deleted file mode 100644
index d8d058b731a74..0000000000000
--- a/x-pack/plugins/transform/public/app/services/es_index_service.ts
+++ /dev/null
@@ -1,29 +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 type { HttpSetup } from '@kbn/core/public';
-import type { DataViewsContract } from '@kbn/data-views-plugin/public';
-import { addInternalBasePath } from '../../../common/constants';
-
-export class IndexService {
- async canDeleteIndex(http: HttpSetup) {
- const privilege = await http.get<{ hasAllPrivileges: boolean }>(
- addInternalBasePath(`privileges`),
- { version: '1' }
- );
- if (!privilege) {
- return false;
- }
- return privilege.hasAllPrivileges;
- }
-
- async dataViewExists(dataViewsContract: DataViewsContract, indexName: string) {
- return (await dataViewsContract.find(indexName)).some(({ title }) => title === indexName);
- }
-}
-
-export const indexService = new IndexService();
From d302856712c4a7742fb08381837b0832fb166b95 Mon Sep 17 00:00:00 2001
From: Walter Rafelsberger
Date: Wed, 23 Aug 2023 08:39:51 +0200
Subject: [PATCH 20/53] fix tests
---
.../transform/public/app/hooks/use_delete_transform.tsx | 3 ++-
.../api_integration/apis/transform/stop_transforms.ts | 8 --------
x-pack/test/api_integration/apis/transform/transforms.ts | 5 -----
.../api_integration/apis/transform/transforms_nodes.ts | 3 ---
.../api_integration/apis/transform/transforms_stats.ts | 2 --
5 files changed, 2 insertions(+), 19 deletions(-)
diff --git a/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx
index 58e3db4e7cd22..55925a86cee85 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx
@@ -33,7 +33,8 @@ export const useDeleteIndexAndTargetIndex = (items: TransformListRow[]) => {
const toastNotifications = useToastNotifications();
const userCanDeleteDataView =
- capabilities.savedObjectsManagement.delete === true || capabilities.indexPatterns.save === true;
+ (capabilities.savedObjectsManagement && capabilities.savedObjectsManagement.delete === true) ||
+ (capabilities.indexPatterns && capabilities.indexPatterns.save === true);
const [deleteDestIndex, setDeleteDestIndex] = useState(true);
const [deleteDataView, setDeleteDataView] = useState(userCanDeleteDataView);
diff --git a/x-pack/test/api_integration/apis/transform/stop_transforms.ts b/x-pack/test/api_integration/apis/transform/stop_transforms.ts
index 7811432e7417a..c982c6b45f1c9 100644
--- a/x-pack/test/api_integration/apis/transform/stop_transforms.ts
+++ b/x-pack/test/api_integration/apis/transform/stop_transforms.ts
@@ -9,7 +9,6 @@ import expect from '@kbn/expect';
import type { PutTransformsRequestSchema } from '@kbn/transform-plugin/common/api_schemas/transforms';
import type { StopTransformsRequestSchema } from '@kbn/transform-plugin/common/api_schemas/stop_transforms';
-import { isStopTransformsResponseSchema } from '@kbn/transform-plugin/common/api_schemas/type_guards';
import { TRANSFORM_STATE } from '@kbn/transform-plugin/common/constants';
@@ -76,7 +75,6 @@ export default ({ getService }: FtrProviderContext) => {
.send(reqBody);
transform.api.assertResponseStatusCode(200, status, body);
- expect(isStopTransformsResponseSchema(body)).to.eql(true);
expect(body[transformId].success).to.eql(true);
expect(typeof body[transformId].error).to.eql('undefined');
await transform.api.waitForTransformState(transformId, TRANSFORM_STATE.STOPPED);
@@ -97,7 +95,6 @@ export default ({ getService }: FtrProviderContext) => {
.send(reqBody);
transform.api.assertResponseStatusCode(200, status, body);
- expect(isStopTransformsResponseSchema(body)).to.eql(true);
expect(body[transformId].success).to.eql(false);
expect(typeof body[transformId].error).to.eql('object');
@@ -121,7 +118,6 @@ export default ({ getService }: FtrProviderContext) => {
.send(reqBody);
transform.api.assertResponseStatusCode(200, status, body);
- expect(isStopTransformsResponseSchema(body)).to.eql(true);
expect(body.invalid_transform_id.success).to.eql(false);
expect(body.invalid_transform_id).to.have.property('error');
});
@@ -158,8 +154,6 @@ export default ({ getService }: FtrProviderContext) => {
.send(reqBody);
transform.api.assertResponseStatusCode(200, status, body);
- expect(isStopTransformsResponseSchema(body)).to.eql(true);
-
await asyncForEach(reqBody, async ({ id: transformId }: { id: string }, idx: number) => {
expect(body[transformId].success).to.eql(true);
await transform.api.waitForTransformState(transformId, TRANSFORM_STATE.STOPPED);
@@ -183,8 +177,6 @@ export default ({ getService }: FtrProviderContext) => {
]);
transform.api.assertResponseStatusCode(200, status, body);
- expect(isStopTransformsResponseSchema(body)).to.eql(true);
-
await asyncForEach(reqBody, async ({ id: transformId }: { id: string }, idx: number) => {
expect(body[transformId].success).to.eql(true);
await transform.api.waitForTransformState(transformId, TRANSFORM_STATE.STOPPED);
diff --git a/x-pack/test/api_integration/apis/transform/transforms.ts b/x-pack/test/api_integration/apis/transform/transforms.ts
index 4c3d1641d6d5f..2016876ba93a6 100644
--- a/x-pack/test/api_integration/apis/transform/transforms.ts
+++ b/x-pack/test/api_integration/apis/transform/transforms.ts
@@ -8,7 +8,6 @@
import expect from '@kbn/expect';
import type { GetTransformsResponseSchema } from '@kbn/transform-plugin/common/api_schemas/transforms';
-import { isGetTransformsResponseSchema } from '@kbn/transform-plugin/common/api_schemas/type_guards';
import { getCommonRequestHeader } from '../../../functional/services/ml/common_api';
import { USER } from '../../../functional/services/transform/security_common';
@@ -43,8 +42,6 @@ export default ({ getService }: FtrProviderContext) => {
}
function assertTransformsResponseBody(body: GetTransformsResponseSchema) {
- expect(isGetTransformsResponseSchema(body)).to.eql(true);
-
expect(body.count).to.eql(expected.apiTransformTransforms.count);
expect(body.transforms).to.have.length(expected.apiTransformTransforms.count);
@@ -62,8 +59,6 @@ export default ({ getService }: FtrProviderContext) => {
}
function assertSingleTransformResponseBody(body: GetTransformsResponseSchema) {
- expect(isGetTransformsResponseSchema(body)).to.eql(true);
-
expect(body.count).to.eql(expected.apiTransformTransformsTransformId.count);
expect(body.transforms).to.have.length(expected.apiTransformTransformsTransformId.count);
diff --git a/x-pack/test/api_integration/apis/transform/transforms_nodes.ts b/x-pack/test/api_integration/apis/transform/transforms_nodes.ts
index bf3e91df69684..10f4413a8f85f 100644
--- a/x-pack/test/api_integration/apis/transform/transforms_nodes.ts
+++ b/x-pack/test/api_integration/apis/transform/transforms_nodes.ts
@@ -8,7 +8,6 @@
import expect from '@kbn/expect';
import type { GetTransformNodesResponseSchema } from '@kbn/transform-plugin/common/api_schemas/transforms';
-import { isGetTransformNodesResponseSchema } from '@kbn/transform-plugin/common/api_schemas/type_guards';
import { getCommonRequestHeader } from '../../../functional/services/ml/common_api';
import { USER } from '../../../functional/services/transform/security_common';
@@ -25,8 +24,6 @@ export default ({ getService }: FtrProviderContext) => {
};
function assertTransformsNodesResponseBody(body: GetTransformNodesResponseSchema) {
- expect(isGetTransformNodesResponseSchema(body)).to.eql(true);
-
expect(body.count).to.not.be.lessThan(expected.apiTransformTransformsNodes.minCount);
}
diff --git a/x-pack/test/api_integration/apis/transform/transforms_stats.ts b/x-pack/test/api_integration/apis/transform/transforms_stats.ts
index 41cdafd0c058f..aea5c049343e9 100644
--- a/x-pack/test/api_integration/apis/transform/transforms_stats.ts
+++ b/x-pack/test/api_integration/apis/transform/transforms_stats.ts
@@ -8,7 +8,6 @@
import expect from '@kbn/expect';
import type { GetTransformsStatsResponseSchema } from '@kbn/transform-plugin/common/api_schemas/transforms_stats';
-import { isGetTransformsStatsResponseSchema } from '@kbn/transform-plugin/common/api_schemas/type_guards';
import { TRANSFORM_STATE } from '@kbn/transform-plugin/common/constants';
import { getCommonRequestHeader } from '../../../functional/services/ml/common_api';
@@ -39,7 +38,6 @@ export default ({ getService }: FtrProviderContext) => {
}
function assertTransformsStatsResponseBody(body: GetTransformsStatsResponseSchema) {
- expect(isGetTransformsStatsResponseSchema(body)).to.eql(true);
expect(body.count).to.eql(expected.apiTransformTransforms.count);
expect(body.transforms).to.have.length(expected.apiTransformTransforms.count);
From 5fbaec275dd7ab35a2f3582b345353c97f081a16 Mon Sep 17 00:00:00 2001
From: Walter Rafelsberger
Date: Wed, 23 Aug 2023 14:07:33 +0200
Subject: [PATCH 21/53] remove success toasts
---
.../public/app/hooks/use_create_transform.tsx | 7 --
.../public/app/hooks/use_delete_transform.tsx | 81 -------------------
.../app/hooks/use_reauthorize_transform.tsx | 9 +--
.../public/app/hooks/use_reset_transform.tsx | 37 ---------
.../app/hooks/use_schedule_now_transform.tsx | 10 +--
.../public/app/hooks/use_start_transform.tsx | 9 +--
.../public/app/hooks/use_stop_transform.tsx | 9 +--
.../public/app/hooks/use_update_transform.ts | 15 +---
.../step_create/step_create_form.tsx | 7 --
.../edit_transform_update_button.tsx | 8 +-
10 files changed, 8 insertions(+), 184 deletions(-)
diff --git a/x-pack/plugins/transform/public/app/hooks/use_create_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_create_transform.tsx
index 7d404ef2c66bb..0b01bc95c8fe8 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_create_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_create_transform.tsx
@@ -54,13 +54,6 @@ export const useCreateTransform = (
onSuccess: (resp) => {
if (resp.errors.length > 0) {
errorToast(resp.errors.length === 1 ? resp.errors[0] : resp.errors);
- } else {
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.stepCreateForm.createTransformSuccessMessage', {
- defaultMessage: 'Request to create transform {transformId} acknowledged.',
- values: { transformId },
- })
- );
}
refreshTransformList();
diff --git a/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx
index 55925a86cee85..2d057c11c4a16 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx
@@ -14,7 +14,6 @@ import { extractErrorMessage } from '@kbn/ml-error-utils';
import { addInternalBasePath } from '../../../common/constants';
import type {
- DeleteTransformStatus,
DeleteTransformsRequestSchema,
DeleteTransformsResponseSchema,
} from '../../../common/api_schemas/delete_transforms';
@@ -110,8 +109,6 @@ export const useDeleteIndexAndTargetIndex = (items: TransformListRow[]) => {
};
};
-type SuccessCountField = keyof Omit;
-
export const useDeleteTransforms = () => {
const { http, overlays, theme } = useAppDependencies();
const refreshTransformList = useRefreshTransformList();
@@ -139,58 +136,12 @@ export const useDeleteTransforms = () => {
),
}),
onSuccess: (results) => {
- const isBulk = Object.keys(results).length > 1;
- const successCount: Record = {
- transformDeleted: 0,
- destIndexDeleted: 0,
- destDataViewDeleted: 0,
- };
for (const transformId in results) {
// hasOwnProperty check to ensure only properties on object itself, and not its prototypes
if (results.hasOwnProperty(transformId)) {
const status = results[transformId];
const destinationIndex = status.destinationIndex;
- // if we are only deleting one transform, show the success toast messages
- if (!isBulk && status.transformDeleted) {
- if (status.transformDeleted?.success) {
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.transformList.deleteTransformSuccessMessage', {
- defaultMessage: 'Request to delete transform {transformId} acknowledged.',
- values: { transformId },
- })
- );
- }
- if (status.destIndexDeleted?.success) {
- toastNotifications.addSuccess(
- i18n.translate(
- 'xpack.transform.deleteTransform.deleteAnalyticsWithIndexSuccessMessage',
- {
- defaultMessage:
- 'Request to delete destination index {destinationIndex} acknowledged.',
- values: { destinationIndex },
- }
- )
- );
- }
- if (status.destDataViewDeleted?.success) {
- toastNotifications.addSuccess(
- i18n.translate(
- 'xpack.transform.deleteTransform.deleteAnalyticsWithDataViewSuccessMessage',
- {
- defaultMessage: 'Request to delete data view {destinationIndex} acknowledged.',
- values: { destinationIndex },
- }
- )
- );
- }
- } else {
- (Object.keys(successCount) as SuccessCountField[]).forEach((key) => {
- if (status[key]?.success) {
- successCount[key] = successCount[key] + 1;
- }
- });
- }
if (status.transformDeleted?.error) {
const error = status.transformDeleted.error.reason;
toastNotifications.addDanger({
@@ -256,38 +207,6 @@ export const useDeleteTransforms = () => {
}
}
- // if we are deleting multiple transforms, combine the success messages
- if (isBulk) {
- if (successCount.transformDeleted > 0) {
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.transformList.bulkDeleteTransformSuccessMessage', {
- defaultMessage:
- 'Successfully deleted {count} {count, plural, one {transform} other {transforms}}.',
- values: { count: successCount.transformDeleted },
- })
- );
- }
-
- if (successCount.destIndexDeleted > 0) {
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.transformList.bulkDeleteDestIndexSuccessMessage', {
- defaultMessage:
- 'Successfully deleted {count} destination {count, plural, one {index} other {indices}}.',
- values: { count: successCount.destIndexDeleted },
- })
- );
- }
- if (successCount.destDataViewDeleted > 0) {
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.transformList.bulkDeleteDestDataViewSuccessMessage', {
- defaultMessage:
- 'Successfully deleted {count} destination data {count, plural, one {view} other {views}}.',
- values: { count: successCount.destDataViewDeleted },
- })
- );
- }
- }
-
refreshTransformList();
},
});
diff --git a/x-pack/plugins/transform/public/app/hooks/use_reauthorize_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_reauthorize_transform.tsx
index c226d82fc0410..7eae534d6f0eb 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_reauthorize_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_reauthorize_transform.tsx
@@ -55,14 +55,7 @@ export const useReauthorizeTransforms = () => {
// hasOwnProperty check to ensure only properties on object itself, and not its prototypes
if (results.hasOwnProperty(transformId)) {
const result = results[transformId];
- if (result.success === true) {
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.transformList.reauthorizeTransformSuccessMessage', {
- defaultMessage: 'Request to reauthorize transform {transformId} acknowledged.',
- values: { transformId },
- })
- );
- } else {
+ if (!result.success) {
toastNotifications.addError(
new Error(JSON.stringify(result.error!.caused_by, null, 2)),
{
diff --git a/x-pack/plugins/transform/public/app/hooks/use_reset_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_reset_transform.tsx
index e3147f0578ea5..f470a2e0f3698 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_reset_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_reset_transform.tsx
@@ -12,7 +12,6 @@ import { i18n } from '@kbn/i18n';
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
import type {
- ResetTransformStatus,
ResetTransformsRequestSchema,
ResetTransformsResponseSchema,
} from '../../../common/api_schemas/reset_transforms';
@@ -22,8 +21,6 @@ import { useAppDependencies, useToastNotifications } from '../app_dependencies';
import { useRefreshTransformList } from '../common';
import { ToastNotificationText } from '../components';
-type SuccessCountField = keyof Omit;
-
export const useResetTransforms = () => {
const { http, overlays, theme } = useAppDependencies();
const refreshTransformList = useRefreshTransformList();
@@ -51,32 +48,11 @@ export const useResetTransforms = () => {
),
}),
onSuccess: (results) => {
- const isBulk = Object.keys(results).length > 1;
- const successCount: Record = {
- transformReset: 0,
- };
for (const transformId in results) {
// hasOwnProperty check to ensure only properties on object itself, and not its prototypes
if (results.hasOwnProperty(transformId)) {
const status = results[transformId];
- // if we are only resetting one transform, show the success toast messages
- if (!isBulk && status.transformReset) {
- if (status.transformReset?.success) {
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.transformList.resetTransformSuccessMessage', {
- defaultMessage: 'Request to reset transform {transformId} acknowledged.',
- values: { transformId },
- })
- );
- }
- } else {
- (Object.keys(successCount) as SuccessCountField[]).forEach((key) => {
- if (status[key]?.success) {
- successCount[key] = successCount[key] + 1;
- }
- });
- }
if (status.transformReset?.error) {
const error = status.transformReset.error.reason;
toastNotifications.addDanger({
@@ -98,19 +74,6 @@ export const useResetTransforms = () => {
}
}
- // if we are deleting multiple transforms, combine the success messages
- if (isBulk) {
- if (successCount.transformReset > 0) {
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.transformList.bulkResetTransformSuccessMessage', {
- defaultMessage:
- 'Successfully reset {count} {count, plural, one {transform} other {transforms}}.',
- values: { count: successCount.transformReset },
- })
- );
- }
- }
-
refreshTransformList();
},
});
diff --git a/x-pack/plugins/transform/public/app/hooks/use_schedule_now_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_schedule_now_transform.tsx
index ac37b25c9478b..6ffc2bf6308d3 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_schedule_now_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_schedule_now_transform.tsx
@@ -55,15 +55,7 @@ export const useScheduleNowTransforms = () => {
// hasOwnProperty check to ensure only properties on object itself, and not its prototypes
if (results.hasOwnProperty(transformId)) {
const result = results[transformId];
- if (result.success === true) {
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.transformList.scheduleNowTransformSuccessMessage', {
- defaultMessage:
- 'Request to schedule transform {transformId} to process data instantly acknowledged.',
- values: { transformId },
- })
- );
- } else {
+ if (!result.success) {
toastNotifications.addError(
new Error(JSON.stringify(result.error!.caused_by, null, 2)),
{
diff --git a/x-pack/plugins/transform/public/app/hooks/use_start_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_start_transform.tsx
index ddb3b1a0e0ef3..63e62276e0d76 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_start_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_start_transform.tsx
@@ -51,14 +51,7 @@ export const useStartTransforms = () => {
// hasOwnProperty check to ensure only properties on object itself, and not its prototypes
if (results.hasOwnProperty(transformId)) {
const result = results[transformId];
- if (result.success === true) {
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.transformList.startTransformSuccessMessage', {
- defaultMessage: 'Request to start transform {transformId} acknowledged.',
- values: { transformId },
- })
- );
- } else {
+ if (!result.success) {
toastNotifications.addError(
new Error(JSON.stringify(result.error!.caused_by, null, 2)),
{
diff --git a/x-pack/plugins/transform/public/app/hooks/use_stop_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_stop_transform.tsx
index 35f58302a256d..506f8c04bf8a4 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_stop_transform.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_stop_transform.tsx
@@ -51,14 +51,7 @@ export const useStopTransforms = () => {
for (const transformId in results) {
// hasOwnProperty check to ensure only properties on object itself, and not its prototypes
if (results.hasOwnProperty(transformId)) {
- if (results[transformId].success === true) {
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.transformList.stopTransformSuccessMessage', {
- defaultMessage: 'Request to stop data frame transform {transformId} acknowledged.',
- values: { transformId },
- })
- );
- } else {
+ if (!results[transformId].success) {
toastNotifications.addDanger(
i18n.translate('xpack.transform.transformList.stopTransformErrorMessage', {
defaultMessage: 'An error occurred stopping the data frame transform {transformId}',
diff --git a/x-pack/plugins/transform/public/app/hooks/use_update_transform.ts b/x-pack/plugins/transform/public/app/hooks/use_update_transform.ts
index 23c295d7c7be9..1c1469ab1a5ba 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_update_transform.ts
+++ b/x-pack/plugins/transform/public/app/hooks/use_update_transform.ts
@@ -7,8 +7,6 @@
import { useMutation } from '@tanstack/react-query';
-import { i18n } from '@kbn/i18n';
-
import type {
PostTransformsUpdateRequestSchema,
PostTransformsUpdateResponseSchema,
@@ -16,7 +14,7 @@ import type {
import { addInternalBasePath } from '../../../common/constants';
import type { TransformId } from '../../../common/types/transform';
-import { useAppDependencies, useToastNotifications } from '../app_dependencies';
+import { useAppDependencies } from '../app_dependencies';
import { useRefreshTransformList } from '../common';
export const useUpdateTransform = (
@@ -25,7 +23,6 @@ export const useUpdateTransform = (
) => {
const { http } = useAppDependencies();
const refreshTransformList = useRefreshTransformList();
- const toastNotifications = useToastNotifications();
const mutation = useMutation({
mutationFn: () =>
@@ -36,15 +33,7 @@ export const useUpdateTransform = (
version: '1',
}
),
- onSuccess: () => {
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.transformList.editTransformSuccessMessage', {
- defaultMessage: 'Transform {transformId} updated.',
- values: { transformId },
- })
- );
- refreshTransformList();
- },
+ onSuccess: () => refreshTransformList(),
});
return mutation;
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.tsx
index 2bca8ec8072e1..ff3ae39844289 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.tsx
@@ -180,13 +180,6 @@ export const StepCreateForm: FC = React.memo(
true
);
- toastNotifications.addSuccess(
- i18n.translate('xpack.transform.stepCreateForm.createDataViewSuccessMessage', {
- defaultMessage: 'Kibana data view {dataViewName} created successfully.',
- values: { dataViewName },
- })
- );
-
setDataViewId(newDataView.id);
setLoading(false);
return true;
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/edit_transform_flyout/edit_transform_update_button.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/edit_transform_flyout/edit_transform_update_button.tsx
index 7b00ce29bf8f3..3279b761a954b 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/edit_transform_flyout/edit_transform_update_button.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/edit_transform_flyout/edit_transform_update_button.tsx
@@ -33,12 +33,8 @@ export const EditTransformUpdateButton: FC = ({
apiError(undefined);
updateTransfrom(undefined, {
- onError: (error) => {
- apiError(getErrorMessage(error));
- },
- onSuccess: () => {
- closeFlyout();
- },
+ onError: (error) => apiError(getErrorMessage(error)),
+ onSuccess: () => closeFlyout(),
});
}
From b986a42e2a1c8ec4e2d10538d0c96b1a6772a628 Mon Sep 17 00:00:00 2001
From: Walter Rafelsberger
Date: Wed, 23 Aug 2023 14:44:55 +0200
Subject: [PATCH 22/53] fix i18n
---
.../plugins/translations/translations/fr-FR.json | 15 ---------------
.../plugins/translations/translations/ja-JP.json | 15 ---------------
.../plugins/translations/translations/zh-CN.json | 15 ---------------
3 files changed, 45 deletions(-)
diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json
index 9f0b2ff73b908..ad1003a6f7cf9 100644
--- a/x-pack/plugins/translations/translations/fr-FR.json
+++ b/x-pack/plugins/translations/translations/fr-FR.json
@@ -37781,18 +37781,14 @@
"xpack.transform.clone.noDataViewErrorPromptText": "Impossible de cloner la transformation {transformId}. Il n'existe aucune vue de données pour {dataViewTitle}.",
"xpack.transform.danglingTasksError": "{count} {count, plural, one {transformation n'a pas de} many {transformations n'ont pas de} other {transformations n'ont pas de}} détails de configuration : [{transformIds}] {count, plural, one {Elle ne peut pas être récupérée et doit être supprimée} many {Elles ne peuvent pas être récupérées et doivent être supprimées} other {Elles ne peuvent pas être récupérées et doivent être supprimées}}.",
"xpack.transform.deleteTransform.deleteAnalyticsWithDataViewErrorMessage": "Une erreur est survenue lors de la suppression de la vue de données {destinationIndex}",
- "xpack.transform.deleteTransform.deleteAnalyticsWithDataViewSuccessMessage": "Requête de suppression de la vue de données {destinationIndex} reconnue.",
"xpack.transform.deleteTransform.deleteAnalyticsWithIndexErrorMessage": "Une erreur s'est produite lors de la suppression de l'index de destination {destinationIndex}",
- "xpack.transform.deleteTransform.deleteAnalyticsWithIndexSuccessMessage": "Requête de suppression de l'index de destination {destinationIndex} reconnue.",
"xpack.transform.deleteTransform.errorWithCheckingIfDataViewExistsNotificationErrorMessage": "Une erreur s'est produite lors de la vérification de l'existence de la vue de données {dataView} : {error}",
"xpack.transform.edit.noDataViewErrorPromptText": "Impossible d'obtenir la vue de données pour la transformation {transformId}. Il n'existe aucune vue de données pour {dataViewTitle}.",
"xpack.transform.forceDeleteTransformMessage": "Supprimer {count} {count, plural, one {transformation} many {transformations} other {transformations}}",
"xpack.transform.managedTransformsWarningCallout": "{count, plural, one {Cette transformation} many {Au moins l'une de ces transformations} other {Au moins l'une de ces transformations}} est préconfigurée par Elastic. Le fait de {action} {count, plural, one {la} many {les} other {les}} avec une heure de fin spécifique peut avoir un impact sur d'autres éléments du produit.",
"xpack.transform.multiTransformActionsMenu.transformsCount": "Sélection effectuée de {count} {count, plural, one {transformation} many {transformations} other {transformations}}",
"xpack.transform.stepCreateForm.createDataViewErrorMessage": "Une erreur est survenue lors de la création de la vue de données Kibana {dataViewName} :",
- "xpack.transform.stepCreateForm.createDataViewSuccessMessage": "La vue de données Kibana {dataViewName} a bien été créée.",
"xpack.transform.stepCreateForm.createTransformErrorMessage": "Une erreur s'est produite lors de la création de la transformation {transformId} :",
- "xpack.transform.stepCreateForm.createTransformSuccessMessage": "La requête pour créer la transformation {transformId} a été reconnue.",
"xpack.transform.stepCreateForm.duplicateDataViewErrorMessage": "Une erreur est survenue lors de la création de la vue de données Kibana {dataViewName} : La vue de données existe déjà.",
"xpack.transform.stepDefineForm.invalidKuerySyntaxErrorMessageQueryBar": "Requête non valide : {queryErrorMessage}",
"xpack.transform.stepDefineForm.queryPlaceholderKql": "Par exemple, {example}",
@@ -37805,41 +37801,30 @@
"xpack.transform.stepDetailsForm.retentionPolicyMaxAgePlaceholderText": "max_age, par exemple {exampleValue}",
"xpack.transform.transformForm.sizeNotationPlaceholder": "Exemples : {example1}, {example2}, {example3}, {example4}",
"xpack.transform.transformList.alertingRules.tooltipContent": "La transformation a {rulesCount} {rulesCount, plural, one { règle} many { règles} other { règles}} d'alerte associée(s)",
- "xpack.transform.transformList.bulkDeleteDestDataViewSuccessMessage": "Suppression réussie de {count} {count, plural, one {vue} many {vues} other {vues}} de données de destination.",
- "xpack.transform.transformList.bulkDeleteDestIndexSuccessMessage": "Suppression réussie de {count} {count, plural, one {index} many {index système non migrés} other {index}} de destination.",
"xpack.transform.transformList.bulkDeleteModalTitle": "Supprimer {count} {count, plural, one {transformation} many {transformations} other {transformations}} ?",
- "xpack.transform.transformList.bulkDeleteTransformSuccessMessage": "Suppression réussie de {count} {count, plural, one {transformation} many {transformations} other {transformations}}.",
"xpack.transform.transformList.bulkReauthorizeModalTitle": "Réautoriser {count} {count, plural, one {transformation} many {transformations} other {transformations}} ?",
"xpack.transform.transformList.bulkResetModalTitle": "Réinitialiser {count} {count, plural, one {transformation} many {transformations} other {transformations}} ?",
- "xpack.transform.transformList.bulkResetTransformSuccessMessage": "Réinitialisation effectuée avec succès de {count} {count, plural, one {transformation} many {transformations} other {transformations}}.",
"xpack.transform.transformList.bulkStartModalTitle": "Démarrer {count} {count, plural, one {transformation} many {transformations} other {transformations}} ?",
"xpack.transform.transformList.bulkStopModalTitle": "Arrêter {count} {count, plural, one {transformation} many {transformations} other {transformations}} ?",
"xpack.transform.transformList.cannotRestartCompleteBatchTransformToolTip": "{transformId} est une transformation par lots terminée et ne peut pas être redémarrée.",
"xpack.transform.transformList.cannotScheduleNowCompleteBatchTransformToolTip": "{transformId} est une transformation par lots terminée qui ne peut pas être planifiée pour traiter les données instantanément.",
"xpack.transform.transformList.deleteModalTitle": "Supprimer {transformId} ?",
"xpack.transform.transformList.deleteTransformErrorMessage": "Une erreur s'est produite lors de la suppression de la transformation {transformId}",
- "xpack.transform.transformList.deleteTransformSuccessMessage": "La requête pour supprimer la transformation {transformId} a été reconnue.",
"xpack.transform.transformList.editFlyoutFormPlaceholderText": "Par défaut : {defaultValue}",
"xpack.transform.transformList.editFlyoutTitle": "Modifier {transformId}",
- "xpack.transform.transformList.editTransformSuccessMessage": "Transformation {transformId} mise à jour.",
"xpack.transform.transformList.reauthorizeModalTitle": "Réautoriser {transformId} ?",
"xpack.transform.transformList.reauthorizeTransformErrorMessage": "Une erreur s'est produite lors de la réautorisation de la transformation {transformId}",
- "xpack.transform.transformList.reauthorizeTransformSuccessMessage": "La requête pour réautoriser la transformation {transformId} a été reconnue.",
"xpack.transform.transformList.resetModalTitle": "Réinitialiser {transformId} ?",
"xpack.transform.transformList.resetTransformErrorMessage": "Une erreur s'est produite lors de la réinitialisation de la transformation {transformId}",
- "xpack.transform.transformList.resetTransformSuccessMessage": "La requête pour réinitialiser la transformation {transformId} a été reconnue.",
"xpack.transform.transformList.rowCollapse": "Masquer les détails pour {transformId}",
"xpack.transform.transformList.rowExpand": "Afficher les détails pour {transformId}",
"xpack.transform.transformList.scheduleNowTransformErrorMessage": "Une erreur s'est produite lors de la planification de la transformation {transformId} pour traiter les données instantanément.",
- "xpack.transform.transformList.scheduleNowTransformSuccessMessage": "La demande de planification de transformation {transformId} pour traiter les données immédiatement a été reconnue.",
"xpack.transform.transformList.startedTransformToolTip": "{transformId} a déjà démarré.",
"xpack.transform.transformList.startModalTitle": "Démarrer {transformId} ?",
"xpack.transform.transformList.startTransformErrorMessage": "Une erreur s'est produite lors du démarrage de la transformation {transformId}",
- "xpack.transform.transformList.startTransformSuccessMessage": "La requête pour démarrer la transformation {transformId} a été reconnue.",
"xpack.transform.transformList.stopModalTitle": "Arrêter {transformId} ?",
"xpack.transform.transformList.stoppedTransformToolTip": "{transformId} est déjà arrêtée.",
"xpack.transform.transformList.stopTransformErrorMessage": "Une erreur s'est produite lors de l'arrêt de la transformation du cadre de données {transformId}",
- "xpack.transform.transformList.stopTransformSuccessMessage": "La requête pour arrêter la transformation du cadre de données {transformId} a été reconnue.",
"xpack.transform.transformList.unauthorizedTransformsCallout.insufficientPermissionsMsg": "{unauthorizedCnt, plural, one {Une transformation a été créée avec des autorisations insuffisantes.} many {# transformations ont été créées avec des autorisations insuffisantes.} other {# transformations ont été créées avec des autorisations insuffisantes.}}",
"xpack.transform.transformList.unauthorizedTransformsCallout.reauthorizeMsg": "Réautorisez pour démarrer {unauthorizedCnt, plural, one {la transformation} many {# transformations} other {# transformations}}.",
"xpack.transform.transformNodes.noTransformNodesCallOutBody": "Vous ne pourrez ni créer ni exécuter de transformations. {learnMoreLink}",
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index e1129d3faa9d1..38725eebe2427 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -37780,18 +37780,14 @@
"xpack.transform.clone.noDataViewErrorPromptText": "トランスフォーム{transformId}を複製できません。{dataViewTitle}のデータビューは存在しません。",
"xpack.transform.danglingTasksError": "{count}個の{count, plural, other {変換}}に構成の詳細がありません:[{transformIds}]。{count, plural, other {それら}}回復できないため、削除してください。",
"xpack.transform.deleteTransform.deleteAnalyticsWithDataViewErrorMessage": "データビュー{destinationIndex}の削除中にエラーが発生しました",
- "xpack.transform.deleteTransform.deleteAnalyticsWithDataViewSuccessMessage": "データビュー {destinationIndex} の削除リクエストが受け付けられました。",
"xpack.transform.deleteTransform.deleteAnalyticsWithIndexErrorMessage": "ディスティネーションインデックス{destinationIndex}の削除中にエラーが発生しました",
- "xpack.transform.deleteTransform.deleteAnalyticsWithIndexSuccessMessage": "ディスティネーションインデックス{destinationIndex}を削除する要求が確認されました。",
"xpack.transform.deleteTransform.errorWithCheckingIfDataViewExistsNotificationErrorMessage": "データビュー{dataView}が存在するかどうかを確認するときにエラーが発生しました:{error}",
"xpack.transform.edit.noDataViewErrorPromptText": "変換{transformId}のデータビューを取得できません。{dataViewTitle}のデータビューは存在しません。",
"xpack.transform.forceDeleteTransformMessage": "{count}{count, plural, other {変換}}の削除",
"xpack.transform.managedTransformsWarningCallout": "{count, plural, other {これらの変換のうちの少なくとも1個の変換}}はElasticによってあらかじめ構成されています。{count, plural, other {それらを}}{action}すると、製品の他の部分に影響する可能性があります。",
"xpack.transform.multiTransformActionsMenu.transformsCount": "{count}個の{count, plural, other {変換}}を選択済み",
"xpack.transform.stepCreateForm.createDataViewErrorMessage": "Kibanaデータビュー{dataViewName}の作成中にエラーが発生しました:",
- "xpack.transform.stepCreateForm.createDataViewSuccessMessage": "Kibanaデータビュー{dataViewName}が正常に作成されました。",
"xpack.transform.stepCreateForm.createTransformErrorMessage": "変換 {transformId} の取得中にエラーが発生しました。",
- "xpack.transform.stepCreateForm.createTransformSuccessMessage": "変換 {transformId} の作成リクエストが受け付けられました。",
"xpack.transform.stepCreateForm.duplicateDataViewErrorMessage": "Kibanaデータビュー{dataViewName}の作成中にエラーが発生しました:データビューはすでに存在します。",
"xpack.transform.stepDefineForm.invalidKuerySyntaxErrorMessageQueryBar": "無効なクエリ:{queryErrorMessage}",
"xpack.transform.stepDefineForm.queryPlaceholderKql": "例: {example}.",
@@ -37804,41 +37800,30 @@
"xpack.transform.stepDetailsForm.retentionPolicyMaxAgePlaceholderText": "max_age 例:{exampleValue}",
"xpack.transform.transformForm.sizeNotationPlaceholder": "例:{example1}, {example2}, {example3}, {example4}",
"xpack.transform.transformList.alertingRules.tooltipContent": "変換には{rulesCount}個の関連付けられたアラート{rulesCount, plural, other { ルール}}があります",
- "xpack.transform.transformList.bulkDeleteDestDataViewSuccessMessage": "{count}個のディスティネーションデータ{count, plural, other {ビュー}}が正常に削除されました。",
- "xpack.transform.transformList.bulkDeleteDestIndexSuccessMessage": "{count}個のディスティネーション{count, plural, other {インデックス}}が正常に削除されました。",
"xpack.transform.transformList.bulkDeleteModalTitle": "{count}{count, plural, other {変換}}を削除しますか?",
- "xpack.transform.transformList.bulkDeleteTransformSuccessMessage": "{count}個の{count, plural, other {トランスフォーム}}が正常に削除されました。",
"xpack.transform.transformList.bulkReauthorizeModalTitle": "{count} {count, plural, other {トランスフォーム}}をもう一度認可しますか?",
"xpack.transform.transformList.bulkResetModalTitle": "{count}個の{count, plural, other {変換}}をリセットしますか?",
- "xpack.transform.transformList.bulkResetTransformSuccessMessage": "{count}個の{count, plural, other {変換}}が正常にリセットされました。",
"xpack.transform.transformList.bulkStartModalTitle": "{count}個の{count, plural, other {変換}}を開始しますか?",
"xpack.transform.transformList.bulkStopModalTitle": "{count}個のを{count, plural, other {変換}}停止しますか?",
"xpack.transform.transformList.cannotRestartCompleteBatchTransformToolTip": "{transformId} は完了済みの一斉変換で、再度開始できません。",
"xpack.transform.transformList.cannotScheduleNowCompleteBatchTransformToolTip": "{transformId}は完了済みのバッチ変換であるため、データの即時処理のスケジュールを設定できません。",
"xpack.transform.transformList.deleteModalTitle": "{transformId}を削除しますか?",
"xpack.transform.transformList.deleteTransformErrorMessage": "変換 {transformId} の削除中にエラーが発生しました",
- "xpack.transform.transformList.deleteTransformSuccessMessage": "変換 {transformId} の削除リクエストが受け付けられました。",
"xpack.transform.transformList.editFlyoutFormPlaceholderText": "デフォルト:{defaultValue}",
"xpack.transform.transformList.editFlyoutTitle": "{transformId}の編集",
- "xpack.transform.transformList.editTransformSuccessMessage": "変換{transformId}が更新されました。",
"xpack.transform.transformList.reauthorizeModalTitle": "{transformId}をもう一度許可しますか?",
"xpack.transform.transformList.reauthorizeTransformErrorMessage": "変換{transformId}の再認可中にエラーが発生しました",
- "xpack.transform.transformList.reauthorizeTransformSuccessMessage": "変換{transformId}の再認可リクエストが受け付けられました。",
"xpack.transform.transformList.resetModalTitle": "{transformId}をリセットしますか?",
"xpack.transform.transformList.resetTransformErrorMessage": "変換{transformId}のリセット中にエラーが発生しました",
- "xpack.transform.transformList.resetTransformSuccessMessage": "変換{transformId}のリセットリクエストが受け付けられました。",
"xpack.transform.transformList.rowCollapse": "{transformId} の詳細を非表示",
"xpack.transform.transformList.rowExpand": "{transformId} の詳細を表示",
"xpack.transform.transformList.scheduleNowTransformErrorMessage": "変換{transformId}でデータの即時処理のスケジュールの設定中にエラーが発生しました。",
- "xpack.transform.transformList.scheduleNowTransformSuccessMessage": "変換{transformId}でデータの即時処理のスケジュールを設定するリクエストが受け付けられました。",
"xpack.transform.transformList.startedTransformToolTip": "{transformId} はすでに開始済みです。",
"xpack.transform.transformList.startModalTitle": "{transformId}を開始しますか?",
"xpack.transform.transformList.startTransformErrorMessage": "変換 {transformId} の開始中にエラーが発生しました",
- "xpack.transform.transformList.startTransformSuccessMessage": "変換 {transformId} の開始リクエストが受け付けられました。",
"xpack.transform.transformList.stopModalTitle": "{transformId}を終了しますか?",
"xpack.transform.transformList.stoppedTransformToolTip": "{transformId} はすでに停止済みです。",
"xpack.transform.transformList.stopTransformErrorMessage": "データフレーム変換 {transformId} の停止中にエラーが発生しました",
- "xpack.transform.transformList.stopTransformSuccessMessage": "データフレーム変換 {transformId} の停止リクエストが受け付けられました。",
"xpack.transform.transformList.unauthorizedTransformsCallout.insufficientPermissionsMsg": "{unauthorizedCnt, plural, other {十分な権限がない状態で#個の変換が作成されました。}}",
"xpack.transform.transformList.unauthorizedTransformsCallout.reauthorizeMsg": "もう一度認可して、{unauthorizedCnt, plural, other {#個の変換}}を開始してください。",
"xpack.transform.transformNodes.noTransformNodesCallOutBody": "変換の作成または実行はできません。{learnMoreLink}。",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index a7195f24d0c46..25f2c6216187a 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -37774,18 +37774,14 @@
"xpack.transform.clone.noDataViewErrorPromptText": "无法克隆转换 {transformId}。对于 {dataViewTitle},不存在数据视图。",
"xpack.transform.danglingTasksError": "{count} 个{count, plural, other {转换}}缺少配置详情:[{transformIds}] 无法将{count, plural, other {其}}恢复,应予以删除。",
"xpack.transform.deleteTransform.deleteAnalyticsWithDataViewErrorMessage": "删除数据视图 {destinationIndex} 时出错",
- "xpack.transform.deleteTransform.deleteAnalyticsWithDataViewSuccessMessage": "删除数据视图 {destinationIndex} 的请求已确认。",
"xpack.transform.deleteTransform.deleteAnalyticsWithIndexErrorMessage": "删除目标索引 {destinationIndex} 时发生错误",
- "xpack.transform.deleteTransform.deleteAnalyticsWithIndexSuccessMessage": "删除目标索引 {destinationIndex} 的请求已确认。",
"xpack.transform.deleteTransform.errorWithCheckingIfDataViewExistsNotificationErrorMessage": "检查数据视图 {dataView} 是否存在时发生错误:{error}",
"xpack.transform.edit.noDataViewErrorPromptText": "无法获取转换 {transformId} 的数据视图。对于 {dataViewTitle},不存在数据视图。",
"xpack.transform.forceDeleteTransformMessage": "删除 {count} {count, plural, other {转换}}",
"xpack.transform.managedTransformsWarningCallout": "{count, plural, other {至少一个此类转换}}由 Elastic 预配置;{action} {count, plural, other {这些转换}}可能会影响该产品的其他部分。",
"xpack.transform.multiTransformActionsMenu.transformsCount": "已选定 {count} 个{count, plural, other {转换}}",
"xpack.transform.stepCreateForm.createDataViewErrorMessage": "创建 Kibana 数据视图 {dataViewName} 时发生错误:",
- "xpack.transform.stepCreateForm.createDataViewSuccessMessage": "已成功创建 Kibana 数据视图 {dataViewName}。",
"xpack.transform.stepCreateForm.createTransformErrorMessage": "创建转换 {transformId} 时出错:",
- "xpack.transform.stepCreateForm.createTransformSuccessMessage": "创建转换 {transformId} 的请求已确认。",
"xpack.transform.stepCreateForm.duplicateDataViewErrorMessage": "创建 Kibana 数据视图 {dataViewName} 时发生错误:数据视图已存在。",
"xpack.transform.stepDefineForm.invalidKuerySyntaxErrorMessageQueryBar": "无效查询:{queryErrorMessage}",
"xpack.transform.stepDefineForm.queryPlaceholderKql": "例如,{example}",
@@ -37798,41 +37794,30 @@
"xpack.transform.stepDetailsForm.retentionPolicyMaxAgePlaceholderText": "max_age,例如 {exampleValue}",
"xpack.transform.transformForm.sizeNotationPlaceholder": "示例:{example1}、{example2}、{example3}、{example4}",
"xpack.transform.transformList.alertingRules.tooltipContent": "转换具有 {rulesCount} 个关联的告警{rulesCount, plural, other { 规则}}",
- "xpack.transform.transformList.bulkDeleteDestDataViewSuccessMessage": "已成功删除 {count} 个目标数据{count, plural, other {视图}}。",
- "xpack.transform.transformList.bulkDeleteDestIndexSuccessMessage": "已成功删除 {count} 个目标数据{count, plural, other {索引}}。",
"xpack.transform.transformList.bulkDeleteModalTitle": "删除 {count} 个 {count, plural, other {转换}}?",
- "xpack.transform.transformList.bulkDeleteTransformSuccessMessage": "已成功删除 {count} 个{count, plural, other {转换}}。",
"xpack.transform.transformList.bulkReauthorizeModalTitle": "重新授权 {count} 个{count, plural, other {转换}}?",
"xpack.transform.transformList.bulkResetModalTitle": "重置 {count} 个{count, plural, other {转换}}?",
- "xpack.transform.transformList.bulkResetTransformSuccessMessage": "已成功重置 {count} 个{count, plural, other {转换}}。",
"xpack.transform.transformList.bulkStartModalTitle": "启动 {count} 个{count, plural, other {转换}}?",
"xpack.transform.transformList.bulkStopModalTitle": "停止 {count} 个{count, plural, other {转换}}?",
"xpack.transform.transformList.cannotRestartCompleteBatchTransformToolTip": "{transformId} 为已完成批量转换,无法重新启动。",
"xpack.transform.transformList.cannotScheduleNowCompleteBatchTransformToolTip": "{transformId} 为已完成的批量转换,无法安排其立即处理数据。",
"xpack.transform.transformList.deleteModalTitle": "删除 {transformId}?",
"xpack.transform.transformList.deleteTransformErrorMessage": "删除转换 {transformId} 时发生错误",
- "xpack.transform.transformList.deleteTransformSuccessMessage": "删除转换 {transformId} 的请求已确认。",
"xpack.transform.transformList.editFlyoutFormPlaceholderText": "默认值:{defaultValue}",
"xpack.transform.transformList.editFlyoutTitle": "编辑 {transformId}",
- "xpack.transform.transformList.editTransformSuccessMessage": "转换 {transformId} 已更新。",
"xpack.transform.transformList.reauthorizeModalTitle": "重新授权 {transformId}?",
"xpack.transform.transformList.reauthorizeTransformErrorMessage": "重新授权转换 {transformId} 时出错",
- "xpack.transform.transformList.reauthorizeTransformSuccessMessage": "重新授权转换 {transformId} 的请求已确认。",
"xpack.transform.transformList.resetModalTitle": "重置 {transformId}?",
"xpack.transform.transformList.resetTransformErrorMessage": "重置转换 {transformId} 时出错",
- "xpack.transform.transformList.resetTransformSuccessMessage": "重置转换 {transformId} 的请求已确认。",
"xpack.transform.transformList.rowCollapse": "隐藏 {transformId} 的详情",
"xpack.transform.transformList.rowExpand": "显示 {transformId} 的详情",
"xpack.transform.transformList.scheduleNowTransformErrorMessage": "计划转换 {transformId} 以立即处理数据时出错。",
- "xpack.transform.transformList.scheduleNowTransformSuccessMessage": "计划转换 {transformId} 以立即处理数据的请求已确认。",
"xpack.transform.transformList.startedTransformToolTip": "{transformId} 已启动。",
"xpack.transform.transformList.startModalTitle": "启动 {transformId}?",
"xpack.transform.transformList.startTransformErrorMessage": "启动转换 {transformId} 时发生错误",
- "xpack.transform.transformList.startTransformSuccessMessage": "启动转换 {transformId} 的请求已确认。",
"xpack.transform.transformList.stopModalTitle": "停止 {transformId}?",
"xpack.transform.transformList.stoppedTransformToolTip": "{transformId} 已停止。",
"xpack.transform.transformList.stopTransformErrorMessage": "停止数据帧转换 {transformId} 时发生错误",
- "xpack.transform.transformList.stopTransformSuccessMessage": "停止数据帧转换 {transformId} 的请求已确认。",
"xpack.transform.transformList.unauthorizedTransformsCallout.insufficientPermissionsMsg": "{unauthorizedCnt, plural, other {已创建 # 个转换,但权限不足。}}",
"xpack.transform.transformList.unauthorizedTransformsCallout.reauthorizeMsg": "重新授权以启动{unauthorizedCnt, plural, other {# 个转换}}。",
"xpack.transform.transformNodes.noTransformNodesCallOutBody": "您将无法创建或运行转换。{learnMoreLink}",
From 32c12ebddf2fb8e7ee0ce9be7de2a9e842f6256e Mon Sep 17 00:00:00 2001
From: Walter Rafelsberger
Date: Thu, 24 Aug 2023 10:39:26 +0200
Subject: [PATCH 23/53] refactor AuthorizationProvider into useAuthorization
hook.
---
x-pack/plugins/transform/public/app/app.tsx | 22 ++-
.../public/app/common/navigation.tsx | 3 +-
.../public/app/components/job_icon.tsx | 2 +-
.../components/toast_notification_text.tsx | 2 +-
.../transform/public/app/hooks/index.ts | 2 +
.../public/app/hooks/use_authorization.ts | 63 ++++++++
.../public/app/hooks/use_index_data.test.tsx | 3 +-
.../components/authorization_provider.tsx | 83 -----------
.../app/lib/authorization/components/index.ts | 1 -
.../components/with_privileges.tsx | 6 +-
.../advanced_pivot_editor_switch.tsx | 2 +-
.../advanced_query_editor_switch.tsx | 2 +-
...dvanced_runtime_mappings_editor_switch.tsx | 3 +-
.../switch_modal.tsx | 3 +-
.../advanced_runtime_mappings_settings.tsx | 3 +-
.../advanced_source_editor.tsx | 2 +-
.../date_picker_apply_switch.tsx | 2 +-
.../source_search_bar/source_search_bar.tsx | 2 +-
.../step_create/step_create_summary.tsx | 2 +-
.../step_define/latest_function_form.tsx | 3 +-
.../step_define/pivot_function_form.tsx | 2 +-
.../transform_function_selector.tsx | 3 +-
.../step_details/step_details_summary.tsx | 2 +-
.../step_details/step_details_time_field.tsx | 3 +-
.../components/switch_modal/switch_modal.tsx | 3 +-
.../components/wizard_nav/wizard_nav.tsx | 2 +-
.../action_clone/clone_action_name.tsx | 3 +-
.../action_clone/use_clone_action.tsx | 7 +-
.../create_alert_rule_action_name.tsx | 3 +-
.../use_create_alert_rule_action.tsx | 6 +-
.../action_delete/delete_action_name.tsx | 3 +-
.../action_delete/use_delete_action.tsx | 11 +-
.../action_discover/discover_action_name.tsx | 3 +-
.../action_edit/edit_action_name.tsx | 10 +-
.../action_edit/use_edit_action.tsx | 6 +-
.../reauthorize_action_modal.tsx | 3 +-
.../reauthorize_action_name.tsx | 10 +-
.../use_reauthorize_action.tsx | 6 +-
.../action_reset/reset_action_name.tsx | 3 +-
.../action_reset/use_reset_action.tsx | 7 +-
.../schedule_now_action_name.tsx | 10 +-
.../use_schedule_now_action.tsx | 6 +-
.../start_action_name.test.tsx.snap | 136 +++++++++++++++++-
.../action_start/start_action_modal.tsx | 3 +-
.../action_start/start_action_name.test.tsx | 9 +-
.../action_start/start_action_name.tsx | 10 +-
.../action_start/use_start_action.tsx | 7 +-
.../stop_action_name.test.tsx.snap | 135 ++++++++++++++++-
.../action_stop/stop_action_name.test.tsx | 9 +-
.../action_stop/stop_action_name.tsx | 10 +-
.../action_stop/use_stop_action.tsx | 7 +-
.../create_transform_button.test.tsx.snap | 75 +++++++---
.../create_transform_button.test.tsx | 9 +-
.../create_transform_button.tsx | 10 +-
.../edit_transform_flyout_callout.tsx | 2 +-
.../edit_transform_flyout_form_text_input.tsx | 2 +-
.../refresh_transform_list_button.tsx | 2 +-
.../search_selection/search_selection.tsx | 3 +-
.../components/stats_bar/stat.tsx | 2 +-
.../components/stats_bar/stats_bar.tsx | 3 +-
.../transform_list/expanded_row_json_pane.tsx | 2 +-
.../transform_list/transform_list.tsx | 6 +-
.../transform_list/transforms_stats_bar.tsx | 2 +-
.../components/transform_list/use_columns.tsx | 6 +-
.../transform_management_section.tsx | 8 +-
65 files changed, 531 insertions(+), 250 deletions(-)
create mode 100644 x-pack/plugins/transform/public/app/hooks/use_authorization.ts
delete mode 100644 x-pack/plugins/transform/public/app/lib/authorization/components/authorization_provider.tsx
diff --git a/x-pack/plugins/transform/public/app/app.tsx b/x-pack/plugins/transform/public/app/app.tsx
index ba4a43bfa0876..3321a9483c910 100644
--- a/x-pack/plugins/transform/public/app/app.tsx
+++ b/x-pack/plugins/transform/public/app/app.tsx
@@ -5,7 +5,7 @@
* 2.0.
*/
-import React, { useContext, FC } from 'react';
+import React, { type FC } from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
@@ -16,19 +16,17 @@ import { ScopedHistory } from '@kbn/core/public';
import { FormattedMessage } from '@kbn/i18n-react';
import { KibanaContextProvider, KibanaThemeProvider } from '@kbn/kibana-react-plugin/public';
-import { addInternalBasePath } from '../../common/constants';
-
import { SectionError } from './components';
import { SECTION_SLUG } from './common/constants';
-import { AuthorizationContext, AuthorizationProvider } from './lib/authorization';
import { AppDependencies } from './app_dependencies';
+import { useAuthorization } from './hooks';
import { CloneTransformSection } from './sections/clone_transform';
import { CreateTransformSection } from './sections/create_transform';
import { TransformManagementSection } from './sections/transform_management';
export const App: FC<{ history: ScopedHistory }> = ({ history }) => {
- const { apiError } = useContext(AuthorizationContext);
- if (apiError !== null) {
+ const { error } = useAuthorization();
+ if (error !== null) {
return (
= ({ history }) => {
defaultMessage="Error fetching user privileges from the server"
/>
}
- error={apiError}
+ error={error}
/>
);
}
@@ -68,13 +66,9 @@ export const renderApp = (element: HTMLElement, appDependencies: AppDependencies
-
-
-
-
-
+
+
+
diff --git a/x-pack/plugins/transform/public/app/common/navigation.tsx b/x-pack/plugins/transform/public/app/common/navigation.tsx
index 601e701c7f16d..ef6696d3e757a 100644
--- a/x-pack/plugins/transform/public/app/common/navigation.tsx
+++ b/x-pack/plugins/transform/public/app/common/navigation.tsx
@@ -5,7 +5,8 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
+
import { Redirect } from 'react-router-dom';
import { SECTION_SLUG } from './constants';
diff --git a/x-pack/plugins/transform/public/app/components/job_icon.tsx b/x-pack/plugins/transform/public/app/components/job_icon.tsx
index 09db5a1c52377..12a5687156611 100644
--- a/x-pack/plugins/transform/public/app/components/job_icon.tsx
+++ b/x-pack/plugins/transform/public/app/components/job_icon.tsx
@@ -5,7 +5,7 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
import { EuiIcon, EuiToolTip } from '@elastic/eui';
import { AuditMessageBase } from '../../../common/types/messages';
diff --git a/x-pack/plugins/transform/public/app/components/toast_notification_text.tsx b/x-pack/plugins/transform/public/app/components/toast_notification_text.tsx
index 6409a8fcf3b45..ca9079745fe3d 100644
--- a/x-pack/plugins/transform/public/app/components/toast_notification_text.tsx
+++ b/x-pack/plugins/transform/public/app/components/toast_notification_text.tsx
@@ -5,7 +5,7 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
import {
EuiButtonEmpty,
diff --git a/x-pack/plugins/transform/public/app/hooks/index.ts b/x-pack/plugins/transform/public/app/hooks/index.ts
index f3e619e2364ce..f83574101ea9c 100644
--- a/x-pack/plugins/transform/public/app/hooks/index.ts
+++ b/x-pack/plugins/transform/public/app/hooks/index.ts
@@ -10,6 +10,7 @@ export { useDocumentationLinks } from './use_documentation_links';
export { useGetDataViewTitles } from './use_get_data_view_titles';
export { useGetEsIndices } from './use_get_es_indices';
export { useGetEsIngestPipelines } from './use_get_es_ingest_pipelines';
+export { useAuthorization } from './use_authorization';
export { useGetTransformAuditMessages } from './use_get_transform_audit_messages';
export { useGetTransform } from './use_get_transform';
export { useGetTransforms } from './use_get_transforms';
@@ -17,6 +18,7 @@ export { useGetTransformsPreview } from './use_get_transforms_preview';
export { useGetTransformStats } from './use_get_transform_stats';
export { useDeleteTransforms, useDeleteIndexAndTargetIndex } from './use_delete_transform';
export { useResetTransforms } from './use_reset_transform';
+export { useSearchItems } from './use_search_items';
export { useScheduleNowTransforms } from './use_schedule_now_transform';
export { useStartTransforms } from './use_start_transform';
export { useStopTransforms } from './use_stop_transform';
diff --git a/x-pack/plugins/transform/public/app/hooks/use_authorization.ts b/x-pack/plugins/transform/public/app/hooks/use_authorization.ts
new file mode 100644
index 0000000000000..7fbc6cfe0ad8e
--- /dev/null
+++ b/x-pack/plugins/transform/public/app/hooks/use_authorization.ts
@@ -0,0 +1,63 @@
+/*
+ * 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 { useQuery } from '@tanstack/react-query';
+
+import type { IHttpFetchError } from '@kbn/core-http-browser';
+
+import { addInternalBasePath, TRANSFORM_REACT_QUERY_KEYS } from '../../../common/constants';
+import type { Privileges } from '../../../common/types/privileges';
+import {
+ type PrivilegesAndCapabilities,
+ type TransformCapabilities,
+ INITIAL_CAPABILITIES,
+} from '../../../common/privilege/has_privilege_factory';
+
+import { useAppDependencies } from '../app_dependencies';
+
+interface Authorization {
+ isLoading: boolean;
+ error: Error | null;
+ privileges: Privileges;
+ capabilities: TransformCapabilities;
+}
+
+const initialData: Authorization = {
+ isLoading: true,
+ error: null,
+ privileges: {
+ hasAllPrivileges: false,
+ missingPrivileges: {},
+ },
+ capabilities: INITIAL_CAPABILITIES,
+};
+
+export const useAuthorization = (): Authorization => {
+ const { http } = useAppDependencies();
+
+ const {
+ isLoading,
+ error,
+ data: privilegesData,
+ } = useQuery(
+ [TRANSFORM_REACT_QUERY_KEYS.GET_PRIVILEGES],
+ ({ signal }) =>
+ http.fetch(addInternalBasePath(`privileges`), {
+ version: '1',
+ method: 'GET',
+ signal,
+ }),
+ { initialData }
+ );
+
+ return {
+ isLoading,
+ privileges: privilegesData.privileges,
+ capabilities: privilegesData.capabilities,
+ error,
+ };
+};
diff --git a/x-pack/plugins/transform/public/app/hooks/use_index_data.test.tsx b/x-pack/plugins/transform/public/app/hooks/use_index_data.test.tsx
index c64d2eb09ee54..640f16f78a0b4 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_index_data.test.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_index_data.test.tsx
@@ -5,7 +5,8 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import '@testing-library/jest-dom/extend-expect';
import { render, screen, waitFor } from '@testing-library/react';
diff --git a/x-pack/plugins/transform/public/app/lib/authorization/components/authorization_provider.tsx b/x-pack/plugins/transform/public/app/lib/authorization/components/authorization_provider.tsx
deleted file mode 100644
index 34760269772d1..0000000000000
--- a/x-pack/plugins/transform/public/app/lib/authorization/components/authorization_provider.tsx
+++ /dev/null
@@ -1,83 +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, { createContext } from 'react';
-import { useQuery } from '@tanstack/react-query';
-
-import type { IHttpFetchError } from '@kbn/core-http-browser';
-
-import { TRANSFORM_REACT_QUERY_KEYS } from '../../../../../common/constants';
-import type { Privileges } from '../../../../../common/types/privileges';
-
-import {
- type PrivilegesAndCapabilities,
- type TransformCapabilities,
- INITIAL_CAPABILITIES,
-} from '../../../../../common/privilege/has_privilege_factory';
-
-import { useAppDependencies } from '../../../app_dependencies';
-
-interface Authorization {
- isLoading: boolean;
- apiError: Error | null;
- privileges: Privileges;
- capabilities: TransformCapabilities;
-}
-
-const initialValue: Authorization = {
- isLoading: true,
- apiError: null,
- privileges: {
- hasAllPrivileges: false,
- missingPrivileges: {},
- },
- capabilities: INITIAL_CAPABILITIES,
-};
-
-export const AuthorizationContext = createContext({ ...initialValue });
-
-interface Props {
- privilegesEndpoint: { path: string; version: string };
- children: React.ReactNode;
-}
-
-export const AuthorizationProvider = ({ privilegesEndpoint, children }: Props) => {
- const { http } = useAppDependencies();
-
- const { path, version } = privilegesEndpoint;
-
- const {
- isLoading,
- error,
- data: privilegesData,
- } = useQuery(
- [TRANSFORM_REACT_QUERY_KEYS.GET_PRIVILEGES],
- ({ signal }) =>
- http.fetch(path, {
- version,
- method: 'GET',
- signal,
- })
- );
-
- const value = {
- isLoading,
- privileges:
- isLoading || privilegesData === undefined
- ? { ...initialValue.privileges }
- : privilegesData.privileges,
- capabilities:
- isLoading || privilegesData === undefined
- ? { ...INITIAL_CAPABILITIES }
- : privilegesData.capabilities,
- apiError: error ? error : null,
- };
-
- return (
- {children}
- );
-};
diff --git a/x-pack/plugins/transform/public/app/lib/authorization/components/index.ts b/x-pack/plugins/transform/public/app/lib/authorization/components/index.ts
index cb0f248efc165..1b04f9287f2c4 100644
--- a/x-pack/plugins/transform/public/app/lib/authorization/components/index.ts
+++ b/x-pack/plugins/transform/public/app/lib/authorization/components/index.ts
@@ -6,6 +6,5 @@
*/
export { createCapabilityFailureMessage } from '../../../../../common/privilege/has_privilege_factory';
-export { AuthorizationProvider, AuthorizationContext } from './authorization_provider';
export { PrivilegesWrapper } from './with_privileges';
export { NotAuthorizedSection } from './not_authorized_section';
diff --git a/x-pack/plugins/transform/public/app/lib/authorization/components/with_privileges.tsx b/x-pack/plugins/transform/public/app/lib/authorization/components/with_privileges.tsx
index 2117591142b26..2623a6429da94 100644
--- a/x-pack/plugins/transform/public/app/lib/authorization/components/with_privileges.tsx
+++ b/x-pack/plugins/transform/public/app/lib/authorization/components/with_privileges.tsx
@@ -5,7 +5,7 @@
* 2.0.
*/
-import React, { useContext, FC } from 'react';
+import React, { type FC } from 'react';
import {
EuiFlexItem,
@@ -19,7 +19,7 @@ import { MissingPrivileges } from '../../../../../common/types/privileges';
import { SectionLoading } from '../../../components';
-import { AuthorizationContext } from './authorization_provider';
+import { useAuthorization } from '../../../hooks';
import { NotAuthorizedSection } from './not_authorized_section';
import {
hasPrivilegeFactory,
@@ -42,7 +42,7 @@ interface Props {
}
export const WithPrivileges = ({ privileges: requiredPrivileges, children }: Props) => {
- const { isLoading, privileges } = useContext(AuthorizationContext);
+ const { isLoading, privileges } = useAuthorization();
const privilegesToArray: Privilege[] = toArray(requiredPrivileges).map((p) => {
const [section, privilege] = p.split('.');
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/advanced_pivot_editor_switch/advanced_pivot_editor_switch.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/advanced_pivot_editor_switch/advanced_pivot_editor_switch.tsx
index 900af603266b8..a125da52b0cae 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/advanced_pivot_editor_switch/advanced_pivot_editor_switch.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/advanced_pivot_editor_switch/advanced_pivot_editor_switch.tsx
@@ -5,7 +5,7 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiFormRow, EuiSwitch } from '@elastic/eui';
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/advanced_query_editor_switch/advanced_query_editor_switch.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/advanced_query_editor_switch/advanced_query_editor_switch.tsx
index 43c6684a5a2bc..cb21e7026f27b 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/advanced_query_editor_switch/advanced_query_editor_switch.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/advanced_query_editor_switch/advanced_query_editor_switch.tsx
@@ -5,7 +5,7 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
import { EuiSwitch } from '@elastic/eui';
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/advanced_runtime_mappings_editor_switch/advanced_runtime_mappings_editor_switch.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/advanced_runtime_mappings_editor_switch/advanced_runtime_mappings_editor_switch.tsx
index 2ee8bc9995df6..c53c5dae0b4ad 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/advanced_runtime_mappings_editor_switch/advanced_runtime_mappings_editor_switch.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/advanced_runtime_mappings_editor_switch/advanced_runtime_mappings_editor_switch.tsx
@@ -5,7 +5,8 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
+
import { EuiSwitch } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { SwitchModal } from './switch_modal';
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/advanced_runtime_mappings_editor_switch/switch_modal.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/advanced_runtime_mappings_editor_switch/switch_modal.tsx
index ff08ab37bb3e6..37dd6dd01f98e 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/advanced_runtime_mappings_editor_switch/switch_modal.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/advanced_runtime_mappings_editor_switch/switch_modal.tsx
@@ -5,7 +5,8 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
+
import { EuiConfirmModal } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
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 db617690efc5f..8b76b8d7d7e1a 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
@@ -5,7 +5,8 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
+
import {
EuiButton,
EuiButtonIcon,
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/advanced_source_editor/advanced_source_editor.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/advanced_source_editor/advanced_source_editor.tsx
index 665c9986e6e69..4fea2f43bd5db 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/advanced_source_editor/advanced_source_editor.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/advanced_source_editor/advanced_source_editor.tsx
@@ -5,7 +5,7 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
import { i18n } from '@kbn/i18n';
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/date_picker_apply_switch/date_picker_apply_switch.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/date_picker_apply_switch/date_picker_apply_switch.tsx
index a57d83b75aa10..2f5672d3ec592 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/date_picker_apply_switch/date_picker_apply_switch.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/date_picker_apply_switch/date_picker_apply_switch.tsx
@@ -5,7 +5,7 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
import { EuiSwitch } from '@elastic/eui';
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/source_search_bar/source_search_bar.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/source_search_bar/source_search_bar.tsx
index e0a52978c0b4a..42b9d556f9dc2 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/source_search_bar/source_search_bar.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/source_search_bar/source_search_bar.tsx
@@ -5,7 +5,7 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
import { EuiCode, EuiInputPopover } from '@elastic/eui';
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_summary.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_summary.tsx
index b7704044fe0b3..2be067c777a1e 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_summary.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_summary.tsx
@@ -5,7 +5,7 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
export const StepCreateSummary: FC = React.memo(() => {
return null;
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/latest_function_form.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/latest_function_form.tsx
index a83c7c7a5871c..ba0d9e93e2cce 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/latest_function_form.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/latest_function_form.tsx
@@ -5,7 +5,8 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
+
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { EuiButtonIcon, EuiCallOut, EuiComboBox, EuiCopy, EuiFormRow } from '@elastic/eui';
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/pivot_function_form.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/pivot_function_form.tsx
index efa28de596a18..861aeb778af74 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/pivot_function_form.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/pivot_function_form.tsx
@@ -5,7 +5,7 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
import {
EuiButton,
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/transform_function_selector.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/transform_function_selector.tsx
index 3aec137a3adf8..441e18ebb43d2 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/transform_function_selector.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/transform_function_selector.tsx
@@ -5,7 +5,8 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
+
import { i18n } from '@kbn/i18n';
import { EuiCard, EuiFlexGroup, EuiFlexItem, EuiIcon, EuiSpacer } from '@elastic/eui';
import { TRANSFORM_FUNCTION, TransformFunction } from '../../../../../../common/constants';
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_summary.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_summary.tsx
index 80203af34e105..b3b11a6e4764e 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_summary.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_summary.tsx
@@ -5,7 +5,7 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
import { i18n } from '@kbn/i18n';
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_time_field.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_time_field.tsx
index d750bf6c7e1fd..76ce803bdb415 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_time_field.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_time_field.tsx
@@ -5,7 +5,8 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
+
import { EuiFormRow, EuiSelect } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { i18n } from '@kbn/i18n';
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/switch_modal/switch_modal.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/switch_modal/switch_modal.tsx
index 2d2a5b1fcad93..cbc53383541ed 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/switch_modal/switch_modal.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/switch_modal/switch_modal.tsx
@@ -5,7 +5,8 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
+
import { i18n } from '@kbn/i18n';
import { EuiConfirmModal } from '@elastic/eui';
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/wizard_nav/wizard_nav.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/wizard_nav/wizard_nav.tsx
index 103b8378cef7f..2ffb8437d4861 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/wizard_nav/wizard_nav.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/wizard_nav/wizard_nav.tsx
@@ -5,7 +5,7 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
import { i18n } from '@kbn/i18n';
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_clone/clone_action_name.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_clone/clone_action_name.tsx
index e6f3eeb4a9064..9af861aaf5c40 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_clone/clone_action_name.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_clone/clone_action_name.tsx
@@ -5,7 +5,8 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
+
import { i18n } from '@kbn/i18n';
import { EuiToolTip } from '@elastic/eui';
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_clone/use_clone_action.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_clone/use_clone_action.tsx
index 35d5e9f05c315..08e698672be76 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_clone/use_clone_action.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_clone/use_clone_action.tsx
@@ -5,14 +5,13 @@
* 2.0.
*/
-import React, { useCallback, useContext, useMemo } from 'react';
+import React, { useCallback, useMemo } from 'react';
import { useHistory } from 'react-router-dom';
import { i18n } from '@kbn/i18n';
-import { AuthorizationContext } from '../../../../lib/authorization';
import { TransformListAction, TransformListRow } from '../../../../common';
import { SECTION_SLUG } from '../../../../common/constants';
-import { useSearchItems } from '../../../../hooks/use_search_items';
+import { useAuthorization, useSearchItems } from '../../../../hooks';
import { useAppDependencies, useToastNotifications } from '../../../../app_dependencies';
import { cloneActionNameText, CloneActionName } from './clone_action_name';
@@ -26,7 +25,7 @@ export const useCloneAction = (forceDisable: boolean, transformNodes: number) =>
const { getDataViewIdByTitle, loadDataViews } = useSearchItems(undefined);
- const { canCreateTransform } = useContext(AuthorizationContext).capabilities;
+ const { canCreateTransform } = useAuthorization().capabilities;
const clickHandler = useCallback(
async (item: TransformListRow) => {
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_create_alert/create_alert_rule_action_name.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_create_alert/create_alert_rule_action_name.tsx
index c8d67a86d579a..dde62aa8cbfda 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_create_alert/create_alert_rule_action_name.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_create_alert/create_alert_rule_action_name.tsx
@@ -5,7 +5,8 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
+
import { EuiToolTip } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_create_alert/use_create_alert_rule_action.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_create_alert/use_create_alert_rule_action.tsx
index 070f1eb08ac60..7c2efa8cc645a 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_create_alert/use_create_alert_rule_action.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_create_alert/use_create_alert_rule_action.tsx
@@ -5,8 +5,8 @@
* 2.0.
*/
-import React, { useCallback, useContext, useMemo } from 'react';
-import { AuthorizationContext } from '../../../../lib/authorization';
+import React, { useCallback, useMemo } from 'react';
+import { useAuthorization } from '../../../../hooks';
import { TransformListAction, TransformListRow } from '../../../../common';
import {
crateAlertRuleActionNameText,
@@ -17,7 +17,7 @@ import { isContinuousTransform } from '../../../../../../common/types/transform'
export type CreateAlertRuleAction = ReturnType;
export const useCreateAlertRuleAction = (forceDisable: boolean) => {
- const { canCreateTransformAlerts } = useContext(AuthorizationContext).capabilities;
+ const { canCreateTransformAlerts } = useAuthorization().capabilities;
const { setCreateAlertRule } = useAlertRuleFlyout();
const clickHandler = useCallback(
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_action_name.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_action_name.tsx
index fa1142938efe7..24488ec60dcf2 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_action_name.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_action_name.tsx
@@ -5,7 +5,8 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
+
import { i18n } from '@kbn/i18n';
import { EuiToolTip } from '@elastic/eui';
import { TransformState, TRANSFORM_STATE } from '../../../../../../common/constants';
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/use_delete_action.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/use_delete_action.tsx
index e81612fe77bac..ddae1b1578d34 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/use_delete_action.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/use_delete_action.tsx
@@ -5,13 +5,16 @@
* 2.0.
*/
-import React, { useContext, useMemo, useState } from 'react';
+import React, { useMemo, useState } from 'react';
import { TRANSFORM_STATE } from '../../../../../../common/constants';
import { TransformListAction, TransformListRow } from '../../../../common';
-import { useDeleteIndexAndTargetIndex, useDeleteTransforms } from '../../../../hooks';
-import { AuthorizationContext } from '../../../../lib/authorization';
+import {
+ useDeleteIndexAndTargetIndex,
+ useDeleteTransforms,
+ useAuthorization,
+} from '../../../../hooks';
import {
deleteActionNameText,
@@ -21,7 +24,7 @@ import {
export type DeleteAction = ReturnType;
export const useDeleteAction = (forceDisable: boolean) => {
- const { canDeleteTransform } = useContext(AuthorizationContext).capabilities;
+ const { canDeleteTransform } = useAuthorization().capabilities;
const { mutate: deleteTransforms } = useDeleteTransforms();
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_discover/discover_action_name.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_discover/discover_action_name.tsx
index f7cc72c2236b0..c3d359e648c28 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_discover/discover_action_name.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_discover/discover_action_name.tsx
@@ -5,7 +5,8 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
+
import { i18n } from '@kbn/i18n';
import { EuiToolTip } from '@elastic/eui';
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_edit/edit_action_name.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_edit/edit_action_name.tsx
index 3bf5ee8e611f6..5a95a9dfa7601 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_edit/edit_action_name.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_edit/edit_action_name.tsx
@@ -5,16 +5,14 @@
* 2.0.
*/
-import React, { useContext, FC } from 'react';
+import React, { type FC } from 'react';
import { i18n } from '@kbn/i18n';
import { EuiToolTip } from '@elastic/eui';
-import {
- createCapabilityFailureMessage,
- AuthorizationContext,
-} from '../../../../lib/authorization';
+import { createCapabilityFailureMessage } from '../../../../lib/authorization';
+import { useAuthorization } from '../../../../hooks';
export const editActionNameText = i18n.translate(
'xpack.transform.transformList.editActionNameText',
@@ -24,7 +22,7 @@ export const editActionNameText = i18n.translate(
);
export const EditActionName: FC = () => {
- const { canCreateTransform } = useContext(AuthorizationContext).capabilities;
+ const { canCreateTransform } = useAuthorization().capabilities;
if (!canCreateTransform) {
return (
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_edit/use_edit_action.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_edit/use_edit_action.tsx
index 19d60b8b64381..e2da5262d9d28 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_edit/use_edit_action.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_edit/use_edit_action.tsx
@@ -5,12 +5,12 @@
* 2.0.
*/
-import React, { useCallback, useContext, useMemo, useState } from 'react';
+import React, { useCallback, useMemo, useState } from 'react';
import { i18n } from '@kbn/i18n';
import { TransformListAction, TransformListRow } from '../../../../common';
-import { AuthorizationContext } from '../../../../lib/authorization';
+import { useAuthorization } from '../../../../hooks';
import { editActionNameText, EditActionName } from './edit_action_name';
import { useSearchItems } from '../../../../hooks/use_search_items';
@@ -19,7 +19,7 @@ import { TransformConfigUnion } from '../../../../../../common/types/transform';
export type EditAction = ReturnType;
export const useEditAction = (forceDisable: boolean, transformNodes: number) => {
- const { canCreateTransform } = useContext(AuthorizationContext).capabilities;
+ const { canCreateTransform } = useAuthorization().capabilities;
const [config, setConfig] = useState();
const [isFlyoutVisible, setIsFlyoutVisible] = useState(false);
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reauthorize/reauthorize_action_modal.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reauthorize/reauthorize_action_modal.tsx
index 9e848fdd8323e..edfde117abbd7 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reauthorize/reauthorize_action_modal.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reauthorize/reauthorize_action_modal.tsx
@@ -5,7 +5,8 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
+
import { i18n } from '@kbn/i18n';
import { EUI_MODAL_CONFIRM_BUTTON, EuiConfirmModal } from '@elastic/eui';
import type { ReauthorizeAction } from './use_reauthorize_action';
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reauthorize/reauthorize_action_name.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reauthorize/reauthorize_action_name.tsx
index e07ae03ec46b0..5e47fbc64c87b 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reauthorize/reauthorize_action_name.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reauthorize/reauthorize_action_name.tsx
@@ -5,14 +5,12 @@
* 2.0.
*/
-import React, { FC, useContext } from 'react';
+import React, { type FC } from 'react';
import { i18n } from '@kbn/i18n';
import { EuiToolTip, EuiText } from '@elastic/eui';
import { needsReauthorization } from '../../../../common/reauthorization_utils';
-import {
- AuthorizationContext,
- createCapabilityFailureMessage,
-} from '../../../../lib/authorization';
+import { createCapabilityFailureMessage } from '../../../../lib/authorization';
+import { useAuthorization } from '../../../../hooks';
import { TransformListRow } from '../../../../common';
export const reauthorizeActionNameText = i18n.translate(
@@ -45,7 +43,7 @@ export const ReauthorizeActionName: FC = ({
forceDisable,
transformNodes,
}) => {
- const { canStartStopTransform } = useContext(AuthorizationContext).capabilities;
+ const { canStartStopTransform } = useAuthorization().capabilities;
// Disable start for batch transforms which have completed.
const someNeedsReauthorization = items.some(needsReauthorization);
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reauthorize/use_reauthorize_action.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reauthorize/use_reauthorize_action.tsx
index b3c11971fb750..f42aaf5a0c6aa 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reauthorize/use_reauthorize_action.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reauthorize/use_reauthorize_action.tsx
@@ -5,7 +5,7 @@
* 2.0.
*/
-import React, { useContext, useMemo, useState } from 'react';
+import React, { useMemo, useState } from 'react';
import { sortTransformsToReauthorize } from './sort_transforms_to_reauthorize';
import { needsReauthorization } from '../../../../common/reauthorization_utils';
@@ -17,11 +17,11 @@ import {
} from './reauthorize_action_name';
import { TransformListAction, TransformListRow } from '../../../../common';
-import { AuthorizationContext } from '../../../../lib/authorization';
+import { useAuthorization } from '../../../../hooks';
export type ReauthorizeAction = ReturnType;
export const useReauthorizeAction = (forceDisable: boolean, transformNodes: number) => {
- const { canStartStopTransform } = useContext(AuthorizationContext).capabilities;
+ const { canStartStopTransform } = useAuthorization().capabilities;
const { mutate: reauthorizeTransforms } = useReauthorizeTransforms();
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reset/reset_action_name.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reset/reset_action_name.tsx
index c6ea0f5f7270d..030b1cad14c65 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reset/reset_action_name.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reset/reset_action_name.tsx
@@ -5,7 +5,8 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
+
import { i18n } from '@kbn/i18n';
import { EuiToolTip } from '@elastic/eui';
import { TransformState, TRANSFORM_STATE } from '../../../../../../common/constants';
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reset/use_reset_action.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reset/use_reset_action.tsx
index 45dcf5b4ba3da..e5f2ea62b984d 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reset/use_reset_action.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reset/use_reset_action.tsx
@@ -5,19 +5,18 @@
* 2.0.
*/
-import React, { useContext, useMemo, useState } from 'react';
+import React, { useMemo, useState } from 'react';
import { TRANSFORM_STATE } from '../../../../../../common/constants';
import { TransformListAction, TransformListRow } from '../../../../common';
-import { useResetTransforms } from '../../../../hooks';
-import { AuthorizationContext } from '../../../../lib/authorization';
+import { useAuthorization, useResetTransforms } from '../../../../hooks';
import { resetActionNameText, isResetActionDisabled, ResetActionName } from './reset_action_name';
export type ResetAction = ReturnType;
export const useResetAction = (forceDisable: boolean) => {
- const { canResetTransform } = useContext(AuthorizationContext).capabilities;
+ const { canResetTransform } = useAuthorization().capabilities;
const { mutate: resetTransforms } = useResetTransforms();
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_schedule_now/schedule_now_action_name.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_schedule_now/schedule_now_action_name.tsx
index 71b6a055c0d94..ca3931603df4c 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_schedule_now/schedule_now_action_name.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_schedule_now/schedule_now_action_name.tsx
@@ -5,14 +5,12 @@
* 2.0.
*/
-import React, { FC, useContext } from 'react';
+import React, { type FC } from 'react';
import { i18n } from '@kbn/i18n';
import { EuiToolTip } from '@elastic/eui';
-import {
- createCapabilityFailureMessage,
- AuthorizationContext,
-} from '../../../../lib/authorization';
+import { createCapabilityFailureMessage } from '../../../../lib/authorization';
+import { useAuthorization } from '../../../../hooks';
import { TransformListRow, isCompletedBatchTransform } from '../../../../common';
export const scheduleNowActionNameText = i18n.translate(
@@ -48,7 +46,7 @@ export const ScheduleNowActionName: FC = ({
forceDisable,
transformNodes,
}) => {
- const { canScheduleNowTransform } = useContext(AuthorizationContext).capabilities;
+ const { canScheduleNowTransform } = useAuthorization().capabilities;
const isBulkAction = items.length > 1;
// Disable schedule-now for batch transforms which have completed.
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_schedule_now/use_schedule_now_action.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_schedule_now/use_schedule_now_action.tsx
index 1d9fb7417dc04..8f5fb462bb28d 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_schedule_now/use_schedule_now_action.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_schedule_now/use_schedule_now_action.tsx
@@ -5,11 +5,11 @@
* 2.0.
*/
-import React, { useContext, useMemo } from 'react';
+import React, { useMemo } from 'react';
import { TRANSFORM_STATE } from '../../../../../../common/constants';
-import { AuthorizationContext } from '../../../../lib/authorization';
+import { useAuthorization } from '../../../../hooks';
import { TransformListAction, TransformListRow } from '../../../../common';
import { useScheduleNowTransforms } from '../../../../hooks';
@@ -21,7 +21,7 @@ import {
export type ScheduleNowAction = ReturnType;
export const useScheduleNowAction = (forceDisable: boolean, transformNodes: number) => {
- const { canScheduleNowTransform } = useContext(AuthorizationContext).capabilities;
+ const { canScheduleNowTransform } = useAuthorization().capabilities;
const { mutate: scheduleNowTransforms } = useScheduleNowTransforms();
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/__snapshots__/start_action_name.test.tsx.snap b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/__snapshots__/start_action_name.test.tsx.snap
index 20b0691b55bf9..466afc71a4811 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/__snapshots__/start_action_name.test.tsx.snap
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/__snapshots__/start_action_name.test.tsx.snap
@@ -1,12 +1,134 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Transform: Transform List Actions Minimal initialization 1`] = `
-
- Start
-
+
+
+
+
`;
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_action_modal.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_action_modal.tsx
index 7ad6897034e10..ab98f36222957 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_action_modal.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_action_modal.tsx
@@ -5,7 +5,8 @@
* 2.0.
*/
-import React, { FC } from 'react';
+import React, { type FC } from 'react';
+
import { i18n } from '@kbn/i18n';
import { EuiConfirmModal, EUI_MODAL_CONFIRM_BUTTON } from '@elastic/eui';
import { StartAction } from './use_start_action';
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_action_name.test.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_action_name.test.tsx
index ba4619b022620..f609dd21325a9 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_action_name.test.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_action_name.test.tsx
@@ -7,6 +7,7 @@
import { shallow } from 'enzyme';
import React from 'react';
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { TransformListRow } from '../../../../common';
import { StartActionName, StartActionNameProps } from './start_action_name';
@@ -16,6 +17,8 @@ import transformListRow from '../../../../common/__mocks__/transform_list_row.js
jest.mock('../../../../../shared_imports');
jest.mock('../../../../app_dependencies');
+const queryClient = new QueryClient();
+
describe('Transform: Transform List Actions ', () => {
test('Minimal initialization', () => {
// @ts-expect-error mock data is too loosely typed
@@ -26,7 +29,11 @@ describe('Transform: Transform List Actions ', () => {
transformNodes: 1,
};
- const wrapper = shallow();
+ const wrapper = shallow(
+
+
+
+ );
expect(wrapper).toMatchSnapshot();
});
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_action_name.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_action_name.tsx
index 844d9755d7073..2a4fa01d63084 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_action_name.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_action_name.tsx
@@ -5,16 +5,14 @@
* 2.0.
*/
-import React, { FC, useContext } from 'react';
+import React, { type FC } from 'react';
import { i18n } from '@kbn/i18n';
import { EuiToolTip } from '@elastic/eui';
import { TRANSFORM_STATE } from '../../../../../../common/constants';
-import {
- createCapabilityFailureMessage,
- AuthorizationContext,
-} from '../../../../lib/authorization';
+import { createCapabilityFailureMessage } from '../../../../lib/authorization';
+import { useAuthorization } from '../../../../hooks';
import { TransformListRow, isCompletedBatchTransform } from '../../../../common';
export const startActionNameText = i18n.translate(
@@ -55,7 +53,7 @@ export const StartActionName: FC = ({
forceDisable,
transformNodes,
}) => {
- const { canStartStopTransform } = useContext(AuthorizationContext).capabilities;
+ const { canStartStopTransform } = useAuthorization().capabilities;
const isBulkAction = items.length > 1;
// Disable start for batch transforms which have completed.
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/use_start_action.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/use_start_action.tsx
index b033cb514cbf2..bbb08854a8cff 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/use_start_action.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/use_start_action.tsx
@@ -5,19 +5,18 @@
* 2.0.
*/
-import React, { useContext, useMemo, useState } from 'react';
+import React, { useMemo, useState } from 'react';
import { TRANSFORM_STATE } from '../../../../../../common/constants';
-import { AuthorizationContext } from '../../../../lib/authorization';
import { TransformListAction, TransformListRow } from '../../../../common';
-import { useStartTransforms } from '../../../../hooks';
+import { useAuthorization, useStartTransforms } from '../../../../hooks';
import { isStartActionDisabled, startActionNameText, StartActionName } from './start_action_name';
export type StartAction = ReturnType;
export const useStartAction = (forceDisable: boolean, transformNodes: number) => {
- const { canStartStopTransform } = useContext(AuthorizationContext).capabilities;
+ const { canStartStopTransform } = useAuthorization().capabilities;
const { mutate: startTransforms } = useStartTransforms();
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/__snapshots__/stop_action_name.test.tsx.snap b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/__snapshots__/stop_action_name.test.tsx.snap
index fd97412fa1875..ec4b06334060f 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/__snapshots__/stop_action_name.test.tsx.snap
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/__snapshots__/stop_action_name.test.tsx.snap
@@ -1,12 +1,133 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Transform: Transform List Actions Minimal initialization 1`] = `
-
- Stop
-
+
+
+
+
`;
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/stop_action_name.test.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/stop_action_name.test.tsx
index 9496dbd82c70d..316142d4b6c73 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/stop_action_name.test.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/stop_action_name.test.tsx
@@ -7,6 +7,7 @@
import { shallow } from 'enzyme';
import React from 'react';
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { TransformListRow } from '../../../../common';
import { StopActionName, StopActionNameProps } from './stop_action_name';
@@ -16,6 +17,8 @@ import transformListRow from '../../../../common/__mocks__/transform_list_row.js
jest.mock('../../../../../shared_imports');
jest.mock('../../../../app_dependencies');
+const queryClient = new QueryClient();
+
describe('Transform: Transform List Actions ', () => {
test('Minimal initialization', () => {
// @ts-expect-error mock data is too loosely typed
@@ -25,7 +28,11 @@ describe('Transform: Transform List Actions ', () => {
items: [item],
};
- const wrapper = shallow();
+ const wrapper = shallow(
+
+
+
+ );
expect(wrapper).toMatchSnapshot();
});
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/stop_action_name.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/stop_action_name.tsx
index 1c729555f7df3..71b98a825b6ba 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/stop_action_name.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/stop_action_name.tsx
@@ -5,17 +5,15 @@
* 2.0.
*/
-import React, { FC, useContext } from 'react';
+import React, { type FC } from 'react';
import { i18n } from '@kbn/i18n';
import { EuiToolTip } from '@elastic/eui';
import { TRANSFORM_STATE } from '../../../../../../common/constants';
import { TransformListRow } from '../../../../common';
-import {
- createCapabilityFailureMessage,
- AuthorizationContext,
-} from '../../../../lib/authorization';
+import { createCapabilityFailureMessage } from '../../../../lib/authorization';
+import { useAuthorization } from '../../../../hooks';
export const stopActionNameText = i18n.translate(
'xpack.transform.transformList.stopActionNameText',
@@ -43,7 +41,7 @@ export interface StopActionNameProps {
}
export const StopActionName: FC = ({ items, forceDisable }) => {
const isBulkAction = items.length > 1;
- const { canStartStopTransform } = useContext(AuthorizationContext).capabilities;
+ const { canStartStopTransform } = useAuthorization().capabilities;
// Disable stop action if one of the transforms is stopped already
const stoppedTransform = items.some(
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/use_stop_action.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/use_stop_action.tsx
index e09d5cc4888d0..b3a4a4b4e909a 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/use_stop_action.tsx
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/use_stop_action.tsx
@@ -5,18 +5,17 @@
* 2.0.
*/
-import React, { useCallback, useContext, useMemo, useState } from 'react';
+import React, { useCallback, useMemo, useState } from 'react';
import { TRANSFORM_STATE } from '../../../../../../common/constants';
-import { AuthorizationContext } from '../../../../lib/authorization';
import { TransformListAction, TransformListRow } from '../../../../common';
-import { useStopTransforms } from '../../../../hooks';
+import { useAuthorization, useStopTransforms } from '../../../../hooks';
import { isStopActionDisabled, stopActionNameText, StopActionName } from './stop_action_name';
import { isManagedTransform } from '../../../../common/managed_transforms_utils';
export type StopAction = ReturnType;
export const useStopAction = (forceDisable: boolean) => {
- const { canStartStopTransform } = useContext(AuthorizationContext).capabilities;
+ const { canStartStopTransform } = useAuthorization().capabilities;
const { mutate: stopTransforms } = useStopTransforms();
const [isModalVisible, setModalVisible] = useState(false);
diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/create_transform_button/__snapshots__/create_transform_button.test.tsx.snap b/x-pack/plugins/transform/public/app/sections/transform_management/components/create_transform_button/__snapshots__/create_transform_button.test.tsx.snap
index a529ef04f9230..e8428dbefb43c 100644
--- a/x-pack/plugins/transform/public/app/sections/transform_management/components/create_transform_button/__snapshots__/create_transform_button.test.tsx.snap
+++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/create_transform_button/__snapshots__/create_transform_button.test.tsx.snap
@@ -1,26 +1,63 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Transform: Transform List Minimal initialization 1`] = `
-
-
-