Skip to content

Incident groups filter bar and pagination (superseded by #34599) - #34588

Closed
ShaileshParmar11 wants to merge 8 commits into
mainfrom
ShaileshParmar11/30414-epic-task-plan
Closed

ShaileshParmar11 wants to merge 8 commits into
mainfrom
ShaileshParmar11/30414-epic-task-plan

Conversation

@ShaileshParmar11

@ShaileshParmar11 ShaileshParmar11 commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Superseded by #34599, which merged this stack as one PR.

Stacked PR 1 of 9 for epic #30414. Base: main — review only this PR's own diff; merge bottom-up.

  1. 👉 Incident groups filter bar and pagination (superseded by #34599) #34588 (issue Query controls: filter bar + pagination #30417) — ShaileshParmar11/30414-epic-task-plan
  2. Incident groups backend: related entities, drill-down parity, paging, group lookup (superseded by #34599) #34589 (issue Incident groups backend: related entities, drill-down parity, bulk severity #34549) — ShaileshParmar11/34549-incident-groups-backend
  3. Incident groups related-entity column, sub-line and table cells (superseded by #34599) #34590 (issue Groups table: related-entity column and sub-line #34550) — ShaileshParmar11/34550-related-entities-ui
  4. Incident group drawer and drill-down (superseded by #34599) #34591 (issue Drill-down view + preview drawer #30418) — ShaileshParmar11/30418-drawer-drilldown
  5. Bulk status and severity changes for incident groups (superseded by #34599) #34592 (issue Selection and bulk actions (Set status / Set severity) #30419) — ShaileshParmar11/30419-bulk-actions
  6. Grouped incidents E2E and retire the flat list (superseded by #34599) #34593 (issue Close-out: Playwright E2E + legacy listing retirement #30420) — ShaileshParmar11/30420-e2e-retire-flat-list
  7. Change an incident's status and severity from its row in a group (superseded by #34599) #34597 (issue Incident rows: change status and severity from the drawer and drill-down #34594) — ShaileshParmar11/incident-inline-actions
  8. Sort incident groups by severity and last seen (superseded by #34599) #34598 (issue Incident groups: sort by severity and last seen #34595) — ShaileshParmar11/incident-groups-sort
  9. Fixes #34616: Grouped incidents in the AI-mode incident manager #34599 (issue Incident groups: filter by severity #34596) — ShaileshParmar11/incident-groups-severity-filter

Describe your changes:

Was for #30417 — superseded by #34599

The filter row of the design above the incident groups, and paging by page number.

  • Filters: test case (debounced search), assignee (users and teams, listed on open, named by display name even after a reload), open statuses, date field and date range. They live in the query string, so links and reloads keep them.
  • Reset to page 1: any change to the filters, the dimension, the ordering or the page size starts over from page 1. A background refresh keeps the current page.
  • Paging: the pager jumps to the page picked, using the page parameter added in Incident groups backend: related entities, drill-down parity, bulk severity #34549 (the next PR in this stack), instead of stepping one page towards it.
  • Empty and error states:
    • Filters that match nothing say so and offer Clear filters.
    • A failed read offers Retry, and raises a toast only when the existing rows stay on screen.
    • The loader keeps the section's height, so the page does not jump.

Paging by page number needs page from #34549. Merge the two together.

Type of change:

  • New feature

High-level design:

  • useIncidentGroups owns the dimension, the filters (parsed from the URL, with invalid values dropped), the sort and the page. The page state is keyed on the query, so any change resets it to 1.
  • Paging is by page number, held in useIncidentGroups. The shared useIncidentPaging hook the drawer and drill-down lists use arrives with them in Incident group drawer and drill-down (superseded by #34599) #34591.
  • IncidentGroupsFilters uses the core FilterSelect and the existing DqDateRangeFilter (which gains an opt-in fullWidth). No antd.
  • Empty and error states use the core EmptyPlaceholder.

Tests:

Use cases covered

  • Filter groups by test case, assignee (user or team), status and date range; the filters survive a reload or a shared link.
  • Jump to any page, including the last; change the page size.
  • A filter that matches nothing offers Clear filters; a failed load offers Retry.

Unit tests

  • I added unit tests for the new/changed logic.
  • Files: IncidentGroupsFilters.test.tsx, IncidentGroupsView.test.tsx, IncidentGroups.utils.test.ts.
  • Coverage on the UI files this PR changes (jest --coverage, limited to this PR's files):
Statements   : 94.18% ( 389/413 )
Branches     : 90.34% ( 159/176 )
Functions    : 83.69% ( 77/92 )
Lines        : 93.88% ( 353/376 )
File                                                     | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s                                   
All files                                                |   94.18 |    90.34 |   83.69 |   93.88 |                                                     
  DqDateRangeFilter.tsx                                  |   96.29 |    91.66 |     100 |   96.15 | 71                                                  
  IncidentManagerPage.tsx                                |     100 |      100 |     100 |     100 |                                                     
  IncidentGroups.constants.ts                            |     100 |      100 |     100 |     100 |                                                     
  IncidentGroups.utils.ts                                |     100 |     98.3 |     100 |     100 | 130                                                 
  IncidentGroupsFilters.tsx                              |     100 |    96.29 |     100 |     100 | 234                                                 
  IncidentGroupsView.tsx                                 |     100 |     93.1 |     100 |     100 | 179,205                                             
  useIncidentGroups.ts                                   |     100 |    94.11 |     100 |     100 | 63                                                  
  incidentManagerAPI.ts                                  |   67.14 |    28.57 |   31.81 |   62.06 | 189-194,200-206,211-217,238-247,251,260-272,286-287 
Test Suites: 43 passed, 43 total
Tests:       461 passed, 461 total
  • incidentManagerAPI.ts: this PR only adds request param types; its uncovered lines are existing request helpers.

Backend integration tests

  • Not applicable (no backend API changes).

Ingestion integration tests

  • Not applicable (no ingestion changes).

Playwright (UI) tests

Manual testing performed

  1. Built the server from this branch and ran it on Postgres + OpenSearch, seeded with ~2,000 incidents: every status and severity, users and teams as owners and assignees, 4 domains, reopened incidents, and a year of history.
  2. Logged in as admin, switched to AI mode and opened /observability/incident-manager.
  3. Filtered by each control, reloaded, and checked the URL keeps the filters.
  4. Jumped from page 2 to page 10 and to the last page.
  5. Checked the no-match and error states in light and dark mode.

UI screen recording / screenshots:

TODO: attach a recording (opened as draft until it is added).

Checklist:

  • I have read the CONTRIBUTING document.
  • My PR title is Fixes <issue-number>: <short explanation>
  • My PR is linked to a GitHub issue via Fixes #<issue-number> above.
  • I have commented on my code, particularly in hard-to-understand areas.
  • For JSON Schema changes: I updated the migration scripts or explained why it is not needed. N/A — no JSON Schema changes.
  • For UI changes: I attached a screen recording and/or screenshots above. (TODO, see above)
  • I have added tests (unit / integration / Playwright as applicable) and listed them above.

@github-actions

github-actions Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

⚠️ UI Checkstyle passed — lint findings in changed files

🔍 ESLint findings in this PR's files — 0 error(s), 2 warning(s)

Errors block the build. Warnings do not yet — they are rules whose backlog is still
being worked down, listed so this PR does not add to it. See docs/ui-code-quality-gate.md.

0 error(s), 2 warning(s) across 2 changed file(s).

Count Rule
1 react-hooks/exhaustive-deps
1 openmetadata-ui-patterns/no-non-adaptive-palette
All findings
Location Rule Message
🟡 src/components/observability/DataQuality/Dashboard/DqDateRangeFilter.tsx:72:6 react-hooks/exhaustive-deps React Hook useEffect has a missing dependency: 'buildValue'. Either include it or remove the dependency array.
🟡 src/components/observability/IncidentManager/IncidentManagerPage.tsx:39:3 openmetadata-ui-patterns/no-non-adaptive-palette Raw palette class "tw:[&_.custom-chart-background]:bg-gray-blue-25" is static — it does not flip in dark mode. Use the theme-adapting "utility-" variant (tw:bg-

Fix locally (fast - only checks files changed in this branch):

make ui-checkstyle-changed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions

github-actions Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

❌ PR checklist incomplete

This PR cannot be merged until the following are addressed on its linked issue:

  • No GitHub issue is linked. Link an issue in the Development section of the PR (or add Fixes #12345 to the description). For a same-org cross-repo issue, add Fixes open-metadata/<repo>#123 to the description.

The fields live on the linked issue in the Shipping project (open the issue → right sidebar → Projects). After you set them, re-run this check (or push a commit) — issue/project changes do not re-trigger it automatically.

Maintainers can bypass this check by adding the skip-pr-checks label.

@github-actions

github-actions Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Jest test Coverage

UI tests summary

Lines Statements Branches Functions
Coverage: 75%
75.42% (114508/151813) 61.1% (70454/115305) 62.45% (23449/37543)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI balanced review requested due to automatic review settings October 3, 2026 12:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Add the filter row of the design above the incident groups (test case,
assignee, open statuses, date field and date range) and page the groups
on the endpoint's opaque cursors.

- Filters persist in the query string under the params the incident
  listing on the same page already reads, so one filter set drives both;
  the listing's own FilterBar is removed.
- Any change to the filters, dimension, ordering or page size starts over
  from the first page; a background refresh keeps the current page.
- Cursors are passed back verbatim as `offset`, never decoded.
- Empty and error states move to the core EmptyPlaceholder.
- DqDateRangeFilter gains an opt-in `fullWidth` so the range trigger
  spans its field like the inputs beside it.
- The pager jumps to the page picked, through the new `page` parameter,
  instead of stepping one page towards it.
- The assignee filter searches users and teams, lists them on open, and
  names a selected assignee by display name, also after a reload. The
  test case search waits for a pause in typing.
- Filters that match nothing say so and offer to clear them, instead of
  the "no active incidents" placeholder.
- A failed read offers Retry, and raises a toast only when the rows stay
  on screen.
- The loader keeps the section's height, so the page does not jump.
A background refresh that came back empty stepped back a page, but the read of that page ran in the foreground: had it failed, the rows on screen were wiped for the error state instead of staying with a toast. The step-back now reads the earlier page the way the refresh was read.
Hand the navigation back from the filter change instead of leaving it floating, test the status against its options with includes, and dedupe it with a Set.
The test case filter searched through a debounced call whose responses landed in whatever order they came back, so an older, slower search could replace the results of a newer one. The search now runs as one query per debounced text, as the assignee picker does, and closing the menu drops the pending text. Each filter caption now labels the group its control sits in, so a trigger that shows only the picked value is still announced with its field.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@gitar-bot

gitar-bot Bot commented Oct 4, 2026

Copy link
Copy Markdown
Code Review ✅ Approved 2 closed / 2 findings

🟡 Medium risk · Incident filtering and page-number navigation change UI requests and shared controls.

Adds incident groups filter bar with debounced test case search, assignee selection, status filtering, and date range; implements page-number-based pagination with automatic reset to page 1 on filter changes. Resolves background refresh on empty result and step-back behavior; comprehensive unit tests cover filters, paging, empty and error states with 94% statement coverage. No issues found.

✅ 2 closed
✅ Edge Case: Refresh past the last page shows 'No active incidents' with no pager

📄 openmetadata-ui/src/main/resources/ui/src/components/observability/IncidentManager/IncidentGroups/useIncidentGroups.ts:110-117 📄 openmetadata-ui/src/main/resources/ui/src/components/observability/IncidentManager/IncidentGroups/useIncidentGroups.ts:179-181 📄 openmetadata-ui/src/main/resources/ui/src/components/observability/IncidentManager/IncidentGroups/IncidentGroupsView.tsx:128-142
A background refresh deliberately keeps currentPage, and refreshKey gets bumped whenever an incident in the table below changes status. Here is how that goes wrong: a user is on the last page, which holds only a few groups, and resolves those incidents. The refetch then asks for a page beyond the new total and gets data: []. IncidentGroupsView treats any empty page as having no groups at all. It shows the 'No active incidents' placeholder (or 'No match found' when filters are set) and drops the pager, so the user cannot get back to the earlier pages even though open groups still exist.

Fix: after a response lands, if data is empty, currentPage > 1 and paging.total > 0, clamp to the last valid page (computeTotalPages(pageSize, total)) and refetch. Another option is to base the empty states on paging.total === 0 instead of an empty page.

✅ Edge Case: Step-back after empty refresh reloads in the foreground, not background

📄 openmetadata-ui/src/main/resources/ui/src/components/observability/IncidentManager/IncidentGroups/useIncidentGroups.ts:146-150 📄 openmetadata-ui/src/main/resources/ui/src/components/observability/IncidentManager/IncidentGroups/useIncidentGroups.ts:183-193
Say a background refresh (new refreshKey) comes back empty on page N>1. The hook calls setPage and returns, but fetchedRefreshKey.current was already set to the new key at line 150. On the re-fetch for the earlier page, fetchedRefreshKey.current === refreshKey, so isBackground is false. The loader then replaces the rows the user was reading, and if that read fails the rows are wiped for the error placeholder with no toast. That breaks the hook's documented rule that a refresh keeps the rows on screen until the new ones land. One fix is to record that the step-back belongs to a background read, so the follow-up fetch keeps that status.

Review coverage

📋 Rules No rules evaluated

🧪 Functional validation Not enabled · Set up

🤖 Auto-approval Not enabled · Set up

Options

Display: compact → Counting what did not apply, without listing it.

Comment with these commands to change the behavior for this request:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Powered by Gitar — free for open source

@sonarqubecloud

sonarqubecloud Bot commented Oct 4, 2026

Copy link
Copy Markdown

@ShaileshParmar11

Copy link
Copy Markdown
Contributor Author

Combined into #34599, which carries the whole grouped incident manager (backend and frontend) as one PR against main. Its content is this stack's, rebased on main, plus fixes for the two open review findings and the standard page sizes.

This branch was previously deployed

1 inactive deployment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

safe to test Add this label to run secure Github workflows on PRs UI UI specific issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants