Repository navigation
Fixes 34616: Grouped incidents release-testing fixes (sort in URL, status menu, translations) - #36397
Conversation
…tions - Keep the grouped view's sort in the URL as sortField/sortType so a reload or a shared link keeps the order. - Offer only the transitions TestCaseResolutionTaskWorkflow allows in the inline status menu: an Assigned incident can be reassigned or resolved. - Use plural keys for the group row counts and status mix, translated in every locale, and show severities as the translated label with its level.
…ox and status modal
- Bulk status changes now skip any incident whose stage has no edge for the new status, using the same INCIDENT_STATUS_MENU_OPTIONS map as the inline menu and the status modal. - One replaceSearch helper writes the group-by, filter and sort params. Group-by changes now also stringify with arrayFormat: 'repeat', so array filters keep round-tripping as repeated params. - Cover the independent field/direction fallback of parseIncidentGroupSort, add a Playwright test for the sort surviving a reload, query the popover Back button by test id, and correct the decision record.
🔄 Playwright impact map auto-refreshedThis PR touched specs or UI source that changed the source→spec routing map. I regenerated What is this file? It is the auto-generated half of Playwright's PR planner. It routes "if source X changes, run specs Y" by walking spec imports and cross-referencing What if I want to regenerate locally instead? Run this before pushing your next change to skip the bot commit: python3 .github/scripts/generate_playwright_impact_map.py
git add .github/playwright/impact-map.generated.json
git commit --amend --no-edit # or a separate commit |
|
| Count | Rule |
|---|---|
| 4 | openmetadata-imports/no-lower-layer-page-imports |
| 3 | react-hooks/exhaustive-deps |
| 2 | openmetadata-imports/review-sequential-api-calls |
All findings
| Location | Rule | Message | |
|---|---|---|---|
| 🟡 | src/components/DataQuality/IncidentManager/Severity/Severity.component.tsx:59:5 |
react-hooks/exhaustive-deps |
React Hook useCallback has a missing dependency: 'onCancel'. Either include it or remove the dependency array. |
| 🟡 | src/components/DataQuality/IncidentManager/TestCaseStatus/InlineTestCaseIncidentStatus.component.tsx:40:1 |
openmetadata-imports/no-lower-layer-page-imports |
Pages are route-level composition modules. Move the shared implementation/type to a lower layer instead of importing a page from here. |
| 🟡 | src/components/DataQuality/IncidentManager/TestCaseStatus/InlineTestCaseIncidentStatus.component.tsx:299:27 |
openmetadata-imports/review-sequential-api-calls |
Review these sequential API requests. If they are independent, start them together with Promise.all/Promise.allSettled; keep sequencing only when data-dependent |
| 🟡 | src/components/DataQuality/TestCaseStatusModal/TestCaseStatusModal.component.tsx:31:1 |
openmetadata-imports/no-lower-layer-page-imports |
Pages are route-level composition modules. Move the shared implementation/type to a lower layer instead of importing a page from here. |
| 🟡 | src/components/DataQuality/TestCaseStatusModal/TestCaseStatusModal.component.tsx:32:1 |
openmetadata-imports/no-lower-layer-page-imports |
Pages are route-level composition modules. Move the shared implementation/type to a lower layer instead of importing a page from here. |
| 🟡 | src/components/DataQuality/TestCaseStatusModal/TestCaseStatusModal.component.tsx:242:25 |
openmetadata-imports/review-sequential-api-calls |
Review these sequential API requests. If they are independent, start them together with Promise.all/Promise.allSettled; keep sequencing only when data-dependent |
| 🟡 | src/components/DataQuality/TestCaseStatusModal/TestCaseStatusModal.component.tsx:275:6 |
react-hooks/exhaustive-deps |
React Hook useEffect has a missing dependency: 'fetchInitialAssign'. Either include it or remove the dependency array. |
| 🟡 | src/components/DataQuality/TestCaseStatusModal/TestCaseStatusModal.component.tsx:290:6 |
react-hooks/exhaustive-deps |
React Hook useEffect has a missing dependency: 'form'. Either include it or remove the dependency array. |
| 🟡 | src/constants/TestSuite.constant.ts:16:1 |
openmetadata-imports/no-lower-layer-page-imports |
Pages are route-level composition modules. Move the shared implementation/type to a lower layer instead of importing a page from here. |
Fix locally (fast - only checks files changed in this branch):
make ui-checkstyle-changed
Code Review ✅ Approved 1 closed / 1 findings🟡 Medium risk · Incident menus now use a shared transition map and sorting persists in URLs; a map mismatch could hide valid status actions. Keeps the grouped incident sort in the URL as ✅ 1 closed✅ Quality: Group sort moved into the URL with no decision record
VerificationRules No rules evaluated Functional validation Not enabledAuto-approval Not enabledFor more verification details, comment OptionsDisplay: compact → Showing compact verification results. Comment with these commands to change the behavior for this request:
Was this helpful? React with 👍 / 👎 | Powered by Gitar — free for open source |
|
…atus menu, translations) (#36397) (#36450) * ui(incidents): keep group sort in URL, limit status menu, fix translations - Keep the grouped view's sort in the URL as sortField/sortType so a reload or a shared link keeps the order. - Offer only the transitions TestCaseResolutionTaskWorkflow allows in the inline status menu: an Assigned incident can be reassigned or resolved. - Use plural keys for the group row counts and status mix, translated in every locale, and show severities as the translated label with its level. * ui(incidents): share severity wording and status transitions with Inbox and status modal * docs(decisions): record that the incident group sort lives in the URL * ui(incidents): organise imports * ui(incidents): share transition map with bulk, tidy sort URL handling - Bulk status changes now skip any incident whose stage has no edge for the new status, using the same INCIDENT_STATUS_MENU_OPTIONS map as the inline menu and the status modal. - One replaceSearch helper writes the group-by, filter and sort params. Group-by changes now also stringify with arrayFormat: 'repeat', so array filters keep round-tripping as repeated params. - Cover the independent field/direction fallback of parseIncidentGroupSort, add a Playwright test for the sort surviving a reload, query the popover Back button by test id, and correct the decision record. * chore(playwright): auto-refresh impact-map.generated.json * ui(incidents): organise imports in bulk utils --------- (cherry picked from commit 53671c0) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
…nt status menu (#36538) Backport of the status-menu part of #36397 to 2.0. An Assigned incident's menu offered New and Ack, which TestCaseResolutionTaskWorkflow has no edge for, so picking either failed with "Transition 'new' is not available for task". The menu now offers only reassign and resolve from Assigned.



Describe your changes:
Fixes #34616
Follow-up to #34599 (grouped incidents in the AI-mode Incident Manager). It fixes the frontend issues found in the 2.1.0 release testing of that feature:
sortFieldandsortType(the same names as the API params), so a reload or a shared link keeps the order. Group by, filters and the open group already lived in the URL; the page and page size stay in component state. An unknown field or direction falls back to its default independently. Recorded in ADR:2026-10-28-incident-group-sort-lives-in-the-url.Transition 'ack' is not available for task .... The menu now offers only whatTestCaseResolutionTaskWorkflowallows from each stage: an Assigned incident can be reassigned or resolved. New and Ack still offer every status, and a Resolved incident is still reopened throughreopenResolvedIncident.Out of scope, tracked for the backend in the release-testing notes:
stateId, while the drawer'slatest=truelisting returns one record per test case.testCaseResolutionStatussearch listing has no deleted-test-case condition.The header stat cards not matching the groups, and not following the filters, are by design and unchanged.
Type of change:
High-level design:
Frontend only; no schema, API or backend change.
useIncidentGroupsderives the sort from the query string withparseIncidentGroupSort(IncidentGroups.utils.ts) instead ofuseState.handleSortChangewritessortFieldandsortTypewithnavigate(..., { replace: true }), the same way the group-by and filter handlers do, so they survive each other's updates. The page reset on a sort change is unchanged: the paging key already includes the sort.INCIDENT_STATUS_MENU_OPTIONS(constants/TestSuite.constant.ts) lists, for each status, the statuses its menu offers, mirroring the edges ofTestCaseResolutionTaskWorkflow.InlineTestCaseIncidentStatusandTestCaseStatusModalboth read it, so the inline menu and the modal cannot drift apart. The modal already had this rule hard-coded; it now shares the constant.label.incident-open-lowercaseandlabel.count-incident-{new,ack,assigned}, each with all six plural forms in every locale (yarn i18n), with real translations.getSeverityLabel(Severity/Severity.utils.ts) builds the label fromlabel.severityand the level. It replacesstartCase(severity)in the severity badge, chip, modal, filters, bulk selection bar and the Inbox incident tile.Tests:
Use cases covered
sortField/sortTypeto the URL; opening a URL that carries them loads the groups in that order; an unknown value falls back to the default.label.severityin the badge, chip, modal, bulk dialog, group table, incident list and Inbox tile.Unit tests
IncidentGroupsView.test.tsx: sort kept in the URL; sort read from a linkIncidentGroups.utils.test.ts:parseIncidentGroupSortInlineTestCaseIncidentStatus.test.tsx: Assigned incident menu offers only Assigned and ResolvedIncidentGroupsPlurals.test.ts: French and Russian plurals for the new keysIncidentStatusBreakdown.test.tsx,IncidentGroupsTable.test.tsx: plural status mixInlineSeverity.test.tsx,Severity.test.tsx,SeverityModal.test.tsx,IncidentGroupBulkStatusModal.test.tsx,IncidentList.test.tsx,taskStatTiles.utils.test.ts: severity label expectationssrc/components/observability/IncidentManager,src/components/DataQuality/IncidentManager,src/components/DataQuality/TestCaseStatusModal,src/components/discovery/personal-space/InboxPage. 95 suites, 1464 tests passed.TestCaseStatusModalandtaskStatTiles): 95.75% lines, 96.03% statements, 87.32% branches, 97.05% functions.yarn tsc --noEmit: 0 errors. ESLint on changed files: 0 errors. The warnings it reports were already there before this change.Backend integration tests
Ingestion integration tests
Playwright (UI) tests
openmetadata-ui/.../ui/playwright/for UI changes.d59151e2526) and a local Docker server built frommain(3e14a887471), withPLAYWRIGHT_IS_OSS=1. Without that variable the setup step calls/api/v1/ingestionRunners, which is a Collate-only endpoint. 26 passed, 0 failed, 0 flaky, 0 skipped (23 spec tests plus 3 setup/teardown steps):Features/AIMode/IncidentGroups.spec.ts: 10 passed. After71823b6655dadded "keeps the sort in the URL across a reload", I ran this spec again: 11 passed.Features/DataQuality/IncidentManagerLocaleLayout.spec.ts: 7 passedFeatures/IncidentManager.spec.ts: 6 passedmake playwright_affectedselects were not run locally (about 70, mostly in the wider data quality area). The merge queue runs the full suite. The command also reports impact-map gaps for several changed files, so the merge queue runs the full suite for those files anyway.'Severity 4'and so on) still hold.keeps the sort in the URL across a reloadtoIncidentGroups.spec.ts. The restricted menu on an Assigned incident is covered by Jest only.Manual testing performed
Ran this branch's UI (
yarn start, port 3001) against a local Docker backend with open incidents, logged in as admin:/observability/incident-manager: sorted by Severity; the URL gainedsortField=severity&sortType=desc; after a reload and in a new tab, the same order and header arrow./incident-manager: it offers only Assigned and Resolved. A New or Ack incident still offers every status.UI screen recording:
Recorded on
d59151e2526. The UI is this branch on the Vite dev server (port 3001), proxied to a local Docker stack built frommain(3e14a887471): server, PostgreSQL and OpenSearch all healthy, and/api/v1/system/versionreports that revision. Data comes from the repo's sample data, plus a fixture seeded through the API with the PlaywrightseedIncidentshelper (one table, three failing test cases: two Assigned, one New, one with Severity 2). The fixture was removed afterwards. Every step in the clip is checked with Playwright assertions against real server responses.grouped-incidents-fixes.mp4
sortField=severity&sortType=descto the URL. After a reload, the groups are still sorted by Severity and the column shows the descending arrow.?lng=fr-FR). The seeded table's row reads "3 ouverts", "2 assignés · 1 nouveau" and "Sévérité 2". Other rows show the singular forms ("1 ouvert", "1 nouveau").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. (No schema change.)
For a UI feature or feature task: as part of PR creation, I ran the PR build in Docker with sample data and embedded a verified GitHub-hosted recording plus build/health evidence above (or explained why this requirement is not applicable).
I have added tests (unit / integration / Playwright as applicable) and listed them above.
Self-review: I reviewed the final diff against
REVIEW.md(thepr-checklistskill runs it) and fixed every 🔴 finding, or answered it on the line below.8c0c7b88926: no 🔴. Fixed in60f888d800a:TestCaseStatusModalnow shares the transition map;label.{open,ack,assigned}-lowercaseare left in place. They are shared locale keys, and removing them from 21 files is a separate cleanup.Decision check: adds
docs/decisions/2026-10-28-incident-group-sort-lives-in-the-url.md(ADR:2026-10-28-incident-group-sort-lives-in-the-url), since keeping the order in the URL reverses the earlier local-state choice and makessortField/sortTypepart of the page's URL contract. The status transition map needs no record: it mirrors the server'sTestCaseResolutionTaskWorkflowrather than deciding a new rule.I have added a test that covers the exact scenario we are fixing.


Confidence Score: 5/5
The changes since the previous review appear safe to merge.Summary
The PR keeps incident-group sorting in the URL, shares the allowed status choices, and translates incident counts and severity labels.
Reviews (5) · Last reviewed commit: "ui(incidents): organise imports in bulk ..." · Reviewed by Greptile