Skip to content

Commit

Permalink
[8.x] [ResponseOps][Alerts] Don't show empty state in grouping c…
Browse files Browse the repository at this point in the history
…omponent while first loading (#195777) (#196106)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[ResponseOps][Alerts] Don't show empty state in grouping
component while first loading
(#195777)](#195777)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https:/sqren/backport)

<!--BACKPORT [{"author":{"name":"Umberto
Pepato","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-10-14T10:50:55Z","message":"[ResponseOps][Alerts]
Don't show empty state in grouping component while first loading
(#195777)\n\n## Summary\r\n\r\nMakes the loading state and empty state
mutually exclusive in the\r\ngrouping component to avoid showing the
empty state when first loading\r\nthe groups data.\r\n\r\n## To
verify\r\n\r\n1. Create one or more O11y rules that fire alerts\r\n2.
Open the O11y > Alerts page\r\n3. Toggle on grouping\r\n4. Reload the
page (possibly after activating network throttling)\r\n5. Verify that
while the loading indicator is shown, the empty state is\r\nnot and
viceversa\r\n\r\n## References\r\n\r\nFixes
#190954","sha":"45a9cf0e343e6c4045834968fa27f6f468cdf3e3","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:ResponseOps","v9.0.0","backport:prev-major"],"title":"[ResponseOps][Alerts]
Don't show empty state in grouping component while first
loading","number":195777,"url":"https:/elastic/kibana/pull/195777","mergeCommit":{"message":"[ResponseOps][Alerts]
Don't show empty state in grouping component while first loading
(#195777)\n\n## Summary\r\n\r\nMakes the loading state and empty state
mutually exclusive in the\r\ngrouping component to avoid showing the
empty state when first loading\r\nthe groups data.\r\n\r\n## To
verify\r\n\r\n1. Create one or more O11y rules that fire alerts\r\n2.
Open the O11y > Alerts page\r\n3. Toggle on grouping\r\n4. Reload the
page (possibly after activating network throttling)\r\n5. Verify that
while the loading indicator is shown, the empty state is\r\nnot and
viceversa\r\n\r\n## References\r\n\r\nFixes
#190954","sha":"45a9cf0e343e6c4045834968fa27f6f468cdf3e3"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https:/elastic/kibana/pull/195777","number":195777,"mergeCommit":{"message":"[ResponseOps][Alerts]
Don't show empty state in grouping component while first loading
(#195777)\n\n## Summary\r\n\r\nMakes the loading state and empty state
mutually exclusive in the\r\ngrouping component to avoid showing the
empty state when first loading\r\nthe groups data.\r\n\r\n## To
verify\r\n\r\n1. Create one or more O11y rules that fire alerts\r\n2.
Open the O11y > Alerts page\r\n3. Toggle on grouping\r\n4. Reload the
page (possibly after activating network throttling)\r\n5. Verify that
while the loading indicator is shown, the empty state is\r\nnot and
viceversa\r\n\r\n## References\r\n\r\nFixes
#190954","sha":"45a9cf0e343e6c4045834968fa27f6f468cdf3e3"}}]}]
BACKPORT-->

Co-authored-by: Umberto Pepato <[email protected]>
  • Loading branch information
kibanamachine and umbopepato authored Oct 14, 2024
1 parent e3d015b commit 30357d6
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 34 deletions.
73 changes: 42 additions & 31 deletions packages/kbn-grouping/src/components/grouping.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,52 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { fireEvent, render, within } from '@testing-library/react';
import { fireEvent, render, within, screen } from '@testing-library/react';
import React from 'react';
import { I18nProvider } from '@kbn/i18n-react';
import { Grouping } from './grouping';
import { Grouping, GroupingProps } from './grouping';
import { createGroupFilter, getNullGroupFilter } from '../containers/query/helpers';
import { METRIC_TYPE } from '@kbn/analytics';
import { getTelemetryEvent } from '../telemetry/const';

import { mockGroupingProps, host1Name, host2Name } from './grouping.mock';
import { SetRequired } from 'type-fest';

const renderChildComponent = jest.fn();
const takeActionItems = jest.fn();
const mockTracker = jest.fn();

const testProps = {
const testProps: SetRequired<GroupingProps<{}>, 'data'> = {
...mockGroupingProps,
renderChildComponent,
takeActionItems,
tracker: mockTracker,
};

describe('grouping container', () => {
describe('Grouping', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('Renders groups count when groupsCount > 0', () => {
const { getByTestId, getAllByTestId, queryByTestId } = render(
render(
<I18nProvider>
<Grouping {...testProps} />
</I18nProvider>
);
expect(getByTestId('unit-count').textContent).toBe('14 events');
expect(getByTestId('group-count').textContent).toBe('3 groups');
expect(getAllByTestId('grouping-accordion').length).toBe(3);
expect(queryByTestId('empty-results-panel')).not.toBeInTheDocument();
expect(screen.getByTestId('unit-count').textContent).toBe('14 events');
expect(screen.getByTestId('group-count').textContent).toBe('3 groups');
expect(screen.getAllByTestId('grouping-accordion').length).toBe(3);
expect(screen.queryByTestId('empty-results-panel')).not.toBeInTheDocument();
});

it('Does not render empty state while loading', () => {
render(
<I18nProvider>
<Grouping {...testProps} isLoading />
</I18nProvider>
);
expect(screen.queryByTestId('empty-results-panel')).not.toBeInTheDocument();
});

it('Does not render group counts when groupsCount = 0', () => {
Expand All @@ -58,25 +69,25 @@ describe('grouping container', () => {
value: 0,
},
};
const { getByTestId, queryByTestId } = render(
render(
<I18nProvider>
<Grouping {...testProps} data={data} />
</I18nProvider>
);
expect(queryByTestId('unit-count')).not.toBeInTheDocument();
expect(queryByTestId('group-count')).not.toBeInTheDocument();
expect(queryByTestId('grouping-accordion')).not.toBeInTheDocument();
expect(getByTestId('empty-results-panel')).toBeInTheDocument();
expect(screen.queryByTestId('unit-count')).not.toBeInTheDocument();
expect(screen.queryByTestId('group-count')).not.toBeInTheDocument();
expect(screen.queryByTestId('grouping-accordion')).not.toBeInTheDocument();
expect(screen.getByTestId('empty-results-panel')).toBeInTheDocument();
});

it('Opens one group at a time when each group is clicked', () => {
const { getAllByTestId } = render(
render(
<I18nProvider>
<Grouping {...testProps} />
</I18nProvider>
);
const group1 = within(getAllByTestId('grouping-accordion')[0]).getAllByRole('button')[0];
const group2 = within(getAllByTestId('grouping-accordion')[1]).getAllByRole('button')[0];
const group1 = within(screen.getAllByTestId('grouping-accordion')[0]).getAllByRole('button')[0];
const group2 = within(screen.getAllByTestId('grouping-accordion')[1]).getAllByRole('button')[0];
fireEvent.click(group1);
expect(renderChildComponent).toHaveBeenNthCalledWith(
1,
Expand All @@ -90,12 +101,12 @@ describe('grouping container', () => {
});

it('Send Telemetry when each group is clicked', () => {
const { getAllByTestId } = render(
render(
<I18nProvider>
<Grouping {...testProps} />
</I18nProvider>
);
const group1 = within(getAllByTestId('grouping-accordion')[0]).getAllByRole('button')[0];
const group1 = within(screen.getAllByTestId('grouping-accordion')[0]).getAllByRole('button')[0];
fireEvent.click(group1);
expect(mockTracker).toHaveBeenNthCalledWith(
1,
Expand All @@ -120,19 +131,19 @@ describe('grouping container', () => {

it('Renders a null group and passes the correct filter to take actions and child component', () => {
takeActionItems.mockReturnValue([<span />]);
const { getAllByTestId, getByTestId } = render(
render(
<I18nProvider>
<Grouping {...testProps} />
</I18nProvider>
);
expect(getByTestId('null-group-icon')).toBeInTheDocument();
expect(screen.getByTestId('null-group-icon')).toBeInTheDocument();

let lastGroup = getAllByTestId('grouping-accordion').at(-1);
let lastGroup = screen.getAllByTestId('grouping-accordion').at(-1);
fireEvent.click(within(lastGroup!).getByTestId('take-action-button'));

expect(takeActionItems).toHaveBeenCalledWith(getNullGroupFilter('host.name'), 2);

lastGroup = getAllByTestId('grouping-accordion').at(-1);
lastGroup = screen.getAllByTestId('grouping-accordion').at(-1);
fireEvent.click(within(lastGroup!).getByTestId('group-panel-toggle'));

expect(renderChildComponent).toHaveBeenCalledWith(getNullGroupFilter('host.name'));
Expand All @@ -149,23 +160,23 @@ describe('grouping container', () => {
expect(groupPanelRenderer).toHaveBeenNthCalledWith(
1,
'host.name',
testProps.data.groupByFields.buckets[0],
testProps.data.groupByFields!.buckets![0],
undefined,
false
);

expect(groupPanelRenderer).toHaveBeenNthCalledWith(
2,
'host.name',
testProps.data.groupByFields.buckets[1],
testProps.data.groupByFields!.buckets![1],
undefined,
false
);

expect(groupPanelRenderer).toHaveBeenNthCalledWith(
3,
'host.name',
testProps.data.groupByFields.buckets[2],
testProps.data.groupByFields!.buckets![2],
'The selected group by field, host.name, is missing a value for this group of events.',
false
);
Expand All @@ -181,20 +192,20 @@ describe('grouping container', () => {
expect(groupPanelRenderer).toHaveBeenNthCalledWith(
1,
'host.name',
testProps.data.groupByFields.buckets[0],
testProps.data.groupByFields!.buckets![0],
undefined,
true
);
});

describe('groupsUnit', () => {
it('renders default groupsUnit text correctly', () => {
const { getByTestId } = render(
render(
<I18nProvider>
<Grouping {...testProps} />
</I18nProvider>
);
expect(getByTestId('group-count').textContent).toBe('3 groups');
expect(screen.getByTestId('group-count').textContent).toBe('3 groups');
});
it('calls custom groupsUnit callback correctly', () => {
// Provide a custom groupsUnit function in testProps
Expand All @@ -203,14 +214,14 @@ describe('grouping container', () => {
);
const customProps = { ...testProps, groupsUnit: customGroupsUnit };

const { getByTestId } = render(
render(
<I18nProvider>
<Grouping {...customProps} />
</I18nProvider>
);

expect(customGroupsUnit).toHaveBeenCalledWith(3, testProps.selectedGroup, true);
expect(getByTestId('group-count').textContent).toBe('3 custom units');
expect(screen.getByTestId('group-count').textContent).toBe('3 custom units');
});
});
});
5 changes: 2 additions & 3 deletions packages/kbn-grouping/src/components/grouping.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,9 @@ const GroupingComponent = <T,>({
css={groupingLevel > 0 ? groupingContainerCssLevel : groupingContainerCss}
className="eui-xScroll"
>
{isLoading && (
{isLoading ? (
<EuiProgress data-test-subj="is-loading-grouping-table" size="xs" color="accent" />
)}
{groupCount > 0 ? (
) : groupCount > 0 ? (
<span data-test-subj={`grouping-level-${groupingLevel}`}>
{groupPanels}
{groupCount > 0 && (
Expand Down

0 comments on commit 30357d6

Please sign in to comment.