mirror of
https://github.com/prymitive/karma
synced 2026-05-07 03:26:52 +00:00
fix(ui): fix alert menu content being under other alert groups
Because every alert group uses 'position: absolute' our menu content rendered after clicking on group header or each alert dropdown is hidden under neighbour groups. To fix this we'll add 'z-index: 100' to the group with currently open menu.
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
</Provider>
|
||||
).find("AlertMenu");
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
</Provider>
|
||||
);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
</Provider>
|
||||
).find("GroupMenu");
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
</span>
|
||||
<span className="flex-shrink-1 flex-grow-1" style={{ minWidth: 0 }}>
|
||||
|
||||
@@ -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 (
|
||||
<MountFade in={true}>
|
||||
<div
|
||||
className="components-grid-alertgrid-alertgroup p-1"
|
||||
style={style}
|
||||
style={{ ...style, ...extraStyle }}
|
||||
>
|
||||
<div className={`card ${cardBackgroundClass}`}>
|
||||
<GroupHeader
|
||||
@@ -207,6 +221,7 @@ const AlertGroup = observer(
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
themedCounters={themedCounters}
|
||||
setIsMenuOpen={this.renderConfig.setIsMenuOpen}
|
||||
/>
|
||||
{this.collapse.value ? null : (
|
||||
<div className="card-body bg-white px-2 py-1">
|
||||
@@ -225,6 +240,7 @@ const AlertGroup = observer(
|
||||
afterUpdate={afterUpdate}
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
setIsMenuOpen={this.renderConfig.setIsMenuOpen}
|
||||
/>
|
||||
))}
|
||||
{group.alerts.length > this.defaultRenderCount ? (
|
||||
|
||||
@@ -274,6 +274,50 @@ describe("<AlertGroup /> 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("<AlertGroup /> card theme", () => {
|
||||
|
||||
Reference in New Issue
Block a user