diff --git a/AGENTS.md b/AGENTS.md index 70963b493..193649a3c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -532,6 +532,7 @@ yarn build ``` ccWidgets/ ├── packages/contact-center/ +│ ├── ai-docs/migration/ # Task refactor migration docs (old → new) │ ├── station-login/ # Widget with ai-docs/ │ ├── user-state/ # Widget with ai-docs/ │ ├── task/ # Widget package @@ -613,6 +614,7 @@ ccWidgets/ - **Repository Rules:** [RULES.md](./RULES.md) - **Templates Overview:** [templates/README.md](./ai-docs/templates/README.md) +- **Task Refactor Migration (Contact Center):** [packages/contact-center/ai-docs/migration/migration-overview.md](./packages/contact-center/ai-docs/migration/migration-overview.md) — overview and entry point for CC SDK task-refactor migration docs --- diff --git a/packages/contact-center/ai-docs/migration/migration-overview.md b/packages/contact-center/ai-docs/migration/migration-overview.md new file mode 100644 index 000000000..6c85ec5db --- /dev/null +++ b/packages/contact-center/ai-docs/migration/migration-overview.md @@ -0,0 +1,158 @@ +# Task Refactor Migration Overview + +## Purpose + +Guide for migrating CC Widgets from ad-hoc task state management to the new SDK state-machine-driven architecture (`task-refactor` branch). This is the single entry point — it tells you what changed, which docs to follow in what order, and what to watch out for. + +--- + +## Architectural Change: Old vs New + +``` +┌─────────────────────────────────────────────────────────────────────────────────┐ +│ OLD (Current Widgets) │ NEW (After Migration) │ +│ │ │ +│ SDK emits 27 task events │ SDK state machine transitions │ +│ │ │ │ │ +│ ▼ │ ▼ │ +│ Store: refreshTaskList() │ SDK: computes TaskUIControls │ +│ + update observables manually │ from (TaskState + TaskContext) │ +│ │ │ │ │ +│ ▼ │ ▼ │ +│ Hooks: getControlsVisibility( │ SDK emits │ +│ deviceType, featureFlags, │ 'task:ui-controls-updated' │ +│ task, agentId, conferenceEnabled) │ │ │ +│ │ │ ▼ │ +│ ▼ │ Widgets read task.uiControls │ +│ Components: flat ControlVisibility │ │ │ +│ (22 controls + 7 state flags) │ ▼ │ +│ │ Components: TaskUIControls │ +│ Logic spread across: │ (17 controls, each │ +│ task-util.ts, task-utils.ts, │ { isVisible, isEnabled }) │ +│ timer-utils.ts, component utils │ │ +│ │ Single source of truth: │ +│ │ task.uiControls │ +└─────────────────────────────────────────────────────────────────────────────────┘ +``` + +> The events themselves have not changed — they are the same events, now emitted via the SDK state machine. The key difference is that task state updates (including UI control computation) are handled by the SDK, not by widgets. + +--- + +## CC Widgets Files Affected + +| Area | Path | +|------|------| +| Store event wrapper | `packages/contact-center/store/src/storeEventsWrapper.ts` | +| Store task utils | `packages/contact-center/store/src/task-utils.ts` | +| Store constants | `packages/contact-center/store/src/constants.ts` | +| Store types | `packages/contact-center/store/src/store.types.ts` | +| Task hooks | `packages/contact-center/task/src/helper.ts` | +| Task UI utils (to be removed) | `packages/contact-center/task/src/Utils/task-util.ts` | +| Task types | `packages/contact-center/task/src/task.types.ts` | +| CC Components — CallControl | `packages/contact-center/cc-components/src/components/task/CallControl/` | +| CC Components — CallControlCAD | `packages/contact-center/cc-components/src/components/task/CallControlCAD/` | +| CC Components types | `packages/contact-center/cc-components/src/components/task/task.types.ts` | +| CC Components — WC wrapper | `packages/contact-center/cc-components/src/wc.ts` | + +> **Not listed:** `timer-utils.ts` and `useHoldTimer.ts` are not directly affected by the task-refactor SDK changes. Timer signature updates (if any) are tracked separately in the hook migration doc. + +--- + +## Execution Order + +Follow these docs in order. Each doc has old vs new code, before/after examples, and files to modify. + +| Order | Document | What to Do | +|-------|----------|------------| +| 1 | [store-event-wiring-migration.md](./store-event-wiring-migration.md) | Update 27 event handlers — switch to SDK `TASK_EVENTS` enum, keep `refreshTaskList()`, add `TASK_UI_CONTROLS_UPDATED` subscription, fix `handleConsultEnd` wiring, replace `isDeclineButtonEnabled` with `task.uiControls.decline.isEnabled` | +| 2 | [store-task-utils-migration.md](./store-task-utils-migration.md) | Remove redundant utils (SDK handles), keep display/timer utils | +| 3 | [call-control-hook-migration.md](./call-control-hook-migration.md) | Replace `getControlsVisibility()` with `task.uiControls` in `useCallControl` + update timer utils | +| 4 | [incoming-task-migration.md](./incoming-task-migration.md) | Use `task.uiControls.accept/decline` instead of visibility functions | +| 5 | [task-list-migration.md](./task-list-migration.md) | Per-task `uiControls` for accept/decline | +| 6 | [component-layer-migration.md](./component-layer-migration.md) | Update `cc-components` props — `ControlVisibility` → `TaskUIControls`, rename control props | + +--- + +## SDK Pending Exports (Prerequisites) + +**What the SDK does not export today** (from the package entry point `src/index.ts`): the items in the table below. They exist in SDK source but are not re-exported from the public package, so widget code cannot import them until they are added to the package. + +**Before implementing:** Check whether each required export is available from the SDK — i.e. whether you can import it from the package. If an item is not yet exported, delay the work that depends on it or implement only the parts that do not need it. Full completion of the migration requires these exports. + +| Item | SDK Change Needed | +|------|---| +| `TaskUIControls` type | Add to `src/index.ts` | +| `getDefaultUIControls()` | Add to `src/index.ts` | +| `TaskState` enum | Add to `src/index.ts` (needed for consult timer labeling) | +| `uiControls` on `ITask` | Add getter to `ITask` interface (currently only on concrete `Task` class) | +| `IVoice`, `IDigital`, `IWebRTC` | Add to `src/index.ts` (optional — for type narrowing) | + +--- + +## Key Types from SDK + +| Type | Purpose | +|------|---------| +| `TaskUIControls` | Pre-computed control states (17 controls, each `{ isVisible, isEnabled }`) | +| `TaskUIControlState` | Shape: `{ isVisible: boolean; isEnabled: boolean }` | +| `getDefaultUIControls()` | Fallback when no task: `task?.uiControls ?? getDefaultUIControls()` | +| `TASK_EVENTS` | Import from SDK — delete local enum in `store.types.ts` | +| `TaskState` | SDK state machine states — needed for consult timer labeling | + +### `TaskUIControls` Structure + +```typescript +type TaskUIControlState = { isVisible: boolean; isEnabled: boolean }; + +type TaskUIControls = { + accept: TaskUIControlState; + decline: TaskUIControlState; + hold: TaskUIControlState; + transfer: TaskUIControlState; + consult: TaskUIControlState; + end: TaskUIControlState; + recording: TaskUIControlState; + mute: TaskUIControlState; + consultTransfer: TaskUIControlState; + endConsult: TaskUIControlState; + conference: TaskUIControlState; + exitConference: TaskUIControlState; + transferConference: TaskUIControlState; + mergeToConference: TaskUIControlState; + wrapup: TaskUIControlState; + switchToMainCall: TaskUIControlState; + switchToConsult: TaskUIControlState; +}; +``` + +Widgets no longer compute control visibility — `task.uiControls` is the single source of truth. + +> Specific constants to delete/keep, event name mappings, and ordering constraints (e.g. "do not delete constant X until helper Y is rewritten") are documented in each migration doc listed in the [Execution Order](#execution-order) table. + +--- + +## SDK Public Method Changes + +| Old | New | Notes | +|-----|-----|-------| +| `task.consultTransfer()` | `task.transfer()` | `consultTransfer` is no longer a separate public method; a single `.transfer()` is used for all transfer types | + +--- + +## CC SDK Reference + +> **Repo:** [webex/webex-js-sdk (task-refactor)](https://github.com/webex/webex-js-sdk/tree/task-refactor) + + + +| File | Purpose | +|------|---------| +| `uiControlsComputer.ts` | Computes `TaskUIControls` from `TaskState` + `TaskContext` — the single source of truth | +| `Task.ts` | Task service exposing `task.uiControls` getter and `task:ui-controls-updated` event | +| `constants.ts` | `TaskState` and `TaskEvent` enums | + +--- + +_Created: 2026-03-09_ +_Updated: 2026-03-19 (addressed Kesari3008/mkesavan feedback, aligned with PR #646 decisions)_