From 3dfaaeb4cd3bbdf5de8fc4aa27d1a3e9f7570153 Mon Sep 17 00:00:00 2001 From: Rankush Kumar Date: Thu, 11 Dec 2025 17:00:25 +0530 Subject: [PATCH] docs(station-login): add AI documentation - AGENTS.md and ARCHITECTURE.md --- .../station-login/ai-docs/AGENTS.md | 327 ++++++++++ .../station-login/ai-docs/ARCHITECTURE.md | 558 ++++++++++++++++++ 2 files changed, 885 insertions(+) create mode 100644 packages/contact-center/station-login/ai-docs/AGENTS.md create mode 100644 packages/contact-center/station-login/ai-docs/ARCHITECTURE.md diff --git a/packages/contact-center/station-login/ai-docs/AGENTS.md b/packages/contact-center/station-login/ai-docs/AGENTS.md new file mode 100644 index 000000000..24efde29e --- /dev/null +++ b/packages/contact-center/station-login/ai-docs/AGENTS.md @@ -0,0 +1,327 @@ +# Station Login Widget + +## Overview + +The Station Login widget provides a user interface for contact center agents to log in and out of their station. It handles device type selection (Extension, Mobile, Browser), team selection, and agent profile management. The widget integrates with the Webex Contact Center SDK and follows the standard three-layer architecture pattern (Widget → Hook → Component → Store). + +**Package:** `@webex/cc-station-login` + +**Version:** See [package.json](../package.json) + +--- + +## Why and What is This Widget Used For? + +### Purpose + +The Station Login widget enables contact center agents to: +- **Login to their station** with appropriate device settings +- **Select their team** from available teams +- **Choose device type** (Extension, Agent DN, Browser-based) +- **Logout from their station** when ending their shift +- **Update their profile settings** while logged in (profile mode) +- **Handle multiple login scenarios** with continuation prompts + +### Key Capabilities + +- **Device Type Support**: Extension, Agent DN (Mobile), and Browser-based login +- **Team Management**: Dropdown selection for multi-team agents +- **Profile Mode**: Update agent profile settings without full re-login +- **Error Handling**: Comprehensive error boundary with callback support +- **Multiple Login Detection**: Alerts and continuation flow for agents logged in elsewhere +- **Validation**: Dial number validation using regex patterns +- **Callbacks**: Extensible callbacks for login, logout, and sign-out events + +--- + +## Examples and Use Cases + +### Getting Started + +#### Basic Usage (React) + +```typescript +import { StationLogin } from '@webex/cc-station-login'; +import React from 'react'; + +function MyApp() { + const handleLogin = () => { + console.log('Agent logged in successfully'); + }; + + const handleLogout = () => { + console.log('Agent logged out successfully'); + }; + + const handleCCSignOut = () => { + console.log('Agent signed out from contact center'); + }; + + return ( + + ); +} +``` + +#### Web Component Usage + +```html + + + + + + + +``` + +#### Profile Mode Usage + +```typescript +import { StationLogin } from '@webex/cc-station-login'; + +function AgentProfile() { + const handleSaveStart = () => { + console.log('Saving profile changes...'); + }; + + const handleSaveEnd = (success: boolean) => { + if (success) { + console.log('Profile updated successfully'); + } else { + console.log('Profile update failed'); + } + }; + + return ( + + ); +} +``` + +### Common Use Cases + +#### 1. Agent Login Flow + +```typescript +// Agent selects team, device type, and enters extension +// Widget handles the login process through the SDK + { + // Navigate to agent desktop + navigateToDesktop(); + }} + onLogout={() => { + // Return to login screen + navigateToLogin(); + }} + onCCSignOut={() => { + // Sign out from entire application + performFullSignOut(); + }} + profileMode={false} +/> +``` + +#### 2. Update Agent Profile Settings + +```typescript +// Agent updates device type or team while logged in + showSpinner()} + onSaveEnd={(success) => { + hideSpinner(); + showNotification(success ? 'Profile updated' : 'Update failed'); + }} + teamId={currentTeamId} + doStationLogout={false} +/> +``` + +#### 3. Handle Multiple Login Sessions + +```typescript +// Widget automatically detects if agent is logged in elsewhere +// Shows alert and provides continuation option + { + console.log('Successfully continued session'); + }} + // Widget handles the multiple login flow internally +/> +``` + +#### 4. Custom Error Handling + +```typescript +import store from '@webex/cc-store'; + +// Set error callback before rendering widget +store.onErrorCallback = (componentName, error) => { + console.error(`Error in ${componentName}:`, error); + // Send to error tracking service + trackError(componentName, error); +}; + +// Widget will call this callback on errors + +``` + +### Integration Patterns + +#### With Custom Authentication + +```typescript +import { StationLogin } from '@webex/cc-station-login'; +import store from '@webex/cc-store'; + +function AuthenticatedApp() { + // Initialize store with SDK instance + useEffect(() => { + const initializeCC = async () => { + // Initialize Contact Center SDK + const cc = await ContactCenter.init({ + token: authToken, + region: 'us1' + }); + + // Set CC instance in store + store.setCC(cc); + }; + + initializeCC(); + }, [authToken]); + + return ; +} +``` + +#### With State Management + +```typescript +import { StationLogin } from '@webex/cc-station-login'; +import { observer } from 'mobx-react-lite'; +import store from '@webex/cc-store'; + +// Observer component that reacts to store changes +const LoginContainer = observer(() => { + const { isAgentLoggedIn, teams, deviceType } = store; + + if (isAgentLoggedIn) { + return ; + } + + return ( + { + // Store automatically updates isAgentLoggedIn + console.log('Teams available:', teams); + console.log('Device type:', deviceType); + }} + profileMode={false} + /> + ); +}); +``` + +--- + +## Dependencies + +**Note:** For exact versions, see [package.json](../package.json) + +### Runtime Dependencies + +| Package | Purpose | +|---------|---------| +| `@webex/cc-components` | React UI components | +| `@webex/cc-store` | MobX singleton store for state management | +| `mobx-react-lite` | React bindings for MobX | +| `react-error-boundary` | Error boundary implementation | + +### Peer Dependencies + +| Package | Purpose | +|---------|---------| +| `react` | React framework | +| `react-dom` | React DOM rendering | +| `@momentum-ui/react-collaboration` | Momentum UI components | + +### Development Dependencies + +Key development tools (see [package.json](../package.json) for versions): +- TypeScript +- Jest (testing) +- Webpack (bundling) +- ESLint (linting) + +### External SDK Dependency + +The widget requires the **Webex Contact Center SDK** (`@webex/contact-center`) to be initialized and available through the store. The SDK provides: +- `stationLogin()` - Login to station +- `stationLogout()` - Logout from station +- `updateAgentProfile()` - Update agent profile settings +- `registerCC()` - Register contact center client +- `deregister()` - Deregister contact center client + +--- + +## Props API + +| Prop | Type | Required | Default | Description | +|------|------|----------|---------|-------------| +| `profileMode` | `boolean` | Yes | - | Shows save button (true) or login/logout (false) | +| `onLogin` | `() => void` | No | - | Callback when login succeeds | +| `onLogout` | `() => void` | No | - | Callback when logout succeeds | +| `onCCSignOut` | `() => void` | No | - | Callback when CC sign out is triggered | +| `onSaveStart` | `() => void` | No | - | Callback when profile save starts | +| `onSaveEnd` | `(success: boolean) => void` | No | - | Callback when profile save ends | +| `teamId` | `string` | No | - | Default team ID | +| `doStationLogout` | `boolean` | No | `true` | Perform station logout on CC sign out | + +--- + +## Installation + +```bash +# Install as part of contact center widgets +yarn add @webex/cc-station-login + +# Or install the entire widgets bundle +yarn add @webex/cc-widgets +``` + +--- + +## Additional Resources + +For detailed component architecture, data flows, and sequence diagrams, see [architecture.md](./architecture.md). + +--- + +_Last Updated: 2025-11-26_ + diff --git a/packages/contact-center/station-login/ai-docs/ARCHITECTURE.md b/packages/contact-center/station-login/ai-docs/ARCHITECTURE.md new file mode 100644 index 000000000..8d3def387 --- /dev/null +++ b/packages/contact-center/station-login/ai-docs/ARCHITECTURE.md @@ -0,0 +1,558 @@ +# Station Login Widget - Architecture + +## Component Overview + +The Station Login widget follows the three-layer architecture pattern: **Widget → Hook → Component → Store → SDK**. This architecture separates concerns between state management, business logic, and presentation. + +### Component Table + +| Layer | Component | File | Config/Props | State | Callbacks | Events | Tests | +|-------|-----------|------|--------------|-------|-----------|--------|-------| +| **Widget** | `StationLogin` | `src/station-login/index.tsx` | `StationLoginProps` | N/A (passes through) | `onLogin`, `onLogout`, `onCCSignOut`, `onSaveStart`, `onSaveEnd` | SDK events (via store) | `tests/station-login/index.tsx` | +| **Widget Internal** | `StationLoginInternal` | `src/station-login/index.tsx` | `StationLoginProps` | Observes store | Same as above | Same as above | Same | +| **Hook** | `useStationLogin` | `src/helper.ts` | `UseStationLoginProps` | `team`, `loginSuccess`, `loginFailure`, `logoutSuccess`, `originalLoginOptions`, `currentLoginOptions`, `saveError` | Wraps props callbacks | Subscribes to SDK events | `tests/helper.ts` | +| **Component** | `StationLoginComponent` | `@webex/cc-components` | `StationLoginComponentProps` | Internal form state | Inherited from hook | N/A | `@webex/cc-components` tests | +| **Store** | `Store` (singleton) | `@webex/cc-store` | N/A | `cc`, `teams`, `loginOptions`, `deviceType`, `dialNumber`, `teamId`, `isAgentLoggedIn`, `showMultipleLoginAlert` | N/A | `AGENT_STATION_LOGIN_SUCCESS`, `AGENT_LOGOUT_SUCCESS` | `@webex/cc-store` tests | +| **SDK** | `ContactCenter` | `@webex/contact-center` | N/A | N/A | N/A | Login/logout events | SDK tests | + +### SDK Methods & Events Integration + +| Component | SDK Methods Used | SDK Events Subscribed | Store Methods Used | +|-----------|------------------|----------------------|-------------------| +| **useStationLogin Hook** | `stationLogin()`, `stationLogout()`, `updateAgentProfile()`, `deregister()` | `AGENT_STATION_LOGIN_SUCCESS`, `AGENT_LOGOUT_SUCCESS` | `setCCCallback()`, `removeCCCallback()`, `setShowMultipleLoginAlert()`, `registerCC()` | +| **Store** | All SDK methods | All SDK events | N/A | +| **Widget** | N/A (via hook) | N/A (via store) | N/A (via hook) | + +### File Structure + +``` +station-login/ +├── src/ +│ ├── helper.ts # useStationLogin hook +│ ├── index.ts # Package exports +│ └── station-login/ +│ ├── index.tsx # Widget component +│ └── station-login.types.ts # TypeScript types +├── tests/ +│ ├── helper.ts # Hook tests (if exists) +│ └── station-login/ +│ └── index.tsx # Widget tests +├── ai-docs/ +│ ├── agent.md # Overview, examples, usage +│ └── architecture.md # Architecture documentation +├── dist/ # Build output +├── package.json # Dependencies and scripts +├── tsconfig.json # TypeScript config +├── webpack.config.js # Webpack build config +├── jest.config.js # Jest test config +└── eslint.config.mjs # ESLint config +``` + +--- + +## Data Flows + +### Layer Communication Flow + +The widget follows a unidirectional data flow pattern across layers: + +```mermaid +graph TB + subgraph "Presentation Layer" + Widget[StationLogin Widget] + Component[StationLoginComponent] + end + + subgraph "Business Logic Layer" + Hook[useStationLogin Hook
helper.ts] + end + + subgraph "State Management Layer" + Store[Store Singleton] + end + + subgraph "SDK Layer" + SDK[Contact Center SDK] + end + + Widget -->|Props
callbacks, config| Hook + Hook -->|Read state
teams, deviceType, etc| Store + Hook -->|Call methods
stationLogin, logout, etc| SDK + Store -->|Register callbacks
Manage SDK instance| SDK + + SDK -->|Events
login success, logout| Store + Store -->|State changes
observable| Hook + Hook -->|Return state
& handlers| Widget + Widget -->|Props
state, handlers, teams| Component + + style Hook fill:#e1f5ff + style Store fill:#fff4e1 + style SDK fill:#f0e1ff +``` + +**Hook Responsibilities:** +- Manages local state +- Subscribes to SDK events +- Handles login/logout logic +- Profile update logic +- Error handling + +**Store Responsibilities:** +- Observable state +- SDK instance holder +- Event callback registry +- Global configuration + +### Hook (helper.ts) Details + +**File:** `src/helper.ts` + +The `useStationLogin` hook is the core business logic layer that: + +1. **Manages Local State:** + - `team` - Selected team ID + - `loginSuccess` / `loginFailure` - Login operation results + - `logoutSuccess` - Logout operation result + - `originalLoginOptions` / `currentLoginOptions` - For profile update comparison + - `saveError` - Profile update error messages + +2. **Subscribes to SDK Events:** + ```typescript + useEffect(() => { + store.setCCCallback(CC_EVENTS.AGENT_STATION_LOGIN_SUCCESS, handleLogin); + store.setCCCallback(CC_EVENTS.AGENT_LOGOUT_SUCCESS, handleLogout); + }, [store.isAgentLoggedIn]); + ``` + +3. **Provides Key Functions:** + - `login()` - Calls `cc.stationLogin()` with selected options + - `logout()` - Calls `cc.stationLogout()` with reason + - `saveLoginOptions()` - Calls `cc.updateAgentProfile()` for profile updates + - `handleContinue()` - Handles multiple login continuation via `store.registerCC()` + - `handleCCSignOut()` - Performs station logout and deregistration + - `setTeam()` - Updates selected team + +4. **Profile Update Logic:** + - Compares `originalLoginOptions` vs `currentLoginOptions` + - Computes `isLoginOptionsChanged` to enable/disable save button + - Only sends changed fields to SDK + - Updates `originalLoginOptions` after successful save + +### Sequence Diagrams + +#### 1. Login Flow + +```mermaid +sequenceDiagram + actor User + participant Widget as StationLogin Widget + participant Hook as useStationLogin Hook + participant Component as StationLoginComponent + participant Store + participant SDK + + User->>Widget: Load widget + activate Widget + Widget->>Hook: useStationLogin() + activate Hook + Hook->>Store: getInstance() + Store-->>Hook: {configuration, teams, deviceTypes} + Hook-->>Widget: {state, handlers} + deactivate Hook + Widget->>Component: Render with state + activate Component + Component->>Component: Display teams dropdown + Component->>Component: Display device types + Component-->>Widget: UI rendered + deactivate Component + deactivate Widget + + Note over User,Component: User Selects Team + User->>Component: Select team from dropdown + activate Component + Component->>Hook: onTeamChange(teamId) + activate Hook + Hook->>Store: runInAction(() => setSelectedTeam(teamId)) + Store-->>Hook: Updated state + Hook-->>Component: New state + deactivate Hook + Component->>Component: Update UI + deactivate Component + + Note over User,Component: User Selects Device Type + User->>Component: Select device type (Extension/Mobile) + activate Component + Component->>Hook: onDeviceTypeChange(type) + activate Hook + Hook->>Store: runInAction(() => setDeviceType(type)) + Store-->>Hook: Updated state + Hook-->>Component: New state + deactivate Hook + Component->>Component: Show appropriate fields + deactivate Component + + Note over User,SDK: User Submits Login + User->>Component: Click Login button + activate Component + Component->>Hook: onLoginClick(credentials) + activate Hook + Hook->>Store: runInAction(() => login(credentials)) + activate Store + Store->>SDK: login({extension, team, deviceType}) + SDK-->>Store: Success/Error + Store-->>Hook: Login result + deactivate Store + Hook-->>Component: Updated state + deactivate Hook + Component->>Component: Show success/error + deactivate Component +``` + +--- + +#### 2. Logout Flow + +```mermaid +sequenceDiagram + actor User + participant Component as StationLoginComponent + participant Hook as useStationLogin Hook + participant Store + participant SDK + + User->>Component: Click Logout button + activate Component + Component->>Hook: logout() + activate Hook + Hook->>SDK: stationLogout({ logoutReason }) + activate SDK + SDK->>SDK: Process logout + SDK-->>Hook: AGENT_LOGOUT_SUCCESS event + deactivate SDK + Hook->>Hook: handleLogout() + Hook->>Hook: Invoke onLogout callback + Hook->>Store: Update state + activate Store + Store->>Store: isAgentLoggedIn = false + Store-->>Hook: State updated + deactivate Store + Hook-->>Component: Updated state + deactivate Hook + Component->>Component: Re-render (logged out UI) + deactivate Component +``` + +--- + +#### 3. Profile Update Flow + +```mermaid +sequenceDiagram + actor User + participant Component as StationLoginComponent + participant Hook as useStationLogin Hook + participant Store + participant SDK + + User->>Component: Modify device type + activate Component + Component->>Hook: setCurrentLoginOptions({ deviceType }) + activate Hook + Hook->>Hook: Compute isLoginOptionsChanged + Hook-->>Component: isLoginOptionsChanged = true + deactivate Hook + Component->>Component: Enable Save button + deactivate Component + + User->>Component: Click Save + activate Component + Component->>Hook: saveLoginOptions() + activate Hook + Hook->>Hook: Invoke onSaveStart() + Hook->>Hook: Build payload + Hook->>SDK: updateAgentProfile(payload) + activate SDK + SDK->>SDK: Update agent profile + SDK-->>Hook: Success response + deactivate SDK + Hook->>Hook: setOriginalLoginOptions = currentLoginOptions + Hook->>Hook: Invoke onSaveEnd(true) + Hook-->>Component: Save complete + deactivate Hook + Component->>Component: Show success message + Component->>Component: Disable Save button + deactivate Component +``` + +--- + +#### 4. Multiple Login Flow + +```mermaid +sequenceDiagram + actor User + participant Component as StationLoginComponent + participant Hook as useStationLogin Hook + participant Store + participant SDK + + User->>Component: Attempt login + activate Component + Component->>Hook: login() + activate Hook + Hook->>SDK: stationLogin() + activate SDK + SDK->>SDK: Detect existing session + SDK-->>Hook: Multiple login detected + deactivate SDK + Hook->>Store: showMultipleLoginAlert = true + Store-->>Component: Re-render with alert + deactivate Hook + Component->>Component: Show alert dialog + Component-->>User: "Already logged in elsewhere" + deactivate Component + + User->>Component: Click Continue + activate Component + Component->>Hook: handleContinue() + activate Hook + Hook->>Store: setShowMultipleLoginAlert(false) + Hook->>Store: registerCC() + activate Store + Store->>SDK: register() + activate SDK + SDK->>SDK: Force register + SDK-->>Store: Success + deactivate SDK + Store->>Store: isAgentLoggedIn = true + Store-->>Hook: Registration complete + deactivate Store + Hook-->>Component: Update state + deactivate Hook + Component->>Component: Hide alert + Component->>Component: Show logged in UI + deactivate Component +``` + +--- + +#### 5. CC Sign Out Flow + +```mermaid +sequenceDiagram + actor User + participant Component as StationLoginComponent + participant Hook as useStationLogin Hook + participant Store + participant SDK + participant App as Application + + User->>Component: Click Sign Out button + activate Component + Component->>Hook: handleCCSignOut() + activate Hook + + alt doStationLogout = true AND isAgentLoggedIn = true + Hook->>SDK: stationLogout({ logoutReason }) + activate SDK + SDK-->>Hook: Logout success + deactivate SDK + Hook->>SDK: deregister() + activate SDK + SDK-->>Hook: Deregister success + deactivate SDK + end + + Hook->>Hook: Invoke onCCSignOut callback + Hook->>App: onCCSignOut() + activate App + App->>App: Handle full sign out + App->>App: Clear session, redirect, etc. + deactivate App + Hook-->>Component: Sign out complete + deactivate Hook + Component-->>User: Signed out + deactivate Component +``` + +--- + +## Troubleshooting Guide + +### Common Issues + +#### 1. Widget Not Rendering + +**Symptoms:** +- Widget shows blank screen +- No error messages + +**Possible Causes:** +- Store not initialized +- SDK instance not set in store +- Missing peer dependencies + +**Solutions:** + +```typescript +// Check if store has CC instance +import store from '@webex/cc-store'; +console.log('CC instance:', store.cc); // Should not be undefined + +// Ensure SDK is initialized before rendering widget +const initializeApp = async () => { + const cc = await ContactCenter.init({ token, region }); + store.setCC(cc); + // Now render widget +}; +``` + +#### 2. Login Fails Silently + +**Symptoms:** +- Login button clicked but nothing happens +- No error or success message + +**Possible Causes:** +- SDK not initialized +- Network issues +- Invalid credentials +- Missing logger + +**Solutions:** + +```typescript +// Check logger +console.log('Logger:', store.logger); // Should be defined + +// Enable detailed logging +store.logger.setLevel('debug'); + +// Check SDK events +store.setCCCallback('error', (error) => { + console.error('SDK Error:', error); +}); +``` + +#### 3. Profile Update Not Working + +**Symptoms:** +- Save button disabled +- Changes not persisted +- `onSaveEnd` called with `false` + +**Possible Causes:** +- `profileMode` not set to `true` +- No actual changes made +- SDK updateAgentProfile failing + +**Solutions:** + +```typescript +// Ensure profileMode is true + + +// Check if changes are detected +const hook = useStationLogin(props); +console.log('Login options changed:', hook.isLoginOptionsChanged); + +// Check save error +console.log('Save error:', hook.saveError); +``` + +#### 4. Multiple Login Alert Not Dismissing + +**Symptoms:** +- Alert stays visible after clicking Continue +- Agent cannot proceed with login + +**Possible Causes:** +- `handleContinue` not called +- `registerCC` failing +- Store state not updating + +**Solutions:** + +```typescript +// Check store state +console.log('Show alert:', store.showMultipleLoginAlert); + +// Manually dismiss (for testing) +store.setShowMultipleLoginAlert(false); + +// Check registration +store.registerCC() + .then(() => console.log('Registered')) + .catch(err => console.error('Registration failed:', err)); +``` + +#### 5. Callbacks Not Firing + +**Symptoms:** +- `onLogin`, `onLogout`, or `onSaveEnd` not called +- Application state not updating + +**Possible Causes:** +- SDK events not properly subscribed +- Store callback registration failing +- Callback references changing + +**Solutions:** + +```typescript +// Ensure callbacks are stable references +const handleLogin = useCallback(() => { + console.log('Login callback'); +}, []); + +// Verify SDK event subscription +useEffect(() => { + const loginHandler = () => console.log('SDK login event'); + store.setCCCallback(CC_EVENTS.AGENT_STATION_LOGIN_SUCCESS, loginHandler); + + return () => { + store.removeCCCallback(CC_EVENTS.AGENT_STATION_LOGIN_SUCCESS, loginHandler); + }; +}, []); +``` + +#### 6. Error Boundary Showing Empty Screen + +**Symptoms:** +- Widget displays nothing +- Error callback invoked + +**Possible Causes:** +- Error in hook +- Error in component rendering +- Store access error + +**Solutions:** + +```typescript +// Set error callback to see details +store.onErrorCallback = (component, error) => { + console.error(`Error in ${component}:`, error); + // Show error UI instead of blank screen + showErrorNotification(error.message); +}; + +// Wrap widget with custom error boundary +}> + + +``` + +--- + +## Related Documentation + +- [Agent Documentation](./agent.md) - Usage examples and props +- [MobX Patterns](../../../../ai-docs/patterns/mobx-patterns.md) - Store patterns +- [React Patterns](../../../../ai-docs/patterns/react-patterns.md) - Component patterns +- [Testing Patterns](../../../../ai-docs/patterns/testing-patterns.md) - Testing guidelines +- [Store Documentation](../../store/ai-docs/agent.md) - Store API reference + +--- + +_Last Updated: 2025-11-26_