chatwoot/app/javascript/widget
Rob Coenen 5608f5a1a2
fix: Widget shows 'away' on initial load despite agents being online (#12869)
## Description

Fixes #12868

This PR fixes a Vue 3 reactivity bug that causes the widget to display
"We are away at the moment" on initial page load, even when agents are
online and the API correctly returns their availability.

## Problem

The widget welcome screen shows "We are away" on first render, only
updating to show correct agent status after navigating to the
conversation view and back. This misleads visitors into thinking no
agents are available.

**Reproduction:** Open website with widget in fresh incognito window,
click bubble immediately → shows "away" despite agents being online.

## Root Cause

Vue 3 reactivity chain breaks in the `useAvailability` composable:

**Before (broken):**
```javascript
// AvailabilityContainer.vue
const { isOnline } = useAvailability(props.agents); // Passes VALUE

// useAvailability.js  
const availableAgents = toRef(agents); // Creates ref from VALUE, doesn't track changes
```

When the API responds and updates the Vuex store, the parent component's
computed `props.agents` updates correctly, but the composable's
`toRef()` doesn't know about the change because it was created from a
static value, not a reactive source.

## Solution

**After (fixed):**
```javascript
// AvailabilityContainer.vue
const { isOnline } = useAvailability(toRef(props, 'agents')); // Passes REACTIVE REF

// useAvailability.js
const availableAgents = computed(() => unref(agents)); // Unwraps ref and tracks changes
```

Now when `props.agents` updates after the API response, the `computed()`
re-evaluates and all downstream reactive properties (`hasOnlineAgents`,
`isOnline`) update correctly.

## Testing

-  Initial page load shows correct agent status immediately
-  Status changes via WebSocket update correctly  
-  No configuration changes or workarounds needed
-  Tested with network monitoring (Puppeteer) confirming API returns
correct data

## Files Changed

1.
`app/javascript/widget/components/Availability/AvailabilityContainer.vue`
   - Pass `toRef(props, 'agents')` instead of `props.agents`

2. `app/javascript/widget/composables/useAvailability.js`
   - Use `computed(() => unref(agents))` instead of `toRef(agents)`
   - Added explanatory comments

## Related Issues

- #5918 - Similar symptoms, closed with workaround (business hours
toggle) rather than fixing root cause
- #5763 - Different issue (mobile app presence)

This is a genuine Vue 3 reactivity bug affecting all widgets,
independent of business hours configuration.

Co-authored-by: rcoenen <rcoenen@users.noreply.github.com>
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
2025-11-20 20:27:44 +05:30
..
api chore: Limit the number of articles retrieved by widget (#11095) 2025-03-15 14:10:12 -07:00
assets chore: Remove older UI (#11720) 2025-07-01 09:43:44 +05:30
components fix: Widget shows 'away' on initial load despite agents being online (#12869) 2025-11-20 20:27:44 +05:30
composables fix: Widget shows 'away' on initial load despite agents being online (#12869) 2025-11-20 20:27:44 +05:30
constants feat: widget opened and closed events (#11240) 2025-04-24 17:01:39 +05:30
helpers feat: Convert availability slots to local timezone (#12273) 2025-08-22 16:12:24 +05:30
i18n chore: Update translations (#12748) 2025-11-03 15:45:32 +05:30
mixins feat: Migrate availability mixins to composable and helper (#11596) 2025-08-22 00:43:34 +05:30
store feat: Support customizable welcome text, availability messages, and UI toggles (#11891) 2025-07-08 14:26:00 -07:00
views feat: Migrate availability mixins to composable and helper (#11596) 2025-08-22 00:43:34 +05:30
App.vue feat: Migrate availability mixins to composable and helper (#11596) 2025-08-22 00:43:34 +05:30
router.js chore: Add cache to improve widget performance (#11163) 2025-03-24 16:04:49 -07:00