fix: fix incorrect alert history state (#5898)

* fix: on unmount remove the  alert disabled state

* fix: get updated alert state from response and fix the alert state mismatch issue
This commit is contained in:
Shaheer Kochai 2024-10-07 09:57:46 +04:30 committed by GitHub
parent c452e23b18
commit 5ef05891ce
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 45 additions and 35 deletions

View File

@ -15,7 +15,7 @@ import {
} from 'pages/AlertDetails/hooks'; } from 'pages/AlertDetails/hooks';
import CopyToClipboard from 'periscope/components/CopyToClipboard'; import CopyToClipboard from 'periscope/components/CopyToClipboard';
import { useAlertRule } from 'providers/Alert'; import { useAlertRule } from 'providers/Alert';
import React from 'react'; import React, { useEffect, useState } from 'react';
import { CSSProperties } from 'styled-components'; import { CSSProperties } from 'styled-components';
import { AlertDef } from 'types/api/alerts/def'; import { AlertDef } from 'types/api/alerts/def';
@ -32,7 +32,7 @@ function AlertActionButtons({
ruleId: string; ruleId: string;
alertDetails: AlertHeaderProps['alertDetails']; alertDetails: AlertHeaderProps['alertDetails'];
}): JSX.Element { }): JSX.Element {
const { isAlertRuleDisabled } = useAlertRule(); const { alertRuleState, setAlertRuleState } = useAlertRule();
const { handleAlertStateToggle } = useAlertRuleStatusToggle({ ruleId }); const { handleAlertStateToggle } = useAlertRuleStatusToggle({ ruleId });
const { handleAlertDuplicate } = useAlertRuleDuplicate({ const { handleAlertDuplicate } = useAlertRuleDuplicate({
@ -79,13 +79,32 @@ function AlertActionButtons({
); );
const isDarkMode = useIsDarkMode(); const isDarkMode = useIsDarkMode();
// state for immediate UI feedback rather than waiting for onSuccess of handleAlertStateTiggle to updating the alertRuleState
const [isAlertRuleDisabled, setIsAlertRuleDisabled] = useState<
undefined | boolean
>(undefined);
useEffect(() => {
if (alertRuleState === undefined) {
setAlertRuleState(alertDetails.state);
setIsAlertRuleDisabled(alertDetails.state === 'disabled');
}
}, [setAlertRuleState, alertRuleState, alertDetails.state]);
// on unmount remove the alert state
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(() => (): void => setAlertRuleState(undefined), []);
return ( return (
<div className="alert-action-buttons"> <div className="alert-action-buttons">
<Tooltip title={isAlertRuleDisabled ? 'Enable alert' : 'Disable alert'}> <Tooltip title={alertRuleState ? 'Enable alert' : 'Disable alert'}>
{isAlertRuleDisabled !== undefined && ( {isAlertRuleDisabled !== undefined && (
<Switch <Switch
size="small" size="small"
onChange={handleAlertStateToggle} onChange={(): void => {
setIsAlertRuleDisabled((prev) => !prev);
handleAlertStateToggle();
}}
checked={!isAlertRuleDisabled} checked={!isAlertRuleDisabled}
/> />
)} )}

View File

@ -2,7 +2,7 @@ import './AlertHeader.styles.scss';
import LineClampedText from 'periscope/components/LineClampedText/LineClampedText'; import LineClampedText from 'periscope/components/LineClampedText/LineClampedText';
import { useAlertRule } from 'providers/Alert'; import { useAlertRule } from 'providers/Alert';
import { useEffect, useMemo } from 'react'; import { useMemo } from 'react';
import AlertActionButtons from './ActionButtons/ActionButtons'; import AlertActionButtons from './ActionButtons/ActionButtons';
import AlertLabels from './AlertLabels/AlertLabels'; import AlertLabels from './AlertLabels/AlertLabels';
@ -19,7 +19,7 @@ export type AlertHeaderProps = {
}; };
}; };
function AlertHeader({ alertDetails }: AlertHeaderProps): JSX.Element { function AlertHeader({ alertDetails }: AlertHeaderProps): JSX.Element {
const { state, alert, labels, disabled } = alertDetails; const { state, alert, labels } = alertDetails;
const labelsWithoutSeverity = useMemo( const labelsWithoutSeverity = useMemo(
() => () =>
@ -29,20 +29,14 @@ function AlertHeader({ alertDetails }: AlertHeaderProps): JSX.Element {
[labels], [labels],
); );
const { isAlertRuleDisabled, setIsAlertRuleDisabled } = useAlertRule(); const { alertRuleState } = useAlertRule();
useEffect(() => {
if (isAlertRuleDisabled === undefined) {
setIsAlertRuleDisabled(disabled);
}
}, [disabled, setIsAlertRuleDisabled, isAlertRuleDisabled]);
return ( return (
<div className="alert-info"> <div className="alert-info">
<div className="alert-info__info-wrapper"> <div className="alert-info__info-wrapper">
<div className="top-section"> <div className="top-section">
<div className="alert-title-wrapper"> <div className="alert-title-wrapper">
<AlertState state={isAlertRuleDisabled ? 'disabled' : state} /> <AlertState state={alertRuleState ?? state} />
<div className="alert-title"> <div className="alert-title">
<LineClampedText text={alert} /> <LineClampedText text={alert} />
</div> </div>

View File

@ -161,7 +161,6 @@ export const useGetAlertRuleDetails = (): Props => {
id: parseInt(ruleId || '', 10), id: parseInt(ruleId || '', 10),
}), }),
enabled: isValidRuleId, enabled: isValidRuleId,
refetchOnMount: false,
refetchOnWindowFocus: false, refetchOnWindowFocus: false,
}); });
@ -369,9 +368,9 @@ export const useAlertRuleStatusToggle = ({
}: { }: {
ruleId: string; ruleId: string;
}): { }): {
handleAlertStateToggle: (state: boolean) => void; handleAlertStateToggle: () => void;
} => { } => {
const { isAlertRuleDisabled, setIsAlertRuleDisabled } = useAlertRule(); const { alertRuleState, setAlertRuleState } = useAlertRule();
const { notifications } = useNotifications(); const { notifications } = useNotifications();
const queryClient = useQueryClient(); const queryClient = useQueryClient();
@ -381,16 +380,17 @@ export const useAlertRuleStatusToggle = ({
[REACT_QUERY_KEY.TOGGLE_ALERT_STATE, ruleId], [REACT_QUERY_KEY.TOGGLE_ALERT_STATE, ruleId],
patchAlert, patchAlert,
{ {
onMutate: () => { onSuccess: (data) => {
setIsAlertRuleDisabled((prev) => !prev); setAlertRuleState(data?.payload?.state);
},
onSuccess: () => {
notifications.success({ notifications.success({
message: `Alert has been ${isAlertRuleDisabled ? 'enabled' : 'disabled'}.`, message: `Alert has been ${
data?.payload?.state === 'disabled' ? 'disabled' : 'enabled'
}.`,
}); });
}, },
onError: (error) => { onError: (error) => {
queryClient.refetchQueries([REACT_QUERY_KEY.ALERT_RULE_DETAILS]); queryClient.refetchQueries([REACT_QUERY_KEY.ALERT_RULE_DETAILS, ruleId]);
handleError(error); handleError(error);
}, },
}, },
@ -399,7 +399,7 @@ export const useAlertRuleStatusToggle = ({
const handleAlertStateToggle = (): void => { const handleAlertStateToggle = (): void => {
const args = { const args = {
id: parseInt(ruleId, 10), id: parseInt(ruleId, 10),
data: { disabled: !isAlertRuleDisabled }, data: { disabled: alertRuleState !== 'disabled' },
}; };
toggleAlertState(args); toggleAlertState(args);
}; };

View File

@ -1,10 +1,8 @@
import React, { createContext, useContext, useState } from 'react'; import React, { createContext, useContext, useState } from 'react';
interface AlertRuleContextType { interface AlertRuleContextType {
isAlertRuleDisabled: boolean | undefined; alertRuleState: string | undefined;
setIsAlertRuleDisabled: React.Dispatch< setAlertRuleState: React.Dispatch<React.SetStateAction<string | undefined>>;
React.SetStateAction<boolean | undefined>
>;
} }
const AlertRuleContext = createContext<AlertRuleContextType | undefined>( const AlertRuleContext = createContext<AlertRuleContextType | undefined>(
@ -16,15 +14,14 @@ function AlertRuleProvider({
}: { }: {
children: React.ReactNode; children: React.ReactNode;
}): JSX.Element { }): JSX.Element {
const [isAlertRuleDisabled, setIsAlertRuleDisabled] = useState< const [alertRuleState, setAlertRuleState] = useState<string | undefined>(
boolean | undefined undefined,
>(undefined);
const value = React.useMemo(
() => ({ isAlertRuleDisabled, setIsAlertRuleDisabled }),
[isAlertRuleDisabled],
); );
const value = React.useMemo(() => ({ alertRuleState, setAlertRuleState }), [
alertRuleState,
]);
return ( return (
<AlertRuleContext.Provider value={value}> <AlertRuleContext.Provider value={value}>
{children} {children}