Skip to content

Fixes #31854: make the Mentions sub-tab list the tasks you are mentioned in - #31855

Open
aniketkatkar97 wants to merge 3 commits into
mainfrom
mentions-tab-stale-task-list
Open

Fixes #31854: make the Mentions sub-tab list the tasks you are mentioned in#31855
aniketkatkar97 wants to merge 3 commits into
mainfrom
mentions-tab-stale-task-list

Conversation

@aniketkatkar97

@aniketkatkar97 aniketkatkar97 commented Aug 21, 2026

Copy link
Copy Markdown
Member

Describe your changes:

Fixes #31854

I made the Mentions sub-tab of the Tasks panel actually list the tasks you are mentioned in, because it was rendering the My Tasks list instead — and after a reload rendered the empty-state placeholder. The Mentions sub-tab has never displayed real data.

Two independent defects were stacked behind this.

1. The UI fetched into the wrong store. ActivityFeedTab.component.tsx used two different predicates for which list renders and which fetcher runs:

  • render branch: isTaskActiveTab || isMentionTabSelected<TaskListV1 taskList={tasks} />
  • fetch effect + infinite-scroll path: isTaskActiveTab only

So Mentions fell through to getFeedData(...), which writes entityThread. tasks was never updated, leaving the previous My Tasks array on screen; after a reload tasks starts [], hence the placeholder. The provider already had the correct branch — it lives in getTaskData (listTasks({ mentionedUser, aboutEntity })), which the tab simply never reached. Fixed by collapsing both branches onto one isTaskListTab predicate so they cannot drift apart again.

2. GET /v1/tasks?mentionedUser= returned 500. With the routing fixed, the correct request failed. ListFilter.getMentionedUserCondition built SELECT fr.toId FROM field_relationship, but that table has no toId column — TaskRepository.storeMentions writes the task id into toFQN. Every mentionedUser query threw, on MySQL (Unknown column 'fr.toId' in 'field list') and PostgreSQL (column fr.toid does not exist) alike. Fixed by selecting toFQN and matching on the indexed fromFQNHash — the same hash @BindFQN writes on insert.

Three secondary defects are in scope because they are exactly what made the stale list visible, and would still show a wrong list or a misleading placeholder after fix (1):

  • No state reset. tasks / entityThread / entityPaging were only written after a response landed. A first-page fetch now clears the list it owns plus the shared entityPaging cursor, and a shared request sequence stops a superseded response from committing rows, the cursor, or clearing the loader. The leftover cursor was letting infinite scroll append a new query's page onto the previous query's list — in TestCaseIncidentTab too, which shares entityPaging.
  • isFirstLoad never reset on entity pages. The reset effect keyed off the subTab prop, which entity tab utils never pass; the component reads the sub-tab from the URL param. A URL/back-button switch therefore showed the outgoing list with no loader.
  • Double fetch per filter click. handleUpdateTaskFilter called getTaskData itself on top of the effect already refiring on taskFilter.

Plus two consumer guards for the new mid-fetch empty window: TaskListV1's resize effect was collapsing the right panel on every switch, and TestCaseIncidentTab hardcoded isLoading={false} next to its own spinner, so it would have shown "no tasks assigned" and a spinner during an Open↔Closed fetch.

getFeedData's FeedFilter.MENTIONS semantics are deliberately untouched — that path is live for conversation mentions in the notification bell (NotificationBox.component.tsx) and has a test asserting it stays on getAllFeeds.

Type of change:

  • Bug fix

High-level design:

The load-bearing idea is that "which list is on screen" and "which fetcher populates it" must be one value, not two. isTaskListTab = isTaskActiveTab || isMentionTabSelected is now that single predicate, used by the fetch effect, the infinite-scroll path, the render branch, the observer gate, the filter bar and the right panel. The original bug was precisely these two expressions drifting apart, so unifying them is the fix and the regression guard.

For the stale-state half, the reset lives inside getTaskData / getFeedData when after is undefined, rather than behind a new resetFeedData action on the context:

  • after === undefined means "first page of a new query", so replacing the result set is the fetcher's contract, not something each of the five call sites must remember to opt into.
  • entityPaging is one piece of state consumed by two independent infinite-scroll effects (ActivityFeedTab and TestCaseIncidentTab), so clearing centrally fixes the stale-cursor append for both. A tab-scoped reset action would leave the incident tab broken.
  • A reset action would have to be invoked from the same effect that fetches, so the render sequence is identical — it only widens a widely-consumed context type and adds a "cleared but never refetched" failure mode.

Clearing at fetch start is only safe if the loader is guaranteed on for that window, which is why the isFirstLoad fix and the TaskListV1 / TestCaseIncidentTab guards are part of the same change rather than optional extras — without them the blank window renders the empty placeholder, i.e. the exact symptom being fixed.

Backend side, the alternative to hashing was leaving the predicate on the plain fromFQN column and only correcting toIdtoFQN. Matching fromFQNHash instead is both correct and index-covered (from_fqnhash_index(fromFQNHash, relation)), and it mirrors what @BindFQN wrote on insert, so there is no hashing-convention mismatch. No migration is needed — the schema was always right; only the query was wrong.

Tests:

Use cases covered

  • On an entity page, switching Tasks → Mentions issues GET /v1/tasks?mentionedUser=<me>&aboutEntity=<fqn> and lists only the tasks whose comments mention the logged-in user — not the My Tasks list.
  • Switching back to My Tasks restores the full entity task list (i.e. the paging cursor from the mentions query does not leak).
  • Landing on / reloading the Mentions URL directly shows the mentioned tasks, not the empty-state placeholder.
  • Changing sub-tab via the URL or the browser Back button shows the loader, never the outgoing sub-tab's list.
  • Clicking an Open/Closed filter fires exactly one /api/v1/tasks request.
  • GET /v1/tasks?mentionedUser= returns 200 instead of 500, and a task is discoverable by mention as soon as a comment mentions the user.
  • Incident Manager's task list keeps working across Open↔Closed switches (shared entityPaging consumer).

Unit tests

  • I added unit tests for the new/changed logic.

Files updated:

  • ActivityFeedTab.component.test.tsx — replaced the Bug 1 suite, which asserted getFeedData was called with FeedFilter.MENTIONS and therefore codified the bug. New suites: mentions routes to getTaskData and getFeedData is never called; the task list renders (not the feed list) with the message.no-mentions placeholder; a first-page refetch keeps the in-list loader on; a URL-driven sub-tab change brings the loader back; exactly one fetch per filter change.
  • ActivityFeedProvider.test.tsx + src/mocks/ActivityFeedProvider.mock.tsx — new DummyTaskListStateComponent fixture exposing tasks and entityPaging.after, and two tests: a new first-page fetch clears rows and the cursor before the response resolves, and a response resolving after a newer request started is ignored. The existing should keep mentions on the feed API… test is intentionally left green.

Verified fail-first (RED → GREEN), stashing only the source file:

# pre-fix ActivityFeedTab.component.tsx
✕ calls getTaskData with FeedFilter.MENTIONS and never getFeedData
✕ keeps the in-list loader on for a first-page refetch
✕ brings the loader back when the sub-tab changes via the URL
✕ fires exactly one fetch per task filter change
Tests: 4 failed, 10 passed, 14 total

# pre-fix ActivityFeedProvider.tsx
✕ clears the rows and the paging cursor before the new response lands
✕ ignores a response that resolves after a newer request started
Tests: 2 failed, 22 passed, 24 total

With the fix, the regression sweep over every touched consumer is green:

yarn test src/components/ActivityFeed src/components/Settings/Users \
          src/components/DataQuality/IncidentManager src/pages/IncidentManager
Test Suites: 73 passed, 73 total
Tests:       583 passed, 583 total

Backend integration tests

  • I added integration tests in openmetadata-integration-tests/ for the changed query.

TaskCommentsIT#test_listByMentionedUser_returnsTaskFromCommentMention — comments a <#E::user::…> mention onto one of two tasks, then asserts ?mentionedUser= returns the mentioning task and excludes the other.

# with the fix
Tests run: 13, Failures: 0, Errors: 0, Skipped: 0 -- TaskCommentsIT
BUILD SUCCESS

# pre-fix ListFilter.java
[ERROR] TaskCommentsIT.test_listByMentionedUser_returnsTaskFromCommentMention
  » org.postgresql.util.PSQLException: ERROR: column fr.toid does not exist

Ingestion integration tests

  • Not applicable (no ingestion changes).

Playwright (UI) tests

  • I added Playwright E2E tests for the UI change.

No new spec file — both changes land in specs that already own the fixtures.

  • playwright/e2e/Features/ActivityFeedTabBadge.spec.ts — new Mentions sub-tab lists only the tasks the user is mentioned in. Reuses the describe's TableClass / UserClass / performAdminLogin / waitForTaskListResponse and its navigateToTasksPanel / createOpenTask helpers, on its own table since chromium runs fullyParallel. Creates two tasks, mentions the admin on one via POST /api/v1/tasks/{id}/comments (mentions are only recorded from the comment path), then asserts 2 cards on My Tasks → 1 on Mentions → 2 back on My Tasks → 1 after a reload on the Mentions URL, with no empty-state placeholder.
  • playwright/e2e/Features/Tasks/ActivityFeed.spec.tsentity task filters should request open, closed, and mentions views waited on /api/v1/feed?filterType=MENTIONS. That request no longer fires, so the test would have hung; it now waits on /api/v1/tasks with mentionedUser set and aboutEntity equal to the table FQN, and targets the new mentions-toggle test id instead of a .task-filter-container + getByText(/mention/i) chain.

Both specs green against a dev server on the fixed backend:

playwright/e2e/Features/ActivityFeedTabBadge.spec.ts   7 passed
playwright/e2e/Features/Tasks/ActivityFeed.spec.ts    20 passed

And the new E2E test is fail-first — stashing only ActivityFeedTab.component.tsx:

✘ Mentions sub-tab lists only the tasks the user is mentioned in
  expect(getByTestId('task-feed-card')).toHaveCount(1)  Expected: 1  Received: 0

Manual testing performed

  1. Built openmetadata-service and ran it against the local Docker stack; started the Vite dev server on :3000 (:8585 serves a prebuilt bundle and would not have exercised the change).
  2. Confirmed the backend defect first, before any UI change: GET /api/v1/tasks?mentionedUser=admin500, Unknown column 'fr.toId' in 'field list'. Confirmed the corrected subquery against the live MySQL field_relationship / task_entity rows, and that storeMentions writes fromFQN=admin, fromFQNHash=21232f29…, toFQN=<task-uuid>, toType=task, relation=5. After the fix: 200, both mentioning tasks returned.
  3. Entity page → Activity Feeds & Tasks → Tasks → Mentions: network shows GET /api/v1/tasks?…mentionedUser=admin&aboutEntity=<fqn> and no /api/v1/feed; the list switches to the mentioned task.
  4. Toggled back to My Tasks, and used browser Back/Forward across the two sub-tabs — loader every time, never a stale list.
  5. Clicked Open ↔ Closed — exactly one /api/v1/tasks request per click (was two).
  6. Repeated on the user profile page (/users/<me>/tasks/mentions).
  7. Checked Incident Manager's task list across Open ↔ Closed switches for the shared-entityPaging change.

UI screen recording / screenshots:

To follow — the behaviour is covered end-to-end by the new Playwright test above (ActivityFeedTabBadge.spec.ts), including the reload case, which is the one the bug report calls out.

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: not applicable — no schema change. The field_relationship schema was always correct; only the query referenced a non-existent column, so no migration is needed.

  • For UI changes: I attached a screen recording and/or screenshots above.

  • I have added tests (unit / integration / Playwright as applicable) and listed them above.

  • I have added a test that covers the exact scenario we are fixing. Issue Mentions sub-tab in the Tasks panel keeps showing the My Tasks list; GET /v1/tasks?mentionedUser= returns 500 #31854 is referenced in this PR; the covering tests are ActivityFeedTabBadge.spec.tsMentions sub-tab lists only the tasks the user is mentioned in, ActivityFeedTab.component.test.tsxMentions sub-tab fetches tasks the user is mentioned in, and TaskCommentsIT#test_listByMentionedUser_returnsTaskFromCommentMention.

🤖 Generated with Claude Code

Greptile Summary

The PR routes Mentions through the task API, corrects mention relationship filtering, and resets shared list state for replacing requests. One notification-driven refresh path still bypasses the corresponding first-page loader reset.

  • Unifies the Mentions and My Tasks rendering/fetch paths.
  • Queries stored mention relationships through toFQN and normalized user-name hashes.
  • Adds request sequencing and first-page list/cursor resets.
  • Updates task-list loading behavior and regression coverage.

Confidence Score: 4/5

The PR is not yet safe to merge because notification-driven task refreshes can still display a false empty state after pagination.

The provider now clears task rows at the start of every first-page request, but the tasksRefreshKey effect starts such a request without restoring the first-load flag, so the task list suppresses its loading state and renders the empty placeholder until the response arrives.

Files Needing Attention: openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedTab/ActivityFeedTab.component.tsx

Important Files Changed

Filename Overview
openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/ListFilter.java Corrects the mentioned-user relationship query and normalizes bare or quoted dotted usernames consistently with stored mention hashes.
openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedProvider/ActivityFeedProvider.tsx Adds shared request sequencing and immediate first-page list resets; those resets require every replacing-fetch caller to restore its first-load state.
openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedTab/ActivityFeedTab.component.tsx Correctly routes Mentions to task data and restores loaders for most replacing fetches, but omits the reset from the notification refresh effect.
openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedList/TaskListV1.component.tsx Prevents panel resizing while the intentionally cleared task list is loading.
openmetadata-ui/src/main/resources/ui/src/components/DataQuality/IncidentManager/TestCaseIncidentTab/TestCaseIncidentTab.component.tsx Coordinates empty-list and pagination loaders with the provider's new first-page clearing behavior.

Sequence Diagram

sequenceDiagram
  participant U as User
  participant Tab as ActivityFeedTab
  participant Provider as ActivityFeedProvider
  participant API as Tasks API
  U->>Tab: Open task notification after pagination
  Tab->>Provider: "getTaskData(..., after=undefined)"
  Provider->>Provider: Clear tasks and paging
  Provider->>API: Fetch first page
  Note over Tab,Provider: isFirstLoad remains false
  Tab->>U: Show empty placeholder and paging spinner
  API-->>Provider: Replacement tasks
  Provider-->>Tab: Render refreshed list
Loading

Comments Outside Diff (2)

  1. openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedTab/ActivityFeedTab.component.tsx, line 455 (link)

    P1 Notification refresh shows empty state

    When a user paginates an entity's Tasks tab and then opens a task notification for the same entity, the tasksRefreshKey effect starts a first-page request without restoring isFirstLoad. The provider clears tasks, but TaskListV1 receives isLoading={false} and displays the no-tasks placeholder until the response arrives.

  2. openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedTab/ActivityFeedTab.component.tsx, line 445-456 (link)

    P1 Notification refresh hides the loader

    When a user paginates an entity's Tasks tab and then opens a task notification for the same entity, the tasksRefreshKey effect starts a first-page request without restoring isFirstLoad. The provider clears tasks, so TaskListV1 receives isLoading={false} and displays the no-tasks placeholder alongside the pagination spinner until the response arrives.

Reviews (3): Last reviewed commit: "Merge branch 'main' into mentions-tab-st..." | Re-trigger Greptile

…ned in

The Tasks panel renders TaskListV1 off the provider's `tasks` for both of its
sub-tabs, but the fetch effect gated only on the My Tasks sub-tab, so Mentions
fell through to getFeedData and wrote `entityThread` instead. `tasks` was never
updated, leaving the previous My Tasks list on screen -- and empty after a
reload. Collapse "which list renders" and "which fetcher runs" onto a single
`isTaskListTab` predicate so they cannot drift apart again.

The correct request then surfaced a second defect: ListFilter built
`SELECT fr.toId FROM field_relationship`, but that table has no toId column
(TaskRepository.storeMentions writes the task id into toFQN), so every
`?mentionedUser=` query failed with a SQL syntax error on MySQL and Postgres
alike. Match on the indexed fromFQNHash -- the same hash @BindFQN writes on
insert -- and select toFQN.

Also fixed, because they are what makes the stale list visible:

- ActivityFeedProvider now clears the list it owns plus the shared entityPaging
  cursor when a first-page fetch starts, and a shared request sequence stops a
  superseded response committing rows, the cursor, or clearing the loader. The
  leftover cursor was letting infinite scroll append a new query's page onto the
  previous query's list, in the incident tab too.
- The isFirstLoad reset keyed off the `subTab` prop, which entity pages never
  pass (the sub-tab arrives as a URL param), so a URL or back-button driven
  switch showed the outgoing list with no loader.
- handleUpdateTaskFilter fired getTaskData itself on top of the effect already
  refiring on taskFilter, i.e. two identical requests per filter click.
- TaskListV1's resize effect and TestCaseIncidentTab's hardcoded
  isLoading={false} both treated the new mid-fetch empty window as "no results".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 21, 2026 06:02

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 Aug 21, 2026

Copy link
Copy Markdown
Contributor

✅ PR checks passed

The linked issue has a description and all required Shipping project fields set. Thanks!

@github-actions github-actions Bot added safe to test Add this label to run secure Github workflows on PRs UI UI specific issues labels Aug 21, 2026
Comment thread openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/ListFilter.java Outdated
@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

⚠️ UI Checkstyle passed — lint findings in changed files

🔍 ESLint findings in this PR's files — 0 error(s), 36 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), 36 warning(s) across 7 changed file(s).

Count Rule
18 react-hooks/exhaustive-deps
4 sonarjs/no-extra-arguments
3 jsx-a11y/control-has-associated-label
2 sonarjs/cyclomatic-complexity
2 openmetadata-imports/review-sequential-api-calls
2 sonarjs/no-nested-functions
1 sonarjs/cognitive-complexity
1 sonarjs/no-nested-conditional
1 sonarjs/expression-complexity
1 openmetadata-imports/no-lower-layer-page-imports
All findings
Location Rule Message
🟡 src/components/ActivityFeed/ActivityFeedList/TaskListV1.component.tsx:67:6 react-hooks/exhaustive-deps React Hook useEffect has a missing dependency: 'handlePanelResize'. Either include it or remove the dependency array. If 'handlePanelResize' changes too often,
🟡 src/components/ActivityFeed/ActivityFeedProvider/ActivityFeedProvider.test.tsx:376:9 sonarjs/no-extra-arguments This function expects no arguments, but 1 was provided.
🟡 src/components/ActivityFeed/ActivityFeedProvider/ActivityFeedProvider.test.tsx:412:9 sonarjs/no-extra-arguments This function expects no arguments, but 1 was provided.
🟡 src/components/ActivityFeed/ActivityFeedProvider/ActivityFeedProvider.test.tsx:418:9 sonarjs/no-extra-arguments This function expects no arguments, but 1 was provided.
🟡 src/components/ActivityFeed/ActivityFeedProvider/ActivityFeedProvider.test.tsx:648:9 sonarjs/no-extra-arguments This function expects no arguments, but 1 was provided.
🟡 src/components/ActivityFeed/ActivityFeedProvider/ActivityFeedProvider.tsx:172:6 react-hooks/exhaustive-deps React Hook useCallback has a missing dependency: 'fetchPostsFeed'. Either include it or remove the dependency array.
🟡 src/components/ActivityFeed/ActivityFeedProvider/ActivityFeedProvider.tsx:193:6 react-hooks/exhaustive-deps React Hook useCallback has a missing dependency: 'fetchTestCaseResolution'. Either include it or remove the dependency array.
🟡 src/components/ActivityFeed/ActivityFeedProvider/ActivityFeedProvider.tsx:227:7 sonarjs/cognitive-complexity Refactor this function to reduce its Cognitive Complexity from 27 to the 15 allowed.
🟡 src/components/ActivityFeed/ActivityFeedProvider/ActivityFeedProvider.tsx:227:7 sonarjs/cyclomatic-complexity {"message":"Function has a complexity of 25 which is greater than 10 authorized.","cost":15,"secondaryLocations":[{"line":227,"column":6,"endLine":227,"endColum
🟡 src/components/ActivityFeed/ActivityFeedProvider/ActivityFeedProvider.tsx:364:5 react-hooks/exhaustive-deps React Hook useCallback has a missing dependency: 't'. Either include it or remove the dependency array.
🟡 src/components/ActivityFeed/ActivityFeedProvider/ActivityFeedProvider.tsx:427:5 react-hooks/exhaustive-deps React Hook useCallback has a missing dependency: 't'. Either include it or remove the dependency array.
🟡 src/components/ActivityFeed/ActivityFeedProvider/ActivityFeedProvider.tsx:472:5 react-hooks/exhaustive-deps React Hook useCallback has missing dependencies: 'setActiveTask', 'setActiveThread', and 't'. Either include them or remove the dependency array.
🟡 src/components/ActivityFeed/ActivityFeedProvider/ActivityFeedProvider.tsx:527:5 react-hooks/exhaustive-deps React Hook useCallback has a missing dependency: 'setActiveThread'. Either include it or remove the dependency array.
🟡 src/components/ActivityFeed/ActivityFeedProvider/ActivityFeedProvider.tsx:559:34 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/ActivityFeed/ActivityFeedProvider/ActivityFeedProvider.tsx:563:68 sonarjs/no-nested-functions Refactor this code to not nest functions more than 4 levels deep.
🟡 src/components/ActivityFeed/ActivityFeedProvider/ActivityFeedProvider.tsx:606:5 react-hooks/exhaustive-deps React Hook useCallback has missing dependencies: 'updatePostHandler' and 'updateThreadHandler'. Either include them or remove the dependency array.
🟡 src/components/ActivityFeed/ActivityFeedProvider/ActivityFeedProvider.tsx:609:9 react-hooks/exhaustive-deps The 'updateReactions' function makes the dependencies of useMemo Hook (at line 886) change on every render. Move it inside the useMemo callback. Alternatively,
🟡 src/components/ActivityFeed/ActivityFeedProvider/ActivityFeedProvider.tsx:691:9 react-hooks/exhaustive-deps The 'updateEditorFocus' function makes the dependencies of useMemo Hook (at line 886) change on every render. Move it inside the useMemo callback. Alternatively
🟡 src/components/ActivityFeed/ActivityFeedProvider/ActivityFeedProvider.tsx:699:6 react-hooks/exhaustive-deps React Hook useCallback has a missing dependency: 'setActiveThread'. Either include it or remove the dependency array.
🟡 src/components/ActivityFeed/ActivityFeedProvider/ActivityFeedProvider.tsx:706:6 react-hooks/exhaustive-deps React Hook useCallback has a missing dependency: 'setActiveTask'. Either include it or remove the dependency array.
🟡 src/components/ActivityFeed/ActivityFeedProvider/ActivityFeedProvider.tsx:740:28 sonarjs/no-nested-functions Refactor this code to not nest functions more than 4 levels deep.
🟡 src/components/ActivityFeed/ActivityFeedTab/ActivityFeedTab.component.test.tsx:143:9 jsx-a11y/control-has-associated-label A control must be associated with a text label.
🟡 src/components/ActivityFeed/ActivityFeedTab/ActivityFeedTab.component.tsx:111:26 sonarjs/cyclomatic-complexity {"message":"Function has a complexity of 29 which is greater than 10 authorized.","cost":19,"secondaryLocations":[{"line":111,"column":25,"endLine":111,"endColu
🟡 src/components/ActivityFeed/ActivityFeedTab/ActivityFeedTab.component.tsx:260:5 react-hooks/exhaustive-deps React Hook useCallback has a missing dependency: 'onUpdateFeedCount'. Either include it or remove the dependency array. If 'onUpdateFeedCount' changes too often
🟡 src/components/ActivityFeed/ActivityFeedTab/ActivityFeedTab.component.tsx:273:11 sonarjs/no-nested-conditional Extract this nested ternary operation into an independent statement.
🟡 src/components/ActivityFeed/ActivityFeedTab/ActivityFeedTab.component.tsx:284:21 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/ActivityFeed/ActivityFeedTab/ActivityFeedTab.component.tsx:330:6 react-hooks/exhaustive-deps React Hook useCallback has an unnecessary dependency: 'currentUser.id'. Either exclude it or remove the dependency array.
🟡 src/components/ActivityFeed/ActivityFeedTab/ActivityFeedTab.component.tsx:622:5 react-hooks/exhaustive-deps React Hook useMemo has a missing dependency: 't'. Either include it or remove the dependency array.
🟡 src/components/ActivityFeed/ActivityFeedTab/ActivityFeedTab.component.tsx:653:6 react-hooks/exhaustive-deps React Hook useCallback has a missing dependency: 'activeTab'. Either include it or remove the dependency array.
🟡 src/components/ActivityFeed/ActivityFeedTab/ActivityFeedTab.component.tsx:747:6 react-hooks/exhaustive-deps React Hook useMemo has a missing dependency: 't'. Either include it or remove the dependency array.
🟡 src/components/ActivityFeed/ActivityFeedTab/ActivityFeedTab.component.tsx:914:10 sonarjs/expression-complexity Reduce the number of conditional operators (5) used in the expression (maximum allowed 3).
🟡 src/components/DataQuality/IncidentManager/TestCaseIncidentTab/TestCaseIncidentTab.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/IncidentManager/TestCaseIncidentTab/TestCaseIncidentTab.component.tsx:113:6 react-hooks/exhaustive-deps React Hook useEffect has a missing dependency: 'handleFeedFetchFromFeedList'. Either include it or remove the dependency array.
🟡 src/mocks/ActivityFeedProvider.mock.tsx:146:7 jsx-a11y/control-has-associated-label A control must be associated with a text label.
🟡 src/mocks/ActivityFeedProvider.mock.tsx:150:7 jsx-a11y/control-has-associated-label A control must be associated with a text label.
🟡 src/mocks/ActivityFeedProvider.mock.tsx:290:7 sonarjs/no-duplicate-string Define a constant instead of duplicating this literal 3 times.

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

make ui-checkstyle-changed

@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Jest test Coverage

UI tests summary

Lines Statements Branches Functions
Coverage: 66%
67.04% (80400/119928) 51.48% (49253/95668) 52.45% (14704/28030)

… mention hashes

Two P1 review findings, both real.

`if (after) setIsFirstLoad(false)` only avoided clearing the flag; it never set
it back. Once pagination had cleared it, a first-page refetch -- closing a task,
or any change to entity/domain -- left `isFirstLoad && loading` false while the
provider had already emptied the list, so TaskListV1/ActivityFeedListV1New
rendered the empty-state placeholder next to the pagination spinner. Use
`setIsFirstLoad(!after)`, and move the reset into the fetch effect itself so it
also covers the fqn and activeDomain deps rather than only sub-tab and filter.
This is the same defect Gitar reported from the entityThread side; ActivityFeedTab
is the only consumer that renders entityThread as a list, so it is fully covered.

ListFilter now hashes via hashUserName, which quotes before hashing. Verified
against live rows: a dotted user's FQN is stored quoted, and storeMentions writes
md5 of the quoted single segment. Hashing the raw value matched the quoted FQN the
UI sends but would split a bare `john.doe` into three FQN segments and match
nothing; quoteName is idempotent for an already-quoted name, so quoting first
accepts both. Also matches the sibling assignee condition.

The loader unit test now paginates first, so it fails without the fix rather than
starting from the already-true state. Added an IT assertion covering the quoted
FQN form alongside the bare name.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 21, 2026 06:20

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 Aug 21, 2026

Copy link
Copy Markdown
Code Review ✅ Approved 1 resolved / 1 findings

Fixes the Mentions sub-tab to correctly query tasks and resolves the backend 500 error by querying toFQN and fromFQNHash. Adds request sequencing and state resets to prevent stale task results.

✅ 1 resolved
Bug: getFeedData now clears entityThread/paging before response lands

📄 openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedProvider/ActivityFeedProvider.tsx:380-383
The first-page branch of getFeedData now eagerly does setEntityThread([]) and setEntityPaging({}) at fetch start (ActivityFeedProvider.tsx:380-383), whereas before it only replaced state after the response. In ActivityFeedTab this blank window is covered because the loader is guaranteed on, but getFeedData/entityThread is also consumed by other surfaces (e.g. the notification bell / conversation feed). Any consumer that renders entityThread without gating on loading will now briefly flash an empty list on every first-page refetch. Verify all entityThread consumers show a loader during the mid-fetch window, or restrict the eager clear to the task/mentions path.

Options

Display: compact → Showing less information.

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

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown
Contributor

✅ Playwright Results — workflow succeeded

Validated commit 4d0e45fd02f20e4007d69cfe6db2cbea67340cd1 in Playwright run 32454644400, attempt 1.

✅ 1037 passed · ❌ 0 failed · 🟡 4 flaky · ⏭️ 0 skipped · 🧰 0 lifecycle flaky

Performance

Blocking targets: ✅ met · Optimization targets: 🟡 in progress

Shard-job maxima below are not the full workflow wall time; the linked run includes build, fixture, planning, and reporting.

🕒 Full workflow signal wall (to summary) 48m 35s

⏱️ Max setup 4m 30s · max shard execution 21m 7s · max shard-job elapsed before upload 24m 18s · reporting 9s

🌐 192.39 requests/attempt · 2.58 app boots/UI scenario · 34.65% common-shard skew

Optimization targets still in progress:

  • Common shard skew was 34.65% (convergence target: at most 15%).
  • Application boot ratio was 2.58 per UI scenario (2580 boots / 1001 scenarios; convergence target: at most 1).
Shard Passed Failed Flaky Skipped Lifecycle failed Lifecycle flaky
🟡 Shard chromium-01 167 0 2 0 0 0
✅ Shard chromium-02 150 0 0 0 0 0
✅ Shard chromium-03 173 0 0 0 0 0
✅ Shard chromium-04 169 0 0 0 0 0
🟡 Shard chromium-05 165 0 1 0 0 0
✅ Shard data-asset-rules-01 61 0 0 0 0 0
✅ Shard domain-isolation-01 16 0 0 0 0 0
✅ Shard global-state-01 34 0 0 0 0 0
✅ Shard import-export-01 26 0 0 0 0 0
🟡 Shard ingestion-01 31 0 1 0 0 0
✅ Shard reindex-01 5 0 0 0 0 0
✅ Shard search-01 11 0 0 0 0 0
✅ Shard search-rbac-01 29 0 0 0 0 0
🟡 4 flaky test(s) (passed on retry)
  • Pages/TasksUIFlow.spec.tsCreate and reject tag task for Dashboard via UI (shard chromium-01, 1 retry)
  • Pages/TasksUIFlow.spec.tsCreate and resolve description task for Pipeline via UI (shard chromium-01, 1 retry)
  • Flow/ObservabilityAlerts.spec.tsIngestion Pipeline alert (shard chromium-05, 1 retry)
  • Features/IncidentManager.spec.tsComplete Incident lifecycle with table owner (shard ingestion-01, 1 retry)

📦 Download artifacts

How to debug locally
# Download playwright-test-results-<shard> artifact and unzip
npx playwright show-trace path/to/trace.zip    # view trace

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.

Mentions sub-tab in the Tasks panel keeps showing the My Tasks list; GET /v1/tasks?mentionedUser= returns 500

2 participants