From 6aa3fa7b85d552649c0b28af08176693d556895f Mon Sep 17 00:00:00 2001 From: Bharath Balan <62698609+bhabalan@users.noreply.github.com> Date: Fri, 9 Jan 2026 08:39:24 +0530 Subject: [PATCH 1/3] feat(consult-popover): add refresh button and other improvements --- .../consult-transfer-popover-hooks.ts | 9 + .../consult-transfer-popover.tsx | 81 ++- .../task/CallControl/call-control.styles.scss | 23 + .../task/CallControl/call-control.tsx | 3 + .../src/components/task/constants.ts | 3 - .../src/components/task/task.types.ts | 8 + ...consult-transfer-popover.snapshot.tsx.snap | 506 +++++++++++++++++- .../consult-transfer-popover.snapshot.tsx | 1 + .../consult-transfer-popover.tsx | 1 + .../CallControl/call-control.snapshot.tsx | 1 + .../task/CallControl/call-control.tsx | 1 + .../call-control-cad.snapshot.tsx | 1 + .../task/CallControlCAD/call-control-cad.tsx | 1 + .../task/src/Utils/task-util.ts | 46 +- packages/contact-center/task/src/helper.ts | 5 + .../task/tests/CallControl/index.tsx | 1 + .../task/tests/CallControlCAD/index.tsx | 4 + 17 files changed, 662 insertions(+), 33 deletions(-) diff --git a/packages/contact-center/cc-components/src/components/task/CallControl/CallControlCustom/consult-transfer-popover-hooks.ts b/packages/contact-center/cc-components/src/components/task/CallControl/CallControlCustom/consult-transfer-popover-hooks.ts index 84c7268dc..c827bc1de 100644 --- a/packages/contact-center/cc-components/src/components/task/CallControl/CallControlCustom/consult-transfer-popover-hooks.ts +++ b/packages/contact-center/cc-components/src/components/task/CallControl/CallControlCustom/consult-transfer-popover-hooks.ts @@ -315,6 +315,14 @@ export function useConsultTransferPopover({ } }, [selectedCategory]); + const handleReload = useCallback(() => { + logger?.info(`CC-Components: Reloading ${selectedCategory} data`, { + module: 'cc-components#consult-transfer-popover-hooks.ts', + method: 'useConsultTransferPopover#handleReload', + }); + loadCategory(selectedCategory, 0, searchQuery, true); + }, [selectedCategory, searchQuery, loadDialNumbers, loadEntryPoints, loadQueues, logger]); + return { selectedCategory, searchQuery, @@ -333,5 +341,6 @@ export function useConsultTransferPopover({ handleQueuesClick, handleDialNumberClick, handleEntryPointClick, + handleReload, }; } diff --git a/packages/contact-center/cc-components/src/components/task/CallControl/CallControlCustom/consult-transfer-popover.tsx b/packages/contact-center/cc-components/src/components/task/CallControl/CallControlCustom/consult-transfer-popover.tsx index 822aba8ba..69dc3719c 100644 --- a/packages/contact-center/cc-components/src/components/task/CallControl/CallControlCustom/consult-transfer-popover.tsx +++ b/packages/contact-center/cc-components/src/components/task/CallControl/CallControlCustom/consult-transfer-popover.tsx @@ -1,6 +1,6 @@ import React, {useState} from 'react'; import {Text, ListNext, TextInput, Button, ButtonCircle, TooltipNext} from '@momentum-ui/react-collaboration'; -import {Icon, Checkbox} from '@momentum-design/components/dist/react'; +import {Icon, Checkbox, Spinner} from '@momentum-design/components/dist/react'; import ConsultTransferListComponent from './consult-transfer-list-item'; import {ConsultTransferPopoverComponentProps} from '../../task.types'; import ConsultTransferEmptyState from './consult-transfer-empty-state'; @@ -16,9 +16,6 @@ import { SEARCH_PLACEHOLDER, CLEAR_SEARCH, SCROLL_TO_LOAD_MORE, - LOADING_MORE_QUEUES, - LOADING_MORE_DIAL_NUMBERS, - LOADING_MORE_ENTRY_POINTS, NO_DATA_AVAILABLE_CONSULT_TRANSFER, } from '../../constants'; import {CATEGORY_AGENTS, CATEGORY_DIAL_NUMBER, CATEGORY_ENTRY_POINT, CATEGORY_QUEUES} from '../../task.types'; @@ -27,6 +24,8 @@ const ConsultTransferPopoverComponent: React.FC +
+ { + if (selectedCategory === CATEGORY_AGENTS && loadBuddyAgents) { + loadBuddyAgents(); + } else { + handleReload(); + } + }} + disabled={loadingBuddyAgents || loadingDialNumbers || loadingEntryPoints || loadingQueues} + > + + + } + color="secondary" + delay={[0, 0]} + placement="bottom-start" + type="description" + variant="small" + className="tooltip" + > +

{`Reload ${selectedCategory}`}

+
+
{consultTransferManualAction.visible && ( {selectedCategory === 'Agents' && - (getAgentsForDisplay(selectedCategory, buddyAgents, searchQuery).length === 0 ? ( + (loadingBuddyAgents ? ( +
+ +
+ ) : getAgentsForDisplay(selectedCategory, buddyAgents, searchQuery).length === 0 ? ( ) : ( renderList( @@ -212,7 +247,11 @@ const ConsultTransferPopoverComponent: React.FC + + + ) : noQueues ? ( ) : (
@@ -223,9 +262,9 @@ const ConsultTransferPopoverComponent: React.FC {loadingQueues ? ( - - {LOADING_MORE_QUEUES} - +
+ +
) : ( {SCROLL_TO_LOAD_MORE} @@ -238,7 +277,11 @@ const ConsultTransferPopoverComponent: React.FC + +
+ ) : noDialNumbers ? ( ) : (
@@ -253,9 +296,9 @@ const ConsultTransferPopoverComponent: React.FC {loadingDialNumbers ? ( - - {LOADING_MORE_DIAL_NUMBERS} - +
+ +
) : ( {SCROLL_TO_LOAD_MORE} @@ -268,7 +311,11 @@ const ConsultTransferPopoverComponent: React.FC + +
+ ) : noEntryPoints ? ( ) : (
@@ -281,9 +328,9 @@ const ConsultTransferPopoverComponent: React.FC {loadingEntryPoints ? ( - - {LOADING_MORE_ENTRY_POINTS} - +
+ +
) : ( {SCROLL_TO_LOAD_MORE} diff --git a/packages/contact-center/cc-components/src/components/task/CallControl/call-control.styles.scss b/packages/contact-center/cc-components/src/components/task/CallControl/call-control.styles.scss index 1b1df41b4..58b02d01f 100644 --- a/packages/contact-center/cc-components/src/components/task/CallControl/call-control.styles.scss +++ b/packages/contact-center/cc-components/src/components/task/CallControl/call-control.styles.scss @@ -230,10 +230,24 @@ min-width: 0; } + .consult-action-buttons { + display: flex; + align-items: center; + gap: 0.5rem; + flex-shrink: 0; + } + + .consult-reload-button, .consult-quick-action-button { flex: 0 0 2rem; /* 32px */ } + .consult-reload-button { + mdc-icon { + --mdc-icon-fill-color: var(--mds-color-theme-text-primary-normal); + } + } + .consult-category-buttons { margin: 0.5rem 0; display: flex; @@ -271,6 +285,15 @@ align-items: center; } + .consult-loading-spinner { + // Centering the spinner in the loading area + display: flex; + justify-content: center; + align-items: center; + min-height: 10rem; + width: 100%; + } + .consult-list-container { flex: 1; overflow-y: auto; diff --git a/packages/contact-center/cc-components/src/components/task/CallControl/call-control.tsx b/packages/contact-center/cc-components/src/components/task/CallControl/call-control.tsx index 9eb5c8f0d..7dfb1b137 100644 --- a/packages/contact-center/cc-components/src/components/task/CallControl/call-control.tsx +++ b/packages/contact-center/cc-components/src/components/task/CallControl/call-control.tsx @@ -45,6 +45,7 @@ function CallControlComponent(props: CallControlComponentProps) { isRecording, setIsRecording, buddyAgents, + loadingBuddyAgents, loadBuddyAgents, transferCall, consultCall, @@ -221,6 +222,8 @@ function CallControlComponent(props: CallControlComponentProps) { heading={button.menuType} buttonIcon={button.icon} buddyAgents={buddyAgents} + loadingBuddyAgents={loadingBuddyAgents} + loadBuddyAgents={loadBuddyAgents} getAddressBookEntries={getAddressBookEntries} getEntryPoints={getEntryPoints} getQueues={getQueuesFetcher} diff --git a/packages/contact-center/cc-components/src/components/task/constants.ts b/packages/contact-center/cc-components/src/components/task/constants.ts index 633dbff01..8308c8b9b 100644 --- a/packages/contact-center/cc-components/src/components/task/constants.ts +++ b/packages/contact-center/cc-components/src/components/task/constants.ts @@ -22,9 +22,6 @@ export const QUEUES = 'Queues'; export const SEARCH_PLACEHOLDER = 'Search...'; export const CLEAR_SEARCH = 'Clear search'; export const SCROLL_TO_LOAD_MORE = 'Scroll to load more'; -export const LOADING_MORE_QUEUES = 'Loading more queues...'; -export const LOADING_MORE_DIAL_NUMBERS = 'Loading more dial numbers...'; -export const LOADING_MORE_ENTRY_POINTS = 'Loading more entry points...'; export const NO_DATA_AVAILABLE_CONSULT_TRANSFER = 'No data available for consult transfer.'; export const VIA_SEARCH_SUFFIX = ' via search'; // Pagination diff --git a/packages/contact-center/cc-components/src/components/task/task.types.ts b/packages/contact-center/cc-components/src/components/task/task.types.ts index 7a0a2c65c..aac63d7ca 100644 --- a/packages/contact-center/cc-components/src/components/task/task.types.ts +++ b/packages/contact-center/cc-components/src/components/task/task.types.ts @@ -282,6 +282,11 @@ export interface ControlProps { */ buddyAgents: BuddyDetails[]; + /** + * Flag to indicate if buddy agents are being loaded + */ + loadingBuddyAgents: boolean; + /** * Function to load buddy agents */ @@ -480,6 +485,7 @@ export type CallControlComponentProps = Pick< | 'isRecording' | 'setIsRecording' | 'buddyAgents' + | 'loadingBuddyAgents' | 'loadBuddyAgents' | 'transferCall' | 'consultCall' @@ -612,6 +618,8 @@ export interface ConsultTransferPopoverComponentProps { heading: string; buttonIcon: string; buddyAgents: BuddyDetails[]; + loadingBuddyAgents: boolean; + loadBuddyAgents?: () => Promise; getAddressBookEntries?: FetchPaginatedList; getEntryPoints?: FetchPaginatedList; getQueues?: FetchPaginatedList; diff --git a/packages/contact-center/cc-components/tests/components/task/CallControl/CallControlCustom/__snapshots__/consult-transfer-popover.snapshot.tsx.snap b/packages/contact-center/cc-components/tests/components/task/CallControl/CallControlCustom/__snapshots__/consult-transfer-popover.snapshot.tsx.snap index f661e7b40..58b4c9df9 100644 --- a/packages/contact-center/cc-components/tests/components/task/CallControl/CallControlCustom/__snapshots__/consult-transfer-popover.snapshot.tsx.snap +++ b/packages/contact-center/cc-components/tests/components/task/CallControl/CallControlCustom/__snapshots__/consult-transfer-popover.snapshot.tsx.snap @@ -36,6 +36,37 @@ exports[`ConsultTransferPopoverComponent Snapshots Interactions should render co style="clip-path: inset(50%); height: 1px; overflow: hidden; position: absolute; width: 1px; white-space: nowrap;" />
+
+ +
+

+ Reload Agents +

+
+
+
+ +
+

+ Reload Queues +

+
+
+
+ +
+

+ Reload Queues +

+
+
+
+ +
+

+ Reload Agents +

+
+
+
+ +
+

+ Reload Agents +

+
+
+
+ +
+

+ Reload Agents +

+
+
+
+ +
+

+ Reload Agents +

+
+
+
+ +
+

+ Reload Agents +

+
+
+
+ +
+

+ Reload Agents +

+
+
+
+ +
+

+ Reload Queues +

+
+
-
-
- No data available for consult transfer. -
+
@@ -2099,6 +2401,37 @@ exports[`ConsultTransferPopoverComponent Snapshots Rendering - Tests for UI elem style="clip-path: inset(50%); height: 1px; overflow: hidden; position: absolute; width: 1px; white-space: nowrap;" /> +
+ +
+

+ Reload Agents +

+
+
+
+ +
+

+ Reload Queues +

+
+
+
+ +
+

+ Reload Agents +

+
+
+
+ +
+

+ Reload Agents +

+
+
+
+ +
+

+ Reload Agents +

+
+
+
+ +
+

+ Reload Queues +

+
+
{ onDialNumberSelect: jest.fn(), onEntryPointSelect: jest.fn(), allowConsultToQueue: true, + loadingBuddyAgents: false, logger: mockLogger, }; diff --git a/packages/contact-center/cc-components/tests/components/task/CallControl/CallControlCustom/consult-transfer-popover.tsx b/packages/contact-center/cc-components/tests/components/task/CallControl/CallControlCustom/consult-transfer-popover.tsx index eb6491f86..4799fbc59 100644 --- a/packages/contact-center/cc-components/tests/components/task/CallControl/CallControlCustom/consult-transfer-popover.tsx +++ b/packages/contact-center/cc-components/tests/components/task/CallControl/CallControlCustom/consult-transfer-popover.tsx @@ -60,6 +60,7 @@ describe('ConsultTransferPopoverComponent', () => { onDialNumberSelect: jest.fn(), onEntryPointSelect: jest.fn(), allowConsultToQueue: true, + loadingBuddyAgents: false, logger: loggerMock, }; diff --git a/packages/contact-center/cc-components/tests/components/task/CallControl/call-control.snapshot.tsx b/packages/contact-center/cc-components/tests/components/task/CallControl/call-control.snapshot.tsx index 949b6e22b..78a5324ec 100644 --- a/packages/contact-center/cc-components/tests/components/task/CallControl/call-control.snapshot.tsx +++ b/packages/contact-center/cc-components/tests/components/task/CallControl/call-control.snapshot.tsx @@ -83,6 +83,7 @@ describe('CallControlComponent Snapshots', () => { setIsRecording: jest.fn(), buddyAgents: mockBuddyAgents, loadBuddyAgents: jest.fn(), + loadingBuddyAgents: false, transferCall: jest.fn(), consultCall: jest.fn(), endConsultCall: jest.fn(), diff --git a/packages/contact-center/cc-components/tests/components/task/CallControl/call-control.tsx b/packages/contact-center/cc-components/tests/components/task/CallControl/call-control.tsx index 7037ec59f..ae6ca7221 100644 --- a/packages/contact-center/cc-components/tests/components/task/CallControl/call-control.tsx +++ b/packages/contact-center/cc-components/tests/components/task/CallControl/call-control.tsx @@ -105,6 +105,7 @@ describe('CallControlComponent', () => { setIsRecording: jest.fn(), buddyAgents: mockBuddyAgents, loadBuddyAgents: jest.fn(), + loadingBuddyAgents: false, transferCall: jest.fn(), consultCall: jest.fn(), endConsultCall: jest.fn(), diff --git a/packages/contact-center/cc-components/tests/components/task/CallControlCAD/call-control-cad.snapshot.tsx b/packages/contact-center/cc-components/tests/components/task/CallControlCAD/call-control-cad.snapshot.tsx index 0b4277f88..77197a228 100644 --- a/packages/contact-center/cc-components/tests/components/task/CallControlCAD/call-control-cad.snapshot.tsx +++ b/packages/contact-center/cc-components/tests/components/task/CallControlCAD/call-control-cad.snapshot.tsx @@ -115,6 +115,7 @@ describe('CallControlCADComponent Snapshots', () => { setIsRecording: jest.fn(), buddyAgents: mockBuddyAgents, loadBuddyAgents: jest.fn(), + loadingBuddyAgents: false, transferCall: jest.fn(), consultCall: jest.fn(), endConsultCall: jest.fn(), diff --git a/packages/contact-center/cc-components/tests/components/task/CallControlCAD/call-control-cad.tsx b/packages/contact-center/cc-components/tests/components/task/CallControlCAD/call-control-cad.tsx index 95af309f8..693209a74 100644 --- a/packages/contact-center/cc-components/tests/components/task/CallControlCAD/call-control-cad.tsx +++ b/packages/contact-center/cc-components/tests/components/task/CallControlCAD/call-control-cad.tsx @@ -125,6 +125,7 @@ describe('CallControlCADComponent', () => { setIsRecording: jest.fn(), buddyAgents: mockBuddyAgents, loadBuddyAgents: jest.fn(), + loadingBuddyAgents: false, transferCall: jest.fn(), consultCall: jest.fn(), endConsultCall: jest.fn(), diff --git a/packages/contact-center/task/src/Utils/task-util.ts b/packages/contact-center/task/src/Utils/task-util.ts index fe87c4eff..430130ab4 100644 --- a/packages/contact-center/task/src/Utils/task-util.ts +++ b/packages/contact-center/task/src/Utils/task-util.ts @@ -41,6 +41,22 @@ function isTelephonySupported(deviceType: string, webRtcEnabled: boolean): boole return (isBrowser && webRtcEnabled) || isAgentDN || isExtension; } +/** + * Check if consulting with an EP_DN agent (matches Agent Desktop's isEPorEPDN) + */ +function isConsultingWithEpDnAgent(task: ITask): boolean { + if (!task?.data?.interaction) { + return false; + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const destAgentType = (task.data.interaction as any).destAgentType; + + return ( + destAgentType === 'EpDn' || destAgentType === 'EPDN' || destAgentType === 'EntryPoint' || destAgentType === 'EP' + ); +} + export function findHoldTimestamp(interaction: Interaction, mType = 'mainCall'): number | null { if (interaction?.media) { const media = Object.values(interaction.media).find((m) => m.mType === mType); @@ -77,7 +93,7 @@ export function getDeclineButtonVisibility(isBrowser: boolean, webRtcEnabled: bo } /** - * Get visibility for End button + * Get visibility for End button (matches Agent Desktop behavior) */ export function getEndButtonVisibility( isBrowser: boolean, @@ -87,10 +103,30 @@ export function getEndButtonVisibility( isConferenceInProgress: boolean, isConsultCompleted: boolean, isHeld: boolean, - consultCallHeld: boolean + consultCallHeld: boolean, + task?: ITask, + agentId?: string ): Visibility { const isVisible = isBrowser || (isEndCallEnabled && isCall) || !isCall; - // Disable if: held (except when in conference and consult not completed) OR consult in progress (unless consult call is held - meaning we're back on main) + const isEpDnConsult = task && agentId ? isConsultingWithEpDnAgent(task) : false; + + // EP_DN consult: End button enabled unless main call is held + if (isEpDnConsult && isConsultInitiatedOrAcceptedOrBeingConsulted) { + const isEnabled = !isHeld || (isConferenceInProgress && !isConsultCompleted); + return {isVisible, isEnabled}; + } + + // Agent-to-agent consult during conference: End button enabled when switched back to main call + if (isConsultInitiatedOrAcceptedOrBeingConsulted && isConferenceInProgress) { + return {isVisible, isEnabled: consultCallHeld}; + } + + // Regular consult without conference: End button enabled only when on main call + if (isConsultInitiatedOrAcceptedOrBeingConsulted && !isConferenceInProgress) { + return {isVisible, isEnabled: consultCallHeld}; + } + + // Default logic for other states const isEnabled = (!isHeld || (isConferenceInProgress && !isConsultCompleted)) && (!isConsultInitiatedOrAcceptedOrBeingConsulted || consultCallHeld); @@ -444,7 +480,9 @@ export function getControlsVisibility( isConferenceInProgress, isConsultCompleted, isHeld, - consultCallHeld + consultCallHeld, + task, + agentId ), muteUnmute: getMuteUnmuteButtonVisibility(isBrowser, webRtcEnabled, isCall, isBeingConsulted), holdResume: getHoldResumeButtonVisibility( diff --git a/packages/contact-center/task/src/helper.ts b/packages/contact-center/task/src/helper.ts index ac1144099..c3e2b6129 100644 --- a/packages/contact-center/task/src/helper.ts +++ b/packages/contact-center/task/src/helper.ts @@ -298,6 +298,7 @@ export const useCallControl = (props: useCallControlProps) => { } = props; const [isRecording, setIsRecording] = useState(true); const [buddyAgents, setBuddyAgents] = useState([]); + const [loadingBuddyAgents, setLoadingBuddyAgents] = useState(false); const [consultAgentName, setConsultAgentName] = useState('Consult Agent'); const [startTimestamp, setStartTimestamp] = useState(0); const [secondsUntilAutoWrapup, setsecondsUntilAutoWrapup] = useState(null); @@ -466,6 +467,7 @@ export const useCallControl = (props: useCallControlProps) => { const loadBuddyAgents = useCallback(async () => { try { + setLoadingBuddyAgents(true); const agents = await store.getBuddyAgents(); logger.info(`Loaded ${agents.length} buddy agents`, {module: 'helper.ts', method: 'loadBuddyAgents'}); setBuddyAgents(agents); @@ -475,6 +477,8 @@ export const useCallControl = (props: useCallControlProps) => { method: 'loadBuddyAgents', }); setBuddyAgents([]); + } finally { + setLoadingBuddyAgents(false); } }, [logger]); @@ -990,6 +994,7 @@ export const useCallControl = (props: useCallControlProps) => { isRecording, setIsRecording, buddyAgents, + loadingBuddyAgents, loadBuddyAgents, transferCall, consultCall, diff --git a/packages/contact-center/task/tests/CallControl/index.tsx b/packages/contact-center/task/tests/CallControl/index.tsx index aee5e3723..5ec67c9fe 100644 --- a/packages/contact-center/task/tests/CallControl/index.tsx +++ b/packages/contact-center/task/tests/CallControl/index.tsx @@ -39,6 +39,7 @@ describe('CallControl Component', () => { setIsRecording: jest.fn(), buddyAgents: [], loadBuddyAgents: jest.fn(), + loadingBuddyAgents: false, transferCall: jest.fn(), consultCall: jest.fn(), endConsultCall: jest.fn(), diff --git a/packages/contact-center/task/tests/CallControlCAD/index.tsx b/packages/contact-center/task/tests/CallControlCAD/index.tsx index 60ae4f7df..1bd6758a5 100644 --- a/packages/contact-center/task/tests/CallControlCAD/index.tsx +++ b/packages/contact-center/task/tests/CallControlCAD/index.tsx @@ -35,6 +35,7 @@ describe('CallControlCAD Component', () => { setIsRecording: jest.fn(), buddyAgents: [], loadBuddyAgents: jest.fn(), + loadingBuddyAgents: false, transferCall: jest.fn(), consultCall: jest.fn(), endConsultCall: jest.fn(), @@ -132,6 +133,7 @@ describe('CallControlCAD Component', () => { setIsRecording: jest.fn(), buddyAgents: [], loadBuddyAgents: jest.fn(), + loadingBuddyAgents: false, transferCall: jest.fn(), consultCall: jest.fn(), endConsultCall: jest.fn(), @@ -210,6 +212,7 @@ describe('CallControlCAD Component', () => { setIsRecording: jest.fn(), buddyAgents: [], loadBuddyAgents: jest.fn(), + loadingBuddyAgents: false, transferCall: jest.fn(), consultCall: jest.fn(), endConsultCall: jest.fn(), @@ -290,6 +293,7 @@ describe('CallControlCAD Component', () => { setIsRecording: jest.fn(), buddyAgents: [], loadBuddyAgents: jest.fn(), + loadingBuddyAgents: false, transferCall: jest.fn(), consultCall: jest.fn(), endConsultCall: jest.fn(), From 36892893a196dbead37dd46d1f5ad2e4c8da4ace Mon Sep 17 00:00:00 2001 From: Bharath Balan <62698609+bhabalan@users.noreply.github.com> Date: Fri, 9 Jan 2026 09:03:41 +0530 Subject: [PATCH 2/3] feat(consult-popover): fix tests for refresh button and other improvements --- .../consult-transfer-popover.tsx | 254 ++++++++++++++- packages/contact-center/task/tests/helper.ts | 106 +++++++ .../task/tests/utils/task-util.ts | 293 ++++++++++++++++++ 3 files changed, 652 insertions(+), 1 deletion(-) diff --git a/packages/contact-center/cc-components/tests/components/task/CallControl/CallControlCustom/consult-transfer-popover.tsx b/packages/contact-center/cc-components/tests/components/task/CallControl/CallControlCustom/consult-transfer-popover.tsx index 4799fbc59..375b76089 100644 --- a/packages/contact-center/cc-components/tests/components/task/CallControl/CallControlCustom/consult-transfer-popover.tsx +++ b/packages/contact-center/cc-components/tests/components/task/CallControl/CallControlCustom/consult-transfer-popover.tsx @@ -2,7 +2,7 @@ import React from 'react'; import {render, fireEvent, waitFor, act} from '@testing-library/react'; import '@testing-library/jest-dom'; import ConsultTransferPopoverComponent from '../../../../../src/components/task/CallControl/CallControlCustom/consult-transfer-popover'; -import {ContactServiceQueue} from '@webex/cc-store'; +import {ContactServiceQueue, EntryPointRecord, AddressBookEntry} from '@webex/cc-store'; import {DEFAULT_PAGE_SIZE} from '../../../../../src/components/task/constants'; const loggerMock = { @@ -308,4 +308,256 @@ describe('ConsultTransferPopoverComponent', () => { expect(getQueuesMock).not.toHaveBeenCalled(); }); }); + + describe('Reload button functionality', () => { + it('renders reload button with correct attributes', async () => { + const screen = await render(); + + const reloadButton = screen.getByTestId('consult-reload-button'); + expect(reloadButton).toBeInTheDocument(); + expect(reloadButton).toHaveAttribute('aria-label', 'Reload Agents'); + + // Check icon is present + const icon = reloadButton.querySelector('mdc-icon[name="refresh-bold"]'); + expect(icon).toBeInTheDocument(); + }); + + it('calls loadBuddyAgents when reload button clicked on Agents tab', async () => { + const mockLoadBuddyAgents = jest.fn().mockResolvedValue(undefined); + const screen = await render( + + ); + + // Default tab is Agents + const reloadButton = screen.getByTestId('consult-reload-button'); + fireEvent.click(reloadButton); + + expect(mockLoadBuddyAgents).toHaveBeenCalledTimes(1); + }); + + it('reloads queues when reload button clicked on Queues tab', async () => { + const getQueuesMock = jest.fn().mockResolvedValue({ + data: [ + {id: 'queue1', name: 'Queue One'} as ContactServiceQueue, + {id: 'queue2', name: 'Queue Two'} as ContactServiceQueue, + ], + meta: {page: 0, totalPages: 1}, + }); + + const screen = await render(); + + // Switch to Queues tab + fireEvent.click(screen.getByText('Queues')); + + await waitFor(() => { + expect(getQueuesMock).toHaveBeenCalledTimes(1); + }); + + // Click reload button + const reloadButton = screen.getByTestId('consult-reload-button'); + fireEvent.click(reloadButton); + + await waitFor(() => { + expect(getQueuesMock).toHaveBeenCalledTimes(2); + expect(loggerMock.info).toHaveBeenCalledWith('CC-Components: Reloading Queues data', { + module: 'cc-components#consult-transfer-popover-hooks.ts', + method: 'useConsultTransferPopover#handleReload', + }); + }); + }); + + it('disables reload button when loadingBuddyAgents is true', async () => { + const screen = await render(); + + const reloadButton = screen.getByTestId('consult-reload-button'); + expect(reloadButton).toBeDisabled(); + }); + + it('updates aria-label when switching tabs', async () => { + // Add getEntryPoints and getAddressBookEntries to enable all tabs + // Note: Entry Point tab only shows when heading is 'Consult' + const propsWithAllTabs = { + ...baseProps, + heading: 'Consult', // Required for Entry Point tab to be visible + getAddressBookEntries: async () => ({ + data: [ + { + id: 'dn1', + name: 'Dial Number One', + number: '12345', + type: 'DN', + } as AddressBookEntry, + ], + meta: {page: 0, totalPages: 1}, + }), + getEntryPoints: async () => ({ + data: [ + { + id: 'ep1', + name: 'Entry Point One', + type: 'EP', + isActive: true, + orgId: 'org1', + } as EntryPointRecord, + ], + meta: {page: 0, totalPages: 1}, + }), + }; + + const screen = await render(); + + // Default is Agents + let reloadButton = screen.getByTestId('consult-reload-button'); + expect(reloadButton).toHaveAttribute('aria-label', 'Reload Agents'); + + // Switch to Queues + fireEvent.click(screen.getByText('Queues')); + reloadButton = screen.getByTestId('consult-reload-button'); + expect(reloadButton).toHaveAttribute('aria-label', 'Reload Queues'); + + // Switch to Dial Number + fireEvent.click(screen.getByText('Dial Number')); + reloadButton = screen.getByTestId('consult-reload-button'); + expect(reloadButton).toHaveAttribute('aria-label', 'Reload Dial Number'); + + // Switch to Entry Point + fireEvent.click(screen.getByText('Entry Point')); + reloadButton = screen.getByTestId('consult-reload-button'); + expect(reloadButton).toHaveAttribute('aria-label', 'Reload Entry Point'); + }); + }); + + describe('Loading states', () => { + it('shows spinner when loadingBuddyAgents is true and no agents', async () => { + const screen = await render( + + ); + + const spinner = screen.container.querySelector('.consult-loading-spinner mdc-spinner'); + expect(spinner).toBeInTheDocument(); + }); + + it('shows agents list when loadingBuddyAgents is false', async () => { + const screen = await render(); + + const agentList = screen.container.querySelector('.agent-list'); + expect(agentList).toBeInTheDocument(); + + const listItems = screen.container.querySelectorAll('.call-control-list-item'); + expect(listItems).toHaveLength(2); + }); + + it('shows spinner for queues when loading and no data', async () => { + const getQueuesMock = jest.fn().mockImplementation( + () => + new Promise((resolve) => { + setTimeout(() => resolve({data: [], meta: {page: 0, totalPages: 0}}), 100); + }) + ); + + const screen = await render(); + + // Switch to Queues tab + fireEvent.click(screen.getByText('Queues')); + + // Should show spinner while loading + await waitFor(() => { + const spinner = screen.container.querySelector('.consult-loading-spinner mdc-spinner'); + expect(spinner).toBeInTheDocument(); + }); + }); + + it('shows spinner in load more area when loading more queues', async () => { + const getQueuesMock = jest.fn().mockResolvedValue({ + data: [ + {id: 'queue1', name: 'Queue One'} as ContactServiceQueue, + {id: 'queue2', name: 'Queue Two'} as ContactServiceQueue, + ], + meta: {page: 0, totalPages: 2}, + }); + + const screen = await render(); + + // Switch to Queues tab + fireEvent.click(screen.getByText('Queues')); + + await waitFor(() => { + const listItems = screen.container.querySelectorAll('.call-control-list-item'); + expect(listItems.length).toBeGreaterThan(0); + }); + + // Should have a load more area + const loadMoreArea = screen.container.querySelector('.consult-load-more'); + expect(loadMoreArea).toBeInTheDocument(); + }); + + it('shows empty state instead of spinner when not loading', async () => { + const screen = await render( + + ); + + const spinner = screen.container.querySelector('.consult-loading-spinner mdc-spinner'); + expect(spinner).not.toBeInTheDocument(); + + const emptyState = screen.container.querySelector('.consult-empty-state'); + expect(emptyState).toBeInTheDocument(); + }); + }); + + describe('Reload with search query', () => { + beforeEach(() => { + jest.useFakeTimers(); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + + it('reloads with current search query on Queues tab', async () => { + const getQueuesMock = jest.fn().mockResolvedValue({ + data: [{id: 'queue1', name: 'Queue One'} as ContactServiceQueue], + meta: {page: 0, totalPages: 1}, + }); + + const screen = await render(); + + // Switch to Queues tab + fireEvent.click(screen.getByText('Queues')); + + await waitFor(() => { + expect(getQueuesMock).toHaveBeenCalledTimes(1); + }); + + // Enter search query + const input = screen.getByPlaceholderText('Search...') as HTMLInputElement; + fireEvent.change(input, {target: {value: 'test query'}}); + + await act(async () => { + jest.advanceTimersByTime(500); + }); + + // Should have called with search query + expect(getQueuesMock).toHaveBeenCalledWith( + expect.objectContaining({ + page: 0, + pageSize: DEFAULT_PAGE_SIZE, + search: 'test query', + }) + ); + + // Click reload - should reload with the same search query + const reloadButton = screen.getByTestId('consult-reload-button'); + fireEvent.click(reloadButton); + + await waitFor(() => { + expect(getQueuesMock).toHaveBeenCalledWith( + expect.objectContaining({ + page: 0, + pageSize: DEFAULT_PAGE_SIZE, + search: 'test query', + }) + ); + }); + }); + }); }); diff --git a/packages/contact-center/task/tests/helper.ts b/packages/contact-center/task/tests/helper.ts index 0087026ee..a0c63d574 100644 --- a/packages/contact-center/task/tests/helper.ts +++ b/packages/contact-center/task/tests/helper.ts @@ -1361,6 +1361,112 @@ describe('useCallControl', () => { getBuddyAgentsSpy.mockRestore(); }); + it('should set loadingBuddyAgents to false initially', () => { + const {result} = renderHook(() => + useCallControl({ + currentTask: mockCurrentTask, + onHoldResume: mockOnHoldResume, + onEnd: mockOnEnd, + onWrapUp: mockOnWrapUp, + logger: mockLogger, + featureFlags: store.featureFlags, + deviceType: store.deviceType, + isMuted: false, + conferenceEnabled: true, + agentId: 'test-agent-id', + }) + ); + expect(result.current.loadingBuddyAgents).toBe(false); + }); + + it('should set loadingBuddyAgents to true during loading and false after success', async () => { + // Create a promise that we can control + let resolveGetBuddyAgents: (value: typeof mockAgents) => void; + const getBuddyAgentsPromise = new Promise((resolve) => { + resolveGetBuddyAgents = resolve; + }); + + const getBuddyAgentsSpy = jest.spyOn(store, 'getBuddyAgents').mockReturnValue(getBuddyAgentsPromise); + + const {result} = renderHook(() => + useCallControl({ + currentTask: mockCurrentTask, + onHoldResume: mockOnHoldResume, + onEnd: mockOnEnd, + onWrapUp: mockOnWrapUp, + logger: mockLogger, + featureFlags: store.featureFlags, + deviceType: store.deviceType, + isMuted: false, + conferenceEnabled: true, + agentId: 'test-agent-id', + }) + ); + + // Initially false + expect(result.current.loadingBuddyAgents).toBe(false); + + // Start loading + let loadPromise: Promise; + act(() => { + loadPromise = result.current.loadBuddyAgents(); + }); + + // Should be true while loading + await waitFor(() => { + expect(result.current.loadingBuddyAgents).toBe(true); + }); + + // Resolve the promise + act(() => { + resolveGetBuddyAgents!(mockAgents); + }); + + // Wait for the load to complete + await act(async () => { + await loadPromise!; + }); + + // Should be false after loading completes + expect(result.current.loadingBuddyAgents).toBe(false); + expect(result.current.buddyAgents).toEqual(mockAgents); + + getBuddyAgentsSpy.mockRestore(); + }); + + it('should set loadingBuddyAgents to false after error', async () => { + const getBuddyAgentsSpy = jest.spyOn(store, 'getBuddyAgents').mockRejectedValue(new Error('Load failed')); + + const {result} = renderHook(() => + useCallControl({ + currentTask: mockCurrentTask, + onHoldResume: mockOnHoldResume, + onEnd: mockOnEnd, + onWrapUp: mockOnWrapUp, + logger: mockLogger, + featureFlags: store.featureFlags, + deviceType: store.deviceType, + isMuted: false, + conferenceEnabled: true, + agentId: 'test-agent-id', + }) + ); + + // Initially false + expect(result.current.loadingBuddyAgents).toBe(false); + + // Load and handle error + await act(async () => { + await result.current.loadBuddyAgents(); + }); + + // Should be false after error + expect(result.current.loadingBuddyAgents).toBe(false); + expect(result.current.buddyAgents).toEqual([]); + + getBuddyAgentsSpy.mockRestore(); + }); + it('should handle rejection when transferring call', async () => { const transferError = new Error('Transfer failed'); const transferSpy = jest.fn().mockRejectedValue(transferError); diff --git a/packages/contact-center/task/tests/utils/task-util.ts b/packages/contact-center/task/tests/utils/task-util.ts index 67a8f01b3..2a1935b54 100644 --- a/packages/contact-center/task/tests/utils/task-util.ts +++ b/packages/contact-center/task/tests/utils/task-util.ts @@ -628,6 +628,299 @@ describe('getControlsVisibility', () => { }); }); +describe('getEndButtonVisibility - EP_DN consult scenarios', () => { + const deviceType = 'BROWSER'; + const featureFlags = { + isEndCallEnabled: true, + isEndConsultEnabled: true, + webRtcEnabled: true, + }; + + it('should enable end button during EP_DN consult when main call is active (not held)', () => { + // Mock a task with EP_DN consult - switching back to main call (consult on hold) + const task = { + ...mockTask, + data: { + ...mockTask.data, + consultMediaResourceId: 'consult', + interaction: { + ...mockTask.data.interaction, + mediaType: 'telephony', + destAgentType: 'EpDn', + state: 'consulting', + media: { + main: { + mediaResourceId: 'main', + mType: 'mainCall', + isHold: false, // Main call is active - switched back to main + participants: ['agent1', 'customer1'], + }, + consult: { + mediaResourceId: 'consult', + mType: 'consult', + isHold: true, // Consult is on hold - we're on main call + participants: ['agent1', 'epdn-agent'], + }, + }, + participants: { + agent1: { + id: 'agent1', + pType: 'Agent', + name: 'Agent One', + consultState: 'Initiated', + isConsulted: false, + hasLeft: false, + }, + customer1: { + id: 'customer1', + pType: 'Customer', + name: 'Customer', + hasLeft: false, + }, + }, + }, + }, + } as ITask; + + const result = getControlsVisibility(deviceType, featureFlags, task, 'agent1', false); + + // EP_DN consult: End button should be enabled when on main call + expect(result.end.isVisible).toBe(true); + expect(result.end.isEnabled).toBe(true); + }); + + it('should disable end button during EP_DN consult when switched to EP_DN agent (main call held)', () => { + // Mock a task with EP_DN consult - switched to EP_DN agent (main call on hold) + const task = { + ...mockTask, + data: { + ...mockTask.data, + consultMediaResourceId: 'consult', + interaction: { + ...mockTask.data.interaction, + mediaType: 'telephony', + destAgentType: 'EPDN', + state: 'consulting', + media: { + main: { + mediaResourceId: 'main', + mType: 'mainCall', + isHold: true, // Main call is held - switched to EP_DN consult + participants: ['agent1', 'customer1'], + }, + consult: { + mediaResourceId: 'consult', + mType: 'consult', + isHold: false, // Consult is active - talking to EP_DN + participants: ['agent1', 'epdn-agent'], + }, + }, + participants: { + agent1: { + id: 'agent1', + pType: 'Agent', + name: 'Agent One', + consultState: 'Initiated', + isConsulted: false, + hasLeft: false, + }, + customer1: { + id: 'customer1', + pType: 'Customer', + name: 'Customer', + hasLeft: false, + }, + }, + }, + }, + } as ITask; + + const result = getControlsVisibility(deviceType, featureFlags, task, 'agent1', false); + + // EP_DN consult: End button should be disabled when main call is held (talking to EP_DN) + expect(result.end.isVisible).toBe(true); + expect(result.end.isEnabled).toBe(false); + }); + + it('should enable end button during EP_DN consult conference when main call is held but conference in progress', () => { + // Mock a task with EP_DN consult in conference state + const task = { + ...mockTask, + data: { + ...mockTask.data, + isConferenceInProgress: true, + consultMediaResourceId: 'consult', + interaction: { + ...mockTask.data.interaction, + mediaType: 'telephony', + destAgentType: 'EntryPoint', + state: 'conferencing', + media: { + main: { + mediaResourceId: 'main', + mType: 'mainCall', + isHold: true, // Main call is held during conference + participants: ['agent1', 'customer1', 'epdn-agent'], + }, + }, + participants: { + agent1: { + id: 'agent1', + pType: 'Agent', + name: 'Agent One', + consultState: 'Conferencing', + isConsulted: false, + hasLeft: false, + }, + customer1: { + id: 'customer1', + pType: 'Customer', + name: 'Customer', + hasLeft: false, + }, + 'epdn-agent': { + id: 'epdn-agent', + pType: 'Agent', + name: 'EP DN Agent', + hasLeft: false, + }, + }, + }, + }, + } as ITask; + + const result = getControlsVisibility(deviceType, featureFlags, task, 'agent1', true); + + expect(result.end.isVisible).toBe(true); + expect(result.end.isEnabled).toBe(true); + }); + + it('should recognize EP destAgentType variant', () => { + const task = { + ...mockTask, + data: { + ...mockTask.data, + consultMediaResourceId: 'consult', + interaction: { + ...mockTask.data.interaction, + destAgentType: 'EP', + mediaType: 'telephony', + state: 'consulting', + media: { + main: { + mediaResourceId: 'main', + mType: 'mainCall', + isHold: false, // Main call active - we're on main call + participants: ['agent1', 'customer1'], + }, + consult: { + mediaResourceId: 'consult', + mType: 'consult', + isHold: true, // Consult on hold + participants: ['agent1', 'ep-agent'], + }, + }, + participants: { + agent1: { + id: 'agent1', + pType: 'Agent', + name: 'Agent One', + consultState: 'Initiated', + isConsulted: false, + hasLeft: false, + }, + customer1: { + id: 'customer1', + pType: 'Customer', + name: 'Customer', + hasLeft: false, + }, + }, + }, + }, + } as ITask; + + const result = getControlsVisibility(deviceType, featureFlags, task, 'agent1', false); + + // EP_DN consult: End button should be enabled when on main call + expect(result.end.isVisible).toBe(true); + expect(result.end.isEnabled).toBe(true); + }); + + it('should handle missing destAgentType as non-EP_DN consult', () => { + const task = { + ...mockTask, + data: { + ...mockTask.data, + consultMediaResourceId: 'consult', + interaction: { + ...mockTask.data.interaction, + mediaType: 'telephony', + state: 'consulting', + media: { + main: { + mediaResourceId: 'main', + mType: 'mainCall', + isHold: true, + participants: ['agent1', 'customer1'], + }, + consult: { + mediaResourceId: 'consult', + mType: 'consult', + isHold: false, + participants: ['agent1', 'agent2'], + }, + }, + participants: { + agent1: { + id: 'agent1', + pType: 'Agent', + consultState: 'Initiated', + hasLeft: false, + }, + }, + }, + }, + } as ITask; + + const result = getControlsVisibility(deviceType, featureFlags, task, 'agent1', false); + + // Should follow regular consult logic (disabled when on consult call) + expect(result.end.isVisible).toBe(true); + expect(result.end.isEnabled).toBe(false); + }); + + it('should handle missing task data gracefully', () => { + const task = { + ...mockTask, + data: undefined, + } as unknown as ITask; + + const result = getControlsVisibility(deviceType, featureFlags, task, 'agent1', false); + + // Should still return valid visibility structure + expect(result.end).toBeDefined(); + expect(result.end.isVisible).toBeDefined(); + expect(result.end.isEnabled).toBeDefined(); + }); + + it('should handle missing interaction data gracefully', () => { + const task = { + ...mockTask, + data: { + ...mockTask.data, + interaction: undefined, + }, + } as unknown as ITask; + + const result = getControlsVisibility(deviceType, featureFlags, task, 'agent1', false); + + expect(result.end).toBeDefined(); + expect(result.end.isVisible).toBeDefined(); + expect(result.end.isEnabled).toBeDefined(); + }); +}); + describe('findHoldTimestamp', () => { it('returns the holdTimestamp for the correct mType', () => { const interaction = { From 6e9e150314ac49bc6914ae095b72f6254dc518fd Mon Sep 17 00:00:00 2001 From: Bharath Balan <62698609+bhabalan@users.noreply.github.com> Date: Fri, 9 Jan 2026 09:08:28 +0530 Subject: [PATCH 3/3] feat(consult-popover): change p tag to Text --- .../consult-transfer-popover.tsx | 2 +- ...consult-transfer-popover.snapshot.tsx.snap | 126 +++++++++++++----- 2 files changed, 95 insertions(+), 33 deletions(-) diff --git a/packages/contact-center/cc-components/src/components/task/CallControl/CallControlCustom/consult-transfer-popover.tsx b/packages/contact-center/cc-components/src/components/task/CallControl/CallControlCustom/consult-transfer-popover.tsx index 69dc3719c..32e1ab744 100644 --- a/packages/contact-center/cc-components/src/components/task/CallControl/CallControlCustom/consult-transfer-popover.tsx +++ b/packages/contact-center/cc-components/src/components/task/CallControl/CallControlCustom/consult-transfer-popover.tsx @@ -150,7 +150,7 @@ const ConsultTransferPopoverComponent: React.FC -

{`Reload ${selectedCategory}`}

+ {`Reload ${selectedCategory}`}
{consultTransferManualAction.visible && ( diff --git a/packages/contact-center/cc-components/tests/components/task/CallControl/CallControlCustom/__snapshots__/consult-transfer-popover.snapshot.tsx.snap b/packages/contact-center/cc-components/tests/components/task/CallControl/CallControlCustom/__snapshots__/consult-transfer-popover.snapshot.tsx.snap index 58b4c9df9..b48bb3cba 100644 --- a/packages/contact-center/cc-components/tests/components/task/CallControl/CallControlCustom/__snapshots__/consult-transfer-popover.snapshot.tsx.snap +++ b/packages/contact-center/cc-components/tests/components/task/CallControl/CallControlCustom/__snapshots__/consult-transfer-popover.snapshot.tsx.snap @@ -62,9 +62,13 @@ exports[`ConsultTransferPopoverComponent Snapshots Interactions should render co class="md-tooltip-label" id="react-aria-:r2m:" > -

+ Reload Agents -

+ @@ -349,9 +353,13 @@ exports[`ConsultTransferPopoverComponent Snapshots Interactions should render co class="md-tooltip-label" id="react-aria-:r2u:" > -

+ Reload Queues -

+ @@ -563,9 +571,13 @@ exports[`ConsultTransferPopoverComponent Snapshots Interactions should render co class="md-tooltip-label" id="react-aria-:r2f:" > -

+ Reload Queues -

+ @@ -777,9 +789,13 @@ exports[`ConsultTransferPopoverComponent Snapshots Rendering - Tests for UI elem class="md-tooltip-label" id="react-aria-:r6:" > -

+ Reload Agents -

+ @@ -1082,9 +1098,13 @@ exports[`ConsultTransferPopoverComponent Snapshots Rendering - Tests for UI elem class="md-tooltip-label" id="react-aria-:r27:" > -

+ Reload Agents -

+ @@ -1444,9 +1464,13 @@ exports[`ConsultTransferPopoverComponent Snapshots Rendering - Tests for UI elem class="md-tooltip-label" id="react-aria-:r1a:" > -

+ Reload Agents -

+ @@ -1713,9 +1737,13 @@ exports[`ConsultTransferPopoverComponent Snapshots Rendering - Tests for UI elem class="md-tooltip-label" id="react-aria-:r1h:" > -

+ Reload Agents -

+ @@ -1858,9 +1886,13 @@ exports[`ConsultTransferPopoverComponent Snapshots Rendering - Tests for UI elem class="md-tooltip-label" id="react-aria-:rk:" > -

+ Reload Agents -

+ @@ -2145,9 +2177,13 @@ exports[`ConsultTransferPopoverComponent Snapshots Rendering - Tests for UI elem class="md-tooltip-label" id="react-aria-:rr:" > -

+ Reload Agents -

+ @@ -2289,9 +2325,11 @@ exports[`ConsultTransferPopoverComponent Snapshots Rendering - Tests for UI elem class="md-tooltip-label" id="react-aria-:r13:" > -

+ Reload Queues -

+ @@ -2427,9 +2465,13 @@ exports[`ConsultTransferPopoverComponent Snapshots Rendering - Tests for UI elem class="md-tooltip-label" id="react-aria-:r1o:" > -

+ Reload Agents -

+ @@ -2639,9 +2681,13 @@ exports[`ConsultTransferPopoverComponent Snapshots Rendering - Tests for UI elem class="md-tooltip-label" id="react-aria-:r20:" > -

+ Reload Queues -

+ @@ -2853,9 +2899,13 @@ exports[`ConsultTransferPopoverComponent Snapshots Rendering - Tests for UI elem class="md-tooltip-label" id="react-aria-:rd:" > -

+ Reload Agents -

+ @@ -3140,9 +3190,13 @@ exports[`ConsultTransferPopoverComponent Snapshots State Management should updat class="md-tooltip-label" id="react-aria-:r3c:" > -

+ Reload Agents -

+ @@ -3348,9 +3402,13 @@ exports[`ConsultTransferPopoverComponent Snapshots State Management should updat class="md-tooltip-label" id="react-aria-:r35:" > -

+ Reload Agents -

+ @@ -3635,9 +3693,13 @@ exports[`ConsultTransferPopoverComponent Snapshots State Management should updat class="md-tooltip-label" id="react-aria-:r3k:" > -

+ Reload Queues -

+