Skip to content

fix: Real-time monitoring displaying incorrect data#37103

Merged
kodiakhq[bot] merged 7 commits intodevelopfrom
fix/real-time-monitoring
Oct 15, 2025
Merged

fix: Real-time monitoring displaying incorrect data#37103
kodiakhq[bot] merged 7 commits intodevelopfrom
fix/real-time-monitoring

Conversation

@aleksandernsilva
Copy link
Contributor

@aleksandernsilva aleksandernsilva commented Sep 30, 2025

Proposed changes (including videos or screenshots)

This PR fixes an issue where real-time monitoring charts were not being initialized correctly and failed to update reactively when filters changed.

Root causes:

  1. Charts were being initialized both by a dedicated useEffect and by updateChartData, creating a race condition that prevented the correct chart instance from receiving data updates.
  2. Charts relied on being re-mounted to reset after a filter change. With the shift to useQuery for data fetching and the removal of random keys, re-mounting now happens less frequently, exposing the underlying issue.

Solution:

  • Updated data-fetching queries to use gcTime: 0, ensuring no data is cached after unmount and preventing stale results when returning to the page.
  • Created a new useChartContext hook to manage chart initialization. Unlike the previous MutableRef approach, this context is consumed by the data-update effect, ensuring updates only run after the chart is fully initialized.

Issue(s)

SUP-874

Steps to test or reproduce

  • Omnichannel > Real-time monitoring
  • First load should display correct data
  • Filter by a department
  • Data should reflect the selected filter

Further comments

Introduced here: #36468

Summary by CodeRabbit

  • New Features
    • Charts now use a shared, lifecycle-managed chart context and automatically reset when no data is available.
  • Bug Fixes
    • Fixed incorrect real-time monitoring displays across agent status, chat counts, departments, and response times.
  • Refactor
    • Reworked chart initialization and update flow for more reliable, responsive rendering and reduced flicker.
  • Chores
    • Version bump recorded for a dependency related to real-time monitoring stability.

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Sep 30, 2025

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is targeting the wrong base branch. It should target 7.12.0, but it targets 7.11.0

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@changeset-bot
Copy link

changeset-bot bot commented Sep 30, 2025

🦋 Changeset detected

Latest commit: f143158

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 42 packages
Name Type
@rocket.chat/meteor Patch
@rocket.chat/core-typings Patch
@rocket.chat/rest-typings Patch
@rocket.chat/uikit-playground Patch
@rocket.chat/api-client Patch
@rocket.chat/apps Patch
@rocket.chat/core-services Patch
@rocket.chat/cron Patch
@rocket.chat/ddp-client Patch
@rocket.chat/freeswitch Patch
@rocket.chat/fuselage-ui-kit Patch
@rocket.chat/gazzodown Patch
@rocket.chat/http-router Patch
@rocket.chat/livechat Patch
@rocket.chat/model-typings Patch
@rocket.chat/ui-avatar Patch
@rocket.chat/ui-client Patch
@rocket.chat/ui-contexts Patch
@rocket.chat/web-ui-registration Patch
@rocket.chat/account-service Patch
@rocket.chat/authorization-service Patch
@rocket.chat/ddp-streamer Patch
@rocket.chat/federation-service Patch
@rocket.chat/omnichannel-transcript Patch
@rocket.chat/presence-service Patch
@rocket.chat/queue-worker Patch
@rocket.chat/stream-hub-service Patch
@rocket.chat/federation-matrix Patch
@rocket.chat/license Patch
@rocket.chat/media-calls Patch
@rocket.chat/omnichannel-services Patch
@rocket.chat/pdf-worker Patch
@rocket.chat/presence Patch
rocketchat-services Patch
@rocket.chat/models Patch
@rocket.chat/network-broker Patch
@rocket.chat/omni-core-ee Patch
@rocket.chat/mock-providers Patch
@rocket.chat/ui-video-conf Patch
@rocket.chat/ui-voip Patch
@rocket.chat/instance-status Patch
@rocket.chat/omni-core Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 30, 2025

Walkthrough

Adds a lifecycle-managed useChartContext hook and resetChart utility, updates useUpdateChartData to accept a chart value, refactors multiple omnichannel real-time chart components to use the new context and set gcTime: 0 on queries, and adds a changeset bump for @rocket.chat/meteor.

Changes

Cohort / File(s) Summary
Changeset
.changeset/rare-schools-laugh.md
Adds a patch changeset for @rocket.chat/meteor with note: "Fixes real-time monitoring displaying incorrect data."
Chart utilities
apps/meteor/app/livechat/client/lib/chartHandler.ts
Adds resetChart<TChartType> to clear chart labels and datasets and call update().
Context hook
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx
New useChartContext hook and UseChartContextProps type: initializes/destroys a Chart when canvas is available and returns the chart or undefined.
Update hook API
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts
Changes UseUpdateChartDataOptions.context from `MutableRefObject<TChart
Omnichannel charts (refactor to context)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/*.tsx
.../AgentStatusChart.tsx, ChatsChart.tsx, ChatDurationChart.tsx, ChatsPerAgentChart.tsx, ChatsPerDepartmentChart.tsx, ResponseTimesChart.tsx
Replaced local ref-based chart init with useChartContext; wired useUpdateChartData to chart value; imported and used resetChart where needed; added gcTime: 0 to queries; guard updates on context availability; AgentStatusChart exported as default.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Comp as Chart Component
  participant UCC as useChartContext
  participant Init as init(canvas, prevChart, t)
  participant Chart as Chart Instance
  participant UUD as useUpdateChartData
  participant API as Data Query

  Comp->>UCC: request chart ({canvas, init, t})
  UCC->>Init: if canvas present, call init(prevChart, t)
  Init-->>UCC: Chart instance
  UCC-->>Comp: return Chart | undefined

  Comp->>API: fetch data (gcTime: 0)
  API-->>Comp: { data, isSuccess }

  alt context available and isSuccess
    Comp->>UUD: updateChartData(chart, data)
    UUD->>Chart: mutate datasets/labels & update()
  else data empty with context
    Comp->>Chart: resetChart(chart)
  else
    Note over Comp: wait for context and/or successful query
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Suggested labels

stat: ready to merge, stat: QA assured

Suggested reviewers

  • ggazzo

Poem

I nibble bugs and stitch the view,
A tiny hook to wake charts new.
I clear the board when numbers part,
redraw the lines and mend the chart.
Hop, live data hop — metrics smart. 🐇📈

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly states that real-time monitoring charts were displaying incorrect data and that this PR fixes that issue, directly matching the core change of introducing a new chart context hook and gcTime updates to resolve the bug.
Linked Issues Check ✅ Passed The changes implement the objectives of SUP-874 by disabling cache with gcTime: 0 across all real-time monitoring queries and replacing manual chart initialization with a managed useChartContext hook to ensure charts initialize fully before updates.
Out of Scope Changes Check ✅ Passed All modifications are directly focused on fixing the chart initialization bug and preventing stale data in real-time monitoring; no unrelated or extraneous changes appear outside the scope of addressing SUP-874.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/real-time-monitoring

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Sep 30, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 67.45%. Comparing base (fef8715) to head (f143158).
⚠️ Report is 1 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop   #37103      +/-   ##
===========================================
+ Coverage    67.41%   67.45%   +0.03%     
===========================================
  Files         3289     3289              
  Lines       111887   111887              
  Branches     20435    20447      +12     
===========================================
+ Hits         75429    75469      +40     
+ Misses       33771    33734      -37     
+ Partials      2687     2684       -3     
Flag Coverage Δ
e2e 57.32% <ø> (+0.01%) ⬆️
unit 71.48% <ø> (+0.04%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@aleksandernsilva aleksandernsilva marked this pull request as ready for review October 1, 2025 18:03
@aleksandernsilva aleksandernsilva requested review from a team as code owners October 1, 2025 18:03
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerAgentChart.tsx (1)

17-23: Dataset init mismatch: 3 series but only 2 data arrays.

drawLineChart is given 3 series labels ([Open, Closed, On_Hold_Chats]) but only [[], []] for dataset values. This can break rendering or drop a series.

Apply this fix:

- drawLineChart(canvas, context, [t('Open'), t('Closed'), t('On_Hold_Chats')], [], [[], []], {
+ drawLineChart(canvas, context, [t('Open'), t('Closed'), t('On_Hold_Chats')], [], [[], [], []], {
♻️ Duplicate comments (1)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ResponseTimesChart.tsx (1)

70-71: gcTime: 0 added correctly.

Same rationale as other charts; no further action.

🧹 Nitpick comments (8)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatDurationChart.tsx (1)

84-94: Consider combining early return guards.

The two separate early returns for !context and !isSuccess could be combined into a single check for clarity.

-	if (!context) {
-		return;
-	}
-
-	if (!isSuccess) {
+	if (!context || !isSuccess) {
 		return;
 	}
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/AgentStatusChart.tsx (2)

51-56: Migration to useChartContext/useUpdateChartData looks solid.

This removes the init race and ensures updates run only after context exists. One improvement: destroy the Chart instance on unmount/canvas change to avoid leaks.

Apply in useChartContext.tsx:

@@
 export const useChartContext = <TChartType extends ChartType>({ key, canvas, init, t }: UseChartContextProps<Chart<TChartType>>) => {
   const contextRef = useRef<Chart<TChartType>>();
+  useEffect(() => {
+    return () => {
+      contextRef.current?.destroy?.();
+      contextRef.current = undefined;
+    };
+  }, [canvas]);

Also applies to: 58-63


65-78: Verify label-to-datapoint mapping; optionally batch updates.

You update in order Offline, Available, Away, Busy while the init labels are [Available, Away, Busy, Offline]. If updateChart matches by label text, order is fine; if by index, values will misalign. Consider batching to avoid 4 redraws.

Example (if index-based or to batch):

- updateChartData(t('Offline'), [offline]);
- updateChartData(t('Available'), [available]);
- updateChartData(t('Away'), [away]);
- updateChartData(t('Busy'), [busy]);
+ // If batching is supported by updateChart/updateChartData:
+ // updateChartData(t('Agents'), [available, away, busy, offline]);
+ // Otherwise, at least match init order:
+ updateChartData(t('Available'), [available]);
+ updateChartData(t('Away'), [away]);
+ updateChartData(t('Busy'), [busy]);
+ updateChartData(t('Offline'), [offline]);
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ResponseTimesChart.tsx (1)

87-99: Minor: ensure label exists in X-axis set; consider batching.

getMomentCurrentLabel should resolve to one of labels; if not, updates will append a new tick. If supported, batch the 4-series update to one chart.update.

apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsChart.tsx (1)

68-81: Verify label mapping; align order or batch.

Init labels: [Open, Queued, On_Hold_Chats, Closed]. Updates run Open, Closed, On_Hold_Chats, Queued. If updateChart matches by label, OK; if index-based, this mismatches. Prefer batching to reduce redraws.

- updateChartData(t('Open'), [open]);
- updateChartData(t('Closed'), [closed]);
- updateChartData(t('On_Hold_Chats'), [onhold]);
- updateChartData(t('Queued'), [queued]);
+ updateChartData(t('Open'), [open]);
+ updateChartData(t('Queued'), [queued]);
+ updateChartData(t('On_Hold_Chats'), [onhold]);
+ updateChartData(t('Closed'), [closed]);
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerAgentChart.tsx (2)

42-47: Context-based init/update path LGTM; consider Chart destroy on unmount.

Adoption is correct. Add destroy in useChartContext to prevent leaks, as suggested in related comments.

Also applies to: 49-54


56-72: Reset and ordering strategy for full refresh.

If agents change across queries, updating without a reset can leave stale labels. Reset before repopulating and use stable ordering to reduce jitter.

- if (data.length === 0) {
-   resetChart(context);
-   return;
- }
-
- data.forEach(([name, value]) => {
-   updateChartData(name, [value.open, value.closed, value.onhold]);
- });
+ resetChart(context);
+ for (const [name, value] of [...data].sort((a, b) => a[0].localeCompare(b[0]))) {
+   updateChartData(name, [value.open, value.closed, value.onhold]);
+ }
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerDepartmentChart.tsx (1)

56-73: Optional: Reset chart on query error
Destructure isError from the useQuery result and insert before the !isSuccess guard:

-   if (!isSuccess) {
+   if (isError) {
+     resetChart(context);
+     return;
+   }
+
+   if (!isSuccess) {
      return;
    }

This clears stale data on failure. The existing data.forEach(([name, value]) => updateChartData(name, [value.open, value.closed])); correctly handles the [departmentName, { open, closed }] tuples returned by your select mapping.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5e821ad and 6c912aa.

📒 Files selected for processing (10)
  • .changeset/rare-schools-laugh.md (1 hunks)
  • apps/meteor/app/livechat/client/lib/chartHandler.ts (1 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/AgentStatusChart.tsx (2 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatDurationChart.tsx (3 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsChart.tsx (2 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerAgentChart.tsx (2 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerDepartmentChart.tsx (2 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ResponseTimesChart.tsx (2 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (7)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/AgentStatusChart.tsx (2)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1)
  • useChartContext (13-35)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts (1)
  • useUpdateChartData (15-32)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerDepartmentChart.tsx (3)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1)
  • useChartContext (13-35)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts (1)
  • useUpdateChartData (15-32)
apps/meteor/app/livechat/client/lib/chartHandler.ts (1)
  • resetChart (213-220)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ResponseTimesChart.tsx (2)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1)
  • useChartContext (13-35)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts (1)
  • useUpdateChartData (15-32)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts (1)
apps/meteor/app/livechat/client/lib/chartHandler.ts (1)
  • updateChart (187-211)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatDurationChart.tsx (2)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1)
  • useChartContext (13-35)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts (1)
  • useUpdateChartData (15-32)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerAgentChart.tsx (3)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1)
  • useChartContext (13-35)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts (1)
  • useUpdateChartData (15-32)
apps/meteor/app/livechat/client/lib/chartHandler.ts (1)
  • resetChart (213-220)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsChart.tsx (2)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1)
  • useChartContext (13-35)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts (1)
  • useUpdateChartData (15-32)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: 🔨 Test Unit / Unit Tests
  • GitHub Check: 🔎 Code Check / Code Lint
  • GitHub Check: 🔎 Code Check / TypeScript
  • GitHub Check: 📦 Meteor Build - coverage
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build
🔇 Additional comments (18)
.changeset/rare-schools-laugh.md (1)

1-6: LGTM!

The changeset correctly documents a patch-level fix for the real-time monitoring data issue.

apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts (2)

8-13: API simplified from ref to direct context value.

The change from MutableRefObject<TChart | undefined> to TChart | undefined removes unnecessary indirection and aligns with the new useChartContext hook pattern. This is a breaking change but is intentional and correct given the architectural refactor.


21-31: Fallback initialization logic is correct.

The logic correctly falls back to init when no context is provided, ensuring the chart is initialized before attempting updates. This maintains compatibility during the transition to context-based initialization.

apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (2)

27-28: LGTM on cache configuration.

staleTime: Infinity with gcTime: 0 is the correct combination: data never becomes stale while the query is active, but cache is cleared immediately on unmount, preventing stale data issues identified in the PR objectives.


16-32: Ignore unnecessary refetch warning: canvas is created via useRef and passed as canvas.current, ensuring a stable reference and no extra reinitialization.

Likely an incorrect or invalid review comment.

apps/meteor/app/livechat/client/lib/chartHandler.ts (1)

213-220: LGTM!

The resetChart utility correctly clears all labels and dataset data before triggering a chart update. Implementation is clean and follows the same pattern as updateChart.

apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatDurationChart.tsx (2)

57-58: LGTM on gcTime configuration.

Setting gcTime: 0 correctly prevents stale cached data when returning to the page, addressing the root cause identified in the PR objectives.


60-72: Chart context integration is correct.

The component correctly adopts the new useChartContext pattern, passing the context directly to useUpdateChartData instead of using a ref. This eliminates the race condition described in the PR objectives.

apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ResponseTimesChart.tsx (1)

73-78: Context-driven init/update path LGTM.

Guarding on context removes the prior race. No issues spotted.

Also applies to: 80-85

apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsChart.tsx (2)

49-50: gcTime: 0 to prevent stale cache on return.

Matches PR goal; good.


52-58: Adopting useChartContext/useUpdateChartData removes the init/update race.

Looks correct; no blocking issues.

Also applies to: 59-64

apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/AgentStatusChart.tsx (1)

48-49: Use of gcTime is correct
The project depends on “@tanstack/react-query” v5.65.1, so gcTime is supported and should remain to prevent stale caches.

apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerAgentChart.tsx (1)

38-40: Remove unnecessary success destructuring in select. The endpoint returns a typed Record<string, { open: number; closed: number; onhold: number }>, so replace

select: ({ success: _, ...data }) => Object.entries(data),

with

select: metrics => Object.entries(metrics),

and, if desired, add generics to useQuery for full type safety:

useQuery<Record<string, AgentMetrics>, Error, [string, AgentMetrics][]>

Likely an incorrect or invalid review comment.

apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerDepartmentChart.tsx (5)

12-14: LGTM! Imports align with the new chart context architecture.

The addition of useChartContext and resetChart supports the PR's goal of eliminating race conditions in chart initialization and providing proper cleanup when data is empty.


73-73: Dependency array is comprehensive.

All dependencies are correctly included:

  • context, data, isSuccess are directly used in the effect
  • updateChartData is stable (from useEffectEvent) but including it is harmless
  • t is included transitively through updateChartData and ensures the effect re-runs if translations change

The exhaustive dependency list prevents stale closures and aligns with React best practices.


42-47: Ignore the canvas ref reactivity concern; useChartContext’s enabled: !!canvas guard plus the parent data query-triggered re-render ensure the chart is initialized once canvas.current is available.

Likely an incorrect or invalid review comment.


49-54: No race condition detected. All updateChartData invocations in the real-time-monitoring charts are wrapped in if (!context) return; (and if (!isSuccess) return;) guards, so the fallback initialization path in useUpdateChartData will never run prematurely.


38-39: Verify API response structure for select transformation.

The select function destructures success and converts remaining properties to entries. Ensure the API response from /v1/livechat/analytics/dashboards/charts/chats-per-department returns an object with a success field and department data as top-level properties.

The gcTime: 0 configuration correctly prevents stale data after unmount, as per the PR objectives.

Run the following script to verify the API response structure:

@aleksandernsilva aleksandernsilva force-pushed the fix/real-time-monitoring branch from 15c0b00 to a99f754 Compare October 1, 2025 18:37
Copy link
Contributor

@lucas-a-pelegrino lucas-a-pelegrino left a comment

Choose a reason for hiding this comment

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

LGTM!

@jessicaschelly
Copy link
Member

Is it possible to add tests? API ones?

@dougfabris dougfabris added this to the 7.12.0 milestone Oct 8, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 6c912aa and 3549835.

📒 Files selected for processing (10)
  • .changeset/rare-schools-laugh.md (1 hunks)
  • apps/meteor/app/livechat/client/lib/chartHandler.ts (1 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/AgentStatusChart.tsx (2 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatDurationChart.tsx (3 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsChart.tsx (2 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerAgentChart.tsx (2 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerDepartmentChart.tsx (2 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ResponseTimesChart.tsx (2 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • .changeset/rare-schools-laugh.md
  • apps/meteor/app/livechat/client/lib/chartHandler.ts
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsChart.tsx
🧰 Additional context used
🧬 Code graph analysis (6)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ResponseTimesChart.tsx (2)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1)
  • useChartContext (11-35)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts (1)
  • useUpdateChartData (15-32)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerAgentChart.tsx (3)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1)
  • useChartContext (11-35)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts (1)
  • useUpdateChartData (15-32)
apps/meteor/app/livechat/client/lib/chartHandler.ts (1)
  • resetChart (213-220)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerDepartmentChart.tsx (3)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1)
  • useChartContext (11-35)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts (1)
  • useUpdateChartData (15-32)
apps/meteor/app/livechat/client/lib/chartHandler.ts (1)
  • resetChart (213-220)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts (1)
apps/meteor/app/livechat/client/lib/chartHandler.ts (1)
  • updateChart (187-211)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/AgentStatusChart.tsx (2)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1)
  • useChartContext (11-35)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts (1)
  • useUpdateChartData (15-32)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatDurationChart.tsx (2)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1)
  • useChartContext (11-35)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts (1)
  • useUpdateChartData (15-32)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build
🔇 Additional comments (2)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerAgentChart.tsx (1)

38-39: Ignore the departments change: the chats-per-agent endpoint returns { success: true, [agentId]: { open, closed, onhold } }, so

select: ({ success: _, ...data }) => Object.entries(data)

correctly extracts each agent’s metrics.

Likely an incorrect or invalid review comment.

apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerDepartmentChart.tsx (1)

38-39: Keep select as { success: _, ...data }
The endpoint returns the metrics map at the top level (e.g. { success: true, Sales: {…}, Support: {…} }), not nested under departments, so the current select correctly extracts each department’s data.

Likely an incorrect or invalid review comment.

@aleksandernsilva aleksandernsilva force-pushed the fix/real-time-monitoring branch from 3549835 to afacca7 Compare October 8, 2025 19:14
@aleksandernsilva aleksandernsilva marked this pull request as draft October 8, 2025 19:32
@aleksandernsilva aleksandernsilva force-pushed the fix/real-time-monitoring branch from afacca7 to 006f4f0 Compare October 9, 2025 17:32
@aleksandernsilva aleksandernsilva marked this pull request as ready for review October 9, 2025 18:57
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1)

33-33: Optional: Consider impact of unmemoized init function.

The effect includes init in its dependency array. If callers don't memoize this function (e.g., with useCallback), the effect will re-run on every parent render, destroying and recreating the chart unnecessarily. Consider documenting this requirement or adding a ref-based approach to avoid dependency on init.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between afacca7 and 006f4f0.

📒 Files selected for processing (7)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/AgentStatusChart.tsx (2 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatDurationChart.tsx (3 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsChart.tsx (2 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerAgentChart.tsx (2 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerDepartmentChart.tsx (2 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ResponseTimesChart.tsx (2 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ResponseTimesChart.tsx
🧰 Additional context used
🧬 Code graph analysis (5)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatDurationChart.tsx (2)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1)
  • useChartContext (12-36)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts (1)
  • useUpdateChartData (15-32)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerAgentChart.tsx (3)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1)
  • useChartContext (12-36)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts (1)
  • useUpdateChartData (15-32)
apps/meteor/app/livechat/client/lib/chartHandler.ts (1)
  • resetChart (213-220)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsChart.tsx (2)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1)
  • useChartContext (12-36)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts (1)
  • useUpdateChartData (15-32)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerDepartmentChart.tsx (4)
packages/fuselage-ui-kit/src/surfaces/FuselageSurfaceRenderer.tsx (1)
  • context (110-120)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1)
  • useChartContext (12-36)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts (1)
  • useUpdateChartData (15-32)
apps/meteor/app/livechat/client/lib/chartHandler.ts (1)
  • resetChart (213-220)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/AgentStatusChart.tsx (2)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1)
  • useChartContext (12-36)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts (1)
  • useUpdateChartData (15-32)
🔇 Additional comments (2)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatDurationChart.tsx (1)

55-58: Confirm gcTime is supported by our React Query version.

gcTime is only available in TanStack Query v5. If we are still on v4, this option will be ignored (and TS will complain), so please double-check the package version before we rely on this change; otherwise keep using cacheTime or bundle the upgrade here.

apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1)

23-23: Verify: Always passing undefined context prevents chart reuse.

The hook always passes undefined as the context parameter to init (line 23), which means the chart is recreated from scratch on every effect run. Chart.js best practice is to reuse instances via chart.update() rather than destroying and recreating. If the init function is designed to handle updates when a chart instance is provided, consider passing the existing context.

Based on learnings about Chart.js: "Reuse chart instances (update() instead of re-creating) for performance."

Is the destroy-and-recreate pattern intentional for this use case, or should the hook attempt to update existing charts when dependencies change?

If updates are preferred, apply this diff:

-	chart = await init(canvas.current, undefined, t);
+	chart = await init(canvas.current, context, t);

And add context to the effect dependencies on line 33.

@aleksandernsilva aleksandernsilva force-pushed the fix/real-time-monitoring branch from 006f4f0 to f54227c Compare October 9, 2025 20:12
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 006f4f0 and f54227c.

📒 Files selected for processing (7)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/AgentStatusChart.tsx (2 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatDurationChart.tsx (3 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsChart.tsx (2 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerAgentChart.tsx (2 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerDepartmentChart.tsx (2 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ResponseTimesChart.tsx (2 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerDepartmentChart.tsx
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/AgentStatusChart.tsx
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatDurationChart.tsx
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx
🧰 Additional context used
🧬 Code graph analysis (3)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerAgentChart.tsx (3)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1)
  • useChartContext (12-44)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts (1)
  • useUpdateChartData (15-32)
apps/meteor/app/livechat/client/lib/chartHandler.ts (1)
  • resetChart (213-220)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ResponseTimesChart.tsx (2)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1)
  • useChartContext (12-44)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts (1)
  • useUpdateChartData (15-32)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsChart.tsx (2)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1)
  • useChartContext (12-44)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts (1)
  • useUpdateChartData (15-32)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build
🔇 Additional comments (5)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ResponseTimesChart.tsx (5)

14-14: LGTM: Import addition supports the refactoring.

The useChartContext import is correctly added to support the new centralized chart initialization pattern.


70-70: LGTM: Cache configuration ensures data freshness.

Setting gcTime: 0 prevents stale cached data when returning to the real-time monitoring page. This is an appropriate tradeoff for a real-time monitoring dashboard where data freshness is critical, though it will trigger a fresh API call on each mount.


73-77: LGTM: Centralized chart initialization resolves race condition.

Using useChartContext replaces the previous manual context management and fixes the race condition where charts were initialized in multiple places. The hook properly manages the chart lifecycle and ensures initialization completes before updates are applied.


79-84: LGTM: Chart updates now use initialized context.

Passing context to useUpdateChartData ensures that chart updates only occur on the properly initialized chart instance, preventing the race condition where updates might target the wrong chart.


86-97: LGTM: Update logic correctly guards against uninitialized state.

The early returns ensure the chart is initialized (context is defined) and data is available (isSuccess) before attempting updates. Adding context to the dependency array ensures the effect runs when the chart becomes available, properly handling the asynchronous initialization flow.

dougfabris
dougfabris previously approved these changes Oct 14, 2025
Copy link
Member

@dougfabris dougfabris left a comment

Choose a reason for hiding this comment

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

@dougfabris dougfabris added the stat: QA assured Means it has been tested and approved by a company insider label Oct 14, 2025
@dionisio-bot dionisio-bot bot added the stat: ready to merge PR tested and approved waiting for merge label Oct 14, 2025
@dougfabris dougfabris removed the stat: QA assured Means it has been tested and approved by a company insider label Oct 14, 2025
@dionisio-bot dionisio-bot bot removed the stat: ready to merge PR tested and approved waiting for merge label Oct 14, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerAgentChart.tsx (1)

17-23: Dataset count mismatch in drawLineChart (3 labels but only 2 datasets).

This will misalign series with labels and can break initialization.

Apply this diff:

- drawLineChart(canvas, context, [t('Open'), t('Closed'), t('On_Hold_Chats')], [], [[], []], {
+ drawLineChart(canvas, context, [t('Open'), t('Closed'), t('On_Hold_Chats')], [], [[], [], []], {
♻️ Duplicate comments (1)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerAgentChart.tsx (1)

35-40: Fix data selection: unwrap the endpoint payload instead of Object.entries over the whole response.

Current selector yields an “agents” meta entry and bogus rows. Explicitly unwrap the agents map.

Apply this diff:

-    select: ({ success: _, ...data }) => Object.entries(data),
+    // API returns { success, agents: Record<string, { open: number; closed: number; onHold?: number; onhold?: number }> }
+    select: ({ success: _, agents }) => Object.entries(agents ?? {}),
🧹 Nitpick comments (1)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerAgentChart.tsx (1)

62-67: Guard metric fields and casing (onHold vs onhold).

Avoid runtime breaks if the server uses different casing or sparse values.

Apply this diff:

-    data.forEach(([name, value]) => {
-      updateChartData(name, [value.open, value.closed, value.onhold]);
-    });
+    data.forEach(([name, value]) => {
+      const open = value?.open ?? 0;
+      const closed = value?.closed ?? 0;
+      const onHold = (value?.onHold ?? value?.onhold) ?? 0;
+      updateChartData(name, [open, closed, onHold]);
+    });

Please confirm the exact field name returned by /v1/livechat/analytics/dashboards/charts/chats-per-agent for “on hold” (onHold vs onhold).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f54227c and 799cfb0.

📒 Files selected for processing (2)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerAgentChart.tsx (2 hunks)
  • apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerDepartmentChart.tsx (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerAgentChart.tsx (3)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1)
  • useChartContext (12-44)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts (1)
  • useUpdateChartData (15-32)
apps/meteor/app/livechat/client/lib/chartHandler.ts (1)
  • resetChart (213-220)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerDepartmentChart.tsx (3)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useChartContext.tsx (1)
  • useChartContext (12-44)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/useUpdateChartData.ts (1)
  • useUpdateChartData (15-32)
apps/meteor/app/livechat/client/lib/chartHandler.ts (1)
  • resetChart (213-220)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build
🔇 Additional comments (3)
apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerAgentChart.tsx (1)

42-53: Lifecycle improvements via useChartContext and resetChart look good.

Also applies to: 56-63

apps/meteor/client/views/omnichannel/realTimeMonitoring/charts/ChatsPerDepartmentChart.tsx (2)

42-53: Context-driven init and reset flow is solid.

Also applies to: 56-69


35-40: Incorrect suggestion: no departments wrapper
The /chats-per-department endpoint returns its metrics as top-level keys (after stripping success), so your selector’s ({ success: _, ...data }) => Object.entries(data) already unwraps the payload correctly—there is no nested departments property.

Likely an incorrect or invalid review comment.

@dougfabris dougfabris added the stat: QA assured Means it has been tested and approved by a company insider label Oct 14, 2025
@dionisio-bot dionisio-bot bot added the stat: ready to merge PR tested and approved waiting for merge label Oct 14, 2025
@kodiakhq kodiakhq bot merged commit 2f59e71 into develop Oct 15, 2025
49 checks passed
@kodiakhq kodiakhq bot deleted the fix/real-time-monitoring branch October 15, 2025 06:26
@scuciatto
Copy link
Member

/patch

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Oct 15, 2025

Pull request #37236 added to Project: "Patch 7.10.2"

@scuciatto
Copy link
Member

/backport 7.9.5

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Oct 15, 2025

Pull request #37237 added to Project: "Patch 7.9.5"

@coderabbitai coderabbitai bot mentioned this pull request Oct 15, 2025
antm-rp pushed a commit to antm-rp/Rocket.Chat that referenced this pull request Oct 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stat: QA assured Means it has been tested and approved by a company insider stat: ready to merge PR tested and approved waiting for merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants