diff --git a/CHANGELOG.md b/CHANGELOG.md index e21168af4..39ee3a312 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ - Docker images reported version as `dev` #2479. +### Changed + +- Alert groups will be rendered fewer details when idle. + ## v0.76 ### Fixed diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupFooter/index.test.tsx b/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupFooter/index.test.tsx index 1ec177deb..1f2b361bc 100644 --- a/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupFooter/index.test.tsx +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupFooter/index.test.tsx @@ -150,4 +150,55 @@ describe("", () => { const tree = MountedGroupFooter(); expect(toDiffableHtml(tree.html())).not.toMatch(/@receiver:/); }); + + it("doesn't render silences when showSilences=false", () => { + for (let index = 0; index < group.alerts.length; index++) { + group.alerts[index].alertmanager[0].silencedBy = ["123456789"]; + } + group.shared.silences = { default: ["123456789"] }; + + alertStore.data.silences = { + default: { + "123456789": MockSilence(), + }, + }; + alertStore.data.silences["default"]["123456789"].id = "123456789"; + + const tree = mount( + , + { + wrappingComponent: ThemeContext.Provider, + wrappingComponentProps: { value: MockThemeContext }, + } + ); + expect( + tree.find("div.components-grid-alertgrid-alertgroup-shared-silence") + ).toHaveLength(0); + }); + + it("doesn't render annotations when showAnnotations=false", () => { + const tree = mount( + , + { + wrappingComponent: ThemeContext.Provider, + wrappingComponentProps: { value: MockThemeContext }, + } + ); + expect(tree.find("RenderLinkAnnotation")).toHaveLength(0); + expect(tree.find("RenderNonLinkAnnotation")).toHaveLength(0); + }); }); diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupFooter/index.tsx b/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupFooter/index.tsx index b88dc0fd3..5e10b20c7 100644 --- a/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupFooter/index.tsx +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupFooter/index.tsx @@ -16,21 +16,33 @@ const GroupFooter: FC<{ afterUpdate: () => void; alertStore: AlertStore; silenceFormStore: SilenceFormStore; -}> = ({ group, alertmanagers, afterUpdate, alertStore, silenceFormStore }) => { + showAnnotations?: boolean; + showSilences?: boolean; +}> = ({ + group, + alertmanagers, + afterUpdate, + alertStore, + silenceFormStore, + showAnnotations = true, + showSilences = true, +}) => { return (
- {group.shared.annotations - .filter((a) => a.isLink === false) - .map((a) => ( - - ))} + {showAnnotations + ? group.shared.annotations + .filter((a) => a.isLink === false) + .map((a) => ( + + )) + : null}
{Object.entries(group.shared.labels).map(([name, value]) => ( ) : null} - {group.shared.annotations - .filter((a) => a.isLink === true) - .map((a) => ( - - ))} - {Object.keys(group.shared.silences).length === 0 ? null : ( + {showAnnotations + ? group.shared.annotations + .filter((a) => a.isLink === true) + .map((a) => ( + + )) + : null} + {Object.keys(group.shared.silences).length === 0 ? null : showSilences ? (
{Object.entries(group.shared.silences).map(([cluster, silences]) => silences.map((silenceID) => ( @@ -75,7 +93,7 @@ const GroupFooter: FC<{ )) )}
- )} + ) : null}
); }; diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/index.test.tsx b/ui/src/Components/Grid/AlertGrid/AlertGroup/index.test.tsx index 95a7ce4fd..170b588cf 100644 --- a/ui/src/Components/Grid/AlertGrid/AlertGroup/index.test.tsx +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/index.test.tsx @@ -205,6 +205,13 @@ describe("", () => { expect(tree.find("ul.list-group")).toHaveLength(0); }); + it("renders reduced details when idle", () => { + MockAlerts(10); + alertStore.ui.setIsIdle(true); + const tree = MountedAlertGroup(jest.fn(), true, 10, MockThemeContext); + expect(tree.find("Alert")).toHaveLength(1); + }); + it("is collapsed by default on desktop when defaultCollapseState=collapsed", () => { // set window.innerWidth to 2k to mock a desktop window ValidateCollapse(2048, "collapsed", true); diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/index.tsx b/ui/src/Components/Grid/AlertGrid/AlertGroup/index.tsx index 059e5aaaf..57344c808 100644 --- a/ui/src/Components/Grid/AlertGrid/AlertGroup/index.tsx +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/index.tsx @@ -6,6 +6,7 @@ import { IconDefinition } from "@fortawesome/fontawesome-svg-core"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faPlus } from "@fortawesome/free-solid-svg-icons/faPlus"; import { faMinus } from "@fortawesome/free-solid-svg-icons/faMinus"; +import { faEllipsisH } from "@fortawesome/free-solid-svg-icons/faEllipsisH"; import { APIAlertT, APIAlertGroupT, AlertStateT } from "Models/APITypes"; import { Settings } from "Stores/Settings"; @@ -201,41 +202,57 @@ const AlertGroup: FC<{ {isCollapsed ? null : (
    - {group.alerts.slice(0, alertsToRender).map((alert) => ( - 1 && - group.alerts.length === 1 - } - afterUpdate={afterUpdate} - alertStore={alertStore} - silenceFormStore={silenceFormStore} - setIsMenuOpen={setIsMenuOpen} - /> - ))} + {group.alerts + .slice(0, alertStore.ui.isIdle ? 1 : alertsToRender) + .map((alert) => ( + 1 && + group.alerts.length === 1 + } + afterUpdate={afterUpdate} + alertStore={alertStore} + silenceFormStore={silenceFormStore} + setIsMenuOpen={setIsMenuOpen} + /> + ))} {group.alerts.length > defaultRenderCount ? ( -
  • - - - {Math.min(alertsToRender, group.alerts.length)} - {" of "} - {group.alerts.length} - - +
  • + {alertStore.ui.isIdle ? ( + + ) : ( + + + + {Math.min(alertsToRender, group.alerts.length)} + {" of "} + {group.alerts.length} + + + + )}
  • ) : null}
@@ -248,6 +265,8 @@ const AlertGroup: FC<{ afterUpdate={afterUpdate} alertStore={alertStore} silenceFormStore={silenceFormStore} + showAnnotations={!alertStore.ui.isIdle} + showSilences={!alertStore.ui.isIdle} /> ) : null}
diff --git a/ui/src/Components/MainModal/Configuration/FilterBarConfiguration.tsx b/ui/src/Components/MainModal/Configuration/FilterBarConfiguration.tsx index 304a17a3b..2edc3722f 100644 --- a/ui/src/Components/MainModal/Configuration/FilterBarConfiguration.tsx +++ b/ui/src/Components/MainModal/Configuration/FilterBarConfiguration.tsx @@ -25,7 +25,7 @@ const FilterBarConfiguration: FC<{ className="custom-control-label cursor-pointer mr-3" htmlFor="configuration-autohide" > - Hide filter bar when idle + Hide filter bar and alert details when idle diff --git a/ui/src/Components/MainModal/Configuration/__snapshots__/FilterBarConfiguration.test.tsx.snap b/ui/src/Components/MainModal/Configuration/__snapshots__/FilterBarConfiguration.test.tsx.snap index d6d13d22e..134ef5181 100644 --- a/ui/src/Components/MainModal/Configuration/__snapshots__/FilterBarConfiguration.test.tsx.snap +++ b/ui/src/Components/MainModal/Configuration/__snapshots__/FilterBarConfiguration.test.tsx.snap @@ -13,7 +13,7 @@ exports[` matches snapshot with default values 1`] = ` diff --git a/ui/src/Components/MainModal/Configuration/__snapshots__/index.test.tsx.snap b/ui/src/Components/MainModal/Configuration/__snapshots__/index.test.tsx.snap index c77771fdb..873150be6 100644 --- a/ui/src/Components/MainModal/Configuration/__snapshots__/index.test.tsx.snap +++ b/ui/src/Components/MainModal/Configuration/__snapshots__/index.test.tsx.snap @@ -108,7 +108,7 @@ exports[` matches snapshot 1`] = ` diff --git a/ui/src/Components/MainModal/__snapshots__/MainModalContent.test.tsx.snap b/ui/src/Components/MainModal/__snapshots__/MainModalContent.test.tsx.snap index 679397618..52c522723 100644 --- a/ui/src/Components/MainModal/__snapshots__/MainModalContent.test.tsx.snap +++ b/ui/src/Components/MainModal/__snapshots__/MainModalContent.test.tsx.snap @@ -127,7 +127,7 @@ exports[` matches snapshot 1`] = ` diff --git a/ui/src/Components/NavBar/index.tsx b/ui/src/Components/NavBar/index.tsx index bcee044d3..f0707f4c4 100644 --- a/ui/src/Components/NavBar/index.tsx +++ b/ui/src/Components/NavBar/index.tsx @@ -27,7 +27,6 @@ const NavBar: FC<{ silenceFormStore: SilenceFormStore; fixedTop?: boolean; }> = ({ alertStore, settingsStore, silenceFormStore, fixedTop = true }) => { - const [isIdle, setIsIdle] = useState(false); const [containerClass, setContainerClass] = useState("visible"); const context = React.useContext(ThemeContext); @@ -44,12 +43,12 @@ const NavBar: FC<{ ); const onActive = useCallback(() => { - setIsIdle(false); - }, []); + alertStore.ui.setIsIdle(false); + }, [alertStore.ui]); const onIdle = useCallback(() => { - setIsIdle(true); - }, []); + alertStore.ui.setIsIdle(true); + }, [alertStore.ui]); const { pause, reset } = useIdleTimer({ timeout: IsMobile() ? MobileIdleTimeout : DesktopIdleTimeout, @@ -60,7 +59,7 @@ const NavBar: FC<{ useEffect(() => { let timer: number; - if (isIdle) { + if (alertStore.ui.isIdle) { timer = window.setTimeout( () => updateBodyPaddingTop(true), context.animations.duration @@ -69,7 +68,12 @@ const NavBar: FC<{ updateBodyPaddingTop(false); } return () => window.clearTimeout(timer); - }, [height, updateBodyPaddingTop, isIdle, context.animations.duration]); + }, [ + height, + updateBodyPaddingTop, + alertStore.ui.isIdle, + context.animations.duration, + ]); useEffect( () => @@ -89,7 +93,7 @@ const NavBar: FC<{
{}} onExited={() => {}} diff --git a/ui/src/Stores/AlertStore.ts b/ui/src/Stores/AlertStore.ts index 66b7d7a5a..4e3b7a98e 100644 --- a/ui/src/Stores/AlertStore.ts +++ b/ui/src/Stores/AlertStore.ts @@ -192,12 +192,18 @@ interface AlertStoreStatusT { stop: () => void; } +interface AlertStoreUIT { + isIdle: boolean; + setIsIdle: (val: boolean) => void; +} + class AlertStore { filters: AlertStoreFiltersT; data: AlertStoreDataT; info: AlertStoreInfoT; settings: AlertStoreSettingsT; status: AlertStoreStatusT; + ui: AlertStoreUIT; constructor(initialFilters: null | string[]) { this.filters = observable( @@ -474,6 +480,18 @@ class AlertStore { { name: "Store status" } ); + this.ui = observable( + { + isIdle: false as boolean, + setIsIdle(val: boolean) { + this.isIdle = val; + }, + }, + { + setIsIdle: action.bound, + } + ); + if (initialFilters !== null) this.filters.setFilters(initialFilters); }