feat: Overview heatmap improvements (#12359)

This PR adds inbox filtering to the conversation traffic heatmap,
allowing users to analyze patterns for specific inboxes. Additionally,
it also adds a new resolution count heatmap that shows when support
teams are most active in resolving conversations, using a green color to
distinguish it from the blue conversation heatmap.

The PR also reorganizes heatmap components into a cleaner structure with
a shared `BaseHeatmapContainer` that handles common functionality like
date range selection, inbox filtering, and data fetching. This makes it
easy to add new heatmap metrics in the future - just create a wrapper
component specifying the metric type and color scheme.

<img width="1926" height="1670" alt="CleanShot 2025-10-13 at 14 01
35@2x"
src="https://github.com/user-attachments/assets/67822a34-6170-4d19-9e11-7ad4ded5c388"
/>

<img width="1964" height="1634" alt="CleanShot 2025-10-13 at 14 03
00@2x"
src="https://github.com/user-attachments/assets/e4613c08-64b8-4fa6-91d8-7510946dd75d"
/>


Unrelated change, the data seeder conversation resolution would not work
correctly, we've fixed it.

---------

Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
This commit is contained in:
Shivam Mishra
2025-10-13 19:15:57 +05:30
committed by GitHub
parent 38f16ba677
commit f1f1ce644c
13 changed files with 668 additions and 307 deletions

View File

@@ -57,11 +57,13 @@ const state = {
uiFlags: {
isFetchingAccountConversationMetric: false,
isFetchingAccountConversationsHeatmap: false,
isFetchingAccountResolutionsHeatmap: false,
isFetchingAgentConversationMetric: false,
isFetchingTeamConversationMetric: false,
},
accountConversationMetric: {},
accountConversationHeatmap: [],
accountResolutionHeatmap: [],
agentConversationMetric: [],
teamConversationMetric: [],
},
@@ -89,6 +91,9 @@ const getters = {
getAccountConversationHeatmapData(_state) {
return _state.overview.accountConversationHeatmap;
},
getAccountResolutionHeatmapData(_state) {
return _state.overview.accountResolutionHeatmap;
},
getAgentConversationMetric(_state) {
return _state.overview.agentConversationMetric;
},
@@ -130,6 +135,16 @@ export const actions = {
commit(types.default.TOGGLE_HEATMAP_LOADING, false);
});
},
fetchAccountResolutionHeatmap({ commit }, reportObj) {
commit(types.default.TOGGLE_RESOLUTION_HEATMAP_LOADING, true);
Report.getReports({ ...reportObj, groupBy: 'hour' }).then(heatmapData => {
let { data } = heatmapData;
data = clampDataBetweenTimeline(data, reportObj.from, reportObj.to);
commit(types.default.SET_RESOLUTION_HEATMAP_DATA, data);
commit(types.default.TOGGLE_RESOLUTION_HEATMAP_LOADING, false);
});
},
fetchAccountSummary({ commit }, reportObj) {
commit(types.default.SET_ACCOUNT_SUMMARY_STATUS, STATUS.FETCHING);
Report.getSummary(
@@ -287,6 +302,9 @@ const mutations = {
[types.default.SET_HEATMAP_DATA](_state, heatmapData) {
_state.overview.accountConversationHeatmap = heatmapData;
},
[types.default.SET_RESOLUTION_HEATMAP_DATA](_state, heatmapData) {
_state.overview.accountResolutionHeatmap = heatmapData;
},
[types.default.TOGGLE_ACCOUNT_REPORT_LOADING](_state, { metric, value }) {
_state.accountReport.isFetching[metric] = value;
},
@@ -299,6 +317,9 @@ const mutations = {
[types.default.TOGGLE_HEATMAP_LOADING](_state, flag) {
_state.overview.uiFlags.isFetchingAccountConversationsHeatmap = flag;
},
[types.default.TOGGLE_RESOLUTION_HEATMAP_LOADING](_state, flag) {
_state.overview.uiFlags.isFetchingAccountResolutionsHeatmap = flag;
},
[types.default.SET_ACCOUNT_SUMMARY](_state, summaryData) {
_state.accountSummary = summaryData;
},