feat(slo): add reset action (#182282)

This commit is contained in:
Kevin Delemme 2024-05-02 10:16:00 -04:00 committed by GitHub
parent 310bba00c6
commit fe41c27995
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 242 additions and 75 deletions

View file

@ -14,12 +14,14 @@ export interface SloResetConfirmationModalProps {
slo: SLOWithSummaryResponse | SLODefinitionResponse;
onCancel: () => void;
onConfirm: () => void;
isLoading?: boolean;
}
export function SloResetConfirmationModal({
slo,
onCancel,
onConfirm,
isLoading,
}: SloResetConfirmationModalProps) {
const { name } = slo;
return (
@ -38,6 +40,7 @@ export function SloResetConfirmationModal({
})}
onCancel={onCancel}
onConfirm={onConfirm}
isLoading={isLoading}
>
{i18n.translate('xpack.slo.resetConfirmationModal.descriptionText', {
defaultMessage: 'Resetting this SLO will also regenerate the historical data.',

View file

@ -1,55 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { GetSLOInstancesResponse } from '@kbn/slo-schema';
import { useQuery } from '@tanstack/react-query';
import { useKibana } from '../utils/kibana_react';
import { sloKeys } from './query_key_factory';
export interface UseFetchSloInstancesResponse {
isInitialLoading: boolean;
isLoading: boolean;
isRefetching: boolean;
isSuccess: boolean;
isError: boolean;
data: GetSLOInstancesResponse | undefined;
}
export function useFetchSloInstances({ sloId }: { sloId?: string }): UseFetchSloInstancesResponse {
const { http } = useKibana().services;
const { isInitialLoading, isLoading, isError, isSuccess, isRefetching, data } = useQuery({
queryKey: sloKeys.detail(sloId),
queryFn: async ({ signal }) => {
try {
const response = await http.get<GetSLOInstancesResponse>(
`/internal/observability/slos/${sloId}/_instances`,
{
query: {},
signal,
}
);
return response;
} catch (error) {
// ignore error for retrieving slos
}
},
keepPreviousData: true,
enabled: Boolean(sloId),
refetchOnWindowFocus: false,
});
return {
data,
isLoading,
isInitialLoading,
isRefetching,
isSuccess,
isError,
};
}

View file

@ -42,8 +42,10 @@ export function useResetSlo() {
}),
});
},
onSuccess: (_data, { name }) => {
onSuccess: (_data, { name, id }) => {
queryClient.invalidateQueries({ queryKey: sloKeys.lists(), exact: false });
queryClient.invalidateQueries({ queryKey: sloKeys.historicalSummaries(), exact: false });
queryClient.invalidateQueries({ queryKey: sloKeys.details(), exact: false });
toasts.addSuccess(
i18n.translate('xpack.slo.slo.reset.successNotification', {
defaultMessage: '{name} reset successfully',

View file

@ -19,10 +19,12 @@ import { SLOWithSummaryResponse } from '@kbn/slo-schema';
import React, { useCallback, useEffect, useState } from 'react';
import { paths } from '../../../../common/locators/paths';
import { SloDeleteConfirmationModal } from '../../../components/slo/delete_confirmation_modal/slo_delete_confirmation_modal';
import { SloResetConfirmationModal } from '../../../components/slo/reset_confirmation_modal/slo_reset_confirmation_modal';
import { useCapabilities } from '../../../hooks/use_capabilities';
import { useCloneSlo } from '../../../hooks/use_clone_slo';
import { useDeleteSlo } from '../../../hooks/use_delete_slo';
import { useFetchRulesForSlo } from '../../../hooks/use_fetch_rules_for_slo';
import { useResetSlo } from '../../../hooks/use_reset_slo';
import { useKibana } from '../../../utils/kibana_react';
import { convertSliApmParamsToApmAppDeeplinkUrl } from '../../../utils/slo/convert_sli_apm_params_to_apm_app_deeplink_url';
import { isApmIndicatorType } from '../../../utils/slo/indicator';
@ -45,14 +47,17 @@ export function HeaderControl({ isLoading, slo }: Props) {
const hasApmReadCapabilities = capabilities.apm.show;
const { hasWriteCapabilities } = useCapabilities();
const { isDeletingSlo, removeDeleteQueryParam } = useGetQueryParams();
const { isDeletingSlo, isResettingSlo, removeDeleteQueryParam, removeResetQueryParam } =
useGetQueryParams();
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
const [isRuleFlyoutVisible, setRuleFlyoutVisibility] = useState<boolean>(false);
const [isEditRuleFlyoutOpen, setIsEditRuleFlyoutOpen] = useState(false);
const [isDeleteConfirmationModalOpen, setDeleteConfirmationModalOpen] = useState(false);
const [isResetConfirmationModalOpen, setResetConfirmationModalOpen] = useState(false);
const { mutate: deleteSlo } = useDeleteSlo();
const { mutateAsync: resetSlo, isLoading: isResetLoading } = useResetSlo();
const { data: rulesBySlo, refetchRules } = useFetchRulesForSlo({
sloIds: slo ? [slo.id] : undefined,
@ -67,7 +72,10 @@ export function HeaderControl({ isLoading, slo }: Props) {
if (isDeletingSlo) {
setDeleteConfirmationModalOpen(true);
}
}, [isDeletingSlo]);
if (isResettingSlo) {
setResetConfirmationModalOpen(true);
}
}, [isDeletingSlo, isResettingSlo]);
const onCloseRuleFlyout = () => {
setRuleFlyoutVisibility(false);
@ -78,7 +86,7 @@ export function HeaderControl({ isLoading, slo }: Props) {
setRuleFlyoutVisibility(true);
};
const { handleNavigateToRules, sloEditUrl, remoteDeleteUrl } = useSloActions({
const { handleNavigateToRules, sloEditUrl, remoteDeleteUrl, remoteResetUrl } = useSloActions({
slo,
rules,
setIsEditRuleFlyoutOpen,
@ -119,13 +127,34 @@ export function HeaderControl({ isLoading, slo }: Props) {
setDeleteConfirmationModalOpen(false);
};
const handleDeleteConfirm = async () => {
const handleDeleteConfirm = () => {
if (slo) {
deleteSlo({ id: slo.id, name: slo.name });
navigate(basePath.prepend(paths.slos));
}
};
const handleReset = () => {
if (!!remoteResetUrl) {
window.open(remoteResetUrl, '_blank');
} else {
setResetConfirmationModalOpen(true);
}
};
const handleResetConfirm = async () => {
if (slo) {
await resetSlo({ id: slo.id, name: slo.name });
removeResetQueryParam();
setResetConfirmationModalOpen(false);
}
};
const handleResetCancel = () => {
removeResetQueryParam();
setResetConfirmationModalOpen(false);
};
const navigate = useCallback(
(url: string) => setTimeout(() => navigateToUrl(url)),
[navigateToUrl]
@ -263,6 +292,21 @@ export function HeaderControl({ isLoading, slo }: Props) {
defaultMessage: 'Delete',
})}
{showRemoteLinkIcon}
</EuiContextMenuItem>,
<EuiContextMenuItem
key="reset"
icon="refresh"
disabled={!hasWriteCapabilities || hasUndefinedRemoteKibanaUrl}
onClick={handleReset}
data-test-subj="sloDetailsHeaderControlPopoverReset"
toolTipContent={
hasUndefinedRemoteKibanaUrl ? NOT_AVAILABLE_FOR_UNDEFINED_REMOTE_KIBANA_URL : ''
}
>
{i18n.translate('xpack.slo.slo.item.actions.reset', {
defaultMessage: 'Reset',
})}
{showRemoteLinkIcon}
</EuiContextMenuItem>
)}
/>
@ -292,6 +336,15 @@ export function HeaderControl({ isLoading, slo }: Props) {
onConfirm={handleDeleteConfirm}
/>
) : null}
{slo && isResetConfirmationModalOpen ? (
<SloResetConfirmationModal
slo={slo}
onCancel={handleResetCancel}
onConfirm={handleResetConfirm}
isLoading={isResetLoading}
/>
) : null}
</>
);
}

View file

@ -6,12 +6,13 @@
*/
import { ALL_VALUE } from '@kbn/slo-schema';
import { useHistory, useLocation } from 'react-router-dom';
import { useCallback } from 'react';
import { useHistory, useLocation } from 'react-router-dom';
export const INSTANCE_SEARCH_PARAM = 'instanceId';
export const REMOTE_NAME_PARAM = 'remoteName';
export const DELETE_SLO = 'delete';
export const RESET_SLO = 'reset';
export function useGetQueryParams() {
const { search, pathname } = useLocation();
@ -21,6 +22,7 @@ export function useGetQueryParams() {
const instanceId = searchParams.get(INSTANCE_SEARCH_PARAM);
const remoteName = searchParams.get(REMOTE_NAME_PARAM);
const deleteSlo = searchParams.get(DELETE_SLO);
const resetSlo = searchParams.get(RESET_SLO);
const removeDeleteQueryParam = useCallback(() => {
const qParams = new URLSearchParams(search);
@ -35,10 +37,25 @@ export function useGetQueryParams() {
}
}, [deleteSlo, history, pathname, search]);
const removeResetQueryParam = useCallback(() => {
const qParams = new URLSearchParams(search);
// remote reset param from url after initial load
if (resetSlo === 'true') {
qParams.delete(RESET_SLO);
history.replace({
pathname,
search: qParams.toString(),
});
}
}, [resetSlo, history, pathname, search]);
return {
instanceId: !!instanceId && instanceId !== ALL_VALUE ? instanceId : undefined,
remoteName,
isDeletingSlo: deleteSlo === 'true',
removeDeleteQueryParam,
isResettingSlo: resetSlo === 'true',
removeResetQueryParam,
};
}

View file

@ -16,6 +16,7 @@ import { useKibana } from '../../../utils/kibana_react';
import {
createRemoteSloDeleteUrl,
createRemoteSloEditUrl,
createRemoteSloResetUrl,
} from '../../../utils/slo/remote_slo_urls';
export const useSloActions = ({
@ -42,6 +43,7 @@ export const useSloActions = ({
sloEditUrl: '',
handleNavigateToRules: () => {},
remoteDeleteUrl: undefined,
remoteResetUrl: undefined,
sloDetailsUrl: '',
};
}
@ -76,6 +78,7 @@ export const useSloActions = ({
);
const remoteDeleteUrl = createRemoteSloDeleteUrl(slo, spaceId);
const remoteResetUrl = createRemoteSloResetUrl(slo, spaceId);
const sloEditUrl = slo.remote
? createRemoteSloEditUrl(slo, spaceId)
@ -85,6 +88,7 @@ export const useSloActions = ({
sloEditUrl,
handleNavigateToRules,
remoteDeleteUrl,
remoteResetUrl,
sloDetailsUrl: http.basePath.prepend(detailsUrl),
};
};

View file

@ -54,6 +54,7 @@ export function OutdatedSlo({ slo, onReset, onDelete }: OutdatedSloProps) {
const handleResetCancel = () => {
setResetConfirmationModalOpen(false);
};
return (
<EuiPanel hasBorder hasShadow={false}>
<EuiFlexGroup alignItems="center" gutterSize="s">

View file

@ -24,14 +24,16 @@ import {
import { ALL_VALUE, HistoricalSummaryResponse, SLOWithSummaryResponse } from '@kbn/slo-schema';
import { Rule } from '@kbn/triggers-actions-ui-plugin/public';
import React, { useState } from 'react';
import { EditBurnRateRuleFlyout } from '../common/edit_burn_rate_rule_flyout';
import { SloDeleteConfirmationModal } from '../../../../components/slo/delete_confirmation_modal/slo_delete_confirmation_modal';
import { SloResetConfirmationModal } from '../../../../components/slo/reset_confirmation_modal/slo_reset_confirmation_modal';
import { useResetSlo } from '../../../../hooks/use_reset_slo';
import { BurnRateRuleParams } from '../../../../typings';
import { useKibana } from '../../../../utils/kibana_react';
import { formatHistoricalData } from '../../../../utils/slo/chart_data_formatter';
import { useSloListActions } from '../../hooks/use_slo_list_actions';
import { useSloFormattedSummary } from '../../hooks/use_slo_summary';
import { BurnRateRuleFlyout } from '../common/burn_rate_rule_flyout';
import { EditBurnRateRuleFlyout } from '../common/edit_burn_rate_rule_flyout';
import { SloCardItemActions } from './slo_card_item_actions';
import { SloCardItemBadges } from './slo_card_item_badges';
@ -76,7 +78,9 @@ export function SloCardItem({ slo, rules, activeAlerts, historicalSummary, refet
const [isAddRuleFlyoutOpen, setIsAddRuleFlyoutOpen] = useState(false);
const [isEditRuleFlyoutOpen, setIsEditRuleFlyoutOpen] = useState(false);
const [isDeleteConfirmationModalOpen, setDeleteConfirmationModalOpen] = useState(false);
const [isResetConfirmationModalOpen, setResetConfirmationModalOpen] = useState(false);
const [isDashboardAttachmentReady, setDashboardAttachmentReady] = useState(false);
const historicalSliData = formatHistoricalData(historicalSummary, 'sli_value');
const { handleCreateRule, handleDeleteCancel, handleDeleteConfirm, handleAttachToDashboardSave } =
@ -87,6 +91,17 @@ export function SloCardItem({ slo, rules, activeAlerts, historicalSummary, refet
setIsAddRuleFlyoutOpen,
});
const { mutateAsync: resetSlo, isLoading: isResetLoading } = useResetSlo();
const handleResetConfirm = async () => {
await resetSlo({ id: slo.id, name: slo.name });
setResetConfirmationModalOpen(false);
};
const handleResetCancel = () => {
setResetConfirmationModalOpen(false);
};
return (
<>
<EuiPanel
@ -132,6 +147,7 @@ export function SloCardItem({ slo, rules, activeAlerts, historicalSummary, refet
setDeleteConfirmationModalOpen={setDeleteConfirmationModalOpen}
setIsEditRuleFlyoutOpen={setIsEditRuleFlyoutOpen}
setDashboardAttachmentReady={setDashboardAttachmentReady}
setResetConfirmationModalOpen={setResetConfirmationModalOpen}
/>
)}
</EuiPanel>
@ -156,6 +172,16 @@ export function SloCardItem({ slo, rules, activeAlerts, historicalSummary, refet
onConfirm={handleDeleteConfirm}
/>
) : null}
{isResetConfirmationModalOpen ? (
<SloResetConfirmationModal
slo={slo}
onCancel={handleResetCancel}
onConfirm={handleResetConfirm}
isLoading={isResetLoading}
/>
) : null}
{isDashboardAttachmentReady ? (
<SavedObjectSaveModalDashboard
objectType={i18n.translate('xpack.slo.item.actions.addToDashboard.objectTypeLabel', {

View file

@ -42,6 +42,7 @@ interface Props {
isActionsPopoverOpen: boolean;
setIsActionsPopoverOpen: (value: boolean) => void;
setDeleteConfirmationModalOpen: (value: boolean) => void;
setResetConfirmationModalOpen: (value: boolean) => void;
setIsAddRuleFlyoutOpen: (value: boolean) => void;
setIsEditRuleFlyoutOpen: (value: boolean) => void;
setDashboardAttachmentReady: (value: boolean) => void;

View file

@ -24,6 +24,7 @@ import React, { useState } from 'react';
import { NOT_AVAILABLE_LABEL } from '../../../../../common/i18n';
import { paths } from '../../../../../common/locators/paths';
import { SloDeleteConfirmationModal } from '../../../../components/slo/delete_confirmation_modal/slo_delete_confirmation_modal';
import { SloResetConfirmationModal } from '../../../../components/slo/reset_confirmation_modal/slo_reset_confirmation_modal';
import { SloStatusBadge } from '../../../../components/slo/slo_status_badge';
import { SloActiveAlertsBadge } from '../../../../components/slo/slo_status_badge/slo_active_alerts_badge';
import { sloKeys } from '../../../../hooks/query_key_factory';
@ -34,12 +35,14 @@ import { useFetchActiveAlerts } from '../../../../hooks/use_fetch_active_alerts'
import { useFetchHistoricalSummary } from '../../../../hooks/use_fetch_historical_summary';
import { useFetchRulesForSlo } from '../../../../hooks/use_fetch_rules_for_slo';
import { useGetFilteredRuleTypes } from '../../../../hooks/use_get_filtered_rule_types';
import { useResetSlo } from '../../../../hooks/use_reset_slo';
import { useSpace } from '../../../../hooks/use_space';
import { useKibana } from '../../../../utils/kibana_react';
import { formatHistoricalData } from '../../../../utils/slo/chart_data_formatter';
import {
createRemoteSloDeleteUrl,
createRemoteSloEditUrl,
createRemoteSloResetUrl,
} from '../../../../utils/slo/remote_slo_urls';
import { SloRemoteBadge } from '../badges/slo_remote_badge';
import { SloRulesBadge } from '../badges/slo_rules_badge';
@ -75,9 +78,13 @@ export function SloListCompactView({ sloList, loading, error }: Props) {
const { hasWriteCapabilities } = useCapabilities();
const filteredRuleTypes = useGetFilteredRuleTypes();
const queryClient = useQueryClient();
const { mutate: deleteSlo } = useDeleteSlo();
const { mutateAsync: resetSlo, isLoading: isResetLoading } = useResetSlo();
const [sloToAddRule, setSloToAddRule] = useState<SLOWithSummaryResponse | undefined>(undefined);
const [sloToDelete, setSloToDelete] = useState<SLOWithSummaryResponse | undefined>(undefined);
const [sloToReset, setSloToReset] = useState<SLOWithSummaryResponse | undefined>(undefined);
const handleDeleteConfirm = () => {
if (sloToDelete) {
@ -90,6 +97,17 @@ export function SloListCompactView({ sloList, loading, error }: Props) {
setSloToDelete(undefined);
};
const handleResetConfirm = async () => {
if (sloToReset) {
await resetSlo({ id: sloToReset.id, name: sloToReset.name });
setSloToReset(undefined);
}
};
const handleResetCancel = () => {
setSloToReset(undefined);
};
const handleSavedRule = async () => {
queryClient.invalidateQueries({ queryKey: sloKeys.rules(), exact: false });
};
@ -242,6 +260,29 @@ export function SloListCompactView({ sloList, loading, error }: Props) {
}
},
},
{
type: 'icon',
icon: 'refresh',
name: buildActionName(
i18n.translate('xpack.slo.item.actions.reset', {
defaultMessage: 'Reset',
})
),
description: i18n.translate('xpack.slo.item.actions.reset', {
defaultMessage: 'Reset',
}),
'data-test-subj': 'sloActionsReset',
enabled: (slo: SLOWithSummaryResponse) =>
(hasWriteCapabilities && !isRemote(slo)) || hasRemoteKibanaUrl(slo),
onClick: (slo: SLOWithSummaryResponse) => {
const remoteResetUrl = createRemoteSloResetUrl(slo, spaceId);
if (!!remoteResetUrl) {
window.open(remoteResetUrl, '_blank');
} else {
setSloToReset(slo);
}
},
},
];
const columns: Array<EuiBasicTableColumn<SLOWithSummaryResponse>> = [
@ -441,6 +482,15 @@ export function SloListCompactView({ sloList, loading, error }: Props) {
onConfirm={handleDeleteConfirm}
/>
) : null}
{sloToReset ? (
<SloResetConfirmationModal
slo={sloToReset}
onCancel={handleResetCancel}
onConfirm={handleResetConfirm}
isLoading={isResetLoading}
/>
) : null}
</>
);
}

View file

@ -30,6 +30,7 @@ interface Props {
isActionsPopoverOpen: boolean;
setIsActionsPopoverOpen: (value: boolean) => void;
setDeleteConfirmationModalOpen: (value: boolean) => void;
setResetConfirmationModalOpen: (value: boolean) => void;
setIsAddRuleFlyoutOpen: (value: boolean) => void;
setIsEditRuleFlyoutOpen: (value: boolean) => void;
setDashboardAttachmentReady?: (value: boolean) => void;
@ -65,6 +66,7 @@ export function SloItemActions({
setIsAddRuleFlyoutOpen,
setIsEditRuleFlyoutOpen,
setDeleteConfirmationModalOpen,
setResetConfirmationModalOpen,
setDashboardAttachmentReady,
btnProps,
}: Props) {
@ -77,12 +79,13 @@ export function SloItemActions({
const { hasWriteCapabilities } = useCapabilities();
const navigateToClone = useCloneSlo();
const { handleNavigateToRules, sloEditUrl, remoteDeleteUrl, sloDetailsUrl } = useSloActions({
slo,
rules,
setIsEditRuleFlyoutOpen,
setIsActionsPopoverOpen,
});
const { handleNavigateToRules, sloEditUrl, remoteDeleteUrl, remoteResetUrl, sloDetailsUrl } =
useSloActions({
slo,
rules,
setIsEditRuleFlyoutOpen,
setIsActionsPopoverOpen,
});
const handleClickActions = () => {
setIsActionsPopoverOpen(!isActionsPopoverOpen);
@ -105,6 +108,15 @@ export function SloItemActions({
}
};
const handleReset = () => {
if (!!remoteResetUrl) {
window.open(remoteResetUrl, '_blank');
} else {
setResetConfirmationModalOpen(true);
setIsActionsPopoverOpen(false);
}
};
const handleCreateRule = () => {
setIsActionsPopoverOpen(false);
setIsAddRuleFlyoutOpen(true);
@ -237,6 +249,20 @@ export function SloItemActions({
{i18n.translate('xpack.slo.item.actions.delete', { defaultMessage: 'Delete' })}
{showRemoteLinkIcon}
</EuiContextMenuItem>,
,
<EuiContextMenuItem
key="reset"
icon="refresh"
disabled={!hasWriteCapabilities || hasUndefinedRemoteKibanaUrl}
onClick={handleReset}
toolTipContent={
hasUndefinedRemoteKibanaUrl ? NOT_AVAILABLE_FOR_UNDEFINED_REMOTE_KIBANA_URL : ''
}
data-test-subj="sloActionsReset"
>
{i18n.translate('xpack.slo.item.actions.reset', { defaultMessage: 'Reset' })}
{showRemoteLinkIcon}
</EuiContextMenuItem>,
].concat(
!isDashboardContext ? (
<EuiContextMenuItem

View file

@ -9,16 +9,18 @@ import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiText } from '@elastic/eui';
import { HistoricalSummaryResponse, SLOWithSummaryResponse } from '@kbn/slo-schema';
import type { Rule } from '@kbn/triggers-actions-ui-plugin/public';
import React, { useState } from 'react';
import { EditBurnRateRuleFlyout } from '../common/edit_burn_rate_rule_flyout';
import { SloDeleteConfirmationModal } from '../../../../components/slo/delete_confirmation_modal/slo_delete_confirmation_modal';
import { useSloFormattedSummary } from '../../hooks/use_slo_summary';
import { BurnRateRuleFlyout } from '../common/burn_rate_rule_flyout';
import { useSloListActions } from '../../hooks/use_slo_list_actions';
import { SloItemActions } from '../slo_item_actions';
import { SloBadges } from '../badges/slo_badges';
import { SloSummary } from '../slo_summary';
import { SloResetConfirmationModal } from '../../../../components/slo/reset_confirmation_modal/slo_reset_confirmation_modal';
import { useResetSlo } from '../../../../hooks/use_reset_slo';
import { BurnRateRuleParams } from '../../../../typings';
import { useSloListActions } from '../../hooks/use_slo_list_actions';
import { useSloFormattedSummary } from '../../hooks/use_slo_summary';
import { SloBadges } from '../badges/slo_badges';
import { BurnRateRuleFlyout } from '../common/burn_rate_rule_flyout';
import { EditBurnRateRuleFlyout } from '../common/edit_burn_rate_rule_flyout';
import { SLOGroupings } from '../common/slo_groupings';
import { SloItemActions } from '../slo_item_actions';
import { SloSummary } from '../slo_summary';
export interface SloListItemProps {
slo: SLOWithSummaryResponse;
@ -41,7 +43,9 @@ export function SloListItem({
const [isAddRuleFlyoutOpen, setIsAddRuleFlyoutOpen] = useState(false);
const [isEditRuleFlyoutOpen, setIsEditRuleFlyoutOpen] = useState(false);
const [isDeleteConfirmationModalOpen, setDeleteConfirmationModalOpen] = useState(false);
const [isResetConfirmationModalOpen, setResetConfirmationModalOpen] = useState(false);
const { mutateAsync: resetSlo, isLoading: isResetLoading } = useResetSlo();
const { sloDetailsUrl } = useSloFormattedSummary(slo);
const { handleCreateRule, handleDeleteCancel, handleDeleteConfirm } = useSloListActions({
@ -51,6 +55,14 @@ export function SloListItem({
setIsAddRuleFlyoutOpen,
});
const handleResetConfirm = async () => {
await resetSlo({ id: slo.id, name: slo.name });
setResetConfirmationModalOpen(false);
};
const handleResetCancel = () => {
setResetConfirmationModalOpen(false);
};
return (
<EuiPanel data-test-subj="sloItem" hasBorder hasShadow={false}>
<EuiFlexGroup responsive={false} alignItems="center">
@ -99,6 +111,7 @@ export function SloListItem({
setIsEditRuleFlyoutOpen={setIsEditRuleFlyoutOpen}
setIsActionsPopoverOpen={setIsActionsPopoverOpen}
setDeleteConfirmationModalOpen={setDeleteConfirmationModalOpen}
setResetConfirmationModalOpen={setResetConfirmationModalOpen}
/>
</EuiFlexItem>
</EuiFlexGroup>
@ -122,6 +135,15 @@ export function SloListItem({
onConfirm={handleDeleteConfirm}
/>
) : null}
{isResetConfirmationModalOpen ? (
<SloResetConfirmationModal
slo={slo}
onCancel={handleResetCancel}
onConfirm={handleResetConfirm}
isLoading={isResetLoading}
/>
) : null}
</EuiPanel>
);
}

View file

@ -45,6 +45,23 @@ export function createRemoteSloDeleteUrl(slo: SLOWithSummaryResponse, spaceId: s
return remoteUrl.toString();
}
export function createRemoteSloResetUrl(slo: SLOWithSummaryResponse, spaceId: string = 'default') {
if (!slo.remote || slo.remote.kibanaUrl === '') {
return undefined;
}
const spacePath = spaceId !== 'default' ? `/s/${spaceId}` : '';
const detailsPath = paths.sloDetails(
slo.id,
![slo.groupBy].flat().includes(ALL_VALUE) && slo.instanceId ? slo.instanceId : undefined
);
const remoteUrl = new URL(path.join(spacePath, detailsPath), slo.remote.kibanaUrl);
remoteUrl.searchParams.append('reset', 'true');
return remoteUrl.toString();
}
export function createRemoteSloEditUrl(slo: SLOWithSummaryResponse, spaceId: string = 'default') {
if (!slo.remote || slo.remote.kibanaUrl === '') {
return undefined;