Skip to content

Commit d5e39b5

Browse files
kibanamachineabhishekbhatia1710jaredburgettelastic
authored
[9.4] [Entity Analytics][UI][Leads Generation] Match UI design with latest mocks (elastic#262457) (elastic#263949)
# Backport This will backport the following commits from `main` to `9.4`: - [[Entity Analytics][UI][Leads Generation] Match UI design with latest mocks (elastic#262457)](elastic#262457) <!--- Backport version: 9.6.6 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport) <!--BACKPORT [{"author":{"name":"Abhishek Bhatia","email":"117628830+abhishekbhatia1710@users.noreply.github.com"},"sourceCommit":{"committedDate":"2026-04-17T05:41:54Z","message":"[Entity Analytics][UI][Leads Generation] Match UI design with latest mocks (elastic#262457)\n\n## Summary\n\nThis PR includes changes related to UI and related backend components\nfor the leads generation.\n\n\n- Landing panel when there are no leads.\n\n<img width=\"1664\" height=\"402\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/3357fe98-3700-4a04-a750-d23e95bd21c8\"\n/>\n\n- Loading panel\n<img width=\"828\" height=\"120\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/595fd342-0411-40ee-ad2f-ff1de920dc2d\"\n/>\n\n- No data found panel\n<img width=\"1659\" height=\"476\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/1f2d3293-491a-4cbc-abf5-6392e6c515e4\"\n/>\n\n\n1. Addition of Tech preview (flask), text `Generated by AI`, using the\nnew `AiButton` and the `ellipsis` which contains the toggle for\nauto-refreshing the leads generation every 24 hours for now.\n\n<img width=\"1660\" height=\"365\" alt=\"Screenshot 2026-04-10 at 1 55 55 PM\"\nsrc=\"https://github.com/user-attachments/assets/0de37838-03cf-4edd-8946-2d4c06e853bb\"\n/>\n\n\nWith ellipsis option :\n\n<img width=\"1663\" height=\"379\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/7a057614-fab8-49b4-98fe-c63f308d3954\"\n/>\n\n\n2. Adding `tags` in the popover for the lead cards and the flyout which\nshows all the labels associated with the leads generated.\n\n\n<img width=\"1657\" height=\"422\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/3fa9daf9-f876-4138-96fd-a4348afed42e\"\n/>\n\n\n4. Improved the \"See All\" flyout to have description and similar\nbehavior as the main UI lead cards with the similar popover.\n\n\n<img width=\"953\" height=\"827\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/529003ce-d93a-4dbd-9aaf-c1dbf61dd8cd\"\n/>\n\n\n6. Improved error handling for the leads generation. The errors are\nthrown and caught and shown on the UI as :\n\n<img width=\"1019\" height=\"546\" alt=\"Screenshot 2026-04-10 at 1 37 57 PM\"\nsrc=\"https://github.com/user-attachments/assets/6559879b-5e3e-4b76-ad8d-f222a58848a4\"\n/>\n\n7. \"See All\" is changed to \"Recent Leads\". The border is just to\nhighlight the screenshot, it is not present in the code.\n<img width=\"1655\" height=\"365\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/46bcaafe-f638-479d-b6e9-0fcec472ae30\"\n/>\n\n8. Pagination is removed from the \"Recent Leads\" flyout.\n<img width=\"957\" height=\"833\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/928175ae-3964-4493-a283-d3c2bd1cecab\"\n/>\n\n9. The overflowing of the lead cards when the viewport is shrinked is\nfixed as well\n\n\nhttps://github.com/user-attachments/assets/7c42cc90-61e3-4c97-80a9-b19ec6a069dd\n\n10. Tech preview tooltip.\n<img width=\"1668\" height=\"180\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/f09f63e2-8431-42d7-94f1-be11b92a1cd9\"\n/>\n\n\n\n### Checklist\n\nCheck the PR satisfies following conditions. \n\nReviewers should verify this PR satisfies this list as well.\n\n- [ ] Any text added follows [EUI's writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing), uses\nsentence case text and includes [i18n\nsupport](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)\n- [ ] The PR description includes the appropriate Release Notes section,\nand the correct `release_note:*` label is applied per the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n- [ ] Review the [backport\nguidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing)\nand apply applicable `backport:*` labels.\n\n---------\n\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>\nCo-authored-by: Jared Burgett <147995946+jaredburgettelastic@users.noreply.github.com>","sha":"0c362af632555885f689987d14051a37c2f7f004","branchLabelMapping":{"^v9.5.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:Entity Analytics","backport:version","v9.4.0","v9.5.0"],"title":"[Entity Analytics][UI][Leads Generation] Match UI design with latest mocks","number":262457,"url":"https://github.com/elastic/kibana/pull/262457","mergeCommit":{"message":"[Entity Analytics][UI][Leads Generation] Match UI design with latest mocks (elastic#262457)\n\n## Summary\n\nThis PR includes changes related to UI and related backend components\nfor the leads generation.\n\n\n- Landing panel when there are no leads.\n\n<img width=\"1664\" height=\"402\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/3357fe98-3700-4a04-a750-d23e95bd21c8\"\n/>\n\n- Loading panel\n<img width=\"828\" height=\"120\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/595fd342-0411-40ee-ad2f-ff1de920dc2d\"\n/>\n\n- No data found panel\n<img width=\"1659\" height=\"476\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/1f2d3293-491a-4cbc-abf5-6392e6c515e4\"\n/>\n\n\n1. Addition of Tech preview (flask), text `Generated by AI`, using the\nnew `AiButton` and the `ellipsis` which contains the toggle for\nauto-refreshing the leads generation every 24 hours for now.\n\n<img width=\"1660\" height=\"365\" alt=\"Screenshot 2026-04-10 at 1 55 55 PM\"\nsrc=\"https://github.com/user-attachments/assets/0de37838-03cf-4edd-8946-2d4c06e853bb\"\n/>\n\n\nWith ellipsis option :\n\n<img width=\"1663\" height=\"379\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/7a057614-fab8-49b4-98fe-c63f308d3954\"\n/>\n\n\n2. Adding `tags` in the popover for the lead cards and the flyout which\nshows all the labels associated with the leads generated.\n\n\n<img width=\"1657\" height=\"422\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/3fa9daf9-f876-4138-96fd-a4348afed42e\"\n/>\n\n\n4. Improved the \"See All\" flyout to have description and similar\nbehavior as the main UI lead cards with the similar popover.\n\n\n<img width=\"953\" height=\"827\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/529003ce-d93a-4dbd-9aaf-c1dbf61dd8cd\"\n/>\n\n\n6. Improved error handling for the leads generation. The errors are\nthrown and caught and shown on the UI as :\n\n<img width=\"1019\" height=\"546\" alt=\"Screenshot 2026-04-10 at 1 37 57 PM\"\nsrc=\"https://github.com/user-attachments/assets/6559879b-5e3e-4b76-ad8d-f222a58848a4\"\n/>\n\n7. \"See All\" is changed to \"Recent Leads\". The border is just to\nhighlight the screenshot, it is not present in the code.\n<img width=\"1655\" height=\"365\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/46bcaafe-f638-479d-b6e9-0fcec472ae30\"\n/>\n\n8. Pagination is removed from the \"Recent Leads\" flyout.\n<img width=\"957\" height=\"833\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/928175ae-3964-4493-a283-d3c2bd1cecab\"\n/>\n\n9. The overflowing of the lead cards when the viewport is shrinked is\nfixed as well\n\n\nhttps://github.com/user-attachments/assets/7c42cc90-61e3-4c97-80a9-b19ec6a069dd\n\n10. Tech preview tooltip.\n<img width=\"1668\" height=\"180\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/f09f63e2-8431-42d7-94f1-be11b92a1cd9\"\n/>\n\n\n\n### Checklist\n\nCheck the PR satisfies following conditions. \n\nReviewers should verify this PR satisfies this list as well.\n\n- [ ] Any text added follows [EUI's writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing), uses\nsentence case text and includes [i18n\nsupport](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)\n- [ ] The PR description includes the appropriate Release Notes section,\nand the correct `release_note:*` label is applied per the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n- [ ] Review the [backport\nguidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing)\nand apply applicable `backport:*` labels.\n\n---------\n\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>\nCo-authored-by: Jared Burgett <147995946+jaredburgettelastic@users.noreply.github.com>","sha":"0c362af632555885f689987d14051a37c2f7f004"}},"sourceBranch":"main","suggestedTargetBranches":["9.4"],"targetPullRequestStates":[{"branch":"9.4","label":"v9.4.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v9.5.0","branchLabelMappingKey":"^v9.5.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/262457","number":262457,"mergeCommit":{"message":"[Entity Analytics][UI][Leads Generation] Match UI design with latest mocks (elastic#262457)\n\n## Summary\n\nThis PR includes changes related to UI and related backend components\nfor the leads generation.\n\n\n- Landing panel when there are no leads.\n\n<img width=\"1664\" height=\"402\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/3357fe98-3700-4a04-a750-d23e95bd21c8\"\n/>\n\n- Loading panel\n<img width=\"828\" height=\"120\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/595fd342-0411-40ee-ad2f-ff1de920dc2d\"\n/>\n\n- No data found panel\n<img width=\"1659\" height=\"476\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/1f2d3293-491a-4cbc-abf5-6392e6c515e4\"\n/>\n\n\n1. Addition of Tech preview (flask), text `Generated by AI`, using the\nnew `AiButton` and the `ellipsis` which contains the toggle for\nauto-refreshing the leads generation every 24 hours for now.\n\n<img width=\"1660\" height=\"365\" alt=\"Screenshot 2026-04-10 at 1 55 55 PM\"\nsrc=\"https://github.com/user-attachments/assets/0de37838-03cf-4edd-8946-2d4c06e853bb\"\n/>\n\n\nWith ellipsis option :\n\n<img width=\"1663\" height=\"379\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/7a057614-fab8-49b4-98fe-c63f308d3954\"\n/>\n\n\n2. Adding `tags` in the popover for the lead cards and the flyout which\nshows all the labels associated with the leads generated.\n\n\n<img width=\"1657\" height=\"422\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/3fa9daf9-f876-4138-96fd-a4348afed42e\"\n/>\n\n\n4. Improved the \"See All\" flyout to have description and similar\nbehavior as the main UI lead cards with the similar popover.\n\n\n<img width=\"953\" height=\"827\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/529003ce-d93a-4dbd-9aaf-c1dbf61dd8cd\"\n/>\n\n\n6. Improved error handling for the leads generation. The errors are\nthrown and caught and shown on the UI as :\n\n<img width=\"1019\" height=\"546\" alt=\"Screenshot 2026-04-10 at 1 37 57 PM\"\nsrc=\"https://github.com/user-attachments/assets/6559879b-5e3e-4b76-ad8d-f222a58848a4\"\n/>\n\n7. \"See All\" is changed to \"Recent Leads\". The border is just to\nhighlight the screenshot, it is not present in the code.\n<img width=\"1655\" height=\"365\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/46bcaafe-f638-479d-b6e9-0fcec472ae30\"\n/>\n\n8. Pagination is removed from the \"Recent Leads\" flyout.\n<img width=\"957\" height=\"833\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/928175ae-3964-4493-a283-d3c2bd1cecab\"\n/>\n\n9. The overflowing of the lead cards when the viewport is shrinked is\nfixed as well\n\n\nhttps://github.com/user-attachments/assets/7c42cc90-61e3-4c97-80a9-b19ec6a069dd\n\n10. Tech preview tooltip.\n<img width=\"1668\" height=\"180\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/f09f63e2-8431-42d7-94f1-be11b92a1cd9\"\n/>\n\n\n\n### Checklist\n\nCheck the PR satisfies following conditions. \n\nReviewers should verify this PR satisfies this list as well.\n\n- [ ] Any text added follows [EUI's writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing), uses\nsentence case text and includes [i18n\nsupport](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)\n- [ ] The PR description includes the appropriate Release Notes section,\nand the correct `release_note:*` label is applied per the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n- [ ] Review the [backport\nguidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing)\nand apply applicable `backport:*` labels.\n\n---------\n\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>\nCo-authored-by: Jared Burgett <147995946+jaredburgettelastic@users.noreply.github.com>","sha":"0c362af632555885f689987d14051a37c2f7f004"}}]}] BACKPORT--> Co-authored-by: Abhishek Bhatia <117628830+abhishekbhatia1710@users.noreply.github.com> Co-authored-by: Jared Burgett <147995946+jaredburgettelastic@users.noreply.github.com>
1 parent c4a0d58 commit d5e39b5

20 files changed

Lines changed: 694 additions & 292 deletions

File tree

Lines changed: 33 additions & 0 deletions
Loading

x-pack/solutions/security/plugins/security_solution/public/entity_analytics/components/threat_hunting/top_threat_hunting_leads/index.test.tsx

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ const defaultProps = {
4545
totalCount: 0,
4646
isLoading: false,
4747
isGenerating: false,
48+
isScheduled: false,
49+
onToggleSchedule: jest.fn(),
4850
onSeeAll: jest.fn(),
4951
onLeadClick: jest.fn(),
5052
onHuntInChat: jest.fn(),
@@ -92,7 +94,11 @@ describe('TopThreatHuntingLeads', () => {
9294

9395
expect(screen.getByTestId('topThreatHuntingLeads')).toBeInTheDocument();
9496
expect(screen.getByTestId('leadsEmptyPrompt')).toBeInTheDocument();
95-
expect(screen.getByText('No hunting leads yet')).toBeInTheDocument();
97+
expect(
98+
screen.getByText(
99+
'Generate leads to surface proactive threat hunting opportunities from your entity data.'
100+
)
101+
).toBeInTheDocument();
96102
expect(screen.queryByTestId('leadsLoadingSpinner')).not.toBeInTheDocument();
97103
});
98104

@@ -124,20 +130,67 @@ describe('TopThreatHuntingLeads', () => {
124130
expect(onSeeAll).toHaveBeenCalledTimes(1);
125131
});
126132

127-
it('"Generate" button calls onGenerate with loading state when isGenerating', () => {
133+
it('shows "Generate" button when no leads exist and calls onGenerate', () => {
128134
const onGenerate = jest.fn();
129135

130-
const { rerender } = render(
131-
<TopThreatHuntingLeads {...defaultProps} onGenerate={onGenerate} />
136+
render(<TopThreatHuntingLeads {...defaultProps} onGenerate={onGenerate} />);
137+
138+
const generateButton = screen.getByTestId('generateLeadsButton');
139+
expect(generateButton).toBeInTheDocument();
140+
expect(screen.queryByTestId('refreshLeadsButton')).not.toBeInTheDocument();
141+
142+
fireEvent.click(generateButton);
143+
expect(onGenerate).toHaveBeenCalledTimes(1);
144+
});
145+
146+
it('keeps "Generate" button when generation produced no leads', () => {
147+
render(<TopThreatHuntingLeads {...defaultProps} hasGenerated />);
148+
149+
expect(screen.getByTestId('generateLeadsButton')).toBeInTheDocument();
150+
expect(screen.queryByTestId('refreshLeadsButton')).not.toBeInTheDocument();
151+
});
152+
153+
it('shows refresh button instead of "Generate" button when leads exist', () => {
154+
const onGenerate = jest.fn();
155+
const lead = createMockLead();
156+
157+
render(
158+
<TopThreatHuntingLeads
159+
{...defaultProps}
160+
leads={[lead]}
161+
totalCount={1}
162+
hasGenerated
163+
onGenerate={onGenerate}
164+
/>
132165
);
133166

134-
fireEvent.click(screen.getByTestId('generateLeadsButton'));
167+
expect(screen.queryByTestId('generateLeadsButton')).not.toBeInTheDocument();
168+
const refreshButton = screen.getByTestId('refreshLeadsButton');
169+
expect(refreshButton).toBeInTheDocument();
170+
171+
fireEvent.click(refreshButton);
135172
expect(onGenerate).toHaveBeenCalledTimes(1);
173+
});
136174

137-
rerender(<TopThreatHuntingLeads {...defaultProps} onGenerate={onGenerate} isGenerating />);
175+
it('displays generated timestamp when leads exist and lastRunTimestamp is provided', () => {
176+
const lead = createMockLead();
138177

139-
const generateButton = screen.getByTestId('generateLeadsButton');
140-
expect(generateButton).toHaveTextContent('Generating...');
178+
render(
179+
<TopThreatHuntingLeads
180+
{...defaultProps}
181+
leads={[lead]}
182+
totalCount={1}
183+
lastRunTimestamp="2026-03-13T14:30:00.000Z"
184+
/>
185+
);
186+
187+
expect(screen.getByTestId('leadsGeneratedTimestamp')).toBeInTheDocument();
188+
});
189+
190+
it('does not display timestamp when no leads exist', () => {
191+
render(<TopThreatHuntingLeads {...defaultProps} lastRunTimestamp="2026-03-13T14:30:00.000Z" />);
192+
193+
expect(screen.queryByTestId('leadsGeneratedTimestamp')).not.toBeInTheDocument();
141194
});
142195

143196
it('lead card click calls onLeadClick', () => {

0 commit comments

Comments
 (0)