diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/AlertMenu.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/AlertMenu.js index 3e21d2129..d0a505ca5 100644 --- a/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/AlertMenu.js +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/AlertMenu.js @@ -95,22 +95,29 @@ const AlertMenu = observer( group: APIGroup.isRequired, alert: APIAlert.isRequired, alertStore: PropTypes.instanceOf(AlertStore).isRequired, - silenceFormStore: PropTypes.instanceOf(SilenceFormStore).isRequired + silenceFormStore: PropTypes.instanceOf(SilenceFormStore).isRequired, + setIsMenuOpen: PropTypes.func.isRequired }; - collapse = observable( - { - value: true, - toggle() { - this.value = !this.value; + constructor(props) { + super(props); + + this.collapse = observable( + { + value: true, + toggle() { + this.value = !this.value; + props.setIsMenuOpen(!this.value); + }, + hide() { + this.value = true; + props.setIsMenuOpen(!this.value); + } }, - hide() { - this.value = true; - } - }, - { toggle: action.bound, hide: action.bound }, - { name: "Alert menu toggle" } - ); + { toggle: action.bound, hide: action.bound }, + { name: "Alert menu toggle" } + ); + } handleClickOutside = action(event => { this.collapse.hide(); diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/AlertMenu.test.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/AlertMenu.test.js index f63b215a3..4576ee460 100644 --- a/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/AlertMenu.test.js +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/AlertMenu.test.js @@ -22,6 +22,7 @@ beforeEach(() => { }); const MockAfterClick = jest.fn(); +const MockSetIsMenuOpen = jest.fn(); const MountedAlertMenu = group => { return mount( @@ -31,6 +32,7 @@ const MountedAlertMenu = group => { alert={alert} alertStore={alertStore} silenceFormStore={silenceFormStore} + setIsMenuOpen={MockSetIsMenuOpen} /> ).find("AlertMenu"); diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/index.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/index.js index 475e0042e..2a3330d60 100644 --- a/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/index.js +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/index.js @@ -28,7 +28,8 @@ const Alert = observer( showReceiver: PropTypes.bool.isRequired, afterUpdate: PropTypes.func.isRequired, alertStore: PropTypes.instanceOf(AlertStore).isRequired, - silenceFormStore: PropTypes.instanceOf(SilenceFormStore).isRequired + silenceFormStore: PropTypes.instanceOf(SilenceFormStore).isRequired, + setIsMenuOpen: PropTypes.func.isRequired }; render() { @@ -39,7 +40,8 @@ const Alert = observer( showReceiver, afterUpdate, alertStore, - silenceFormStore + silenceFormStore, + setIsMenuOpen } = this.props; let classNames = [ @@ -92,6 +94,7 @@ const Alert = observer( alert={alert} alertStore={alertStore} silenceFormStore={silenceFormStore} + setIsMenuOpen={setIsMenuOpen} /> {alert.alertmanager .map(am => am.inhibitedBy.length) diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/index.test.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/index.test.js index 0b25cfe59..5f30902fe 100644 --- a/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/index.test.js +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/index.test.js @@ -30,6 +30,7 @@ afterEach(() => { }); const MockAfterUpdate = jest.fn(); +const MockSetIsMenuOpen = jest.fn(); const MockedAlert = () => { return MockAlert( @@ -54,6 +55,7 @@ const MountedAlert = (alert, group, showAlertmanagers, showReceiver) => { afterUpdate={MockAfterUpdate} alertStore={alertStore} silenceFormStore={silenceFormStore} + setIsMenuOpen={MockSetIsMenuOpen} /> ); diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupHeader/GroupMenu.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupHeader/GroupMenu.js index 9fd219a11..8ccba09d3 100644 --- a/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupHeader/GroupMenu.js +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupHeader/GroupMenu.js @@ -93,22 +93,29 @@ const GroupMenu = observer( group: APIGroup.isRequired, alertStore: PropTypes.instanceOf(AlertStore).isRequired, silenceFormStore: PropTypes.instanceOf(SilenceFormStore).isRequired, - themed: PropTypes.bool.isRequired + themed: PropTypes.bool.isRequired, + setIsMenuOpen: PropTypes.func.isRequired }; - collapse = observable( - { - value: true, - toggle() { - this.value = !this.value; + constructor(props) { + super(props); + + this.collapse = observable( + { + value: true, + toggle() { + this.value = !this.value; + props.setIsMenuOpen(!this.value); + }, + hide() { + this.value = true; + props.setIsMenuOpen(!this.value); + } }, - hide() { - this.value = true; - } - }, - { toggle: action.bound, hide: action.bound }, - { name: "Alert group menu toggle" } - ); + { toggle: action.bound, hide: action.bound }, + { name: "Alert group menu toggle" } + ); + } handleClickOutside = action(event => { this.collapse.hide(); diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupHeader/GroupMenu.test.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupHeader/GroupMenu.test.js index ec6288ec7..d910183d5 100644 --- a/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupHeader/GroupMenu.test.js +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupHeader/GroupMenu.test.js @@ -20,6 +20,7 @@ beforeEach(() => { }); const MockAfterClick = jest.fn(); +const MockSetIsMenuOpen = jest.fn(); const MountedGroupMenu = (group, themed) => { return mount( @@ -29,6 +30,7 @@ const MountedGroupMenu = (group, themed) => { alertStore={alertStore} silenceFormStore={silenceFormStore} themed={themed} + setIsMenuOpen={MockSetIsMenuOpen} /> ).find("GroupMenu"); diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupHeader/index.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupHeader/index.js index ede512463..caa3a0520 100644 --- a/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupHeader/index.js +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupHeader/index.js @@ -25,7 +25,8 @@ const GroupHeader = observer( group: APIGroup.isRequired, alertStore: PropTypes.instanceOf(AlertStore).isRequired, silenceFormStore: PropTypes.instanceOf(SilenceFormStore).isRequired, - themedCounters: PropTypes.bool.isRequired + themedCounters: PropTypes.bool.isRequired, + setIsMenuOpen: PropTypes.func.isRequired }; render() { @@ -34,7 +35,8 @@ const GroupHeader = observer( group, alertStore, silenceFormStore, - themedCounters + themedCounters, + setIsMenuOpen } = this.props; return ( @@ -49,6 +51,7 @@ const GroupHeader = observer( alertStore={alertStore} silenceFormStore={silenceFormStore} themed={!themedCounters} + setIsMenuOpen={setIsMenuOpen} /> diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/index.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/index.js index e952ec5ca..3e0cc34a1 100644 --- a/ui/src/Components/Grid/AlertGrid/AlertGroup/index.js +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/index.js @@ -71,9 +71,18 @@ const AlertGroup = observer( alertGroupConfig.config.defaultRenderCount ); - this.renderConfig = observable({ - alertsToRender: this.defaultRenderCount - }); + this.renderConfig = observable( + { + alertsToRender: this.defaultRenderCount, + isMenuOpen: false, + setIsMenuOpen(val) { + this.isMenuOpen = val; + } + }, + { + setIsMenuOpen: action.bound + } + ); let defaultCollapseState; switch (alertGroupConfig.config.defaultCollapseState) { @@ -194,11 +203,16 @@ const AlertGroup = observer( } } + let extraStyle = {}; + if (this.renderConfig.isMenuOpen) { + extraStyle.zIndex = 100; + } + return (
{this.collapse.value ? null : (
@@ -225,6 +240,7 @@ const AlertGroup = observer( afterUpdate={afterUpdate} alertStore={alertStore} silenceFormStore={silenceFormStore} + setIsMenuOpen={this.renderConfig.setIsMenuOpen} /> ))} {group.alerts.length > this.defaultRenderCount ? ( diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/index.test.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/index.test.js index 0581a56c0..c79616719 100644 --- a/ui/src/Components/Grid/AlertGrid/AlertGroup/index.test.js +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/index.test.js @@ -274,6 +274,50 @@ describe(" renderConfig", () => { it("clicking + icon loads 5 more alert if there's 25 in total and we're showing 16", () => { ValidateLoadButtonAction(25, 1, /fa-plus/, 22, 17); }); + + it("uses 'z-index: 100' style after setIsMenuOpen() is called on any Alert", () => { + MockAlerts(5); + const tree = MountedAlertGroup(jest.fn(), false); + const instance = tree.find("AlertGroup").instance(); + + expect(instance.renderConfig.isMenuOpen).toBe(false); + + tree + .find("Alert") + .at(0) + .props() + .setIsMenuOpen(true); + expect(instance.renderConfig.isMenuOpen).toBe(true); + tree.update(); + expect( + tree + .find(".components-grid-alertgrid-alertgroup") + .at(0) + .props().style.zIndex + ).toEqual(100); + }); + + it("uses 'z-index: 100' style after setIsMenuOpen() is called on AlertGroup header menu", () => { + MockAlerts(5); + const tree = MountedAlertGroup(jest.fn(), false); + const instance = tree.find("AlertGroup").instance(); + + expect(instance.renderConfig.isMenuOpen).toBe(false); + + tree + .find("GroupHeader") + .at(0) + .props() + .setIsMenuOpen(true); + expect(instance.renderConfig.isMenuOpen).toBe(true); + tree.update(); + expect( + tree + .find(".components-grid-alertgrid-alertgroup") + .at(0) + .props().style.zIndex + ).toEqual(100); + }); }); describe(" card theme", () => {