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 CollapsibleAlertPanel from './CollapsibleAlertPanel';
|
||||
import Checkbox from '../../components/Checkbox';
|
||||
import { isPresent } from '../../utils';
|
||||
import { Rule } from '../../types/types';
|
||||
import { useLocalStorage } from '../../hooks/useLocalStorage';
|
||||
|
||||
export type RuleState = keyof RuleStatus<any>;
|
||||
|
||||
|
@ -40,12 +41,12 @@ const stateColorTuples: Array<[RuleState, 'success' | 'warning' | 'danger']> = [
|
|||
];
|
||||
|
||||
const AlertsContent: FC<AlertsProps> = ({ groups = [], statsCount }) => {
|
||||
const [filter, setFilter] = useState<RuleStatus<boolean>>({
|
||||
const [filter, setFilter] = useLocalStorage('alerts-status-filter', {
|
||||
firing: true,
|
||||
pending: true,
|
||||
inactive: true,
|
||||
});
|
||||
const [showAnnotations, setShowAnnotations] = useState(false);
|
||||
const [showAnnotations, setShowAnnotations] = useLocalStorage('alerts-annotations-status', { checked: false });
|
||||
|
||||
const toggleFilter = (ruleState: RuleState) => () => {
|
||||
setFilter({
|
||||
|
@ -54,6 +55,10 @@ const AlertsContent: FC<AlertsProps> = ({ groups = [], statsCount }) => {
|
|||
});
|
||||
};
|
||||
|
||||
const toggleAnnotations = () => {
|
||||
setShowAnnotations({ checked: !showAnnotations.checked });
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="d-flex togglers-wrapper">
|
||||
|
@ -62,7 +67,7 @@ const AlertsContent: FC<AlertsProps> = ({ groups = [], statsCount }) => {
|
|||
<Checkbox
|
||||
key={state}
|
||||
wrapperStyles={{ marginRight: 10 }}
|
||||
defaultChecked
|
||||
checked={filter[state]}
|
||||
id={`${state}-toggler`}
|
||||
onClick={toggleFilter(state)}
|
||||
>
|
||||
|
@ -74,8 +79,9 @@ const AlertsContent: FC<AlertsProps> = ({ groups = [], statsCount }) => {
|
|||
})}
|
||||
<Checkbox
|
||||
wrapperStyles={{ marginLeft: 'auto' }}
|
||||
checked={showAnnotations.checked}
|
||||
id="show-annotations-toggler"
|
||||
onClick={() => setShowAnnotations(!showAnnotations)}
|
||||
onClick={() => toggleAnnotations()}
|
||||
>
|
||||
<span style={{ fontSize: '0.9rem', lineHeight: 1.9 }}>Show annotations</span>
|
||||
</Checkbox>
|
||||
|
@ -90,7 +96,7 @@ const AlertsContent: FC<AlertsProps> = ({ groups = [], statsCount }) => {
|
|||
{group.rules.map((rule, j) => {
|
||||
return (
|
||||
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