From 5f1cabec2c070753d3b46bcecb903f089761972a Mon Sep 17 00:00:00 2001 From: shahzad31 Date: Mon, 11 Dec 2023 11:49:30 +0100 Subject: [PATCH] clone slo --- .../embeddable/slo/overview/slo_overview.tsx | 2 +- .../public/hooks/slo/use_clone_slo.ts | 87 ++++--------------- .../slo_details/components/header_control.tsx | 18 +--- .../pages/slo_details/slo_details.test.tsx | 32 ++----- .../slo_edit/components/slo_edit_form.tsx | 24 ++--- .../public/pages/slo_edit/slo_edit.tsx | 6 +- .../components/card_view/slo_card_item.tsx | 19 ++-- .../components/card_view/slos_card_view.tsx | 44 +++++----- .../common/burn_rate_rule_flyout.tsx | 30 +++++-- .../compact_view/slo_list_compact_view.tsx | 15 +--- .../slos/components/slo_item_actions.tsx | 22 ++--- .../public/pages/slos/slos.test.tsx | 15 ++-- .../translations/translations/fr-FR.json | 2 - .../translations/translations/ja-JP.json | 2 - .../translations/translations/zh-CN.json | 2 - 15 files changed, 109 insertions(+), 211 deletions(-) diff --git a/x-pack/plugins/observability/public/embeddable/slo/overview/slo_overview.tsx b/x-pack/plugins/observability/public/embeddable/slo/overview/slo_overview.tsx index 0bd1b7048dcc0..cb0a6492ed310 100644 --- a/x-pack/plugins/observability/public/embeddable/slo/overview/slo_overview.tsx +++ b/x-pack/plugins/observability/public/embeddable/slo/overview/slo_overview.tsx @@ -112,7 +112,7 @@ export function SloOverview({ return (
- + ; export function useCloneSlo() { const { - http, - notifications: { toasts }, + http: { basePath }, + application: { navigateToUrl }, } = useKibana().services; - const queryClient = useQueryClient(); - return useMutation< - CreateSLOResponse, - ServerError, - { slo: CreateSLOInput; originalSloId?: string }, - { previousData?: FindSLOResponse; queryKey?: QueryKey } - >( - ['cloneSlo'], - ({ slo }: { slo: CreateSLOInput; originalSloId?: string }) => { - const body = JSON.stringify(slo); - return http.post(`/api/observability/slos`, { body }); + return useCallback( + (slo: SLOWithSummaryResponse) => { + navigateToUrl( + basePath.prepend( + paths.observability.sloCreateWithEncodedForm( + encode({ ...slo, name: `[Copy] ${slo.name}`, id: undefined }) + ) + ) + ); }, - { - onMutate: async ({ slo, originalSloId }) => { - await queryClient.cancelQueries({ queryKey: sloKeys.lists(), exact: false }); - - const queriesData = queryClient.getQueriesData({ - queryKey: sloKeys.lists(), - exact: false, - }); - const [queryKey, previousData] = queriesData?.at(0) ?? []; - - const originalSlo = previousData?.results?.find((el) => el.id === originalSloId); - const optimisticUpdate = { - page: previousData?.page ?? 1, - perPage: previousData?.perPage ?? 25, - total: previousData?.total ? previousData.total + 1 : 1, - results: [ - ...(previousData?.results ?? []), - { ...originalSlo, name: slo.name, id: uuidv4(), summary: undefined }, - ], - }; - - if (queryKey) { - queryClient.setQueryData(queryKey, optimisticUpdate); - } - - return { queryKey, previousData }; - }, - // If the mutation fails, use the context returned from onMutate to roll back - onError: (error, { slo }, context) => { - if (context?.previousData && context?.queryKey) { - queryClient.setQueryData(context.queryKey, context.previousData); - } - - toasts.addError(new Error(error.body?.message ?? error.message), { - title: i18n.translate('xpack.observability.slo.clone.errorNotification', { - defaultMessage: 'Failed to clone {name}', - values: { name: slo.name }, - }), - }); - }, - onSuccess: (_data, { slo }) => { - toasts.addSuccess( - i18n.translate('xpack.observability.slo.clone.successNotification', { - defaultMessage: 'Successfully created {name}', - values: { name: slo.name }, - }) - ); - queryClient.invalidateQueries({ queryKey: sloKeys.lists(), exact: false }); - }, - } + [navigateToUrl, basePath] ); } diff --git a/x-pack/plugins/observability/public/pages/slo_details/components/header_control.tsx b/x-pack/plugins/observability/public/pages/slo_details/components/header_control.tsx index 615edf3ef65f3..34eb1f278e7a3 100644 --- a/x-pack/plugins/observability/public/pages/slo_details/components/header_control.tsx +++ b/x-pack/plugins/observability/public/pages/slo_details/components/header_control.tsx @@ -10,20 +10,16 @@ import { i18n } from '@kbn/i18n'; import { EuiButton, EuiContextMenuItem, EuiContextMenuPanel, EuiPopover } from '@elastic/eui'; import { SLOWithSummaryResponse } from '@kbn/slo-schema'; +import { useCloneSlo } from '../../../hooks/slo/use_clone_slo'; import { SloDeleteConfirmationModal } from '../../../components/slo/delete_confirmation_modal/slo_delete_confirmation_modal'; import { useCapabilities } from '../../../hooks/slo/use_capabilities'; import { useKibana } from '../../../utils/kibana_react'; -import { useCloneSlo } from '../../../hooks/slo/use_clone_slo'; import { useDeleteSlo } from '../../../hooks/slo/use_delete_slo'; import { isApmIndicatorType } from '../../../utils/slo/indicator'; import { convertSliApmParamsToApmAppDeeplinkUrl } from '../../../utils/slo/convert_sli_apm_params_to_apm_app_deeplink_url'; import { SLO_BURN_RATE_RULE_TYPE_ID } from '../../../../common/constants'; import { rulesLocatorID, sloFeatureId } from '../../../../common'; import { paths } from '../../../../common/locators/paths'; -import { - transformSloResponseToCreateSloForm, - transformCreateSLOFormToCreateSLOInput, -} from '../../slo_edit/helpers/process_slo_form_values'; import type { RulesParams } from '../../../locators/rules'; export interface Props { @@ -47,7 +43,6 @@ export function HeaderControl({ isLoading, slo }: Props) { const [isRuleFlyoutVisible, setRuleFlyoutVisibility] = useState(false); const [isDeleteConfirmationModalOpen, setDeleteConfirmationModalOpen] = useState(false); - const { mutate: cloneSlo } = useCloneSlo(); const { mutate: deleteSlo } = useDeleteSlo(); const handleActionsClick = () => setIsPopoverOpen((value) => !value); @@ -101,17 +96,12 @@ export function HeaderControl({ isLoading, slo }: Props) { } }; + const navigateToClone = useCloneSlo(); + const handleClone = async () => { if (slo) { setIsPopoverOpen(false); - - const newSlo = transformCreateSLOFormToCreateSLOInput( - transformSloResponseToCreateSloForm({ ...slo, name: `[Copy] ${slo.name}` })! - ); - - cloneSlo({ slo: newSlo, originalSloId: slo.id }); - - navigate(basePath.prepend(paths.observability.slos)); + navigateToClone(slo); } }; diff --git a/x-pack/plugins/observability/public/pages/slo_details/slo_details.test.tsx b/x-pack/plugins/observability/public/pages/slo_details/slo_details.test.tsx index de21fb145677f..5a06bbd9bf2db 100644 --- a/x-pack/plugins/observability/public/pages/slo_details/slo_details.test.tsx +++ b/x-pack/plugins/observability/public/pages/slo_details/slo_details.test.tsx @@ -17,7 +17,6 @@ import { useFetchSloDetails } from '../../hooks/slo/use_fetch_slo_details'; import { useFetchHistoricalSummary } from '../../hooks/slo/use_fetch_historical_summary'; import { useFetchActiveAlerts } from '../../hooks/slo/use_fetch_active_alerts'; import { ActiveAlerts } from '../../hooks/slo/active_alerts'; -import { useCloneSlo } from '../../hooks/slo/use_clone_slo'; import { useDeleteSlo } from '../../hooks/slo/use_delete_slo'; import { render } from '../../utils/test_helper'; import { SloDetailsPage } from './slo_details'; @@ -30,6 +29,7 @@ import { import { chartPluginMock } from '@kbn/charts-plugin/public/mocks'; import { buildApmAvailabilityIndicator } from '../../data/slo/indicator'; import { ALL_VALUE } from '@kbn/slo-schema'; +import { encode } from '@kbn/rison'; jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), @@ -44,7 +44,6 @@ jest.mock('../../hooks/slo/use_capabilities'); jest.mock('../../hooks/slo/use_fetch_active_alerts'); jest.mock('../../hooks/slo/use_fetch_slo_details'); jest.mock('../../hooks/slo/use_fetch_historical_summary'); -jest.mock('../../hooks/slo/use_clone_slo'); jest.mock('../../hooks/slo/use_delete_slo'); const useKibanaMock = useKibana as jest.Mock; @@ -55,12 +54,10 @@ const useCapabilitiesMock = useCapabilities as jest.Mock; const useFetchActiveAlertsMock = useFetchActiveAlerts as jest.Mock; const useFetchSloDetailsMock = useFetchSloDetails as jest.Mock; const useFetchHistoricalSummaryMock = useFetchHistoricalSummary as jest.Mock; -const useCloneSloMock = useCloneSlo as jest.Mock; const useDeleteSloMock = useDeleteSlo as jest.Mock; const mockNavigate = jest.fn(); const mockLocator = jest.fn(); -const mockClone = jest.fn(); const mockDelete = jest.fn(); const mockCapabilities = { apm: { show: true }, @@ -120,7 +117,6 @@ describe('SLO Details Page', () => { data: historicalSummaryData, }); useFetchActiveAlertsMock.mockReturnValue({ isLoading: false, data: new ActiveAlerts() }); - useCloneSloMock.mockReturnValue({ mutate: mockClone }); useDeleteSloMock.mockReturnValue({ mutate: mockDelete }); useLocationMock.mockReturnValue({ search: '' }); }); @@ -248,28 +244,12 @@ describe('SLO Details Page', () => { fireEvent.click(button!); - const { - id, - createdAt, - enabled, - revision, - summary, - settings, - updatedAt, - instanceId, - ...newSlo - } = slo; - - expect(mockClone).toBeCalledWith({ - originalSloId: slo.id, - slo: { - ...newSlo, - name: `[Copy] ${newSlo.name}`, - }, - }); - await waitFor(() => { - expect(mockNavigate).toBeCalledWith(paths.observability.slos); + expect(mockNavigate).toBeCalledWith( + paths.observability.sloCreateWithEncodedForm( + encode({ ...slo, name: `[Copy] ${slo.name}`, id: undefined }) + ) + ); }); }); diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/slo_edit_form.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/slo_edit_form.tsx index 6627f910a7c27..e5f8e9b02ce2a 100644 --- a/x-pack/plugins/observability/public/pages/slo_edit/components/slo_edit_form.tsx +++ b/x-pack/plugins/observability/public/pages/slo_edit/components/slo_edit_form.tsx @@ -18,8 +18,7 @@ import { i18n } from '@kbn/i18n'; import type { GetSLOResponse } from '@kbn/slo-schema'; import React, { useCallback, useEffect, useState } from 'react'; import { FormProvider, useForm } from 'react-hook-form'; -import { sloFeatureId } from '../../../../common'; -import { SLO_BURN_RATE_RULE_TYPE_ID } from '../../../../common/constants'; +import { BurnRateRuleFlyout } from '../../slos/components/common/burn_rate_rule_flyout'; import { paths } from '../../../../common/locators/paths'; import { useCreateSlo } from '../../../hooks/slo/use_create_slo'; import { useFetchRulesForSlo } from '../../../hooks/slo/use_fetch_rules_for_slo'; @@ -54,7 +53,6 @@ export function SloEditForm({ slo }: Props) { const { application: { navigateToUrl }, http: { basePath }, - triggersActionsUi: { getAddRuleFlyout: AddRuleFlyout }, } = useKibana().services; const isEditMode = slo !== undefined; @@ -146,10 +144,6 @@ export function SloEditForm({ slo }: Props) { setIsCreateRuleCheckboxChecked(!isCreateRuleCheckboxChecked); }; - const handleCloseRuleFlyout = async () => { - navigateToUrl(basePath.prepend(paths.observability.slos)); - }; - return ( <> @@ -256,17 +250,11 @@ export function SloEditForm({ slo }: Props) { - {isAddRuleFlyoutOpen && slo ? ( - - ) : null} + ); } diff --git a/x-pack/plugins/observability/public/pages/slo_edit/slo_edit.tsx b/x-pack/plugins/observability/public/pages/slo_edit/slo_edit.tsx index 27fda5cfc61fa..485ee068fc6f7 100644 --- a/x-pack/plugins/observability/public/pages/slo_edit/slo_edit.tsx +++ b/x-pack/plugins/observability/public/pages/slo_edit/slo_edit.tsx @@ -33,7 +33,7 @@ export function SloEditPage() { const { sloId } = useParams<{ sloId: string | undefined }>(); const { hasAtLeast } = useLicense(); const hasRightLicense = hasAtLeast('platinum'); - const { data: slo, isInitialLoading } = useFetchSloDetails({ sloId }); + const { data: slo } = useFetchSloDetails({ sloId }); useBreadcrumbs([ { @@ -66,10 +66,6 @@ export function SloEditPage() { navigateToUrl(basePath.prepend(paths.observability.slos)); } - if (sloId && isInitialLoading) { - return null; - } - return ( { +const getSubTitle = (slo: SLOWithSummaryResponse) => { return slo.groupBy && slo.groupBy !== ALL_VALUE ? `${slo.groupBy}: ${slo.instanceId}` : ''; }; @@ -88,14 +89,14 @@ export function SloCardItem({ slo, rules, activeAlerts, historicalSummary, cards } }} paddingSize="none" - style={{ - height: '182px', - overflow: 'hidden', - position: 'relative', - }} + css={css` + height: 182px; + overflow: hidden; + position: relative; + `} title={slo.summary.status} > - + {(isMouseOver || isActionsPopoverOpen) && ( ; }) { const { @@ -147,7 +146,7 @@ export function SloCardChart({ } = useKibana().services; const cardColor = useSloCardColor(slo.summary.status); - const subTitle = getSubTitle(slo, cardsPerRow); + const subTitle = getSubTitle(slo); const { sliValue, sloTarget, sloDetailsUrl } = useSloFormattedSummary(slo); return ( diff --git a/x-pack/plugins/observability/public/pages/slos/components/card_view/slos_card_view.tsx b/x-pack/plugins/observability/public/pages/slos/components/card_view/slos_card_view.tsx index a8d43c35217d1..3e1a80f147f2e 100644 --- a/x-pack/plugins/observability/public/pages/slos/components/card_view/slos_card_view.tsx +++ b/x-pack/plugins/observability/public/pages/slos/components/card_view/slos_card_view.tsx @@ -68,27 +68,29 @@ export function SloListCardView({ } return ( - - {sloList.map((slo) => ( - - - historicalSummary.sloId === slo.id && - historicalSummary.instanceId === (slo.instanceId ?? ALL_VALUE) - )?.data - } - historicalSummaryLoading={historicalSummaryLoading} - cardsPerRow={Number(cardsPerRow)} - /> - - ))} + + {sloList + .filter((slo) => slo.summary) + .map((slo) => ( + + + historicalSummary.sloId === slo.id && + historicalSummary.instanceId === (slo.instanceId ?? ALL_VALUE) + )?.data + } + historicalSummaryLoading={historicalSummaryLoading} + cardsPerRow={Number(cardsPerRow)} + /> + + ))} ); } diff --git a/x-pack/plugins/observability/public/pages/slos/components/common/burn_rate_rule_flyout.tsx b/x-pack/plugins/observability/public/pages/slos/components/common/burn_rate_rule_flyout.tsx index a02730231ae5f..871c11d39bdde 100644 --- a/x-pack/plugins/observability/public/pages/slos/components/common/burn_rate_rule_flyout.tsx +++ b/x-pack/plugins/observability/public/pages/slos/components/common/burn_rate_rule_flyout.tsx @@ -8,6 +8,7 @@ import React from 'react'; import { SLOWithSummaryResponse } from '@kbn/slo-schema'; import { useQueryClient } from '@tanstack/react-query'; +import { paths } from '../../../../../common/locators/paths'; import { useGetFilteredRuleTypes } from '../../../../hooks/use_get_filtered_rule_types'; import { sloKeys } from '../../../../hooks/slo/query_key_factory'; import { useKibana } from '../../../../utils/kibana_react'; @@ -17,13 +18,17 @@ import { sloFeatureId } from '../../../../../common'; export function BurnRateRuleFlyout({ slo, isAddRuleFlyoutOpen, + canChangeTrigger, setIsAddRuleFlyoutOpen, }: { - slo: SLOWithSummaryResponse; + slo?: SLOWithSummaryResponse; isAddRuleFlyoutOpen: boolean; - setIsAddRuleFlyoutOpen: (value: boolean) => void; + canChangeTrigger?: boolean; + setIsAddRuleFlyoutOpen?: (value: boolean) => void; }) { const { + application: { navigateToUrl }, + http: { basePath }, triggersActionsUi: { getAddRuleFlyout: AddRuleFlyout }, } = useKibana().services; @@ -32,19 +37,30 @@ export function BurnRateRuleFlyout({ const queryClient = useQueryClient(); const handleSavedRule = async () => { - queryClient.invalidateQueries({ queryKey: sloKeys.rules(), exact: false }); + if (setIsAddRuleFlyoutOpen) { + queryClient.invalidateQueries({ queryKey: sloKeys.rules(), exact: false }); + } else { + navigateToUrl(basePath.prepend(paths.observability.slos)); + } }; - return isAddRuleFlyoutOpen ? ( + const handleCloseRuleFlyout = async () => { + if (setIsAddRuleFlyoutOpen) { + setIsAddRuleFlyoutOpen(false); + } else { + navigateToUrl(basePath.prepend(paths.observability.slos)); + } + }; + + return isAddRuleFlyoutOpen && slo ? ( { - setIsAddRuleFlyoutOpen(false); - }} + onClose={handleCloseRuleFlyout} useRuleProducer /> ) : null; diff --git a/x-pack/plugins/observability/public/pages/slos/components/compact_view/slo_list_compact_view.tsx b/x-pack/plugins/observability/public/pages/slos/components/compact_view/slo_list_compact_view.tsx index 6052007abc328..2337469358361 100644 --- a/x-pack/plugins/observability/public/pages/slos/components/compact_view/slo_list_compact_view.tsx +++ b/x-pack/plugins/observability/public/pages/slos/components/compact_view/slo_list_compact_view.tsx @@ -19,6 +19,7 @@ import { i18n } from '@kbn/i18n'; import { ALL_VALUE, SLOWithSummaryResponse } from '@kbn/slo-schema'; import { useQueryClient } from '@tanstack/react-query'; import React, { useState } from 'react'; +import { useCloneSlo } from '../../../../hooks/slo/use_clone_slo'; import { rulesLocatorID, sloFeatureId } from '../../../../../common'; import { SLO_BURN_RATE_RULE_TYPE_ID } from '../../../../../common/constants'; import { NOT_AVAILABLE_LABEL } from '../../../../../common/i18n'; @@ -28,7 +29,6 @@ import { SloStatusBadge } from '../../../../components/slo/slo_status_badge'; import { SloActiveAlertsBadge } from '../../../../components/slo/slo_status_badge/slo_active_alerts_badge'; import { sloKeys } from '../../../../hooks/slo/query_key_factory'; import { useCapabilities } from '../../../../hooks/slo/use_capabilities'; -import { useCloneSlo } from '../../../../hooks/slo/use_clone_slo'; import { useDeleteSlo } from '../../../../hooks/slo/use_delete_slo'; import { useFetchActiveAlerts } from '../../../../hooks/slo/use_fetch_active_alerts'; import { useFetchHistoricalSummary } from '../../../../hooks/slo/use_fetch_historical_summary'; @@ -37,10 +37,6 @@ import { useGetFilteredRuleTypes } from '../../../../hooks/use_get_filtered_rule import { RulesParams } from '../../../../locators/rules'; import { useKibana } from '../../../../utils/kibana_react'; import { formatHistoricalData } from '../../../../utils/slo/chart_data_formatter'; -import { - transformCreateSLOFormToCreateSLOInput, - transformSloResponseToCreateSloForm, -} from '../../../slo_edit/helpers/process_slo_form_values'; import { SloRulesBadge } from '../badges/slo_rules_badge'; import { SloListEmpty } from '../slo_list_empty'; import { SloListError } from '../slo_list_error'; @@ -72,7 +68,6 @@ export function SloListCompactView({ sloList, loading, error }: Props) { const filteredRuleTypes = useGetFilteredRuleTypes(); const queryClient = useQueryClient(); - const { mutate: cloneSlo } = useCloneSlo(); const { mutate: deleteSlo } = useDeleteSlo(); const [sloToAddRule, setSloToAddRule] = useState(undefined); @@ -102,6 +97,8 @@ export function SloListCompactView({ sloList, loading, error }: Props) { list: sloList.map((slo) => ({ sloId: slo.id, instanceId: slo.instanceId ?? ALL_VALUE })), }); + const navigateToClone = useCloneSlo(); + const actions: Array> = [ { type: 'icon', @@ -180,11 +177,7 @@ export function SloListCompactView({ sloList, loading, error }: Props) { 'data-test-subj': 'sloActionsClone', enabled: (_) => hasWriteCapabilities, onClick: (slo: SLOWithSummaryResponse) => { - const newSlo = transformCreateSLOFormToCreateSLOInput( - transformSloResponseToCreateSloForm({ ...slo, name: `[Copy] ${slo.name}` })! - ); - - cloneSlo({ slo: newSlo, originalSloId: slo.id }); + navigateToClone(slo); }, }, { diff --git a/x-pack/plugins/observability/public/pages/slos/components/slo_item_actions.tsx b/x-pack/plugins/observability/public/pages/slos/components/slo_item_actions.tsx index 4fb03968d40a0..51652abe13542 100644 --- a/x-pack/plugins/observability/public/pages/slos/components/slo_item_actions.tsx +++ b/x-pack/plugins/observability/public/pages/slos/components/slo_item_actions.tsx @@ -17,16 +17,12 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; import { ALL_VALUE, SLOWithSummaryResponse } from '@kbn/slo-schema'; import styled from 'styled-components'; -import { useCapabilities } from '../../../hooks/slo/use_capabilities'; import { useCloneSlo } from '../../../hooks/slo/use_clone_slo'; +import { useCapabilities } from '../../../hooks/slo/use_capabilities'; import { useKibana } from '../../../utils/kibana_react'; import { paths } from '../../../../common/locators/paths'; import { RulesParams } from '../../../locators/rules'; import { rulesLocatorID } from '../../../../common'; -import { - transformCreateSLOFormToCreateSLOInput, - transformSloResponseToCreateSloForm, -} from '../../slo_edit/helpers/process_slo_form_values'; interface Props { slo: SLOWithSummaryResponse; @@ -73,7 +69,6 @@ export function SloItemActions({ }, } = useKibana().services; const { hasWriteCapabilities } = useCapabilities(); - const { mutate: cloneSlo } = useCloneSlo(); const sloDetailsUrl = basePath.prepend( paths.observability.sloDetails( @@ -94,18 +89,15 @@ export function SloItemActions({ navigateToUrl(basePath.prepend(paths.observability.sloEdit(slo.id))); }; - const handleNavigateToRules = async () => { - const locator = locators.get(rulesLocatorID); - locator?.navigate({ params: { sloId: slo.id } }, { replace: false }); - }; + const navigateToClone = useCloneSlo(); const handleClone = () => { - const newSlo = transformCreateSLOFormToCreateSLOInput( - transformSloResponseToCreateSloForm({ ...slo, name: `[Copy] ${slo.name}` })! - ); + navigateToClone(slo); + }; - cloneSlo({ slo: newSlo, originalSloId: slo.id }); - setIsActionsPopoverOpen(false); + const handleNavigateToRules = async () => { + const locator = locators.get(rulesLocatorID); + locator?.navigate({ params: { sloId: slo.id } }, { replace: false }); }; const handleDelete = () => { diff --git a/x-pack/plugins/observability/public/pages/slos/slos.test.tsx b/x-pack/plugins/observability/public/pages/slos/slos.test.tsx index 40fd12d4b003e..1f28e822b96f9 100644 --- a/x-pack/plugins/observability/public/pages/slos/slos.test.tsx +++ b/x-pack/plugins/observability/public/pages/slos/slos.test.tsx @@ -15,7 +15,6 @@ import { paths } from '../../../common/locators/paths'; import { historicalSummaryData } from '../../data/slo/historical_summary_data'; import { emptySloList, sloList } from '../../data/slo/slo'; import { useCapabilities } from '../../hooks/slo/use_capabilities'; -import { useCloneSlo } from '../../hooks/slo/use_clone_slo'; import { useCreateSlo } from '../../hooks/slo/use_create_slo'; import { useDeleteSlo } from '../../hooks/slo/use_delete_slo'; import { useFetchHistoricalSummary } from '../../hooks/slo/use_fetch_historical_summary'; @@ -24,6 +23,7 @@ import { useLicense } from '../../hooks/use_license'; import { useKibana } from '../../utils/kibana_react'; import { render } from '../../utils/test_helper'; import { SlosPage } from './slos'; +import { encode } from '@kbn/rison'; jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), @@ -35,7 +35,6 @@ jest.mock('../../utils/kibana_react'); jest.mock('../../hooks/use_license'); jest.mock('../../hooks/slo/use_fetch_slo_list'); jest.mock('../../hooks/slo/use_create_slo'); -jest.mock('../../hooks/slo/use_clone_slo'); jest.mock('../../hooks/slo/use_delete_slo'); jest.mock('../../hooks/slo/use_fetch_historical_summary'); jest.mock('../../hooks/slo/use_capabilities'); @@ -44,17 +43,14 @@ const useKibanaMock = useKibana as jest.Mock; const useLicenseMock = useLicense as jest.Mock; const useFetchSloListMock = useFetchSloList as jest.Mock; const useCreateSloMock = useCreateSlo as jest.Mock; -const useCloneSloMock = useCloneSlo as jest.Mock; const useDeleteSloMock = useDeleteSlo as jest.Mock; const useFetchHistoricalSummaryMock = useFetchHistoricalSummary as jest.Mock; const useCapabilitiesMock = useCapabilities as jest.Mock; const mockCreateSlo = jest.fn(); -const mockCloneSlo = jest.fn(); const mockDeleteSlo = jest.fn(); useCreateSloMock.mockReturnValue({ mutate: mockCreateSlo }); -useCloneSloMock.mockReturnValue({ mutate: mockCloneSlo }); useDeleteSloMock.mockReturnValue({ mutate: mockDeleteSlo }); const mockNavigate = jest.fn(); @@ -358,7 +354,14 @@ describe('SLOs Page', () => { button.click(); - expect(mockCloneSlo).toBeCalled(); + await waitFor(() => { + const slo = sloList.results.at(0); + expect(mockNavigate).toBeCalledWith( + paths.observability.sloCreateWithEncodedForm( + encode({ ...slo, name: `[Copy] ${slo!.name}`, id: undefined }) + ) + ); + }); }); }); }); diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index b129680ed6c91..717d0db715526 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -28799,8 +28799,6 @@ "xpack.observability.slo.alerting.burnRate.reasonForInstanceId": "{actionGroupName} : Le taux d'avancement pour le (les) dernier(s) {longWindowDuration} est de {longWindowBurnRate} et pour le (les) dernier(s) {shortWindowDuration} est de {shortWindowBurnRate} pour {instanceId}. Alerter si supérieur à {burnRateThreshold} pour les deux fenêtres", "xpack.observability.slo.burnRate.breachedStatustSubtitle": "Au rythme actuel, le budget d'erreur sera épuisé en {hour} heures.", "xpack.observability.slo.burnRate.threshold": "Le seuil est {threshold}x", - "xpack.observability.slo.clone.errorNotification": "Échec du clonage de {name}", - "xpack.observability.slo.clone.successNotification": "{name} créé avec succès", "xpack.observability.slo.create.errorNotification": "Un problème est survenu lors de la création de {name}", "xpack.observability.slo.create.successNotification": "{name} créé avec succès", "xpack.observability.slo.deleteConfirmationModal.partitionByDisclaimerText": "Ce SLO a été généré avec une clé de partition sur \"{partitionKey}\". La suppression de cette définition de SLO entraînera la suppression de toutes les instances.", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 1606d64b05224..6fec3112555f8 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -28799,8 +28799,6 @@ "xpack.observability.slo.alerting.burnRate.reasonForInstanceId": "{actionGroupName}:過去{longWindowDuration}のバーンレートは{longWindowBurnRate}、{instanceId}の過去{shortWindowDuration}のバーンレートは{shortWindowBurnRate}です。両期間とも{burnRateThreshold}を超えたらアラート", "xpack.observability.slo.burnRate.breachedStatustSubtitle": "現在のレートでは、エラー予算は{hour}時間後に使い果たされます。", "xpack.observability.slo.burnRate.threshold": "しきい値は{threshold}xです", - "xpack.observability.slo.clone.errorNotification": "{name}を複製できませんでした", - "xpack.observability.slo.clone.successNotification": "{name}の作成が正常に完了しました", "xpack.observability.slo.create.errorNotification": "{name}の作成中に問題が発生しました", "xpack.observability.slo.create.successNotification": "{name}の作成が正常に完了しました", "xpack.observability.slo.deleteConfirmationModal.partitionByDisclaimerText": "このSLOは\"{partitionKey}\"のパーティションキーで生成されました。このSLO定義を削除すると、すべてのインスタンスが削除されます。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index dfaaa19f0959d..9924ed6ecf886 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -28796,8 +28796,6 @@ "xpack.observability.slo.alerting.burnRate.reasonForInstanceId": "{actionGroupName}:过去 {longWindowDuration} 的消耗速度为 {longWindowBurnRate},且对于 {instanceId},过去 {shortWindowDuration} 为 {shortWindowBurnRate}。两个窗口超出 {burnRateThreshold} 时告警", "xpack.observability.slo.burnRate.breachedStatustSubtitle": "按照当前的速率,错误预算将在 {hour} 小时后耗尽。", "xpack.observability.slo.burnRate.threshold": "阈值为 {threshold}x", - "xpack.observability.slo.clone.errorNotification": "无法克隆 {name}", - "xpack.observability.slo.clone.successNotification": "已成功创建 {name}", "xpack.observability.slo.create.errorNotification": "创建 {name} 时出现问题", "xpack.observability.slo.create.successNotification": "已成功创建 {name}", "xpack.observability.slo.deleteConfirmationModal.partitionByDisclaimerText": "已使用分区密钥“{partitionKey}”生成此 SLO。删除此 SLO 定义将导致删除所有实例。",