mirror of
https://github.com/prometheus/prometheus.git
synced 2024-11-09 23:24:05 -08:00
preserve state on page reload for alert status filters and annotations with useLocalStorage(), add toggleAnnotations method, and add passing tests (#7374)
Signed-off-by: Lisa Carpenter <carpenter.lisa@gmail.com>
This commit is contained in:
parent
66dfb951c4
commit
dff31c2826
39
web/ui/react-app/src/pages/alerts/AlertContents.test.tsx
Normal file
39
web/ui/react-app/src/pages/alerts/AlertContents.test.tsx
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { shallow } from 'enzyme';
|
||||||
|
import AlertsContent from './AlertContents';
|
||||||
|
|
||||||
|
describe('AlertsContent', () => {
|
||||||
|
const defaultProps = {
|
||||||
|
groups: [],
|
||||||
|
statsCount: {
|
||||||
|
inactive: 0,
|
||||||
|
pending: 0,
|
||||||
|
firing: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const wrapper = shallow(<AlertsContent {...defaultProps} />);
|
||||||
|
|
||||||
|
it('matches a snapshot', () => {
|
||||||
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
[
|
||||||
|
{ selector: '#inactive-toggler', propName: 'inactive' },
|
||||||
|
{ selector: '#pending-toggler', propName: 'pending' },
|
||||||
|
{ selector: '#firing-toggler', propName: 'firing' },
|
||||||
|
].forEach(testCase => {
|
||||||
|
it(`toggles the ${testCase.propName} checkbox from true to false when clicked and back to true when clicked again`, () => {
|
||||||
|
wrapper.find(testCase.selector).invoke('onClick')(testCase.propName);
|
||||||
|
expect(wrapper.find(testCase.selector).prop('checked')).toBe(false);
|
||||||
|
wrapper.find(testCase.selector).invoke('onClick')(testCase.propName);
|
||||||
|
expect(wrapper.find(testCase.selector).prop('checked')).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('toggles the "annotations" checkbox from false to true when clicked and back to true when clicked again', () => {
|
||||||
|
wrapper.find('#show-annotations-toggler').invoke('onClick')();
|
||||||
|
expect(wrapper.find('#show-annotations-toggler').prop('checked')).toBe(true);
|
||||||
|
wrapper.find('#show-annotations-toggler').invoke('onClick')();
|
||||||
|
expect(wrapper.find('#show-annotations-toggler').prop('checked')).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,9 +1,10 @@
|
||||||
import React, { FC, useState, Fragment } from 'react';
|
import React, { FC, Fragment } from 'react';
|
||||||
import { Badge } from 'reactstrap';
|
import { Badge } from 'reactstrap';
|
||||||
import CollapsibleAlertPanel from './CollapsibleAlertPanel';
|
import CollapsibleAlertPanel from './CollapsibleAlertPanel';
|
||||||
import Checkbox from '../../components/Checkbox';
|
import Checkbox from '../../components/Checkbox';
|
||||||
import { isPresent } from '../../utils';
|
import { isPresent } from '../../utils';
|
||||||
import { Rule } from '../../types/types';
|
import { Rule } from '../../types/types';
|
||||||
|
import { useLocalStorage } from '../../hooks/useLocalStorage';
|
||||||
|
|
||||||
export type RuleState = keyof RuleStatus<any>;
|
export type RuleState = keyof RuleStatus<any>;
|
||||||
|
|
||||||
|
@ -40,12 +41,12 @@ const stateColorTuples: Array<[RuleState, 'success' | 'warning' | 'danger']> = [
|
||||||
];
|
];
|
||||||
|
|
||||||
const AlertsContent: FC<AlertsProps> = ({ groups = [], statsCount }) => {
|
const AlertsContent: FC<AlertsProps> = ({ groups = [], statsCount }) => {
|
||||||
const [filter, setFilter] = useState<RuleStatus<boolean>>({
|
const [filter, setFilter] = useLocalStorage('alerts-status-filter', {
|
||||||
firing: true,
|
firing: true,
|
||||||
pending: true,
|
pending: true,
|
||||||
inactive: true,
|
inactive: true,
|
||||||
});
|
});
|
||||||
const [showAnnotations, setShowAnnotations] = useState(false);
|
const [showAnnotations, setShowAnnotations] = useLocalStorage('alerts-annotations-status', { checked: false });
|
||||||
|
|
||||||
const toggleFilter = (ruleState: RuleState) => () => {
|
const toggleFilter = (ruleState: RuleState) => () => {
|
||||||
setFilter({
|
setFilter({
|
||||||
|
@ -54,6 +55,10 @@ const AlertsContent: FC<AlertsProps> = ({ groups = [], statsCount }) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const toggleAnnotations = () => {
|
||||||
|
setShowAnnotations({ checked: !showAnnotations.checked });
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="d-flex togglers-wrapper">
|
<div className="d-flex togglers-wrapper">
|
||||||
|
@ -62,7 +67,7 @@ const AlertsContent: FC<AlertsProps> = ({ groups = [], statsCount }) => {
|
||||||
<Checkbox
|
<Checkbox
|
||||||
key={state}
|
key={state}
|
||||||
wrapperStyles={{ marginRight: 10 }}
|
wrapperStyles={{ marginRight: 10 }}
|
||||||
defaultChecked
|
checked={filter[state]}
|
||||||
id={`${state}-toggler`}
|
id={`${state}-toggler`}
|
||||||
onClick={toggleFilter(state)}
|
onClick={toggleFilter(state)}
|
||||||
>
|
>
|
||||||
|
@ -74,8 +79,9 @@ const AlertsContent: FC<AlertsProps> = ({ groups = [], statsCount }) => {
|
||||||
})}
|
})}
|
||||||
<Checkbox
|
<Checkbox
|
||||||
wrapperStyles={{ marginLeft: 'auto' }}
|
wrapperStyles={{ marginLeft: 'auto' }}
|
||||||
|
checked={showAnnotations.checked}
|
||||||
id="show-annotations-toggler"
|
id="show-annotations-toggler"
|
||||||
onClick={() => setShowAnnotations(!showAnnotations)}
|
onClick={() => toggleAnnotations()}
|
||||||
>
|
>
|
||||||
<span style={{ fontSize: '0.9rem', lineHeight: 1.9 }}>Show annotations</span>
|
<span style={{ fontSize: '0.9rem', lineHeight: 1.9 }}>Show annotations</span>
|
||||||
</Checkbox>
|
</Checkbox>
|
||||||
|
@ -90,7 +96,7 @@ const AlertsContent: FC<AlertsProps> = ({ groups = [], statsCount }) => {
|
||||||
{group.rules.map((rule, j) => {
|
{group.rules.map((rule, j) => {
|
||||||
return (
|
return (
|
||||||
filter[rule.state] && (
|
filter[rule.state] && (
|
||||||
<CollapsibleAlertPanel key={rule.name + j} showAnnotations={showAnnotations} rule={rule} />
|
<CollapsibleAlertPanel key={rule.name + j} showAnnotations={showAnnotations.checked} rule={rule} />
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`AlertsContent matches a snapshot 1`] = `
|
||||||
|
<Fragment>
|
||||||
|
<div
|
||||||
|
className="d-flex togglers-wrapper"
|
||||||
|
>
|
||||||
|
<Memo(Checkbox)
|
||||||
|
checked={true}
|
||||||
|
id="inactive-toggler"
|
||||||
|
key="inactive"
|
||||||
|
onClick={[Function]}
|
||||||
|
wrapperStyles={
|
||||||
|
Object {
|
||||||
|
"marginRight": 10,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Badge
|
||||||
|
className="text-capitalize"
|
||||||
|
color="success"
|
||||||
|
pill={false}
|
||||||
|
tag="span"
|
||||||
|
>
|
||||||
|
inactive
|
||||||
|
(
|
||||||
|
0
|
||||||
|
)
|
||||||
|
</Badge>
|
||||||
|
</Memo(Checkbox)>
|
||||||
|
<Memo(Checkbox)
|
||||||
|
checked={true}
|
||||||
|
id="pending-toggler"
|
||||||
|
key="pending"
|
||||||
|
onClick={[Function]}
|
||||||
|
wrapperStyles={
|
||||||
|
Object {
|
||||||
|
"marginRight": 10,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Badge
|
||||||
|
className="text-capitalize"
|
||||||
|
color="warning"
|
||||||
|
pill={false}
|
||||||
|
tag="span"
|
||||||
|
>
|
||||||
|
pending
|
||||||
|
(
|
||||||
|
0
|
||||||
|
)
|
||||||
|
</Badge>
|
||||||
|
</Memo(Checkbox)>
|
||||||
|
<Memo(Checkbox)
|
||||||
|
checked={true}
|
||||||
|
id="firing-toggler"
|
||||||
|
key="firing"
|
||||||
|
onClick={[Function]}
|
||||||
|
wrapperStyles={
|
||||||
|
Object {
|
||||||
|
"marginRight": 10,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Badge
|
||||||
|
className="text-capitalize"
|
||||||
|
color="danger"
|
||||||
|
pill={false}
|
||||||
|
tag="span"
|
||||||
|
>
|
||||||
|
firing
|
||||||
|
(
|
||||||
|
0
|
||||||
|
)
|
||||||
|
</Badge>
|
||||||
|
</Memo(Checkbox)>
|
||||||
|
<Memo(Checkbox)
|
||||||
|
checked={false}
|
||||||
|
id="show-annotations-toggler"
|
||||||
|
onClick={[Function]}
|
||||||
|
wrapperStyles={
|
||||||
|
Object {
|
||||||
|
"marginLeft": "auto",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"fontSize": "0.9rem",
|
||||||
|
"lineHeight": 1.9,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Show annotations
|
||||||
|
</span>
|
||||||
|
</Memo(Checkbox)>
|
||||||
|
</div>
|
||||||
|
</Fragment>
|
||||||
|
`;
|
Loading…
Reference in a new issue