diff --git a/x-pack/plugins/ml/public/application/components/annotations/annotations_table/annotations_table.js b/x-pack/plugins/ml/public/application/components/annotations/annotations_table/annotations_table.js index c6ca4fb821984..9dabfce163dbb 100644 --- a/x-pack/plugins/ml/public/application/components/annotations/annotations_table/annotations_table.js +++ b/x-pack/plugins/ml/public/application/components/annotations/annotations_table/annotations_table.js @@ -506,7 +506,7 @@ export class AnnotationsTable extends Component { this.openSingleMetricView(annotation)} disabled={!isDrillDownAvailable} - iconType="stats" + iconType="visLine" aria-label={openInSingleMetricViewerAriaLabelText} /> diff --git a/x-pack/plugins/ml/public/application/components/anomalies_table/links_menu.js b/x-pack/plugins/ml/public/application/components/anomalies_table/links_menu.js index 0e4d736a01e47..5a7d2a9c3ddaa 100644 --- a/x-pack/plugins/ml/public/application/components/anomalies_table/links_menu.js +++ b/x-pack/plugins/ml/public/application/components/anomalies_table/links_menu.js @@ -415,7 +415,7 @@ class LinksMenuUI extends Component { items.push( { this.closePopover(); this.viewSeries(); diff --git a/x-pack/plugins/ml/public/application/components/anomaly_results_view_selector/anomaly_results_view_selector.tsx b/x-pack/plugins/ml/public/application/components/anomaly_results_view_selector/anomaly_results_view_selector.tsx index b9eaf6c5d56ec..78acb422851e3 100644 --- a/x-pack/plugins/ml/public/application/components/anomaly_results_view_selector/anomaly_results_view_selector.tsx +++ b/x-pack/plugins/ml/public/application/components/anomaly_results_view_selector/anomaly_results_view_selector.tsx @@ -27,7 +27,7 @@ export const AnomalyResultsViewSelector: FC = ({ viewId }) => { label: i18n.translate('xpack.ml.anomalyResultsViewSelector.singleMetricViewerLabel', { defaultMessage: 'View results in the Single Metric Viewer', }), - iconType: 'stats', + iconType: 'visLine', value: 'timeseriesexplorer', 'data-test-subj': 'mlAnomalyResultsViewSelectorSingleMetricViewer', }, @@ -36,7 +36,7 @@ export const AnomalyResultsViewSelector: FC = ({ viewId }) => { label: i18n.translate('xpack.ml.anomalyResultsViewSelector.anomalyExplorerLabel', { defaultMessage: 'View results in the Anomaly Explorer', }), - iconType: 'tableOfContents', + iconType: 'visTable', value: 'explorer', 'data-test-subj': 'mlAnomalyResultsViewSelectorExplorer', }, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx index 13706eb548ec8..23a16ba84ef92 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/view_results_panel/view_results_panel.tsx @@ -28,7 +28,7 @@ export const ViewResultsPanel: FC = ({ jobId, analysisType }) => { } + icon={} title={i18n.translate('xpack.ml.dataframe.analytics.create.viewResultsCardTitle', { defaultMessage: 'View Results', })} diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_button.test.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_action_name.test.ts similarity index 99% rename from x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_button.test.ts rename to x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_action_name.test.ts index 9db32e298691e..ee59b0c6c6388 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_button.test.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_action_name.test.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { isAdvancedConfig } from './clone_button'; +import { isAdvancedConfig } from './clone_action_name'; describe('Analytics job clone action', () => { describe('isAdvancedConfig', () => { diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_button.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_action_name.tsx similarity index 88% rename from x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_button.tsx rename to x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_action_name.tsx index d78e1bcc1a913..60c699ba0d370 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_button.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_action_name.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiButtonEmpty, EuiToolTip } from '@elastic/eui'; +import { EuiToolTip } from '@elastic/eui'; import React, { FC } from 'react'; import { isEqual, cloneDeep } from 'lodash'; import { i18n } from '@kbn/i18n'; @@ -14,10 +14,7 @@ import { DataFrameAnalyticsConfig, isOutlierAnalysis } from '../../../../common' import { isClassificationAnalysis, isRegressionAnalysis } from '../../../../common/analytics'; import { DEFAULT_RESULTS_FIELD } from '../../../../common/constants'; import { useMlKibana, useNavigateToPath } from '../../../../../contexts/kibana'; -import { - CreateAnalyticsFormProps, - DEFAULT_NUM_TOP_FEATURE_IMPORTANCE_VALUES, -} from '../../hooks/use_create_analytics_form'; +import { DEFAULT_NUM_TOP_FEATURE_IMPORTANCE_VALUES } from '../../hooks/use_create_analytics_form'; import { State } from '../../hooks/use_create_analytics_form/state'; import { DataFrameAnalyticsListRow } from '../analytics_list/common'; import { extractErrorMessage } from '../../../../../../../common/util/errors'; @@ -328,25 +325,12 @@ export function extractCloningConfig({ }) as unknown) as CloneDataFrameAnalyticsConfig; } -const buttonText = i18n.translate('xpack.ml.dataframe.analyticsList.cloneJobButtonLabel', { - defaultMessage: 'Clone job', -}); - -export function getCloneAction(createAnalyticsForm: CreateAnalyticsFormProps) { - const { actions } = createAnalyticsForm; - - const onClick = async (item: DeepReadonly) => { - await actions.setJobClone(item.config); - }; - - return { - name: buttonText, - description: buttonText, - icon: 'copy', - onClick, - 'data-test-subj': 'mlAnalyticsJobCloneButton', - }; -} +export const cloneActionNameText = i18n.translate( + 'xpack.ml.dataframe.analyticsList.cloneActionNameText', + { + defaultMessage: 'Clone', + } +); export const useNavigateToWizardWithClonedJob = () => { const { @@ -405,32 +389,11 @@ export const useNavigateToWizardWithClonedJob = () => { }; }; -interface CloneButtonProps { +interface CloneActionNameProps { isDisabled: boolean; - onClick: () => void; } -/** - * Temp component to have Clone job button with the same look as the other actions. - * Replace with {@link getCloneAction} as soon as all the actions are refactored - * to support EuiContext with a valid DOM structure without nested buttons. - */ -export const CloneButton: FC = ({ isDisabled, onClick }) => { - const button = ( - - {buttonText} - - ); - +export const CloneActionName: FC = ({ isDisabled }) => { if (isDisabled) { return ( = ({ isDisabled, onClick }) => { defaultMessage: 'You do not have permission to clone analytics jobs.', })} > - {button} + <>{cloneActionNameText} ); } - return button; + return <>{cloneActionNameText}; }; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/index.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/index.ts index 4e6357c4ea454..723279d04388e 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/index.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/index.ts @@ -7,7 +7,6 @@ export { extractCloningConfig, isAdvancedConfig, - useNavigateToWizardWithClonedJob, - CloneButton, CloneDataFrameAnalyticsConfig, -} from './clone_button'; +} from './clone_action_name'; +export { useCloneAction } from './use_clone_action'; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/use_clone_action.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/use_clone_action.tsx new file mode 100644 index 0000000000000..53043d4e503fe --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/use_clone_action.tsx @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useCallback, useMemo } from 'react'; + +import { DataFrameAnalyticsListAction, DataFrameAnalyticsListRow } from '../analytics_list/common'; + +import { + cloneActionNameText, + useNavigateToWizardWithClonedJob, + CloneActionName, +} from './clone_action_name'; + +export type CloneAction = ReturnType; +export const useCloneAction = (canCreateDataFrameAnalytics: boolean) => { + const navigateToWizardWithClonedJob = useNavigateToWizardWithClonedJob(); + + const clickHandler = useCallback((item: DataFrameAnalyticsListRow) => { + navigateToWizardWithClonedJob(item); + }, []); + + const action: DataFrameAnalyticsListAction = useMemo( + () => ({ + name: (item: DataFrameAnalyticsListRow) => ( + + ), + enabled: () => canCreateDataFrameAnalytics, + description: cloneActionNameText, + icon: 'copy', + type: 'icon', + onClick: clickHandler, + 'data-test-subj': 'mlAnalyticsJobCloneButton', + }), + [] + ); + + return { action }; +}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_button_modal.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_modal.tsx similarity index 98% rename from x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_button_modal.tsx rename to x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_modal.tsx index f94dccee479bd..5ffa5e304b996 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_button_modal.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_modal.tsx @@ -18,7 +18,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { DeleteAction } from './use_delete_action'; -export const DeleteButtonModal: FC = ({ +export const DeleteActionModal: FC = ({ closeModal, deleteAndCloseModal, deleteTargetIndex, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/action_delete.test.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_name.test.tsx similarity index 73% rename from x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/action_delete.test.tsx rename to x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_name.test.tsx index 99455a33cf084..e033af6436130 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/action_delete.test.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_name.test.tsx @@ -14,8 +14,8 @@ import { i18nServiceMock, } from '../../../../../../../../../../src/core/public/mocks'; -import { DeleteButton } from './delete_button'; -import { DeleteButtonModal } from './delete_button_modal'; +import { DeleteActionName } from './delete_action_name'; +import { DeleteActionModal } from './delete_action_modal'; import { useDeleteAction } from './use_delete_action'; jest.mock('../../../../../capabilities/check_capabilities', () => ({ @@ -49,38 +49,39 @@ describe('DeleteAction', () => { jest.clearAllMocks(); }); - test('When isDisabled prop is true, inner button should be disabled.', () => { - const { getByTestId } = render( - {}} /> + it('should display a tooltip when isDisabled prop is true.', () => { + const { container } = render( + ); - expect(getByTestId('mlAnalyticsJobDeleteButton')).toHaveAttribute('disabled'); + expect(container.querySelector('.euiToolTipAnchor')).toBeInTheDocument(); }); - test('When isDisabled prop is true, inner button should not be disabled.', () => { - const { getByTestId } = render( - {}} /> + it('should not display a tooltip when isDisabled prop is false.', () => { + const { container } = render( + ); - expect(getByTestId('mlAnalyticsJobDeleteButton')).not.toHaveAttribute('disabled'); + expect(container.querySelector('.euiToolTipAnchor')).not.toBeInTheDocument(); }); describe('When delete model is open', () => { - test('should allow to delete target index by default.', () => { + it('should allow to delete target index by default.', () => { const mock = jest.spyOn(CheckPrivilige, 'checkPermission'); mock.mockImplementation((p) => p === 'canDeleteDataFrameAnalytics'); const TestComponent = () => { - const deleteAction = useDeleteAction(); + const deleteAction = useDeleteAction(true); return ( <> - {deleteAction.isModalVisible && } - } + ); }; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_button.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_name.tsx similarity index 62% rename from x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_button.tsx rename to x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_name.tsx index 2bc3935c3b9f1..ccf45da81670c 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_button.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_name.tsx @@ -6,36 +6,23 @@ import React, { FC } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiButtonEmpty, EuiToolTip } from '@elastic/eui'; +import { EuiToolTip } from '@elastic/eui'; import { createPermissionFailureMessage } from '../../../../../capabilities/check_capabilities'; import { isDataFrameAnalyticsRunning, DataFrameAnalyticsListRow } from '../analytics_list/common'; -const buttonText = i18n.translate('xpack.ml.dataframe.analyticsList.deleteActionName', { - defaultMessage: 'Delete', -}); +export const deleteActionNameText = i18n.translate( + 'xpack.ml.dataframe.analyticsList.deleteActionNameText', + { + defaultMessage: 'Delete', + } +); -interface DeleteButtonProps { +interface DeleteActionNameProps { isDisabled: boolean; item: DataFrameAnalyticsListRow; - onClick: () => void; } -export const DeleteButton: FC = ({ isDisabled, item, onClick }) => { - const button = ( - - {buttonText} - - ); - +export const DeleteActionName: FC = ({ isDisabled, item }) => { if (isDisabled) { return ( = ({ isDisabled, item, onClick : createPermissionFailureMessage('canStartStopDataFrameAnalytics') } > - {button} + <>{deleteActionNameText} ); } - return button; + return <>{deleteActionNameText}; }; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/index.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/index.ts index ef891d7c4a128..640cc39c90662 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/index.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/index.ts @@ -4,6 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -export { DeleteButton } from './delete_button'; -export { DeleteButtonModal } from './delete_button_modal'; +export { DeleteActionName } from './delete_action_name'; +export { DeleteActionModal } from './delete_action_modal'; export { useDeleteAction } from './use_delete_action'; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/use_delete_action.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/use_delete_action.tsx similarity index 77% rename from x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/use_delete_action.ts rename to x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/use_delete_action.tsx index 461b1749c7936..60a7267db1e25 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/use_delete_action.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/use_delete_action.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { useEffect, useState } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; import { i18n } from '@kbn/i18n'; @@ -21,10 +21,16 @@ import { canDeleteIndex, } from '../../services/analytics_service'; -import { DataFrameAnalyticsListRow } from '../analytics_list/common'; +import { + isDataFrameAnalyticsRunning, + DataFrameAnalyticsListAction, + DataFrameAnalyticsListRow, +} from '../analytics_list/common'; + +import { deleteActionNameText, DeleteActionName } from './delete_action_name'; export type DeleteAction = ReturnType; -export const useDeleteAction = () => { +export const useDeleteAction = (canDeleteDataFrameAnalytics: boolean) => { const [item, setItem] = useState(); const [isModalVisible, setModalVisible] = useState(false); @@ -33,7 +39,7 @@ export const useDeleteAction = () => { const [userCanDeleteIndex, setUserCanDeleteIndex] = useState(false); const [indexPatternExists, setIndexPatternExists] = useState(false); - const { savedObjects, notifications } = useMlKibana().services; + const { savedObjects } = useMlKibana().services; const savedObjectsClient = savedObjects.client; const indexName = item?.config.dest.index ?? ''; @@ -58,10 +64,9 @@ export const useDeleteAction = () => { setIndexPatternExists(false); } } catch (e) { - const { toasts } = notifications; const error = extractErrorMessage(e); - toasts.addDanger( + toastNotificationService.displayDangerToast( i18n.translate( 'xpack.ml.dataframe.analyticsList.errorWithCheckingIfIndexPatternExistsNotificationErrorMessage', { @@ -75,15 +80,14 @@ export const useDeleteAction = () => { }; const checkUserIndexPermission = () => { try { - const userCanDelete = canDeleteIndex(indexName); + const userCanDelete = canDeleteIndex(indexName, toastNotificationService); if (userCanDelete) { setUserCanDeleteIndex(true); } } catch (e) { - const { toasts } = notifications; const error = extractErrorMessage(e); - toasts.addDanger( + toastNotificationService.displayDangerToast( i18n.translate( 'xpack.ml.dataframe.analyticsList.errorWithCheckingIfUserCanDeleteIndexNotificationErrorMessage', { @@ -130,7 +134,27 @@ export const useDeleteAction = () => { setModalVisible(true); }; + const action: DataFrameAnalyticsListAction = useMemo( + () => ({ + name: (i: DataFrameAnalyticsListRow) => ( + + ), + enabled: (i: DataFrameAnalyticsListRow) => + !isDataFrameAnalyticsRunning(i.stats.state) && canDeleteDataFrameAnalytics, + description: deleteActionNameText, + icon: 'trash', + type: 'icon', + onClick: (i: DataFrameAnalyticsListRow) => openModal(i), + 'data-test-subj': 'mlAnalyticsJobDeleteButton', + }), + [] + ); + return { + action, closeModal, deleteAndCloseModal, deleteTargetIndex, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/edit_button_flyout.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/edit_action_flyout.tsx similarity index 99% rename from x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/edit_button_flyout.tsx rename to x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/edit_action_flyout.tsx index 14b743997f30a..867f89d9e5e4a 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/edit_button_flyout.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/edit_action_flyout.tsx @@ -43,7 +43,7 @@ import { EditAction } from './use_edit_action'; let mmLValidator: (value: any) => MemoryInputValidatorResult; -export const EditButtonFlyout: FC> = ({ closeFlyout, item }) => { +export const EditActionFlyout: FC> = ({ closeFlyout, item }) => { const { id: jobId, config } = item; const { state } = item.stats; const initialAllowLazyStart = diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/edit_button.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/edit_action_name.tsx similarity index 50% rename from x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/edit_button.tsx rename to x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/edit_action_name.tsx index e17862bf326f1..5b7f40c81f118 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/edit_button.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/edit_action_name.tsx @@ -8,33 +8,20 @@ import React, { FC } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiButtonEmpty, EuiToolTip } from '@elastic/eui'; +import { EuiToolTip } from '@elastic/eui'; -const buttonText = i18n.translate('xpack.ml.dataframe.analyticsList.editActionName', { - defaultMessage: 'Edit', -}); +export const editActionNameText = i18n.translate( + 'xpack.ml.dataframe.analyticsList.editActionNameText', + { + defaultMessage: 'Edit', + } +); -interface EditButtonProps { +interface EditActionNameProps { isDisabled: boolean; - onClick: () => void; } -export const EditButton: FC = ({ isDisabled, onClick }) => { - const button = ( - - {buttonText} - - ); - +export const EditActionName: FC = ({ isDisabled }) => { if (isDisabled) { return ( = ({ isDisabled, onClick }) => { defaultMessage: 'You do not have permission to edit analytics jobs.', })} > - {button} + <>{editActionNameText} ); } - return button; + return <>{editActionNameText}; }; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/index.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/index.ts index cfb0bba16ca18..07b3949717797 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/index.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/index.ts @@ -4,6 +4,5 @@ * you may not use this file except in compliance with the Elastic License. */ -export { EditButton } from './edit_button'; -export { EditButtonFlyout } from './edit_button_flyout'; +export { EditActionFlyout } from './edit_action_flyout'; export { isEditActionFlyoutVisible, useEditAction } from './use_edit_action'; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/use_edit_action.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/use_edit_action.tsx similarity index 56% rename from x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/use_edit_action.ts rename to x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/use_edit_action.tsx index 82a7bcc91997a..67f0d9d059570 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/use_edit_action.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/use_edit_action.tsx @@ -4,9 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import { useState } from 'react'; +import React, { useMemo, useState } from 'react'; -import { DataFrameAnalyticsListRow } from '../analytics_list/common'; +import { DataFrameAnalyticsListAction, DataFrameAnalyticsListRow } from '../analytics_list/common'; + +import { editActionNameText, EditActionName } from './edit_action_name'; export const isEditActionFlyoutVisible = (editAction: any): editAction is Required => { return editAction.isFlyoutVisible === true && editAction.item !== undefined; @@ -18,7 +20,7 @@ export interface EditAction { closeFlyout: () => void; openFlyout: (newItem: DataFrameAnalyticsListRow) => void; } -export const useEditAction = () => { +export const useEditAction = (canStartStopDataFrameAnalytics: boolean) => { const [item, setItem] = useState(); const [isFlyoutVisible, setIsFlyoutVisible] = useState(false); @@ -28,7 +30,21 @@ export const useEditAction = () => { setIsFlyoutVisible(true); }; + const action: DataFrameAnalyticsListAction = useMemo( + () => ({ + name: () => , + enabled: () => canStartStopDataFrameAnalytics, + description: editActionNameText, + icon: 'pencil', + type: 'icon', + onClick: (i: DataFrameAnalyticsListRow) => openFlyout(i), + 'data-test-subj': 'mlAnalyticsJobEditButton', + }), + [canStartStopDataFrameAnalytics] + ); + return { + action, isFlyoutVisible, item, closeFlyout, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_start/index.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_start/index.ts index df6bbb7c61908..cda5b0ee1ec79 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_start/index.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_start/index.ts @@ -4,6 +4,5 @@ * you may not use this file except in compliance with the Elastic License. */ -export { StartButton } from './start_button'; -export { StartButtonModal } from './start_button_modal'; export { useStartAction } from './use_start_action'; +export { StartActionModal } from './start_action_modal'; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_start/start_button_modal.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_start/start_action_modal.tsx similarity index 96% rename from x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_start/start_button_modal.tsx rename to x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_start/start_action_modal.tsx index 664dbe5c62b2f..fa559e807f5ea 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_start/start_button_modal.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_start/start_action_modal.tsx @@ -10,7 +10,7 @@ import { EuiConfirmModal, EuiOverlayMask, EUI_MODAL_CONFIRM_BUTTON } from '@elas import { StartAction } from './use_start_action'; -export const StartButtonModal: FC = ({ closeModal, item, startAndCloseModal }) => { +export const StartActionModal: FC = ({ closeModal, item, startAndCloseModal }) => { return ( <> {item !== undefined && ( diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_start/start_button.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_start/start_action_name.tsx similarity index 65% rename from x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_start/start_button.tsx rename to x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_start/start_action_name.tsx index 98b9279d8469a..1b39f3c8a7167 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_start/start_button.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_start/start_action_name.tsx @@ -6,44 +6,30 @@ import React, { FC } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiButtonEmpty, EuiToolTip } from '@elastic/eui'; +import { EuiToolTip } from '@elastic/eui'; import { createPermissionFailureMessage } from '../../../../../capabilities/check_capabilities'; import { DataFrameAnalyticsListRow } from '../analytics_list/common'; -const buttonText = i18n.translate('xpack.ml.dataframe.analyticsList.startActionName', { - defaultMessage: 'Start', -}); +export const startActionNameText = i18n.translate( + 'xpack.ml.dataframe.analyticsList.startActionNameText', + { + defaultMessage: 'Start', + } +); -interface StartButtonProps { +interface StartActionNameProps { canStartStopDataFrameAnalytics: boolean; isDisabled: boolean; item: DataFrameAnalyticsListRow; - onClick: () => void; } -export const StartButton: FC = ({ +export const StartActionName: FC = ({ canStartStopDataFrameAnalytics, isDisabled, item, - onClick, }) => { - const button = ( - - {buttonText} - - ); - if (isDisabled) { return ( = ({ }) } > - {button} + <>{startActionNameText} ); } - return button; + return <>{startActionNameText}; }; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_start/use_start_action.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_start/use_start_action.ts deleted file mode 100644 index 3c1087ff587d8..0000000000000 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_start/use_start_action.ts +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { useState } from 'react'; - -import { DataFrameAnalyticsListRow } from '../analytics_list/common'; -import { startAnalytics } from '../../services/analytics_service'; -import { useToastNotificationService } from '../../../../../services/toast_notification_service'; - -export type StartAction = ReturnType; -export const useStartAction = () => { - const [isModalVisible, setModalVisible] = useState(false); - - const [item, setItem] = useState(); - - const toastNotificationService = useToastNotificationService(); - - const closeModal = () => setModalVisible(false); - const startAndCloseModal = () => { - if (item !== undefined) { - setModalVisible(false); - startAnalytics(item, toastNotificationService); - } - }; - - const openModal = (newItem: DataFrameAnalyticsListRow) => { - setItem(newItem); - setModalVisible(true); - }; - - return { - closeModal, - isModalVisible, - item, - openModal, - startAndCloseModal, - }; -}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_start/use_start_action.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_start/use_start_action.tsx new file mode 100644 index 0000000000000..f72c4d8a1f556 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_start/use_start_action.tsx @@ -0,0 +1,80 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useMemo, useState } from 'react'; + +import { + isCompletedAnalyticsJob, + isDataFrameAnalyticsFailed, + isDataFrameAnalyticsRunning, + DataFrameAnalyticsListAction, + DataFrameAnalyticsListRow, +} from '../analytics_list/common'; +import { startAnalytics } from '../../services/analytics_service'; +import { useToastNotificationService } from '../../../../../services/toast_notification_service'; + +import { startActionNameText, StartActionName } from './start_action_name'; + +export type StartAction = ReturnType; +export const useStartAction = (canStartStopDataFrameAnalytics: boolean) => { + const [isModalVisible, setModalVisible] = useState(false); + + const [item, setItem] = useState(); + + const toastNotificationService = useToastNotificationService(); + + const closeModal = () => setModalVisible(false); + const startAndCloseModal = () => { + if (item !== undefined) { + setModalVisible(false); + startAnalytics(item, toastNotificationService); + } + }; + + const openModal = (newItem: DataFrameAnalyticsListRow) => { + setItem(newItem); + setModalVisible(true); + }; + + const startButtonEnabled = (i: DataFrameAnalyticsListRow) => { + if (!isDataFrameAnalyticsRunning(i.stats.state)) { + // Disable start for analytics jobs which have completed. + const completeAnalytics = isCompletedAnalyticsJob(i.stats); + return canStartStopDataFrameAnalytics && !completeAnalytics; + } + return canStartStopDataFrameAnalytics; + }; + + const action: DataFrameAnalyticsListAction = useMemo( + () => ({ + name: (i: DataFrameAnalyticsListRow) => ( + + ), + available: (i: DataFrameAnalyticsListRow) => + !isDataFrameAnalyticsRunning(i.stats.state) && !isDataFrameAnalyticsFailed(i.stats.state), + enabled: startButtonEnabled, + description: startActionNameText, + icon: 'play', + type: 'icon', + onClick: openModal, + 'data-test-subj': 'mlAnalyticsJobStartButton', + }), + [] + ); + + return { + action, + closeModal, + isModalVisible, + item, + openModal, + startAndCloseModal, + }; +}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_stop/index.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_stop/index.ts index ce03305e3d859..f45b90222611b 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_stop/index.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_stop/index.ts @@ -4,6 +4,5 @@ * you may not use this file except in compliance with the Elastic License. */ -export { StopButton } from './stop_button'; -export { StopButtonModal } from './stop_button_modal'; -export { useForceStopAction } from './use_force_stop_action'; +export { useStopAction } from './use_stop_action'; +export { StopActionModal } from './stop_action_modal'; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_stop/stop_button_modal.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_stop/stop_action_modal.tsx similarity index 91% rename from x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_stop/stop_button_modal.tsx rename to x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_stop/stop_action_modal.tsx index 387f42cc85ef3..0b483ce4cad16 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_stop/stop_button_modal.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_stop/stop_action_modal.tsx @@ -9,13 +9,9 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiConfirmModal, EuiOverlayMask, EUI_MODAL_CONFIRM_BUTTON } from '@elastic/eui'; -import { ForceStopAction } from './use_force_stop_action'; +import { StopAction } from './use_stop_action'; -export const StopButtonModal: FC = ({ - closeModal, - item, - forceStopAndCloseModal, -}) => { +export const StopActionModal: FC = ({ closeModal, item, forceStopAndCloseModal }) => { return ( <> {item !== undefined && ( diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_stop/stop_action_name.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_stop/stop_action_name.tsx new file mode 100644 index 0000000000000..99c8d960cf3b9 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_stop/stop_action_name.tsx @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC } from 'react'; +import { i18n } from '@kbn/i18n'; + +import { EuiToolTip } from '@elastic/eui'; + +import { createPermissionFailureMessage } from '../../../../../capabilities/check_capabilities'; + +export const stopActionNameText = i18n.translate( + 'xpack.ml.dataframe.analyticsList.stopActionNameText', + { + defaultMessage: 'Stop', + } +); + +interface StopActionNameProps { + isDisabled: boolean; +} + +export const StopActionName: FC = ({ isDisabled }) => { + if (isDisabled) { + return ( + + <>{stopActionNameText} + + ); + } + + return <>{stopActionNameText}; +}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_stop/stop_button.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_stop/stop_button.tsx deleted file mode 100644 index 3bac183d9f391..0000000000000 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_stop/stop_button.tsx +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React, { FC } from 'react'; -import { i18n } from '@kbn/i18n'; - -import { EuiButtonEmpty, EuiToolTip } from '@elastic/eui'; - -import { createPermissionFailureMessage } from '../../../../../capabilities/check_capabilities'; - -import { DataFrameAnalyticsListRow } from '../analytics_list/common'; - -const buttonText = i18n.translate('xpack.ml.dataframe.analyticsList.stopActionName', { - defaultMessage: 'Stop', -}); - -interface StopButtonProps { - isDisabled: boolean; - item: DataFrameAnalyticsListRow; - onClick: () => void; -} - -export const StopButton: FC = ({ isDisabled, item, onClick }) => { - const button = ( - - {buttonText} - - ); - - if (isDisabled) { - return ( - - {button} - - ); - } - - return button; -}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_stop/use_force_stop_action.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_stop/use_force_stop_action.ts deleted file mode 100644 index 5a4e748948731..0000000000000 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_stop/use_force_stop_action.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { useState } from 'react'; - -import { DataFrameAnalyticsListRow } from '../analytics_list/common'; -import { stopAnalytics } from '../../services/analytics_service'; - -export type ForceStopAction = ReturnType; -export const useForceStopAction = () => { - const [isModalVisible, setModalVisible] = useState(false); - - const [item, setItem] = useState(); - - const closeModal = () => setModalVisible(false); - const forceStopAndCloseModal = () => { - if (item !== undefined) { - setModalVisible(false); - stopAnalytics(item); - } - }; - - const openModal = (newItem: DataFrameAnalyticsListRow) => { - setItem(newItem); - setModalVisible(true); - }; - - return { - closeModal, - isModalVisible, - item, - openModal, - forceStopAndCloseModal, - }; -}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_stop/use_stop_action.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_stop/use_stop_action.tsx new file mode 100644 index 0000000000000..546744c992709 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_stop/use_stop_action.tsx @@ -0,0 +1,67 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useCallback, useMemo, useState } from 'react'; + +import { + isDataFrameAnalyticsFailed, + isDataFrameAnalyticsRunning, + DataFrameAnalyticsListAction, + DataFrameAnalyticsListRow, +} from '../analytics_list/common'; +import { stopAnalytics } from '../../services/analytics_service'; + +import { stopActionNameText, StopActionName } from './stop_action_name'; + +export type StopAction = ReturnType; +export const useStopAction = (canStartStopDataFrameAnalytics: boolean) => { + const [isModalVisible, setModalVisible] = useState(false); + + const [item, setItem] = useState(); + + const closeModal = () => setModalVisible(false); + const forceStopAndCloseModal = () => { + if (item !== undefined) { + setModalVisible(false); + stopAnalytics(item); + } + }; + + const openModal = (newItem: DataFrameAnalyticsListRow) => { + setItem(newItem); + setModalVisible(true); + }; + + const clickHandler = useCallback( + (i: DataFrameAnalyticsListRow) => { + if (canStartStopDataFrameAnalytics) { + if (isDataFrameAnalyticsFailed(i.stats.state)) { + openModal(i); + } else { + stopAnalytics(i); + } + } + }, + [stopAnalytics] + ); + + const action: DataFrameAnalyticsListAction = useMemo( + () => ({ + name: () => , + available: (i: DataFrameAnalyticsListRow) => + isDataFrameAnalyticsRunning(i.stats.state) || isDataFrameAnalyticsFailed(i.stats.state), + enabled: () => canStartStopDataFrameAnalytics, + description: stopActionNameText, + icon: 'stop', + type: 'icon', + onClick: clickHandler, + 'data-test-subj': 'mlAnalyticsJobStopButton', + }), + [clickHandler] + ); + + return { action, closeModal, isModalVisible, item, openModal, forceStopAndCloseModal }; +}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_view/get_view_action.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_view/get_view_action.tsx deleted file mode 100644 index e123af204b515..0000000000000 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_view/get_view_action.tsx +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; - -import { EuiTableActionsColumnType } from '@elastic/eui'; - -import { DataFrameAnalyticsListRow } from '../analytics_list/common'; - -import { ViewButton } from './view_button'; - -export const getViewAction = (): EuiTableActionsColumnType< - DataFrameAnalyticsListRow ->['actions'][number] => ({ - isPrimary: true, - render: (item: DataFrameAnalyticsListRow) => , -}); diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_view/index.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_view/index.ts index 5ac12c12071fd..076c07abfe920 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_view/index.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_view/index.ts @@ -4,5 +4,5 @@ * you may not use this file except in compliance with the Elastic License. */ -export { getViewAction } from './get_view_action'; +export { useViewAction } from './use_view_action'; export { ViewButton } from './view_button'; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_view/use_view_action.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_view/use_view_action.tsx new file mode 100644 index 0000000000000..a3595b51d0a59 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_view/use_view_action.tsx @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useCallback, useMemo } from 'react'; + +import { getAnalysisType } from '../../../../common/analytics'; +import { useNavigateToPath } from '../../../../../contexts/kibana'; + +import { + getResultsUrl, + DataFrameAnalyticsListAction, + DataFrameAnalyticsListRow, +} from '../analytics_list/common'; + +import { getViewLinkStatus } from './get_view_link_status'; +import { viewActionButtonText, ViewButton } from './view_button'; + +export type ViewAction = ReturnType; +export const useViewAction = () => { + const navigateToPath = useNavigateToPath(); + + const clickHandler = useCallback((item: DataFrameAnalyticsListRow) => { + const analysisType = getAnalysisType(item.config.analysis); + navigateToPath(getResultsUrl(item.id, analysisType)); + }, []); + + const action: DataFrameAnalyticsListAction = useMemo( + () => ({ + isPrimary: true, + name: (item: DataFrameAnalyticsListRow) => , + enabled: (item: DataFrameAnalyticsListRow) => !getViewLinkStatus(item).disabled, + description: viewActionButtonText, + icon: 'visTable', + type: 'icon', + onClick: clickHandler, + 'data-test-subj': 'mlAnalyticsJobViewButton', + }), + [clickHandler] + ); + + return { action }; +}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_view/view_button.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_view/view_button.tsx index 9472a3af852fc..d46ddf1fcaaba 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_view/view_button.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_view/view_button.tsx @@ -6,53 +6,33 @@ import React, { FC } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiButtonEmpty, EuiToolTip } from '@elastic/eui'; +import { EuiToolTip } from '@elastic/eui'; -import { getAnalysisType } from '../../../../common/analytics'; -import { useNavigateToPath } from '../../../../../contexts/kibana'; - -import { getResultsUrl, DataFrameAnalyticsListRow } from '../analytics_list/common'; +import { DataFrameAnalyticsListRow } from '../analytics_list/common'; import { getViewLinkStatus } from './get_view_link_status'; +export const viewActionButtonText = i18n.translate( + 'xpack.ml.dataframe.analyticsList.viewActionName', + { + defaultMessage: 'View', + } +); + interface ViewButtonProps { item: DataFrameAnalyticsListRow; } export const ViewButton: FC = ({ item }) => { - const navigateToPath = useNavigateToPath(); - const { disabled, tooltipContent } = getViewLinkStatus(item); - const analysisType = getAnalysisType(item.config.analysis); - - const onClickHandler = () => navigateToPath(getResultsUrl(item.id, analysisType)); - - const buttonText = i18n.translate('xpack.ml.dataframe.analyticsList.viewActionName', { - defaultMessage: 'View', - }); - - const button = ( - - {buttonText} - - ); if (disabled) { return ( - {button} + <>{viewActionButtonText} ); } - return button; + return <>{viewActionButtonText}; }; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/common.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/common.ts index 39489836773b3..774864ae964a8 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/common.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/common.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Query, Ast } from '@elastic/eui'; +import { EuiTableActionsColumnType, Query, Ast } from '@elastic/eui'; import { DATA_FRAME_TASK_STATE } from './data_frame_task_state'; export { DATA_FRAME_TASK_STATE }; @@ -139,3 +139,11 @@ export function isCompletedAnalyticsJob(stats: DataFrameAnalyticsStats) { export function getResultsUrl(jobId: string, analysisType: ANALYSIS_CONFIG_TYPE | string) { return `#/data_frame_analytics/exploration?_g=(ml:(jobId:${jobId},analysisType:${analysisType}))`; } + +// The single Action type is not exported as is +// from EUI so we use that code to get the single +// Action type from the array of actions. +type ArrayElement = ArrayType[number]; +export type DataFrameAnalyticsListAction = ArrayElement< + EuiTableActionsColumnType['actions'] +>; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/use_actions.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/use_actions.tsx index d355335039085..20ae48a12ecf9 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/use_actions.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/use_actions.tsx @@ -10,26 +10,14 @@ import { EuiTableActionsColumnType } from '@elastic/eui'; import { checkPermission } from '../../../../../capabilities/check_capabilities'; -import { stopAnalytics } from '../../services/analytics_service'; +import { useCloneAction } from '../action_clone'; +import { useDeleteAction, DeleteActionModal } from '../action_delete'; +import { isEditActionFlyoutVisible, useEditAction, EditActionFlyout } from '../action_edit'; +import { useStartAction, StartActionModal } from '../action_start'; +import { useStopAction, StopActionModal } from '../action_stop'; +import { useViewAction } from '../action_view'; -import { useNavigateToWizardWithClonedJob, CloneButton } from '../action_clone'; -import { useDeleteAction, DeleteButton, DeleteButtonModal } from '../action_delete'; -import { - isEditActionFlyoutVisible, - useEditAction, - EditButton, - EditButtonFlyout, -} from '../action_edit'; -import { useStartAction, StartButton, StartButtonModal } from '../action_start'; -import { StopButton, useForceStopAction, StopButtonModal } from '../action_stop'; -import { getViewAction } from '../action_view'; - -import { - isCompletedAnalyticsJob, - isDataFrameAnalyticsRunning, - isDataFrameAnalyticsFailed, - DataFrameAnalyticsListRow, -} from './common'; +import { DataFrameAnalyticsListRow } from './common'; export const useActions = ( isManagementTable: boolean @@ -41,126 +29,38 @@ export const useActions = ( const canDeleteDataFrameAnalytics: boolean = checkPermission('canDeleteDataFrameAnalytics'); const canStartStopDataFrameAnalytics: boolean = checkPermission('canStartStopDataFrameAnalytics'); + const viewAction = useViewAction(); + const cloneAction = useCloneAction(canCreateDataFrameAnalytics); + const deleteAction = useDeleteAction(canDeleteDataFrameAnalytics); + const editAction = useEditAction(canStartStopDataFrameAnalytics); + const startAction = useStartAction(canStartStopDataFrameAnalytics); + const stopAction = useStopAction(canStartStopDataFrameAnalytics); + let modals: JSX.Element | null = null; const actions: EuiTableActionsColumnType['actions'] = [ - getViewAction(), + viewAction.action, ]; // isManagementTable will be the same for the lifecycle of the component // Disabling lint error to fix console error in management list due to action hooks using deps not initialized in management if (isManagementTable === false) { - /* eslint-disable react-hooks/rules-of-hooks */ - const deleteAction = useDeleteAction(); - const editAction = useEditAction(); - const startAction = useStartAction(); - const stopAction = useForceStopAction(); - /* eslint-disable react-hooks/rules-of-hooks */ - modals = ( <> - {startAction.isModalVisible && } - {stopAction.isModalVisible && } - {deleteAction.isModalVisible && } - {isEditActionFlyoutVisible(editAction) && } + {startAction.isModalVisible && } + {stopAction.isModalVisible && } + {deleteAction.isModalVisible && } + {isEditActionFlyoutVisible(editAction) && } ); - const startButtonEnabled = (item: DataFrameAnalyticsListRow) => { - if (!isDataFrameAnalyticsRunning(item.stats.state)) { - // Disable start for analytics jobs which have completed. - const completeAnalytics = isCompletedAnalyticsJob(item.stats); - return canStartStopDataFrameAnalytics && !completeAnalytics; - } - return canStartStopDataFrameAnalytics; - }; - - const navigateToWizardWithClonedJob = useNavigateToWizardWithClonedJob(); - actions.push( ...[ - { - render: (item: DataFrameAnalyticsListRow) => { - if ( - !isDataFrameAnalyticsRunning(item.stats.state) && - !isDataFrameAnalyticsFailed(item.stats.state) - ) { - return ( - { - if (startButtonEnabled(item)) { - startAction.openModal(item); - } - }} - /> - ); - } - - return ( - { - if (canStartStopDataFrameAnalytics) { - if (isDataFrameAnalyticsFailed(item.stats.state)) { - stopAction.openModal(item); - } else { - stopAnalytics(item); - } - } - }} - /> - ); - }, - }, - { - render: (item: DataFrameAnalyticsListRow) => { - return ( - { - if (canStartStopDataFrameAnalytics) { - editAction.openFlyout(item); - } - }} - /> - ); - }, - }, - { - render: (item: DataFrameAnalyticsListRow) => { - return ( - { - if (canStartStopDataFrameAnalytics) { - deleteAction.openModal(item); - } - }} - /> - ); - }, - }, - { - render: (item: DataFrameAnalyticsListRow) => { - return ( - { - if (canCreateDataFrameAnalytics) { - navigateToWizardWithClonedJob(item); - } - }} - /> - ); - }, - }, + startAction.action, + stopAction.action, + editAction.action, + cloneAction.action, + deleteAction.action, ] ); } diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/reducer.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/reducer.ts index 8d8421a116b91..7cd9fcc052f1a 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/reducer.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/reducer.ts @@ -45,7 +45,7 @@ import { TRAINING_PERCENT_MAX, } from '../../../../common/analytics'; import { indexPatterns } from '../../../../../../../../../../src/plugins/data/public'; -import { isAdvancedConfig } from '../../components/action_clone/clone_button'; +import { isAdvancedConfig } from '../../components/action_clone/clone_action_name'; const mmlAllowedUnitsStr = `${ALLOWED_DATA_UNITS.slice(0, ALLOWED_DATA_UNITS.length - 1).join( ', ' diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/services/analytics_service/delete_analytics.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/services/analytics_service/delete_analytics.ts index 7d3ee986a4ef1..9de859742438e 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/services/analytics_service/delete_analytics.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/services/analytics_service/delete_analytics.ts @@ -5,7 +5,6 @@ */ import { i18n } from '@kbn/i18n'; import { extractErrorMessage } from '../../../../../../../common/util/errors'; -import { getToastNotifications } from '../../../../../util/dependency_cache'; import { ml } from '../../../../../services/ml_api_service'; import { ToastNotificationService } from '../../../../../services/toast_notification_service'; import { refreshAnalyticsList$, REFRESH_ANALYTICS_LIST_STATE } from '../../../../common'; @@ -18,13 +17,12 @@ export const deleteAnalytics = async ( d: DataFrameAnalyticsListRow, toastNotificationService: ToastNotificationService ) => { - const toastNotifications = getToastNotifications(); try { if (isDataFrameAnalyticsFailed(d.stats.state)) { await ml.dataFrameAnalytics.stopDataFrameAnalytics(d.config.id, true); } await ml.dataFrameAnalytics.deleteDataFrameAnalytics(d.config.id); - toastNotifications.addSuccess( + toastNotificationService.displaySuccessToast( i18n.translate('xpack.ml.dataframe.analyticsList.deleteAnalyticsSuccessMessage', { defaultMessage: 'Request to delete data frame analytics job {analyticsId} acknowledged.', values: { analyticsId: d.config.id }, @@ -48,7 +46,6 @@ export const deleteAnalyticsAndDestIndex = async ( deleteDestIndexPattern: boolean, toastNotificationService: ToastNotificationService ) => { - const toastNotifications = getToastNotifications(); const destinationIndex = Array.isArray(d.config.dest.index) ? d.config.dest.index[0] : d.config.dest.index; @@ -62,7 +59,7 @@ export const deleteAnalyticsAndDestIndex = async ( deleteDestIndexPattern ); if (status.analyticsJobDeleted?.success) { - toastNotifications.addSuccess( + toastNotificationService.displaySuccessToast( i18n.translate('xpack.ml.dataframe.analyticsList.deleteAnalyticsSuccessMessage', { defaultMessage: 'Request to delete data frame analytics job {analyticsId} acknowledged.', values: { analyticsId: d.config.id }, @@ -80,7 +77,7 @@ export const deleteAnalyticsAndDestIndex = async ( } if (status.destIndexDeleted?.success) { - toastNotifications.addSuccess( + toastNotificationService.displaySuccessToast( i18n.translate('xpack.ml.dataframe.analyticsList.deleteAnalyticsWithIndexSuccessMessage', { defaultMessage: 'Request to delete destination index {destinationIndex} acknowledged.', values: { destinationIndex }, @@ -89,7 +86,7 @@ export const deleteAnalyticsAndDestIndex = async ( } if (status.destIndexDeleted?.error) { const error = extractErrorMessage(status.destIndexDeleted.error); - toastNotifications.addDanger( + toastNotificationService.displayDangerToast( i18n.translate('xpack.ml.dataframe.analyticsList.deleteAnalyticsWithIndexErrorMessage', { defaultMessage: 'An error occurred deleting destination index {destinationIndex}: {error}', @@ -99,7 +96,7 @@ export const deleteAnalyticsAndDestIndex = async ( } if (status.destIndexPatternDeleted?.success) { - toastNotifications.addSuccess( + toastNotificationService.displaySuccessToast( i18n.translate( 'xpack.ml.dataframe.analyticsList.deleteAnalyticsWithIndexPatternSuccessMessage', { @@ -111,7 +108,7 @@ export const deleteAnalyticsAndDestIndex = async ( } if (status.destIndexPatternDeleted?.error) { const error = extractErrorMessage(status.destIndexPatternDeleted.error); - toastNotifications.addDanger( + toastNotificationService.displayDangerToast( i18n.translate( 'xpack.ml.dataframe.analyticsList.deleteAnalyticsWithIndexPatternErrorMessage', { @@ -133,8 +130,10 @@ export const deleteAnalyticsAndDestIndex = async ( refreshAnalyticsList$.next(REFRESH_ANALYTICS_LIST_STATE.REFRESH); }; -export const canDeleteIndex = async (indexName: string) => { - const toastNotifications = getToastNotifications(); +export const canDeleteIndex = async ( + indexName: string, + toastNotificationService: ToastNotificationService +) => { try { const privilege = await ml.hasPrivileges({ index: [ @@ -150,7 +149,7 @@ export const canDeleteIndex = async (indexName: string) => { return privilege.securityDisabled === true || privilege.has_all_requested === true; } catch (e) { const error = extractErrorMessage(e); - toastNotifications.addDanger( + toastNotificationService.displayDangerToast( i18n.translate('xpack.ml.dataframe.analyticsList.deleteAnalyticsPrivilegeErrorMessage', { defaultMessage: 'User does not have permission to delete index {indexName}: {error}', values: { indexName, error }, diff --git a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_charts_container.js b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_charts_container.js index 9988298c25c51..4fb783bfb6006 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_charts_container.js +++ b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_charts_container.js @@ -104,7 +104,7 @@ function ExplorerChartContainer({ series, severity, tooManyBuckets, wrapLabel }) window.open(getExploreSeriesLink(series), '_blank')} > diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_actions/results.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_actions/results.js index 781b9126b7cbe..74072aa7e9638 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_actions/results.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_actions/results.js @@ -51,7 +51,7 @@ export function ResultLinks({ jobs }) { this.openSingleMetricView(forecast)} isDisabled={forecast.forecast_status !== FORECAST_REQUEST_STATE.FINISHED} - iconType="stats" + iconType="visLine" aria-label={viewForecastAriaLabel} /> ); diff --git a/x-pack/plugins/ml/public/application/overview/components/analytics_panel/actions.tsx b/x-pack/plugins/ml/public/application/overview/components/analytics_panel/actions.tsx new file mode 100644 index 0000000000000..081101e241990 --- /dev/null +++ b/x-pack/plugins/ml/public/application/overview/components/analytics_panel/actions.tsx @@ -0,0 +1,54 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useCallback, FC } from 'react'; +import { EuiToolTip, EuiButtonEmpty } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +import { useNavigateToPath } from '../../../contexts/kibana'; +import { getAnalysisType } from '../../../data_frame_analytics/common/analytics'; +import { + getResultsUrl, + DataFrameAnalyticsListRow, +} from '../../../data_frame_analytics/pages/analytics_management/components/analytics_list/common'; + +interface Props { + item: DataFrameAnalyticsListRow; +} + +export const ViewLink: FC = ({ item }) => { + const navigateToPath = useNavigateToPath(); + + const clickHandler = useCallback(() => { + const analysisType = getAnalysisType(item.config.analysis); + navigateToPath(getResultsUrl(item.id, analysisType)); + }, []); + + const openJobsInAnomalyExplorerText = i18n.translate( + 'xpack.ml.overview.analytics.resultActions.openJobText', + { + defaultMessage: 'View job results', + } + ); + + return ( + + + {i18n.translate('xpack.ml.overview.analytics.viewActionName', { + defaultMessage: 'View', + })} + + + ); +}; diff --git a/x-pack/plugins/ml/public/application/overview/components/analytics_panel/table.tsx b/x-pack/plugins/ml/public/application/overview/components/analytics_panel/table.tsx index b28729dcf157f..fc0645a0e9498 100644 --- a/x-pack/plugins/ml/public/application/overview/components/analytics_panel/table.tsx +++ b/x-pack/plugins/ml/public/application/overview/components/analytics_panel/table.tsx @@ -23,9 +23,10 @@ import { getTaskStateBadge, progressColumn, } from '../../../data_frame_analytics/pages/analytics_management/components/analytics_list/use_columns'; -import { getViewAction } from '../../../data_frame_analytics/pages/analytics_management/components/action_view'; import { formatHumanReadableDateTimeSeconds } from '../../../util/date_utils'; +import { ViewLink } from './actions'; + type DataFrameAnalyticsTableColumns = [ EuiTableFieldDataColumnType, EuiTableComputedColumnType, @@ -89,7 +90,11 @@ export const AnalyticsTable: FC = ({ items }) => { name: i18n.translate('xpack.ml.overview.analyticsList.tableActionLabel', { defaultMessage: 'Actions', }), - actions: [getViewAction()], + actions: [ + { + render: (item: DataFrameAnalyticsListRow) => , + }, + ], width: '100px', }, ]; diff --git a/x-pack/plugins/ml/public/application/overview/components/anomaly_detection_panel/actions.tsx b/x-pack/plugins/ml/public/application/overview/components/anomaly_detection_panel/actions.tsx index 3a64c623dd129..07a555c13dbf5 100644 --- a/x-pack/plugins/ml/public/application/overview/components/anomaly_detection_panel/actions.tsx +++ b/x-pack/plugins/ml/public/application/overview/components/anomaly_detection_panel/actions.tsx @@ -30,13 +30,13 @@ export const ExplorerLink: FC = ({ jobsList }) => { color="text" size="xs" href={getLink('explorer', jobsList)} - iconType="tableOfContents" + iconType="visTable" aria-label={openJobsInAnomalyExplorerText} className="results-button" data-test-subj={`openOverviewJobsInAnomalyExplorer`} > - {i18n.translate('xpack.ml.overview.anomalyDetection.exploreActionName', { - defaultMessage: 'Explore', + {i18n.translate('xpack.ml.overview.anomalyDetection.viewActionName', { + defaultMessage: 'View', })} diff --git a/x-pack/plugins/ml/public/application/services/toast_notification_service.ts b/x-pack/plugins/ml/public/application/services/toast_notification_service.ts index d93d6833c7cb4..94381ae3f1e51 100644 --- a/x-pack/plugins/ml/public/application/services/toast_notification_service.ts +++ b/x-pack/plugins/ml/public/application/services/toast_notification_service.ts @@ -20,6 +20,10 @@ export type ToastNotificationService = ReturnType viewForecast(forecast.forecast_id)} - iconType="stats" + iconType="visLine" aria-label={viewForecastAriaLabel} /> ); diff --git a/x-pack/plugins/ml/public/ui_actions/open_in_anomaly_explorer_action.tsx b/x-pack/plugins/ml/public/ui_actions/open_in_anomaly_explorer_action.tsx index e18f593145f9c..e327befcf7293 100644 --- a/x-pack/plugins/ml/public/ui_actions/open_in_anomaly_explorer_action.tsx +++ b/x-pack/plugins/ml/public/ui_actions/open_in_anomaly_explorer_action.tsx @@ -17,7 +17,7 @@ export function createOpenInExplorerAction(getStartServices: MlCoreSetup['getSta id: 'open-in-anomaly-explorer', type: OPEN_IN_ANOMALY_EXPLORER_ACTION, getIconType(context: ActionContextMapping[typeof OPEN_IN_ANOMALY_EXPLORER_ACTION]): string { - return 'tableOfContents'; + return 'visTable'; }, getDisplayName() { return i18n.translate('xpack.ml.actions.openInAnomalyExplorerTitle', { diff --git a/x-pack/plugins/transform/public/app/common/index.ts b/x-pack/plugins/transform/public/app/common/index.ts index 009c8c7a2a9f5..45ddc440057b2 100644 --- a/x-pack/plugins/transform/public/app/common/index.ts +++ b/x-pack/plugins/transform/public/app/common/index.ts @@ -31,7 +31,7 @@ export { IndexPattern, REFRESH_TRANSFORM_LIST_STATE, } from './transform'; -export { TRANSFORM_LIST_COLUMN, TransformListRow } from './transform_list'; +export { TRANSFORM_LIST_COLUMN, TransformListAction, TransformListRow } from './transform_list'; export { getTransformProgress, isCompletedBatchTransform, diff --git a/x-pack/plugins/transform/public/app/common/transform_list.ts b/x-pack/plugins/transform/public/app/common/transform_list.ts index a27fc0b3e0dbb..a2a762a7e2dfb 100644 --- a/x-pack/plugins/transform/public/app/common/transform_list.ts +++ b/x-pack/plugins/transform/public/app/common/transform_list.ts @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import { EuiTableActionsColumnType } from '@elastic/eui'; + import { TransformId } from '../../../common'; import { TransformPivotConfig } from './transform'; import { TransformStats } from './transform_stats'; @@ -20,3 +22,11 @@ export interface TransformListRow { mode?: string; // added property on client side to allow filtering by this field stats: TransformStats; } + +// The single Action type is not exported as is +// from EUI so we use that code to get the single +// Action type from the array of actions. +type ArrayElement = ArrayType[number]; +export type TransformListAction = ArrayElement< + EuiTableActionsColumnType['actions'] +>; 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 new file mode 100644 index 0000000000000..7ef634514de80 --- /dev/null +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_clone/clone_action_name.tsx @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC } from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiToolTip } from '@elastic/eui'; + +import { createCapabilityFailureMessage } from '../../../../lib/authorization'; + +export const cloneActionNameText = i18n.translate( + 'xpack.transform.transformList.cloneActionNameText', + { + defaultMessage: 'Clone', + } +); + +interface CloneActionNameProps { + disabled: boolean; +} + +export const CloneActionName: FC = ({ disabled }) => { + if (disabled) { + return ( + + <>{cloneActionNameText} + + ); + } + + return <>{cloneActionNameText}; +}; diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_clone/clone_button.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_clone/clone_button.tsx deleted file mode 100644 index 7b371d35f8d4c..0000000000000 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_clone/clone_button.tsx +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React, { FC, useContext } from 'react'; -import { useHistory } from 'react-router-dom'; -import { i18n } from '@kbn/i18n'; -import { EuiButtonEmpty, EuiToolTip } from '@elastic/eui'; - -import { - createCapabilityFailureMessage, - AuthorizationContext, -} from '../../../../lib/authorization'; - -import { SECTION_SLUG } from '../../../../constants'; - -interface CloneActionProps { - itemId: string; -} - -export const CloneButton: FC = ({ itemId }) => { - const history = useHistory(); - - const { canCreateTransform } = useContext(AuthorizationContext).capabilities; - - const buttonText = i18n.translate('xpack.transform.transformList.cloneActionName', { - defaultMessage: 'Clone', - }); - - function clickHandler() { - history.push(`/${SECTION_SLUG.CLONE_TRANSFORM}/${itemId}`); - } - - const buttonDisabled = !canCreateTransform; - - const button = ( - - {buttonText} - - ); - - if (buttonDisabled) { - return ( - - {button} - - ); - } - - return button; -}; diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_clone/index.ts b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_clone/index.ts index 727cc87c70f2c..fca9e156d1e9d 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_clone/index.ts +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_clone/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { CloneButton } from './clone_button'; +export { useCloneAction } from './use_clone_action'; 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 new file mode 100644 index 0000000000000..c2d772322ca06 --- /dev/null +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_clone/use_clone_action.tsx @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useCallback, useContext, useMemo } from 'react'; +import { useHistory } from 'react-router-dom'; + +import { AuthorizationContext } from '../../../../lib/authorization'; +import { TransformListAction, TransformListRow } from '../../../../common'; +import { SECTION_SLUG } from '../../../../constants'; + +import { cloneActionNameText, CloneActionName } from './clone_action_name'; + +export type CloneAction = ReturnType; +export const useCloneAction = (forceDisable: boolean) => { + const history = useHistory(); + + const { canCreateTransform } = useContext(AuthorizationContext).capabilities; + + const clickHandler = useCallback( + (item: TransformListRow) => { + history.push(`/${SECTION_SLUG.CLONE_TRANSFORM}/${item.id}`); + }, + [history] + ); + + const action: TransformListAction = useMemo( + () => ({ + name: (item: TransformListRow) => , + enabled: () => canCreateTransform && !forceDisable, + description: cloneActionNameText, + icon: 'copy', + type: 'icon', + onClick: clickHandler, + 'data-test-subj': 'transformActionClone', + }), + [canCreateTransform, forceDisable, clickHandler] + ); + + return { action }; +}; diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/__snapshots__/delete_action_name.test.tsx.snap b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/__snapshots__/delete_action_name.test.tsx.snap new file mode 100644 index 0000000000000..fe1e813ca9843 --- /dev/null +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/__snapshots__/delete_action_name.test.tsx.snap @@ -0,0 +1,7 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Transform: Transform List Actions Minimal initialization 1`] = ` + + Delete + +`; diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/__snapshots__/delete_button.test.tsx.snap b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/__snapshots__/delete_button.test.tsx.snap deleted file mode 100644 index 8d4568c5ce20e..0000000000000 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/__snapshots__/delete_button.test.tsx.snap +++ /dev/null @@ -1,22 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Transform: Transform List Actions Minimal initialization 1`] = ` - - - Delete - - -`; diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_button_modal.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_action_modal.tsx similarity index 99% rename from x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_button_modal.tsx rename to x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_action_modal.tsx index 668e535198649..3c06af1eecb59 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_button_modal.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_action_modal.tsx @@ -20,7 +20,7 @@ import { TRANSFORM_STATE } from '../../../../../../common'; import { DeleteAction } from './use_delete_action'; -export const DeleteButtonModal: FC = ({ +export const DeleteActionModal: FC = ({ closeModal, deleteAndCloseModal, deleteDestIndex, diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_button.test.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_action_name.test.tsx similarity index 53% rename from x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_button.test.tsx rename to x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_action_name.test.tsx index 63f8243b403d3..ecba7a0a24536 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_button.test.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_action_name.test.tsx @@ -5,26 +5,22 @@ */ import { shallow } from 'enzyme'; -import React, { ComponentProps } from 'react'; +import React from 'react'; -import { TransformListRow } from '../../../../common'; -import { DeleteButton } from './delete_button'; - -import transformListRow from '../../../../common/__mocks__/transform_list_row.json'; +import { DeleteActionName, DeleteActionNameProps } from './delete_action_name'; jest.mock('../../../../../shared_imports'); jest.mock('../../../../../app/app_dependencies'); describe('Transform: Transform List Actions ', () => { test('Minimal initialization', () => { - const item: TransformListRow = transformListRow; - const props: ComponentProps = { - forceDisable: false, - items: [item], - onClick: () => {}, + const props: DeleteActionNameProps = { + canDeleteTransform: true, + disabled: false, + isBulkAction: false, }; - const wrapper = shallow(); + const wrapper = shallow(); expect(wrapper).toMatchSnapshot(); }); }); diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_button.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_action_name.tsx similarity index 51% rename from x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_button.tsx rename to x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_action_name.tsx index dc6ddcfc45a11..d8ab72f15c59c 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_button.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_action_name.tsx @@ -4,34 +4,39 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { FC, useContext } from 'react'; +import React, { FC } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiButtonEmpty, EuiToolTip } from '@elastic/eui'; +import { EuiToolTip } from '@elastic/eui'; import { TRANSFORM_STATE } from '../../../../../../common'; -import { - AuthorizationContext, - createCapabilityFailureMessage, -} from '../../../../lib/authorization'; +import { createCapabilityFailureMessage } from '../../../../lib/authorization'; import { TransformListRow } from '../../../../common'; -interface DeleteButtonProps { - items: TransformListRow[]; - forceDisable?: boolean; - onClick: (items: TransformListRow[]) => void; -} - -const transformCanNotBeDeleted = (i: TransformListRow) => - ![TRANSFORM_STATE.STOPPED, TRANSFORM_STATE.FAILED].includes(i.stats.state); +export const deleteActionNameText = i18n.translate( + 'xpack.transform.transformList.deleteActionNameText', + { + defaultMessage: 'Delete', + } +); -export const DeleteButton: FC = ({ items, forceDisable, onClick }) => { - const isBulkAction = items.length > 1; +const transformCanNotBeDeleted = (item: TransformListRow) => + ![TRANSFORM_STATE.STOPPED, TRANSFORM_STATE.FAILED].includes(item.stats.state); +export const isDeleteActionDisabled = (items: TransformListRow[], forceDisable: boolean) => { const disabled = items.some(transformCanNotBeDeleted); - const { canDeleteTransform } = useContext(AuthorizationContext).capabilities; + return forceDisable === true || disabled; +}; - const buttonText = i18n.translate('xpack.transform.transformList.deleteActionName', { - defaultMessage: 'Delete', - }); +export interface DeleteActionNameProps { + canDeleteTransform: boolean; + disabled: boolean; + isBulkAction: boolean; +} + +export const DeleteActionName: FC = ({ + canDeleteTransform, + disabled, + isBulkAction, +}) => { const bulkDeleteButtonDisabledText = i18n.translate( 'xpack.transform.transformList.deleteBulkActionDisabledToolTipContent', { @@ -45,23 +50,6 @@ export const DeleteButton: FC = ({ items, forceDisable, onCli } ); - const buttonDisabled = forceDisable === true || disabled || !canDeleteTransform; - - const button = ( - onClick(items)} - size="xs" - > - {buttonText} - - ); - if (disabled || !canDeleteTransform) { let content; if (disabled) { @@ -72,10 +60,10 @@ export const DeleteButton: FC = ({ items, forceDisable, onCli return ( - {button} + <>{deleteActionNameText} ); } - return button; + return <>{deleteActionNameText}; }; diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/index.ts b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/index.ts index ef891d7c4a128..efc849e84add3 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/index.ts +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/index.ts @@ -4,6 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -export { DeleteButton } from './delete_button'; -export { DeleteButtonModal } from './delete_button_modal'; export { useDeleteAction } from './use_delete_action'; +export { DeleteActionModal } from './delete_action_modal'; +export { isDeleteActionDisabled, DeleteActionName } from './delete_action_name'; diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/use_delete_action.ts b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/use_delete_action.tsx similarity index 66% rename from x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/use_delete_action.ts rename to x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/use_delete_action.tsx index d76eebe954d7b..e573709fa6e63 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/use_delete_action.ts +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/use_delete_action.tsx @@ -4,15 +4,24 @@ * you may not use this file except in compliance with the Elastic License. */ -import { useMemo, useState } from 'react'; +import React, { useContext, useMemo, useState } from 'react'; import { TRANSFORM_STATE } from '../../../../../../common'; -import { TransformListRow } from '../../../../common'; +import { TransformListAction, TransformListRow } from '../../../../common'; import { useDeleteIndexAndTargetIndex, useDeleteTransforms } from '../../../../hooks'; +import { AuthorizationContext } from '../../../../lib/authorization'; + +import { + deleteActionNameText, + isDeleteActionDisabled, + DeleteActionName, +} from './delete_action_name'; export type DeleteAction = ReturnType; -export const useDeleteAction = () => { +export const useDeleteAction = (forceDisable: boolean) => { + const { canDeleteTransform } = useContext(AuthorizationContext).capabilities; + const deleteTransforms = useDeleteTransforms(); const [isModalVisible, setModalVisible] = useState(false); @@ -58,7 +67,30 @@ export const useDeleteAction = () => { } }; + const action: TransformListAction = useMemo( + () => ({ + name: (item: TransformListRow) => ( + + ), + enabled: (item: TransformListRow) => + !isDeleteActionDisabled([item], forceDisable) && canDeleteTransform, + description: deleteActionNameText, + icon: 'trash', + type: 'icon', + onClick: (item: TransformListRow) => openModal([item]), + 'data-test-subj': 'transformActionDelete', + }), + [canDeleteTransform, forceDisable] + ); + return { + action, closeModal, deleteAndCloseModal, deleteDestIndex, diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_edit/edit_button.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_edit/edit_action_name.tsx similarity index 52% rename from x-pack/plugins/transform/public/app/sections/transform_management/components/action_edit/edit_button.tsx rename to x-pack/plugins/transform/public/app/sections/transform_management/components/action_edit/edit_action_name.tsx index 7bae8807425fc..04c6ebe43c8c3 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_edit/edit_button.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_edit/edit_action_name.tsx @@ -8,47 +8,30 @@ import React, { useContext, FC } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiButtonEmpty, EuiToolTip } from '@elastic/eui'; +import { EuiToolTip } from '@elastic/eui'; import { createCapabilityFailureMessage, AuthorizationContext, } from '../../../../lib/authorization'; -interface EditButtonProps { - onClick: () => void; -} -export const EditButton: FC = ({ onClick }) => { - const { canCreateTransform } = useContext(AuthorizationContext).capabilities; - - const buttonText = i18n.translate('xpack.transform.transformList.editActionName', { +export const editActionNameText = i18n.translate( + 'xpack.transform.transformList.editActionNameText', + { defaultMessage: 'Edit', - }); - - const buttonDisabled = !canCreateTransform; - - const button = ( - - {buttonText} - - ); + } +); + +export const EditActionName: FC = () => { + const { canCreateTransform } = useContext(AuthorizationContext).capabilities; if (!canCreateTransform) { return ( - {button} + <>{editActionNameText} ); } - return button; + return <>{editActionNameText}; }; diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_edit/index.ts b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_edit/index.ts index 17a2ad9444f8d..a3077a8824045 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_edit/index.ts +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_edit/index.ts @@ -4,5 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { EditButton } from './edit_button'; export { useEditAction } from './use_edit_action'; diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_edit/use_edit_action.ts b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_edit/use_edit_action.ts deleted file mode 100644 index ace3ec8f636e6..0000000000000 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_edit/use_edit_action.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { useState } from 'react'; - -import { TransformPivotConfig } from '../../../../common'; - -export const useEditAction = () => { - const [config, setConfig] = useState(); - const [isFlyoutVisible, setIsFlyoutVisible] = useState(false); - const closeFlyout = () => setIsFlyoutVisible(false); - const showFlyout = (newConfig: TransformPivotConfig) => { - setConfig(newConfig); - setIsFlyoutVisible(true); - }; - - return { - config, - closeFlyout, - isFlyoutVisible, - showFlyout, - }; -}; 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 new file mode 100644 index 0000000000000..1fe20f1acae5a --- /dev/null +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_edit/use_edit_action.tsx @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useContext, useMemo, useState } from 'react'; + +import { TransformListAction, TransformListRow, TransformPivotConfig } from '../../../../common'; +import { AuthorizationContext } from '../../../../lib/authorization'; + +import { editActionNameText, EditActionName } from './edit_action_name'; + +export const useEditAction = (forceDisable: boolean) => { + const { canCreateTransform } = useContext(AuthorizationContext).capabilities; + + const [config, setConfig] = useState(); + const [isFlyoutVisible, setIsFlyoutVisible] = useState(false); + const closeFlyout = () => setIsFlyoutVisible(false); + const showFlyout = (newConfig: TransformPivotConfig) => { + setConfig(newConfig); + setIsFlyoutVisible(true); + }; + + const action: TransformListAction = useMemo( + () => ({ + name: () => , + enabled: () => canCreateTransform || !forceDisable, + description: editActionNameText, + icon: 'pencil', + type: 'icon', + onClick: (item: TransformListRow) => showFlyout(item.config), + 'data-test-subj': 'transformActionEdit', + }), + [canCreateTransform, forceDisable] + ); + + return { + action, + config, + closeFlyout, + isFlyoutVisible, + showFlyout, + }; +}; diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/__snapshots__/start_button.test.tsx.snap b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/__snapshots__/start_action_name.test.tsx.snap similarity index 56% rename from x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/__snapshots__/start_button.test.tsx.snap rename to x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/__snapshots__/start_action_name.test.tsx.snap index 543f8f9dfcffe..5a24e30a0657e 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/__snapshots__/start_button.test.tsx.snap +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/__snapshots__/start_action_name.test.tsx.snap @@ -6,17 +6,6 @@ exports[`Transform: Transform List Actions Minimal initializatio delay="regular" position="top" > - - Start - + Start `; diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/index.ts b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/index.ts index df6bbb7c61908..835df35c3c3bc 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/index.ts +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/index.ts @@ -4,6 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -export { StartButton } from './start_button'; -export { StartButtonModal } from './start_button_modal'; export { useStartAction } from './use_start_action'; +export { StartActionModal } from './start_action_modal'; +export { StartActionName } from './start_action_name'; diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_button_modal.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_action_modal.tsx similarity index 94% rename from x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_button_modal.tsx rename to x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_action_modal.tsx index 2ef0d20c45116..9f7dbee10cef0 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_button_modal.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_action_modal.tsx @@ -10,12 +10,7 @@ import { EuiConfirmModal, EuiOverlayMask, EUI_MODAL_CONFIRM_BUTTON } from '@elas import { StartAction } from './use_start_action'; -export const StartButtonModal: FC = ({ - closeModal, - isModalVisible, - items, - startAndCloseModal, -}) => { +export const StartActionModal: FC = ({ closeModal, items, startAndCloseModal }) => { const isBulkAction = items.length > 1; const bulkStartModalTitle = i18n.translate('xpack.transform.transformList.bulkStartModalTitle', { diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_button.test.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_action_name.test.tsx similarity index 77% rename from x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_button.test.tsx rename to x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_action_name.test.tsx index b88e1257f56ad..9c06675d69ca4 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_button.test.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_action_name.test.tsx @@ -5,10 +5,10 @@ */ import { shallow } from 'enzyme'; -import React, { ComponentProps } from 'react'; +import React from 'react'; import { TransformListRow } from '../../../../common'; -import { StartButton } from './start_button'; +import { StartActionName, StartActionNameProps } from './start_action_name'; import transformListRow from '../../../../common/__mocks__/transform_list_row.json'; @@ -18,13 +18,12 @@ jest.mock('../../../../../app/app_dependencies'); describe('Transform: Transform List Actions ', () => { test('Minimal initialization', () => { const item: TransformListRow = transformListRow; - const props: ComponentProps = { + const props: StartActionNameProps = { forceDisable: false, items: [item], - onClick: () => {}, }; - 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_button.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_action_name.tsx similarity index 73% rename from x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_button.tsx rename to x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_action_name.tsx index 7f5595043b775..191df0c16cba0 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_button.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_action_name.tsx @@ -6,7 +6,7 @@ import React, { FC, useContext } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiButtonEmpty, EuiToolTip } from '@elastic/eui'; +import { EuiToolTip } from '@elastic/eui'; import { TRANSFORM_STATE } from '../../../../../../common'; @@ -16,19 +16,37 @@ import { } from '../../../../lib/authorization'; import { TransformListRow, isCompletedBatchTransform } from '../../../../common'; -interface StartButtonProps { +export const startActionNameText = i18n.translate( + 'xpack.transform.transformList.startActionNameText', + { + defaultMessage: 'Start', + } +); + +export const isStartActionDisabled = ( + items: TransformListRow[], + canStartStopTransform: boolean +) => { + // Disable start for batch transforms which have completed. + const completedBatchTransform = items.some((i: TransformListRow) => isCompletedBatchTransform(i)); + // Disable start action if one of the transforms is already started or trying to restart will throw error + const startedTransform = items.some( + (i: TransformListRow) => i.stats.state === TRANSFORM_STATE.STARTED + ); + + return ( + !canStartStopTransform || completedBatchTransform || startedTransform || items.length === 0 + ); +}; + +export interface StartActionNameProps { items: TransformListRow[]; forceDisable?: boolean; - onClick: (items: TransformListRow[]) => void; } -export const StartButton: FC = ({ items, forceDisable, onClick }) => { +export const StartActionName: FC = ({ items, forceDisable }) => { const { canStartStopTransform } = useContext(AuthorizationContext).capabilities; const isBulkAction = items.length > 1; - const buttonText = i18n.translate('xpack.transform.transformList.startActionName', { - defaultMessage: 'Start', - }); - // Disable start for batch transforms which have completed. const completedBatchTransform = items.some((i: TransformListRow) => isCompletedBatchTransform(i)); // Disable start action if one of the transforms is already started or trying to restart will throw error @@ -70,8 +88,7 @@ export const StartButton: FC = ({ items, forceDisable, onClick ); } - const actionIsDisabled = - !canStartStopTransform || completedBatchTransform || startedTransform || items.length === 0; + const actionIsDisabled = isStartActionDisabled(items, canStartStopTransform); let content: string | undefined; if (actionIsDisabled && items.length > 0) { @@ -84,30 +101,13 @@ export const StartButton: FC = ({ items, forceDisable, onClick } } - const buttonDisabled = forceDisable === true || actionIsDisabled; - - const button = ( - onClick(items)} - size="xs" - > - {buttonText} - - ); - - if (buttonDisabled && content !== undefined) { + if ((forceDisable === true || actionIsDisabled) && content !== undefined) { return ( - {button} + <>{startActionNameText} ); } - return button; + return <>{startActionNameText}; }; diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/use_start_action.ts b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/use_start_action.ts deleted file mode 100644 index 32d2dc6dabf86..0000000000000 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/use_start_action.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { useState } from 'react'; - -import { TransformListRow } from '../../../../common'; -import { useStartTransforms } from '../../../../hooks'; - -export type StartAction = ReturnType; -export const useStartAction = () => { - const startTransforms = useStartTransforms(); - - const [isModalVisible, setModalVisible] = useState(false); - const [items, setItems] = useState([]); - - const closeModal = () => setModalVisible(false); - - const startAndCloseModal = () => { - setModalVisible(false); - startTransforms(items); - }; - - const openModal = (newItems: TransformListRow[]) => { - // EUI issue: Might trigger twice, one time as an array, - // one time as a single object. See https://github.com/elastic/eui/issues/3679 - if (Array.isArray(newItems)) { - setItems(newItems); - setModalVisible(true); - } - }; - - return { - closeModal, - isModalVisible, - items, - openModal, - startAndCloseModal, - }; -}; 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 new file mode 100644 index 0000000000000..8d6a4376c55b3 --- /dev/null +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/use_start_action.tsx @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useContext, useMemo, useState } from 'react'; + +import { TRANSFORM_STATE } from '../../../../../../common'; + +import { AuthorizationContext } from '../../../../lib/authorization'; +import { TransformListAction, TransformListRow } from '../../../../common'; +import { useStartTransforms } from '../../../../hooks'; + +import { isStartActionDisabled, startActionNameText, StartActionName } from './start_action_name'; + +export type StartAction = ReturnType; +export const useStartAction = (forceDisable: boolean) => { + const { canStartStopTransform } = useContext(AuthorizationContext).capabilities; + + const startTransforms = useStartTransforms(); + + const [isModalVisible, setModalVisible] = useState(false); + const [items, setItems] = useState([]); + + const closeModal = () => setModalVisible(false); + + const startAndCloseModal = () => { + setModalVisible(false); + startTransforms(items); + }; + + const openModal = (newItems: TransformListRow[]) => { + // EUI issue: Might trigger twice, one time as an array, + // one time as a single object. See https://github.com/elastic/eui/issues/3679 + if (Array.isArray(newItems)) { + setItems(newItems); + setModalVisible(true); + } + }; + + const action: TransformListAction = useMemo( + () => ({ + name: (item: TransformListRow) => ( + + ), + available: (item: TransformListRow) => item.stats.state === TRANSFORM_STATE.STOPPED, + enabled: (item: TransformListRow) => !isStartActionDisabled([item], canStartStopTransform), + description: startActionNameText, + icon: 'play', + type: 'icon', + onClick: (item: TransformListRow) => openModal([item]), + 'data-test-subj': 'transformActionStart', + }), + [canStartStopTransform, forceDisable] + ); + + return { + action, + closeModal, + isModalVisible, + items, + openModal, + startAndCloseModal, + }; +}; diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/__snapshots__/stop_button.test.tsx.snap b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/__snapshots__/stop_action_name.test.tsx.snap similarity index 56% rename from x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/__snapshots__/stop_button.test.tsx.snap rename to x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/__snapshots__/stop_action_name.test.tsx.snap index 646162d370ac6..e3740ae9a0978 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/__snapshots__/stop_button.test.tsx.snap +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/__snapshots__/stop_action_name.test.tsx.snap @@ -6,17 +6,6 @@ exports[`Transform: Transform List Actions Minimal initialization delay="regular" position="top" > - - Stop - + Stop `; diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/index.ts b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/index.ts index 858b6c70501b3..3b4da24298a96 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/index.ts +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/index.ts @@ -4,4 +4,5 @@ * you may not use this file except in compliance with the Elastic License. */ -export { StopButton } from './stop_button'; +export { useStopAction } from './use_stop_action'; +export { StopActionName } from './stop_action_name'; diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/stop_button.test.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/stop_action_name.test.tsx similarity index 79% rename from x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/stop_button.test.tsx rename to x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/stop_action_name.test.tsx index d9c07a9dccc8f..643e8c6126f0f 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/stop_button.test.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/stop_action_name.test.tsx @@ -5,10 +5,10 @@ */ import { shallow } from 'enzyme'; -import React, { ComponentProps } from 'react'; +import React from 'react'; import { TransformListRow } from '../../../../common'; -import { StopButton } from './stop_button'; +import { StopActionName, StopActionNameProps } from './stop_action_name'; import transformListRow from '../../../../common/__mocks__/transform_list_row.json'; @@ -18,12 +18,12 @@ jest.mock('../../../../../app/app_dependencies'); describe('Transform: Transform List Actions ', () => { test('Minimal initialization', () => { const item: TransformListRow = transformListRow; - const props: ComponentProps = { + const props: StopActionNameProps = { forceDisable: false, 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_button.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/stop_action_name.tsx similarity index 67% rename from x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/stop_button.tsx rename to x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/stop_action_name.tsx index 1c672193dd1ee..e1ea82cb371e8 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/stop_button.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/stop_action_name.tsx @@ -6,7 +6,7 @@ import React, { FC, useContext } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiButtonEmpty, EuiToolTip } from '@elastic/eui'; +import { EuiToolTip } from '@elastic/eui'; import { TRANSFORM_STATE } from '../../../../../../common'; @@ -15,19 +15,34 @@ import { createCapabilityFailureMessage, AuthorizationContext, } from '../../../../lib/authorization'; -import { useStopTransforms } from '../../../../hooks'; -interface StopButtonProps { +export const stopActionNameText = i18n.translate( + 'xpack.transform.transformList.stopActionNameText', + { + defaultMessage: 'Stop', + } +); + +export const isStopActionDisabled = ( + items: TransformListRow[], + canStartStopTransform: boolean, + forceDisable: boolean +) => { + // Disable stop action if one of the transforms is stopped already + const stoppedTransform = items.some( + (i: TransformListRow) => i.stats.state === TRANSFORM_STATE.STOPPED + ); + + return forceDisable === true || !canStartStopTransform || stoppedTransform === true; +}; + +export interface StopActionNameProps { items: TransformListRow[]; forceDisable?: boolean; } -export const StopButton: FC = ({ items, forceDisable }) => { +export const StopActionName: FC = ({ items, forceDisable }) => { const isBulkAction = items.length > 1; const { canStartStopTransform } = useContext(AuthorizationContext).capabilities; - const stopTransforms = useStopTransforms(); - const buttonText = i18n.translate('xpack.transform.transformList.stopActionName', { - defaultMessage: 'Stop', - }); // Disable stop action if one of the transforms is stopped already const stoppedTransform = items.some( @@ -52,28 +67,6 @@ export const StopButton: FC = ({ items, forceDisable }) => { ); } - const handleStop = () => { - stopTransforms(items); - }; - - const buttonDisabled = - forceDisable === true || !canStartStopTransform || stoppedTransform === true; - - const button = ( - - {buttonText} - - ); - if (!canStartStopTransform || stoppedTransform) { return ( = ({ items, forceDisable }) => { : stoppedTransformMessage } > - {button} + <>{stopActionNameText} ); } - return button; + return <>{stopActionNameText}; }; 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 new file mode 100644 index 0000000000000..e0a7e0b489ab6 --- /dev/null +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/use_stop_action.tsx @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useCallback, useContext, useMemo } from 'react'; + +import { TRANSFORM_STATE } from '../../../../../../common'; + +import { AuthorizationContext } from '../../../../lib/authorization'; +import { TransformListAction, TransformListRow } from '../../../../common'; +import { useStopTransforms } from '../../../../hooks'; + +import { isStopActionDisabled, stopActionNameText, StopActionName } from './stop_action_name'; + +export type StopAction = ReturnType; +export const useStopAction = (forceDisable: boolean) => { + const { canStartStopTransform } = useContext(AuthorizationContext).capabilities; + + const stopTransforms = useStopTransforms(); + + const clickHandler = useCallback((item: TransformListRow) => stopTransforms([item]), [ + stopTransforms, + ]); + + const action: TransformListAction = useMemo( + () => ({ + name: (item: TransformListRow) => ( + + ), + available: (item: TransformListRow) => item.stats.state !== TRANSFORM_STATE.STOPPED, + enabled: (item: TransformListRow) => + !isStopActionDisabled([item], canStartStopTransform, forceDisable), + description: stopActionNameText, + icon: 'stop', + type: 'icon', + onClick: clickHandler, + 'data-test-subj': 'transformActionStop', + }), + [canStartStopTransform, forceDisable, clickHandler] + ); + + return { action }; +}; 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 a31251943061a..cf32bf0455a1b 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 @@ -31,13 +31,19 @@ import { TRANSFORM_MODE, TRANSFORM_LIST_COLUMN, } from '../../../../common'; +import { useStopTransforms } from '../../../../hooks'; import { AuthorizationContext } from '../../../../lib/authorization'; import { CreateTransformButton } from '../create_transform_button'; import { RefreshTransformListButton } from '../refresh_transform_list_button'; -import { useDeleteAction, DeleteButton, DeleteButtonModal } from '../action_delete'; -import { useStartAction, StartButton, StartButtonModal } from '../action_start'; -import { StopButton } from '../action_stop'; +import { + isDeleteActionDisabled, + useDeleteAction, + DeleteActionName, + DeleteActionModal, +} from '../action_delete'; +import { useStartAction, StartActionName, StartActionModal } from '../action_start'; +import { StopActionName } from '../action_stop'; import { ItemIdToExpandedRowMap, Clause, TermClause, FieldClause, Value } from './common'; import { getTaskStateBadge, useColumns } from './use_columns'; @@ -89,8 +95,8 @@ export const TransformList: FC = ({ const [transformSelection, setTransformSelection] = useState([]); const [isActionsMenuOpen, setIsActionsMenuOpen] = useState(false); - const bulkStartAction = useStartAction(); - const bulkDeleteAction = useDeleteAction(); + const bulkStartAction = useStartAction(false); + const bulkDeleteAction = useDeleteAction(false); const [searchError, setSearchError] = useState(undefined); @@ -100,6 +106,8 @@ export const TransformList: FC = ({ const [sortField, setSortField] = useState(TRANSFORM_LIST_COLUMN.ID); const [sortDirection, setSortDirection] = useState('asc'); + const stopTransforms = useStopTransforms(); + const { capabilities } = useContext(AuthorizationContext); const disabled = !capabilities.canCreateTransform || @@ -257,13 +265,23 @@ export const TransformList: FC = ({ const bulkActionMenuItems = [
- + bulkStartAction.openModal(transformSelection)}> + +
,
- + stopTransforms(transformSelection)}> + +
,
- + bulkDeleteAction.openModal(transformSelection)}> + +
, ]; @@ -381,8 +399,8 @@ export const TransformList: FC = ({ return (
{/* Bulk Action Modals */} - {bulkStartAction.isModalVisible && } - {bulkDeleteAction.isModalVisible && } + {bulkStartAction.isModalVisible && } + {bulkDeleteAction.isModalVisible && } {/* Single Action Modals */} {singleActionModals} diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_actions.test.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_actions.test.tsx index e58d5ed572667..dafde8dd58123 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_actions.test.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_actions.test.tsx @@ -14,12 +14,17 @@ jest.mock('../../../../../app/app_dependencies'); describe('Transform: Transform List Actions', () => { test('useActions()', () => { const { result } = renderHook(() => useActions({ forceDisable: false })); - const actions: ReturnType['actions'] = result.current.actions; + const actions = result.current.actions; - expect(actions).toHaveLength(4); - expect(typeof actions[0].render).toBe('function'); - expect(typeof actions[1].render).toBe('function'); - expect(typeof actions[2].render).toBe('function'); - expect(typeof actions[3].render).toBe('function'); + // Using `any` for the callback. Somehow the EUI types don't pass + // on the `data-test-subj` attribute correctly. We're interested + // in the runtime result here anyway. + expect(actions.map((a: any) => a['data-test-subj'])).toStrictEqual([ + 'transformActionStart', + 'transformActionStop', + 'transformActionEdit', + 'transformActionClone', + 'transformActionDelete', + ]); }); }); diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_actions.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_actions.tsx index a6b1aa1a1b5c5..616e03a61e0ed 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_actions.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_actions.tsx @@ -6,74 +6,47 @@ import React from 'react'; -import { EuiTableComputedColumnType } from '@elastic/eui'; - -import { TRANSFORM_STATE } from '../../../../../../common'; +import { EuiTableActionsColumnType } from '@elastic/eui'; import { TransformListRow } from '../../../../common'; -import { CloneButton } from '../action_clone'; -import { useDeleteAction, DeleteButton, DeleteButtonModal } from '../action_delete'; +import { useCloneAction } from '../action_clone'; +import { useDeleteAction, DeleteActionModal } from '../action_delete'; import { EditTransformFlyout } from '../edit_transform_flyout'; -import { useEditAction, EditButton } from '../action_edit'; -import { useStartAction, StartButton, StartButtonModal } from '../action_start'; -import { StopButton } from '../action_stop'; +import { useEditAction } from '../action_edit'; +import { useStartAction, StartActionModal } from '../action_start'; +import { useStopAction } from '../action_stop'; export const useActions = ({ forceDisable, }: { forceDisable: boolean; -}): { actions: Array>; modals: JSX.Element } => { - const deleteAction = useDeleteAction(); - const editAction = useEditAction(); - const startAction = useStartAction(); +}): { + actions: EuiTableActionsColumnType['actions']; + modals: JSX.Element; +} => { + const cloneAction = useCloneAction(forceDisable); + const deleteAction = useDeleteAction(forceDisable); + const editAction = useEditAction(forceDisable); + const startAction = useStartAction(forceDisable); + const stopAction = useStopAction(forceDisable); return { modals: ( <> - {startAction.isModalVisible && } + {startAction.isModalVisible && } {editAction.config && editAction.isFlyoutVisible && ( )} - {deleteAction.isModalVisible && } + {deleteAction.isModalVisible && } ), actions: [ - { - render: (item: TransformListRow) => { - if (item.stats.state === TRANSFORM_STATE.STOPPED) { - return ( - - ); - } - return ; - }, - }, - { - render: (item: TransformListRow) => { - return editAction.showFlyout(item.config)} />; - }, - }, - { - render: (item: TransformListRow) => { - return ; - }, - }, - { - render: (item: TransformListRow) => { - return ( - - ); - }, - }, + startAction.action, + stopAction.action, + editAction.action, + cloneAction.action, + deleteAction.action, ], }; }; diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 814c532657f60..6a9909c4291ff 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -11187,11 +11187,9 @@ "xpack.ml.dataframe.analytics.regressionExploration.trainingErrorTitle": "トレーニングエラー", "xpack.ml.dataframe.analytics.regressionExploration.trainingFilterText": ".テストデータをフィルタリングしています。", "xpack.ml.dataframe.analyticsList.analyticsDetails.tabs.analyticsMessagesLabel": "ジョブメッセージ", - "xpack.ml.dataframe.analyticsList.cloneJobButtonLabel": "ジョブのクローンを作成します", "xpack.ml.dataframe.analyticsList.completeBatchAnalyticsToolTip": "{analyticsId}は完了済みの分析ジョブで、再度開始できません。", "xpack.ml.dataframe.analyticsList.createDataFrameAnalyticsButton": "ジョブを作成", "xpack.ml.dataframe.analyticsList.deleteActionDisabledToolTipContent": "削除するにはデータフレーム分析ジョブを停止してください。", - "xpack.ml.dataframe.analyticsList.deleteActionName": "削除", "xpack.ml.dataframe.analyticsList.deleteAnalyticsErrorMessage": "データフレーム分析ジョブ{analyticsId}の削除中にエラーが発生しました。", "xpack.ml.dataframe.analyticsList.deleteAnalyticsPrivilegeErrorMessage": "ユーザーはインデックス{indexName}を削除する権限がありません。{error}", "xpack.ml.dataframe.analyticsList.deleteAnalyticsSuccessMessage": "データフレーム分析ジョブ{analyticsId}の削除リクエストが受け付けられました。", @@ -11206,7 +11204,6 @@ "xpack.ml.dataframe.analyticsList.deleteModalTitle": "{analyticsId}の削除", "xpack.ml.dataframe.analyticsList.description": "説明", "xpack.ml.dataframe.analyticsList.destinationIndex": "デスティネーションインデックス", - "xpack.ml.dataframe.analyticsList.editActionName": "編集", "xpack.ml.dataframe.analyticsList.editActionPermissionTooltip": "分析ジョブを編集する権限がありません。", "xpack.ml.dataframe.analyticsList.editFlyout.allowLazyStartAriaLabel": "lazy startの許可を更新します。", "xpack.ml.dataframe.analyticsList.editFlyout.allowLazyStartFalseValue": "False", @@ -11246,7 +11243,6 @@ "xpack.ml.dataframe.analyticsList.rowExpand": "{analyticsId}の詳細を表示", "xpack.ml.dataframe.analyticsList.showDetailsColumn.screenReaderDescription": "このカラムには各ジョブの詳細を示すクリック可能なコントロールが含まれます", "xpack.ml.dataframe.analyticsList.sourceIndex": "ソースインデックス", - "xpack.ml.dataframe.analyticsList.startActionName": "開始", "xpack.ml.dataframe.analyticsList.startAnalyticsErrorTitle": "ジョブの開始エラー", "xpack.ml.dataframe.analyticsList.startAnalyticsSuccessMessage": "データフレーム分析 {analyticsId} の開始リクエストが受け付けられました。", "xpack.ml.dataframe.analyticsList.startModalBody": "データフレーム分析ジョブは、クラスターの検索とインデックスによる負荷を増やします。過剰な負荷が生じた場合は分析ジョブを停止してください。この分析ジョブを開始してよろしいですか?", @@ -11255,7 +11251,6 @@ "xpack.ml.dataframe.analyticsList.startModalTitle": "{analyticsId}の開始", "xpack.ml.dataframe.analyticsList.status": "ステータス", "xpack.ml.dataframe.analyticsList.statusFilter": "ステータス", - "xpack.ml.dataframe.analyticsList.stopActionName": "停止", "xpack.ml.dataframe.analyticsList.stopAnalyticsErrorMessage": "データフレーム分析{analyticsId}の停止中にエラーが発生しました。{error}", "xpack.ml.dataframe.analyticsList.stopAnalyticsSuccessMessage": "データフレーム分析 {analyticsId} の停止リクエストが受け付けられました。", "xpack.ml.dataframe.analyticsList.tableActionLabel": "アクション", @@ -12305,7 +12300,6 @@ "xpack.ml.overview.anomalyDetection.emptyPromptText": "異常検知により、時系列データの異常な動作を検出できます。データに隠れた異常を自動的に検出して問題をより素早く解決しましょう。", "xpack.ml.overview.anomalyDetection.errorPromptTitle": "異常検出ジョブリストの取得中にエラーが発生しました。", "xpack.ml.overview.anomalyDetection.errorWithFetchingAnomalyScoreNotificationErrorMessage": "異常スコアの取得中にエラーが発生しました: {error}", - "xpack.ml.overview.anomalyDetection.exploreActionName": "探索", "xpack.ml.overview.anomalyDetection.manageJobsButtonText": "ジョブの管理", "xpack.ml.overview.anomalyDetection.panelTitle": "異常検知", "xpack.ml.overview.anomalyDetection.refreshJobsButtonText": "更新", @@ -18244,12 +18238,10 @@ "xpack.transform.transformList.bulkDeleteTransformSuccessMessage": "{count} {count, plural, one {個の変換} other {個の変換}}を正常に削除しました。", "xpack.transform.transformList.bulkForceDeleteModalBody": "{count, plural, one {この} other {これらの}} {count} {count, plural, one {変換} other {変換}}を強制的に削除しますか?{count, plural, one {} other {}}現在の状態に関係なく、{count, plural, one {個の変換} other {個の変換}}は削除されます。", "xpack.transform.transformList.bulkStartModalTitle": "{count} 件の{count, plural, one {変換} other {変換}}を開始", - "xpack.transform.transformList.cloneActionName": "クローンを作成", "xpack.transform.transformList.completeBatchTransformBulkActionToolTip": "1 つまたは複数の変換が完了済みの一斉変換で、再度開始できません。", "xpack.transform.transformList.completeBatchTransformToolTip": "{transformId} は完了済みの一斉変換で、再度開始できません。", "xpack.transform.transformList.createTransformButton": "変換の作成", "xpack.transform.transformList.deleteActionDisabledToolTipContent": "削除するにはデータフレームジョブを停止してください。", - "xpack.transform.transformList.deleteActionName": "削除", "xpack.transform.transformList.deleteBulkActionDisabledToolTipContent": "削除するには、選択された変換のうちの 1 つまたは複数を停止する必要があります。", "xpack.transform.transformList.deleteModalBody": "この変換を削除してよろしいですか?", "xpack.transform.transformList.deleteModalCancelButton": "キャンセル", @@ -18258,7 +18250,6 @@ "xpack.transform.transformList.deleteTransformErrorMessage": "変換 {transformId} の削除中にエラーが発生しました", "xpack.transform.transformList.deleteTransformGenericErrorMessage": "変換を削除するための API エンドポイントの呼び出し中にエラーが発生しました。", "xpack.transform.transformList.deleteTransformSuccessMessage": "変換 {transformId} の削除リクエストが受け付けられました。", - "xpack.transform.transformList.editActionName": "編集", "xpack.transform.transformList.editFlyoutCalloutDocs": "ドキュメントを表示", "xpack.transform.transformList.editFlyoutCalloutText": "このフォームでは、変換を更新できます。更新できるプロパティのリストは、変換を作成するときに定義できるリストのサブセットです。", "xpack.transform.transformList.editFlyoutCancelButtonText": "キャンセル", @@ -18280,7 +18271,6 @@ "xpack.transform.transformList.rowCollapse": "{transformId} の詳細を非表示", "xpack.transform.transformList.rowExpand": "{transformId} の詳細を表示", "xpack.transform.transformList.showDetailsColumn.screenReaderDescription": "このカラムには変換ごとの詳細を示すクリック可能なコントロールが含まれます", - "xpack.transform.transformList.startActionName": "開始", "xpack.transform.transformList.startedTransformBulkToolTip": "1 つまたは複数の変換が既に開始済みです。", "xpack.transform.transformList.startedTransformToolTip": "{transformId} は既に開始済みです。", "xpack.transform.transformList.startModalBody": "変換は、クラスターの検索とインデックスによる負荷を増やします。過剰な負荷が生じた場合は変換を停止してください。{count, plural, one {この} other {これら}} {count} 件の{count, plural, one {変換} other {変換}}を開始してよろしいですか?", @@ -18289,7 +18279,6 @@ "xpack.transform.transformList.startModalTitle": "{transformId} を開始", "xpack.transform.transformList.startTransformErrorMessage": "変換 {transformId} の開始中にエラーが発生しました", "xpack.transform.transformList.startTransformSuccessMessage": "変換 {transformId} の開始リクエストが受け付けられました。", - "xpack.transform.transformList.stopActionName": "停止", "xpack.transform.transformList.stoppedTransformBulkToolTip": "1 つまたは複数の変換が既に開始済みです。", "xpack.transform.transformList.stoppedTransformToolTip": "{transformId} は既に停止済みです。", "xpack.transform.transformList.stopTransformErrorMessage": "データフレーム変換 {transformId} の停止中にエラーが発生しました", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 667706c886bc8..a2565d8af3ec9 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -11190,11 +11190,9 @@ "xpack.ml.dataframe.analytics.regressionExploration.trainingErrorTitle": "训练误差", "xpack.ml.dataframe.analytics.regressionExploration.trainingFilterText": ".筛留测试数据。", "xpack.ml.dataframe.analyticsList.analyticsDetails.tabs.analyticsMessagesLabel": "作业消息", - "xpack.ml.dataframe.analyticsList.cloneJobButtonLabel": "克隆作业", "xpack.ml.dataframe.analyticsList.completeBatchAnalyticsToolTip": "{analyticsId} 为已完成的分析作业,无法重新启动。", "xpack.ml.dataframe.analyticsList.createDataFrameAnalyticsButton": "创建作业", "xpack.ml.dataframe.analyticsList.deleteActionDisabledToolTipContent": "停止数据帧分析作业,以便将其删除。", - "xpack.ml.dataframe.analyticsList.deleteActionName": "删除", "xpack.ml.dataframe.analyticsList.deleteAnalyticsErrorMessage": "删除数据帧分析作业 {analyticsId} 时发生错误", "xpack.ml.dataframe.analyticsList.deleteAnalyticsPrivilegeErrorMessage": "用户无权删除索引 {indexName}:{error}", "xpack.ml.dataframe.analyticsList.deleteAnalyticsSuccessMessage": "删除的数据帧分析作业 {analyticsId} 的请求已确认。", @@ -11210,7 +11208,6 @@ "xpack.ml.dataframe.analyticsList.deleteTargetIndexPatternTitle": "删除索引模式 {indexPattern}", "xpack.ml.dataframe.analyticsList.description": "描述", "xpack.ml.dataframe.analyticsList.destinationIndex": "目标 IP", - "xpack.ml.dataframe.analyticsList.editActionName": "编辑", "xpack.ml.dataframe.analyticsList.editActionPermissionTooltip": "您无权编辑分析作业。", "xpack.ml.dataframe.analyticsList.editFlyout.allowLazyStartAriaLabel": "更新允许惰性启动。", "xpack.ml.dataframe.analyticsList.editFlyout.allowLazyStartFalseValue": "False", @@ -11250,7 +11247,6 @@ "xpack.ml.dataframe.analyticsList.rowExpand": "显示 {analyticsId} 的详情", "xpack.ml.dataframe.analyticsList.showDetailsColumn.screenReaderDescription": "此列包含可单击控件,用于显示每个作业的更多详情", "xpack.ml.dataframe.analyticsList.sourceIndex": "源索引", - "xpack.ml.dataframe.analyticsList.startActionName": "开始", "xpack.ml.dataframe.analyticsList.startAnalyticsErrorTitle": "启动作业时出错", "xpack.ml.dataframe.analyticsList.startAnalyticsSuccessMessage": "数据帧分析 {analyticsId} 启动请求已确认。", "xpack.ml.dataframe.analyticsList.startModalBody": "数据帧分析作业将增加集群的搜索和索引负荷。如果负荷超载,请停止分析作业。是否确定要启动此分析作业?", @@ -11259,7 +11255,6 @@ "xpack.ml.dataframe.analyticsList.startModalTitle": "启动 {analyticsId}", "xpack.ml.dataframe.analyticsList.status": "状态", "xpack.ml.dataframe.analyticsList.statusFilter": "状态", - "xpack.ml.dataframe.analyticsList.stopActionName": "停止", "xpack.ml.dataframe.analyticsList.stopAnalyticsErrorMessage": "停止数据帧分析 {analyticsId} 时发生错误:{error}", "xpack.ml.dataframe.analyticsList.stopAnalyticsSuccessMessage": "数据帧分析 {analyticsId} 停止请求已确认。", "xpack.ml.dataframe.analyticsList.tableActionLabel": "操作", @@ -12309,7 +12304,6 @@ "xpack.ml.overview.anomalyDetection.emptyPromptText": "通过异常检测,可发现时序数据中的异常行为。开始自动发现数据中隐藏的异常并更快捷地解决问题。", "xpack.ml.overview.anomalyDetection.errorPromptTitle": "获取异常检测作业列表时出错。", "xpack.ml.overview.anomalyDetection.errorWithFetchingAnomalyScoreNotificationErrorMessage": "获取异常分数时出错:{error}", - "xpack.ml.overview.anomalyDetection.exploreActionName": "浏览", "xpack.ml.overview.anomalyDetection.manageJobsButtonText": "管理作业", "xpack.ml.overview.anomalyDetection.panelTitle": "异常检测", "xpack.ml.overview.anomalyDetection.refreshJobsButtonText": "刷新", @@ -18251,12 +18245,10 @@ "xpack.transform.transformList.bulkDeleteTransformSuccessMessage": "已成功删除 {count} 个{count, plural, one {转换} other {转换}}。", "xpack.transform.transformList.bulkForceDeleteModalBody": "确定要强制删除{count, plural, one {这} other {这}} {count} 个{count, plural, one {转换} other {转换}}?无论{count, plural, one {转换} other {转换}}的当前状态如何,都将删除{count, plural, one {} other {}}。", "xpack.transform.transformList.bulkStartModalTitle": "启动 {count} 个 {count, plural, one {转换} other {转换}}?", - "xpack.transform.transformList.cloneActionName": "克隆", "xpack.transform.transformList.completeBatchTransformBulkActionToolTip": "一个或多个转换为已完成批量转换,无法重新启动。", "xpack.transform.transformList.completeBatchTransformToolTip": "{transformId} 为已完成批量转换,无法重新启动。", "xpack.transform.transformList.createTransformButton": "创建转换", "xpack.transform.transformList.deleteActionDisabledToolTipContent": "停止数据帧作业,以便将其删除。", - "xpack.transform.transformList.deleteActionName": "删除", "xpack.transform.transformList.deleteBulkActionDisabledToolTipContent": "一个或多个选定数据帧转换必须停止,才能删除。", "xpack.transform.transformList.deleteModalBody": "是否确定要删除此转换?", "xpack.transform.transformList.deleteModalCancelButton": "取消", @@ -18265,7 +18257,6 @@ "xpack.transform.transformList.deleteTransformErrorMessage": "删除转换 {transformId} 时发生错误", "xpack.transform.transformList.deleteTransformGenericErrorMessage": "调用用于删除转换的 API 终端节点时发生错误。", "xpack.transform.transformList.deleteTransformSuccessMessage": "删除转换 {transformId} 的请求已确认。", - "xpack.transform.transformList.editActionName": "编辑", "xpack.transform.transformList.editFlyoutCalloutDocs": "查看文档", "xpack.transform.transformList.editFlyoutCalloutText": "此表单允许您更新转换。可以更新的属性列表是创建转换时可以定义的列表子集。", "xpack.transform.transformList.editFlyoutCancelButtonText": "取消", @@ -18287,7 +18278,6 @@ "xpack.transform.transformList.rowCollapse": "隐藏 {transformId} 的详情", "xpack.transform.transformList.rowExpand": "显示 {transformId} 的详情", "xpack.transform.transformList.showDetailsColumn.screenReaderDescription": "此列包含可单击控件,用于显示每个转换的更多详情", - "xpack.transform.transformList.startActionName": "开始", "xpack.transform.transformList.startedTransformBulkToolTip": "一个或多个选定数据帧转换已启动。", "xpack.transform.transformList.startedTransformToolTip": "{transformId} 已启动。", "xpack.transform.transformList.startModalBody": "转换将增加集群的搜索和索引负荷。如果负荷超载,请停止转换。是否确定要启动{count, plural, one {这} other {这}} {count} 个 {count, plural, one {转换} other {转换}}?", @@ -18296,7 +18286,6 @@ "xpack.transform.transformList.startModalTitle": "启动 {transformId}", "xpack.transform.transformList.startTransformErrorMessage": "启动转换 {transformId} 时发生错误", "xpack.transform.transformList.startTransformSuccessMessage": "启动转换 {transformId} 的请求已确认。", - "xpack.transform.transformList.stopActionName": "停止", "xpack.transform.transformList.stoppedTransformBulkToolTip": "一个或多个选定数据帧转换已停止。", "xpack.transform.transformList.stoppedTransformToolTip": "{transformId} 已停止。", "xpack.transform.transformList.stopTransformErrorMessage": "停止数据帧转换 {transformId} 时发生错误",