mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
feat(slo): add reset action (#182282)
This commit is contained in:
parent
310bba00c6
commit
fe41c27995
13 changed files with 242 additions and 75 deletions
|
@ -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.',
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
}
|
|
@ -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',
|
||||
|
|
|
@ -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}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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', {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue