Skip to content

Commit

Permalink
fix(cc-store): receive webex on init, add store types (#341)
Browse files Browse the repository at this point in the history
  • Loading branch information
mkesavan13 authored Nov 26, 2024
1 parent 9b3c5ac commit 9648969
Show file tree
Hide file tree
Showing 11 changed files with 283 additions and 80 deletions.
42 changes: 28 additions & 14 deletions docs/react-samples/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,19 @@
import React, { useEffect } from 'react';
import React, { useEffect, useState } from 'react';
import store from '@webex/cc-store'
import {StationLogin} from '@webex/cc-station-login';
import {UserState} from '@webex/cc-user-state';

function App() {
const token = '';
const [isSdkReady, setIsSdkReady] = useState(false);
const [accessToken, setAccessToken] = useState("");

const webexConfig = {
fedramp: false,
logger: {
level: 'log' // TODO: We will add more logging levels later and set the righ levels
},
level: 'log'
}
}

useEffect(() => {
const init = async () => {
await store.init(webexConfig, token);
}

init();
}, [])

const onLogin = () => {
console.log('Agent login has been succesful');
}
Expand All @@ -32,8 +25,29 @@ function App() {
return (
<>
<h1>Contact Center widgets in a react app</h1>
<StationLogin onLogin={onLogin} onLogout={onLogout} />
<UserState />
<input
type="text"
placeholder="Enter your access token"
value={accessToken}
onChange={(e) => setAccessToken(e.target.value)}
/>
<button
disabled={accessToken.trim() === ""}
onClick={() => {
store.init({webexConfig, access_token: accessToken}).then(() => {
setIsSdkReady(true);
});
}}
>Init Widgets</button>
{/* write code to check if sdk is ready and load components */}
{
isSdkReady && (
<>
<StationLogin onLogin={onLogin} onLogout={onLogout} />
<UserState />
</>
)
}
</>
);
}
Expand Down
35 changes: 35 additions & 0 deletions docs/web-component-samples/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const widgetsContainer = document.getElementById('widgets-container');
const accessTokenElem = document.getElementById('access_token_elem');
const ccStationLogin = document.getElementById('cc-station-login');

function switchButtonState(){
const buttonElem = document.querySelector('button');
buttonElem.disabled = accessTokenElem.value.trim() === '';
}

function initWidgets(){
const webexConfig = {
fedramp: false,
logger: {
level: 'log'
},
}
store.init({
webexConfig,
access_token: accessTokenElem.value.trim()
}).then(() => {
ccStationLogin.onLogin = loginSuccess;
ccStationLogin.onLogout = logoutSuccess;
widgetsContainer.classList.remove('disabled');
}).catch((error) => {
console.error('Failed to initialize widgets:', error);
});
}

function loginSuccess(){
console.log('Agent login has been succesful');
}

function logoutSuccess(){
console.log('Agent logout has been succesful');
}
34 changes: 20 additions & 14 deletions docs/web-component-samples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,29 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>CC Widgets as web-component</title>
<style>
.disabled {
display: none;
}
</style>
</head>
<body>
<h1>Contact Center widgets as web-component</h1>
<input
type="text"
placeholder="Enter your access token"
id="access_token_elem"
onkeyup="switchButtonState()"
autocomplete="off"
spellcheck="false"
autocapitalize="off"
/>
<button onclick="initWidgets()" disabled>Init Widgets</button>
<div id="widgets-container" class="disabled">
<widget-cc-station-login id="cc-station-login"></widget-cc-station-login>
<widget-cc-user-state></widget-cc-user-state>
</div>
<script src="dist/bundle.js"></script>
<widget-cc-station-login></widget-cc-station-login>
<widget-cc-user-state></widget-cc-user-state>
<script src="app.js"></script>
</body>
<script>
const token = '';

const webexConfig = {
fedramp: false,
logger: {
level: 'log' // TODO: We will add more logging levels later and set the righ levels
},
}

store.init(webexConfig, token);
</script>
</html>
2 changes: 1 addition & 1 deletion docs/web-component-samples/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ import store from '@webex/cc-store';
import '@webex/cc-station-login';
import '@webex/cc-user-state';

//@ts-ignore
// @ts-ignore
window.store = store;
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@ const StationLogin: React.FunctionComponent<StationLoginProps> = observer(({onLo
return <StationLoginPresentational {...props} />;
});

const WebStationLogin = r2wc(StationLogin);
const WebStationLogin = r2wc(StationLogin, {
props: {
onLogin: "function",
onLogout: "function"
}
});

if (!customElements.get('widget-cc-station-login')) {
customElements.define('widget-cc-station-login', WebStationLogin);
Expand Down
9 changes: 6 additions & 3 deletions packages/contact-center/store/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,11 @@
"test:unit": "jest"
},
"dependencies": {
"@webex/plugin-cc": "3.5.0-wxcc.2",
"mobx": "6.13.5",
"react": "18.3.1",
"react-dom": "18.3.1",
"typescript": "5.6.3",
"webex": "3.6.0-wxcc.3"
"webex": "3.6.0-wxcc.5"
},
"devDependencies": {
"@babel/core": "7.25.2",
Expand All @@ -48,7 +47,11 @@
"jest": {
"testEnvironment": "jsdom",
"//": "We can remove this when we have tests",
"passWithNoTests": true
"passWithNoTests": true,
"testMatch": [
"**/tests/**/*.ts",
"**/tests/**/*.tsx"
]
},
"stableVersion": "1.0.0"
}
1 change: 1 addition & 0 deletions packages/contact-center/store/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import store from './store';
export * from './store.types';
export default store;
45 changes: 36 additions & 9 deletions packages/contact-center/store/src/store.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import {makeAutoObservable, observable} from 'mobx';
import Webex from 'webex';
import {IContactCenter, IAgentProfile, Team} from '@webex/plugin-cc';
import {
AgentLogin,
IContactCenter,
Profile,
Team,
WithWebex,
InitParams,
IStore
} from './store.types';

class Store {
class Store implements IStore {
teams: Team[] = [];
loginOptions: string[] = [];
cc: IContactCenter;
Expand All @@ -11,20 +19,39 @@ class Store {
makeAutoObservable(this, {cc: observable.ref});
}

init(webexConfig: any, access_token: string): Promise<void> {
registerCC(webex: WithWebex['webex']): Promise<void> {
this.cc = webex.cc;
return this.cc.register().then((response: Profile) => {
this.teams = response.teams;
this.loginOptions = response.loginVoiceOptions;
}).catch((error) => {
console.error('Error registering contact center', error);
return Promise.reject(error);
});
}

init(options: InitParams): Promise<void> {
if('webex' in options) {
// If devs decide to go with webex, they will have to listen to the ready event before calling init
// This has to be documented
return this.registerCC(options.webex);
}
return new Promise((resolve, reject) => {

const timer = setTimeout(() => {
reject(new Error('Webex SDK failed to initialize'));
}, 6000);

const webex = Webex.init({
config: webexConfig,
config: options.webexConfig,
credentials: {
access_token: access_token
access_token: options.access_token
}
});

webex.once('ready', () => {
this.cc = webex.cc;
this.cc.register().then((response: IAgentProfile) => {
this.teams = response.teams;
this.loginOptions = response.loginVoiceOptions;
clearTimeout(timer);
this.registerCC(webex).then(() => {
resolve();
})
.catch((error) => {
Expand Down
31 changes: 31 additions & 0 deletions packages/contact-center/store/src/store.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {AgentLogin, IContactCenter, Profile, Team} from '@webex/plugin-cc';

interface WithWebex {
webex: { cc: IContactCenter };
}

interface WithWebexConfig {
webexConfig: any; // Replace 'any' with the actual type of webexConfig
access_token: string;
}

type InitParams = WithWebex | WithWebexConfig;

interface IStore {
teams: Team[];
loginOptions: string[];
cc: IContactCenter;

registerCC(webex: WithWebex['webex']): Promise<Profile>;
init(params: InitParams): Promise<void>;
}

export type {
IContactCenter,
Profile,
Team,
AgentLogin,
WithWebex,
InitParams,
IStore
}
Loading

0 comments on commit 9648969

Please sign in to comment.