diff --git a/app/javascript/dashboard/helper/ReconnectService.js b/app/javascript/dashboard/helper/ReconnectService.js index 12ada24bd..39b48ebff 100644 --- a/app/javascript/dashboard/helper/ReconnectService.js +++ b/app/javascript/dashboard/helper/ReconnectService.js @@ -6,6 +6,7 @@ import { isAInboxViewRoute, isNotificationRoute, } from 'dashboard/helper/routeHelpers'; +import { cacheableModels } from 'dashboard/helper/CacheHelper/cacheableModels'; const MAX_DISCONNECT_SECONDS = 10800; @@ -99,14 +100,14 @@ class ReconnectService { }; revalidateCaches = async () => { - const { label, inbox, team } = await this.store.dispatch( - 'accounts/getCacheKeys' + const keys = (await this.store.dispatch('accounts/getCacheKeys')) || {}; + await Promise.all( + cacheableModels + .filter(model => keys[model.name] !== undefined) + .map(model => + this.store.dispatch(model.dispatchPath, { newKey: keys[model.name] }) + ) ); - await Promise.all([ - this.store.dispatch('labels/revalidate', { newKey: label }), - this.store.dispatch('inboxes/revalidate', { newKey: inbox }), - this.store.dispatch('teams/revalidate', { newKey: team }), - ]); }; handleRouteSpecificFetch = async () => { diff --git a/app/javascript/dashboard/helper/actionCable.js b/app/javascript/dashboard/helper/actionCable.js index 74b82105c..b00d0f0e4 100644 --- a/app/javascript/dashboard/helper/actionCable.js +++ b/app/javascript/dashboard/helper/actionCable.js @@ -5,6 +5,7 @@ import { BUS_EVENTS } from 'shared/constants/busEvents'; import { emitter } from 'shared/helpers/mitt'; import { useImpersonation } from 'dashboard/composables/useImpersonation'; import { FEATURE_FLAGS } from 'dashboard/featureFlags'; +import { cacheableModels } from './CacheHelper/cacheableModels'; const { isImpersonating } = useImpersonation(); const UNREAD_COUNTS_REFETCH_THROTTLE_MS = 5000; @@ -256,10 +257,12 @@ class ActionCableConnector extends BaseActionCableConnector { }; onCacheInvalidate = data => { - const keys = data.cache_keys; - this.app.$store.dispatch('labels/revalidate', { newKey: keys.label }); - this.app.$store.dispatch('inboxes/revalidate', { newKey: keys.inbox }); - this.app.$store.dispatch('teams/revalidate', { newKey: keys.team }); + const keys = data.cache_keys || {}; + cacheableModels.forEach(model => { + const newKey = keys[model.name]; + if (newKey === undefined) return; + this.app.$store.dispatch(model.dispatchPath, { newKey }); + }); }; } diff --git a/app/javascript/dashboard/helper/specs/ReconnectService.spec.js b/app/javascript/dashboard/helper/specs/ReconnectService.spec.js index 60bd825ee..6b0894662 100644 --- a/app/javascript/dashboard/helper/specs/ReconnectService.spec.js +++ b/app/javascript/dashboard/helper/specs/ReconnectService.spec.js @@ -254,11 +254,13 @@ describe('ReconnectService', () => { }); describe('revalidateCaches', () => { - it('should dispatch revalidate actions for labels, inboxes, and teams', async () => { + it('should dispatch revalidate actions for every cacheable model returned by the server', async () => { storeMock.dispatch.mockResolvedValueOnce({ label: 'labelKey', inbox: 'inboxKey', team: 'teamKey', + canned_response: 'cannedKey', + account_user: 'accountUserKey', }); await reconnectService.revalidateCaches(); expect(storeMock.dispatch).toHaveBeenCalledWith('accounts/getCacheKeys'); @@ -271,6 +273,31 @@ describe('ReconnectService', () => { expect(storeMock.dispatch).toHaveBeenCalledWith('teams/revalidate', { newKey: 'teamKey', }); + expect(storeMock.dispatch).toHaveBeenCalledWith( + 'revalidateCannedResponses', + { newKey: 'cannedKey' } + ); + expect(storeMock.dispatch).toHaveBeenCalledWith('agents/revalidate', { + newKey: 'accountUserKey', + }); + }); + + it('should skip dispatches for models the server does not yet emit', async () => { + storeMock.dispatch.mockResolvedValueOnce({ + label: 'labelKey', + inbox: 'inboxKey', + team: 'teamKey', + // canned_response / account_user omitted (older server) + }); + await reconnectService.revalidateCaches(); + expect(storeMock.dispatch).not.toHaveBeenCalledWith( + 'revalidateCannedResponses', + expect.anything() + ); + expect(storeMock.dispatch).not.toHaveBeenCalledWith( + 'agents/revalidate', + expect.anything() + ); }); });