Skip to content

fix(call-control): add-call-control-widget #362

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Jan 29, 2025

Conversation

Shreyas281299
Copy link

@Shreyas281299 Shreyas281299 commented Jan 17, 2025

THIS PR COMPLETES: https://jira-eng-gpk2.cisco.com/jira/browse/SPARK-589818

DESCRIPTION

Changes made

  • Added call-control widget
  • Added the ability to hold the call, resume-pause recording, end and wrap up the call
  • Incoming task notification gets hidden once the call has been accepted
  • The accept-decline button on the task-list gets hidden

Tests

  • Accepted/Declined the call from task list
  • Accepted/Declined the call from incoming call notification
  • Held/Resumed the call
  • Ended the call from agent's side
  • Ended the call from the customer's side
  • Paused the recording
  • Resumed the recording (No way to verify this right now, we can verify this in the transfer stories)

Vidcasts

Summary by CodeRabbit

Release Notes

  • New Features

    • Added Call Control functionality to the application
    • Introduced ability to hold, resume, pause, and end calls
    • Added wrap-up code selection for completed calls
  • Improvements

    • Enhanced task management with new observable properties
    • Improved user interface for call control interactions
  • UI Updates

    • New styling for call control components
    • Added dropdown for selecting wrap-up reasons

The release introduces comprehensive call control features, allowing users to manage calls more effectively with intuitive controls and wrap-up options.

Copy link

coderabbitai bot commented Jan 17, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This pull request introduces a new CallControl component to the contact center application, enhancing task and call management functionality. The changes span multiple packages, including cc-widgets, store, and task. The implementation adds new methods for managing call states, introduces wrap-up codes, and provides a comprehensive UI for controlling calls during active tasks. The changes are focused on improving the user's ability to interact with and manage ongoing communication tasks.

Changes

File Change Summary
docs/react-samples/src/App.tsx Added CallControl import and conditional rendering
packages/contact-center/cc-widgets/src/index.ts Updated imports and exports to include CallControl
packages/contact-center/store/src/store.ts Added wrapupCodes and currentTask properties, new setCurrentTask method
packages/contact-center/task/src/CallControl/... New component files for Call Control functionality
packages/contact-center/task/src/task.types.ts Added new interfaces for call control props and removed isMissed property

Sequence Diagram

sequenceDiagram
    participant User
    participant CallControl
    participant Store
    participant Task

    User->>CallControl: Interact with call controls
    CallControl->>Store: Update current task state
    Store->>Task: Manage task actions
    Task-->>CallControl: Return task status
    CallControl-->>User: Update UI based on task state
Loading

Possibly related PRs

Suggested reviewers

  • mkesavan13

Poem

🐰 Hop, hop, a call control delight!
Widgets dancing with all their might
Wrap-up codes and tasks so bright
MobX magic taking flight
Coding rabbits win the fight! 🚀


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@Shreyas281299
Copy link
Author

@CodeRabbit review

Copy link

coderabbitai bot commented Jan 17, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Shreyas281299 Shreyas281299 requested review from Kesari3008 and mkesavan13 and removed request for Kesari3008 January 17, 2025 07:06
Copy link

@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: 9

🧹 Nitpick comments (14)
packages/contact-center/task/src/helper.ts (5)

69-69: Consider removing unnecessary store.setCurrentTask(null) after declining a task

Setting store.setCurrentTask(null); after declining a task may be redundant if the current task is already null. Review whether this call is necessary to prevent unnecessary state updates.


116-117: Consolidate state resets into a single function

You're resetting isAnswered and isEnded to false when a new task is assigned. Consider creating a helper function to reset these states, enhancing code readability and maintainability.


210-236: Refactor holdResume function to eliminate duplicated code

The holdResume function contains duplicated logic for holding and resuming calls. Refactoring can improve readability and reduce maintenance effort.

Here’s a suggested refactor:

const holdResume = (hold: boolean) => {
-  if (hold) {
-    currentTask
-      .hold()
-      .then(() => {
-        onHoldResume();
-      })
-      .catch((error: Error) => {
-        logger.error(`Error holding call: ${error}`, {
-          module: 'widget-cc-task#helper.ts',
-          method: 'useCallControl#holdResume',
-        });
-      });
-  } else {
-    currentTask
-      .resume()
-      .then(() => {
-        onHoldResume();
-      })
-      .catch((error: Error) => {
-        logger.error(`Error resuming call: ${error}`, {
-          module: 'widget-cc-task#helper.ts',
-          method: 'useCallControl#holdResume',
-        });
-      });
-  }
+  const action = hold ? 'hold' : 'resume';
+  currentTask[action]()
+    .then(() => {
+      onHoldResume();
+    })
+    .catch((error: Error) => {
+      logger.error(`Error ${hold ? 'holding' : 'resuming'} call: ${error}`, {
+        module: 'widget-cc-task#helper.ts',
+        method: 'useCallControl#holdResume',
+      });
+    });
};

238-254: Refactor pauseResumeRecording to reduce code duplication

The pauseResumeRecording function has similar code blocks for pausing and resuming recording. Refactoring can simplify the code.

Refactored function:

const pauseResumeRecording = (pause: boolean) => {
-  if (pause) {
-    currentTask.pauseRecording().catch((error: Error) => {
-      logger.error(`Error pausing recording: ${error}`, {
-        module: 'widget-cc-task#helper.ts',
-        method: 'useCallControl#pauseResumeRecording',
-      });
-    });
-  } else {
-    currentTask.resumeRecording().catch((error: Error) => {
-      logger.error(`Error resuming recording: ${error}`, {
-        module: 'widget-cc-task#helper.ts',
-        method: 'useCallControl#pauseResumeRecording',
-      });
-    });
-  }
+  const action = pause ? 'pauseRecording' : 'resumeRecording';
+  currentTask[action]().catch((error: Error) => {
+    logger.error(`Error ${pause ? 'pausing' : 'resuming'} recording: ${error}`, {
+      module: 'widget-cc-task#helper.ts',
+      method: 'useCallControl#pauseResumeRecording',
+    });
+  });
};

256-268: Consider resetting current task in the store after ending a call

In the endCall function, after ending the task, you might want to reset the current task in the store with store.setCurrentTask(null); to reflect that there's no active task.

packages/contact-center/task/src/CallControl/index.tsx (1)

9-15: Consider adding error boundaries and prop validation.

While the component implementation is clean, consider these improvements for robustness:

  1. Wrap with an error boundary to handle potential runtime errors
  2. Add prop-types or TypeScript interface validation for the callback props
  3. Consider adding loading and error states

Example error boundary implementation:

class CallControlErrorBoundary extends React.Component<{children: React.ReactNode}> {
  state = { hasError: false };
  
  static getDerivedStateFromError(error: Error) {
    return { hasError: true };
  }
  
  render() {
    if (this.state.hasError) {
      return <div>Error loading call controls</div>;
    }
    return this.props.children;
  }
}

// Usage
const CallControl: React.FunctionComponent<CallControlProps> = observer(({onHoldResume, onEnd, onWrapUp}) => {
  // ... existing implementation
});

export const CallControlWithErrorBoundary = (props: CallControlProps) => (
  <CallControlErrorBoundary>
    <CallControl {...props} />
  </CallControlErrorBoundary>
);
packages/contact-center/store/src/store.ts (1)

33-35: Add validation in setCurrentTask method.

The method should validate the task object before assignment:

-setCurrentTask(task: any): void {
+setCurrentTask(task: Task | null): void {
+  if (task !== null && !this.isValidTask(task)) {
+    throw new Error('Invalid task object');
+  }
   this.currentTask = task;
 }
+
+private isValidTask(task: Task): boolean {
+  return typeof task.hold === 'function' &&
+         typeof task.resume === 'function' &&
+         typeof task.end === 'function' &&
+         typeof task.wrapup === 'function';
+}
packages/contact-center/task/src/task.types.ts (1)

123-135: Add JSDoc comments for the new ControlProps interface.

The interface lacks documentation for its properties and methods. Add JSDoc comments to improve code maintainability.

+/**
+ * Interface for call control functionality
+ */
 export interface ControlProps {
+  /** Current task being handled */
   currentTask: ITask;
+  /** Callback for hold/resume action */
   onHoldResume: () => void;
+  /** Callback for end call action */
   onEnd: () => void;
+  /** Callback for wrap-up action */
   onWrapUp: () => void;
   logger: ILogger;
   wrapupCodes: any[];
   wrapupRequired: boolean;
+  /** Function to hold or resume a call */
   holdResume: (hold: boolean) => void;
+  /** Function to pause or resume call recording */
   pauseResumeRecording: (pause: boolean) => void;
+  /** Function to end the current call */
   endCall: () => void;
+  /** Function to wrap up a call with reason and ID */
   wrapupCall: (wrapupReason: string, wrapupId: string) => void;
 }
packages/contact-center/task/src/CallControl/call-control.presentational.tsx (2)

66-80: Add aria-label to improve accessibility.

The select and button elements lack proper aria labels for screen readers.

-  <select className="select" onChange={handleWrapupChange} defaultValue="" disabled={!wrapupRequired}>
+  <select 
+    className="select" 
+    onChange={handleWrapupChange} 
+    defaultValue="" 
+    disabled={!wrapupRequired}
+    aria-label="Select wrap-up reason"
+  >
   ...
   <button
     className="btn"
     onClick={handleWrapupCall}
     disabled={!wrapupRequired && !selectedWrapupReason}
+    aria-label="Wrap up call"
   >

21-28: Logic in handlePauseResumeRecording can be simplified.

The conditional logic can be simplified by directly passing the negated state.

 const handlePauseResumeRecording = () => {
-  if (isRecordingPaused) {
-    pauseResumeRecording(true);
-  } else {
-    pauseResumeRecording(false);
-  }
+  pauseResumeRecording(!isRecordingPaused);
   setIsRecordingPaused(!isRecordingPaused);
 };
packages/contact-center/task/tests/CallControl/call-control.presentational.tsx (1)

17-24: Add type safety to defaultProps mock object.

The mock object should use proper typing to ensure type safety in tests.

+import {CallControlPresentationalProps} from '../../src/task.types';

-  const defaultProps = {
+  const defaultProps: CallControlPresentationalProps = {
packages/contact-center/task/src/IncomingTask/incoming-task.presentational.tsx (2)

123-125: Consider using early return pattern for better readability.

The conditional rendering can be made more explicit using early returns.

-  if (!currentTask || isAnswered) {
-    return <></>; // hidden component
-  }
+  if (!currentTask) {
+    return null; // No task available
+  }
+
+  if (isAnswered) {
+    return null; // Task already answered
+  }

Line range hint 4-122: Move inline styles to a separate CSS/SCSS file.

Large inline style objects make the component harder to maintain and can impact performance. Consider moving styles to a separate CSS/SCSS file.

Create a new file incoming-task.styles.scss and move the styles there. This will improve maintainability and enable better style reuse.

packages/contact-center/task/tests/helper.ts (1)

512-795: Add missing test cases for better coverage.

Consider adding the following test cases to improve coverage:

  1. Test behavior when callback handlers (onHoldResume, onEnd, onWrapUp) are null/undefined
  2. Test validation of task state before performing operations (e.g., can't hold an ended call)

Example test case for null callbacks:

it('should handle null callback handlers gracefully', async () => {
  const {result} = renderHook(() =>
    useCallControl({
      currentTask: mockCurrentTask,
      logger: mockLogger,
    })
  );

  await act(async () => {
    await result.current.holdResume(true);
    await result.current.endCall();
    await result.current.wrapupCall('reason', 123);
  });

  expect(mockCurrentTask.hold).toHaveBeenCalled();
  expect(mockCurrentTask.end).toHaveBeenCalled();
  expect(mockCurrentTask.wrapup).toHaveBeenCalled();
});
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 61b5ea9 and 87898e8.

📒 Files selected for processing (13)
  • docs/react-samples/src/App.tsx (2 hunks)
  • packages/contact-center/cc-widgets/src/index.ts (1 hunks)
  • packages/contact-center/store/src/store.ts (2 hunks)
  • packages/contact-center/task/src/CallControl/call-control.presentational.tsx (1 hunks)
  • packages/contact-center/task/src/CallControl/call-control.styles.scss (1 hunks)
  • packages/contact-center/task/src/CallControl/index.tsx (1 hunks)
  • packages/contact-center/task/src/IncomingTask/incoming-task.presentational.tsx (1 hunks)
  • packages/contact-center/task/src/helper.ts (8 hunks)
  • packages/contact-center/task/src/index.ts (1 hunks)
  • packages/contact-center/task/src/task.types.ts (2 hunks)
  • packages/contact-center/task/tests/CallControl/call-control.presentational.tsx (1 hunks)
  • packages/contact-center/task/tests/CallControl/index.tsx (1 hunks)
  • packages/contact-center/task/tests/helper.ts (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/contact-center/task/src/CallControl/call-control.styles.scss
🔇 Additional comments (9)
packages/contact-center/task/src/helper.ts (3)

50-50: Verify the necessity of updating store.setCurrentTask after accepting a task

After accepting a task, you are updating the store with store.setCurrentTask(task);. Ensure that this action aligns with your application's state management strategy and that it doesn't introduce unintended side effects.


146-146: Ensure consistency when updating store.setCurrentTask after accepting an incoming task

In the accept function, you're setting the current task in the store with store.setCurrentTask(currentTask);. Confirm that this is consistent with how tasks are managed elsewhere in your application.


165-165: Review the necessity of store.setCurrentTask(null) after declining an incoming task

After declining a task, you're setting store.setCurrentTask(null);. Verify if this is required or if the store already reflects the absence of a current task.

packages/contact-center/task/src/index.ts (1)

3-4: Added CallControl component to exports

The CallControl component is correctly imported and exported, making it accessible to other modules.

packages/contact-center/cc-widgets/src/index.ts (2)

3-3: Imported CallControl from @webex/cc-task module

Successfully imported the CallControl component, ensuring it's available for use within the package.


6-6: Exported CallControl component from cc-widgets package

Including CallControl in the exports makes it available to consumers of the cc-widgets package.

packages/contact-center/task/src/CallControl/index.tsx (1)

12-12: Verify the spread operation safety.

The spread operation combining hook results with wrapupCodes could potentially overwrite properties. Consider using a more explicit merge strategy.

✅ Verification successful

The spread operation is safe and appropriate.

The useCallControl hook returns a fixed set of properties (currentTask, endCall, holdResume, pauseResumeRecording, wrapupCall, wrapupRequired) that do not conflict with the wrapupCodes property being added.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for potential property conflicts in useCallControl hook result
ast-grep --pattern 'useCallControl($$$)' 

Length of output: 7751


Script:

#!/bin/bash
# Find useCallControl hook implementation
ast-grep --pattern 'const useCallControl = $$$'
ast-grep --pattern 'function useCallControl($$$)'
ast-grep --pattern 'export const useCallControl = $$$'

Length of output: 7756

packages/contact-center/task/tests/helper.ts (2)

2-2: LGTM!

The import statement for useCallControl is correctly placed alongside other hook imports.


512-795: Well-structured test suite with comprehensive coverage!

The test implementation follows testing best practices:

  • Proper setup and teardown
  • Comprehensive error handling
  • Good use of async/await
  • Clear test descriptions

</div>
)}
</div>
{!currentTask && (
Copy link
Author

Choose a reason for hiding this comment

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

Check the sdk for task limit and hide accordingly


const {currentTask, holdResume, pauseResumeRecording, endCall, wrapupCall, wrapupCodes, wrapupRequired} = props;
const handleHoldResume = () => {
if (isHeld) {
Copy link
Author

Choose a reason for hiding this comment

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

See if there is any event or state change from the sdk

Copy link
Contributor

Choose a reason for hiding this comment

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

This if-else block can be one liner

toggleHold(!isHeld);

Copy link
Author

Choose a reason for hiding this comment

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

Updated

Copy link
Author

Choose a reason for hiding this comment

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

See if on promise resolution if we get any data.

Copy link
Author

Choose a reason for hiding this comment

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

We are not getting any data

});
});
}
};
Copy link
Contributor

Choose a reason for hiding this comment

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

  const toggleHold = (hold: boolean) => {
    if(!onHoldResume) return;

    const logLocation = {
      module: 'widget-cc-task#helper.ts',
      method: 'useCallControl#holdResume',
    };

    if (hold) {
      currentTask.hold()
        .then(() => onHoldResume())
        .catch((error: Error) => {
          logger.error(`Error holding call: ${error}`, logLocation);
        });

      return;
    }

    currentTask.resume()
      .then(() => onHoldResume())
      .catch((error: Error) => {
        logger.error(`Error resuming call: ${error}`, logLocation);
      });    
  };

We can update the code as shown and follow similar pattern to keep the code clean

Copy link
Author

Choose a reason for hiding this comment

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

Updated

Copy link
Contributor

@Kesari3008 Kesari3008 left a comment

Choose a reason for hiding this comment

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

Would like to discuss few things in the code based on the comments.

@Kesari3008
Copy link
Contributor

Also, did we have any discussion from accessibility perspective?

Copy link
Contributor

@mkesavan13 mkesavan13 left a comment

Choose a reason for hiding this comment

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

Thanks for the Vidcasts. I notice that the User State goes to available as soon as we end the call. Ideally, the user state is not supposed to go to Available until the agent has wrapped up the call. Can we check how does the Agent Desktop work today on this and see why that's not happening in our case?

@Shreyas281299
Copy link
Author

Thanks for the Vidcasts. I notice that the User State goes to available as soon as we end the call. Ideally, the user state is not supposed to go to Available until the agent has wrapped up the call. Can we check how does the Agent Desktop work today on this and see why that's not happening in our case?

The agent state should remain available but in the UI it should say Engaged
Created a ticket for this will pick this up adhoc -https://jira-eng-gpk2.cisco.com/jira/browse/SPARK-608917

@Shreyas281299
Copy link
Author

Also, did we have any discussion from accessibility perspective?

Since the UI Is still placeholder we haven't, but when we will design the UI we will take accessibility with it.

@Shreyas281299
Copy link
Author

Tested using chrome extension

Screen.Recording.2025-01-28.at.6.00.04.PM.mov

Copy link
Contributor

@Kesari3008 Kesari3008 left a comment

Choose a reason for hiding this comment

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

Did we test dial number scenario also for call control? I was trying to test and not sure it is able to handle the call control widget display along with incomingTask widget appearing/disappearing.
Please check this flow too before merging.

Appriving the code as I won't be available tomorrow but please ensure to address these commenst as they are critici=al

<button className="btn" onClick={handletoggleRecording} disabled={wrapupRequired}>
{isRecording ? 'Pause Recording' : 'Resume Recording'}
</button>
<button className="btn" onClick={endCall} disabled={wrapupRequired}>
Copy link
Contributor

Choose a reason for hiding this comment

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

This button shouldn't always be enabled. We have a feature flag isEndCallEnabled which is by default false. So only end from call control widget should be possible if this is set

Copy link
Author

Choose a reason for hiding this comment

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

I want unable to find this flag in agentProfile and in the task object. Creating a task for this to be handled later https://jira-eng-gpk2.cisco.com/jira/browse/SPARK-609158

return <></>; // hidden component
}

const callAssociationDetails = currentTask.data.interaction.callAssociatedDetails;
const callAssociationDetails = incomingTask.data.interaction.callAssociatedDetails;
Copy link
Contributor

Choose a reason for hiding this comment

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

I only see the audio element added here in the incoming task object but not in call control. How are we ensuring for browser case that remote audio is received and played? I observed one-way audio in my testing. Please check this before merging.

Copy link
Author

Choose a reason for hiding this comment

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

Great catch! Ive moved the audio to call-control after discussing with Arun and Kesava, we are assuming if a dev needs to have audio of the call they need to use the call-control widget. If we get an ask that wants otherwise we can pick this up again

@Shreyas281299
Copy link
Author

Did we test dial number scenario also for call control? I was trying to test and not sure it is able to handle the call control widget display along with incomingTask widget appearing/disappearing. Please check this flow too before merging.

Appriving the code as I won't be available tomorrow but please ensure to address these commenst as they are critici=al

We did a testing for direct number, We were able to connect and control the call from the widgets.

Copy link
Contributor

@rarajes2 rarajes2 left a comment

Choose a reason for hiding this comment

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

Looks good.

@Shreyas281299 Shreyas281299 merged commit a677f5e into webex:ccwidgets Jan 29, 2025
2 checks passed
@sreenara
Copy link
Contributor

🎉 This PR is included in version 1.28.0-ccwidgets.12 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

mkesavan13 pushed a commit to mkesavan13/widgets that referenced this pull request Jan 29, 2025
# [1.28.0-ccwidgets.12](webex/widgets@v1.28.0-ccwidgets.11...v1.28.0-ccwidgets.12) (2025-01-29)

### Bug Fixes

* **call-control:** add-call-control-widget ([webex#362](webex#362)) ([a677f5e](webex@a677f5e))
@sreenara
Copy link
Contributor

sreenara commented Feb 5, 2025

🎉 This PR is included in version 1.28.0-ccconnectors.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

mkesavan13 pushed a commit to mkesavan13/widgets that referenced this pull request Feb 7, 2025
# [1.28.0-ccconnectors.1](webex/widgets@v1.27.5...v1.28.0-ccconnectors.1) (2025-02-05)

### Bug Fixes

* add material to all components ([webex#376](webex#376)) ([de0ca28](webex@de0ca28))
* **bundling:** fixed the multiple React instance and useRef errors  ([webex#355](webex#355)) ([473cd4f](webex@473cd4f))
* **call-control:** add-call-control-widget ([webex#362](webex#362)) ([a677f5e](webex@a677f5e))
* **cc-station-login:** material design ui ([webex#377](webex#377)) ([aec7034](webex@aec7034))
* **cc-store:** receive webex on init, add store types ([webex#341](webex#341)) ([9648969](webex@9648969))
* **cc-widgets:** ship-all-widgets-together ([webex#345](webex#345)) ([83d5a37](webex@83d5a37))
* cleanup and using mobx-react-lite ([webex#356](webex#356)) ([0b304c4](webex@0b304c4))
* convert npm to yarn ([webex#234](webex#234)) ([432ed3c](webex@432ed3c))
* **release:** add-publish-step-in-tooling ([webex#334](webex#334)) ([ca32235](webex@ca32235))
* rename agent state to user state ([webex#361](webex#361)) ([fe409db](webex@fe409db))
* **samples:** change samples index html hrefs ([webex#367](webex#367)) ([ff126ab](webex@ff126ab))
* **user-state:** receive agent stateChange event ([webex#350](webex#350)) ([21d6ce7](webex@21d6ce7))

### Features

* **cc-components:** setup and move user state sample ui comp ([webex#359](webex#359)) ([16a44d0](webex@16a44d0))
* **cc-store:** add logger from sdk ([webex#354](webex#354)) ([a62494b](webex@a62494b))
* **cc-widgets:** added Agent-Multi-Login-Alert Feature ([webex#364](webex#364)) ([f7d75ca](webex@f7d75ca))
* **release:** add new branch to circleci ([18f7bec](webex@18f7bec))
* **release:** publish pipeline for wxcc widgets ([webex#324](webex#324)) ([864fb52](webex@864fb52))
* taskList and IncomingTask widgets added ([webex#348](webex#348)) ([ce3a619](webex@ce3a619))
* **user-state:** load and change state, client timer ([webex#347](webex#347)) ([f1ccaeb](webex@f1ccaeb))
* **widget-cc-station-login:** Spark 575845 login widget ([webex#239](webex#239)) ([66b8a20](webex@66b8a20))
* **widgets:** added-relogin-logic ([webex#357](webex#357)) ([94dd415](webex@94dd415))
* **widgets:** shifted-timer-to-worker ([webex#352](webex#352)) ([c06fe9c](webex@c06fe9c))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants